26 double x2,
double *integral );
27static nfu_status ptwXY_integrateWithFunction3(
double x,
double *y,
void *argList );
32 double x2,
double y2,
double *value ) {
35 double r, _sign = 1.0;
36 double ratioX, logX, ratioY, logY, numerator;
46 switch( interpolation ) {
48 *value = 0.5 * ( y1 + y2 ) * ( x2 - x1 );
51 if( ( y1 <= 0. ) || ( y2 <= 0. ) ) {
53 "0 or negative values for log-y integration: y1 = %.17e, y2 = %.17e", y1, y2 );
57 if( fabs( r - 1. ) < 1e-4 ) {
59 *value = y1 * ( x2 - x1 ) / ( 1. + r * ( -0.5 + r * ( 1. / 3. + r * ( -0.25 + .2 * r ) ) ) ); }
61 *value = ( y2 - y1 ) * ( x2 - x1 ) / log( r );
66 if( ( x1 <= 0. ) || ( x2 <= 0. ) ) {
68 "0 or negative values for log-x integration: x1 = %.17e, x2 = %.17e", x1, x2 );
72 if( fabs( r - 1. ) < 1e-4 ) {
74 r = r * ( -0.5 + r * ( 1. / 3. + r * ( -0.25 + .2 * r ) ) );
75 *value = x1 * ( y2 - y1 ) * r / ( 1. + r ) + y2 * ( x2 - x1 ); }
77 *value = ( y1 - y2 ) * ( x2 - x1 ) / log( r ) + x2 * y2 - x1 * y1;
83 if( fabs( ratioX - 1. ) < 1e-4 ) {
85 logX = ratioX * ( 1. + ratioX * ( -0.5 + ratioX * ( 1. / 3. - 0.25 * ratioX ) ) );
92 if( fabs( ratioY - 1. ) < 1e-4 ) {
94 logY = ratioY * ( 1. + ratioY * ( -0.5 + ratioY * ( 1. / 3. - 0.25 * ratioY ) ) );
100 numerator = ratioX * ratioY - 1.0;
101 if( numerator < 1e-4 ) {
102 *value = y1 * x1 * logX * ( 1.0 + 0.5 * numerator * ( 1.0 + numerator * ( 1 + 0.5 * numerator * ( 1 + 19.0 * numerator / 30.0 ) ) / 6.0 ) ); }
104 *value = y1 * x1 * numerator / ( logY / logX + 1.0 );
108 *value = y1 * ( x2 - x1 );
124 int64_t i, n = ptwXY->
length;
125 double dSum, x, y, x1, x2, y1, y2, _sign = 1.;
142 if( domainMax < domainMin ) {
144 domainMin = domainMax;
154 for( i = 0, point = ptwXY->
points; i < n; i++, point++ ) {
155 if( point->
x >= domainMin )
break;
162 if( x2 > domainMin ) {
169 if( x2 > domainMax ) {
187 for( ; i < n; i++, point++ ) {
192 if( x2 > domainMax ) {
230 double domainMin, domainMax;
264 for( i1 = 0; i1 < ptwXY->
length; i1++ ) ptwXY->
points[i1].
y /= sum;
274 double domainMin, domainMax;
297 int64_t i, n = ptwXY->
length;
298 double sum = 0., x, y, x1, x2, y1, y2, _sign = 1., invLog, dx, dy, ratioX, logX, ratioY, logY, numerator;
316 if( domainMax < domainMin ) {
318 domainMin = domainMax;
328 for( i = 0, point = ptwXY->
points; i < n; ++i, ++point ) {
329 if( point->
x >= domainMin )
break;
336 if( x2 > domainMin ) {
349 for( ; i < n; ++i, ++point ) {
354 if( x2 > domainMax ) {
364 sum += 0.5 * ( x2 - x1 ) * y1 * ( x1 + x2 );
367 sum += ( x2 - x1 ) * ( y1 * ( 2 * x1 + x2 ) + y2 * ( x1 + 2 * x2 ) ) / 6.;
373 if( fabs( ratioY - 1 ) < 1e-3 ) {
377 sum2 = x1 * ( 1.0 + 0.5 * ratioY * ( 1.0 + ratioY * ( -1.0 + 0.5 * ratioY * ( 1.0 - 19 * ratioY / 30 ) ) / 6.0 ) );
378 sum2 += 0.5 * ( x2 - x1 ) * ( 1.0 + ratioY * ( 2.0 + 0.25 * ratioY * ( -1.0 + ratioY * ( 7 - 4.25 * ratioY ) / 15.0 ) ) / 3.0 );
379 sum += y1 * ( x2 - x1 ) * sum2;
382 invLog = 1.0 / log( ratioY );
383 sum += dx * invLog * ( dx * ( y2 - dy * invLog ) + x1 * dy );
387 sum += 0.5 * ( x2 - x1 ) * y1 * ( x1 + x2 );
389 if( fabs( ratioX - 1 ) < 1e-3 ) {
391 sum += 0.5 * ( y2 - y1 ) * x1 * ( x2 - x1 ) * ( 1.0 + ratioX * ( 5.0 + ratioX * ratioX * ( 1.0 + ratioX ) / 30.0 ) / 6.0 ); }
393 logX = log( ratioX );
394 sum += 0.25 * ( y2 - y1 ) * x1 * x1 * ( 1.0 + ratioX * ratioX * ( 2.0 * logX - 1.0 ) ) / logX;
399 if( fabs( ratioX - 1. ) < 1e-4 ) {
401 logX = ratioX * ( 1. + ratioX * ( -0.5 + ratioX * ( 1. / 3. - 0.25 * ratioX ) ) );
404 logX = log( ratioX );
408 if( fabs( ratioY - 1. ) < 1e-4 ) {
410 logY = ratioY * ( 1. + ratioY * ( -0.5 + ratioY * ( 1. / 3. - 0.25 * ratioY ) ) );
413 logY = log( ratioY );
416 numerator = ratioX * ratioX * ratioY - 1.0;
417 if( numerator < 1e-4 ) {
418 sum += y1 * x1 * x1 * logX * ( 1.0 + 0.5 * numerator * ( 1.0 + numerator * ( 1 + 0.5 * numerator * ( 1 + 19.0 * numerator / 30.0 ) ) / 6.0 ) ); }
420 sum += y1 * x1 * x1 * numerator / ( logY / logX + 2.0 );
426 if( x2 == domainMax )
break;
429 *value = _sign * sum;
439 double domainMin, domainMax;
462 int64_t i, n = ptwXY->
length;
463 double sum = 0., x, y, x1, x2, y1, y2, _sign = 1., sqrt_x1, sqrt_x2, inv_apb, c;
482 if( domainMax < domainMin ) {
484 domainMin = domainMax;
494 for( i = 0, point = ptwXY->
points; i < n; ++i, ++point ) {
495 if( point->
x >= domainMin )
break;
501 if( x2 > domainMin ) {
514 sqrt_x2 = sqrt( x2 );
515 for( ; i < n; ++i, ++point ) {
521 if( x2 > domainMax ) {
529 sqrt_x2 = sqrt( x2 );
530 inv_apb = sqrt_x1 + sqrt_x2;
531 c = 2. * ( sqrt_x1 * sqrt_x2 + x1 + x2 );
534 sum += ( sqrt_x2 - sqrt_x1 ) * y1 * 2.5 * c;
537 sum += ( sqrt_x2 - sqrt_x1 ) * ( y1 * ( c + x1 * ( 1. + sqrt_x2 / inv_apb ) ) + y2 * ( c + x2 * ( 1. + sqrt_x1 / inv_apb ) ) );
542 if( x2 == domainMax )
break;
545 *value = 2. / 15. * _sign * sum;
556 double x1, y1, x2, y2, y2p, xg1, xg2, sum;
575 if( ptwX_norm == NULL ) {
597 return( groupedData );
600 if( ( groupedData =
ptwX_new( smr, ngs ) ) == NULL )
goto Err;
601 xg1 = groupBoundaries->
points[0];
604 for( igs = 0, i = 1; igs < ngs; igs++ ) {
605 xg2 = groupBoundaries->
points[igs+1];
608 for( ; i < f->
length; i++, x1 = x2, y1 = y2 ) {
610 if( x2 > xg2 )
break;
613 sum += ( y1 + y2p ) * ( x2 - x1 );
618 sum /= ( xg2 - xg1 ); }
620 if( ptwX_norm->
points[igs] == 0. ) {
624 sum /= ptwX_norm->
points[igs];
627 groupedData->
points[igs] = 0.5 * sum;
633 return( groupedData );
638 if( groupedData != NULL )
ptwX_free( groupedData );
649 double x1, fy1, gy1, x2, fy2, gy2, fy2p, gy2p, xg1, xg2, sum;
668 "Other interpolation not supported for integration: source1." );
673 "Other interpolation not supported for integration: source2." );
679 if( ptwX_norm == NULL ) {
696 if( ( ff->length == 0 ) || ( gg->length == 0 ) ) {
701 return( groupedData );
711 if( ( groupedData =
ptwX_new( smr, ngs ) ) == NULL )
goto Err;
712 xg1 = groupBoundaries->
points[0];
715 gy1 = g->points[0].y;
716 for( igs = 0, i = 1; igs < ngs; igs++ ) {
717 xg2 = groupBoundaries->
points[igs+1];
720 for( ; i < f->
length; i++, x1 = x2, fy1 = fy2, gy1 = gy2 ) {
722 if( x2 > xg2 )
break;
725 gy2p = gy2 = g->points[i].y;
727 sum += ( ( fy1 + fy2p ) * ( gy1 + gy2p ) + fy1 * gy1 + fy2p * gy2p ) * ( x2 - x1 );
732 sum /= ( xg2 - xg1 ); }
734 if( ptwX_norm->
points[igs] == 0. ) {
738 sum /= ptwX_norm->
points[igs];
741 groupedData->
points[igs] = sum / 6.;
750 return( groupedData );
758 if( groupedData != NULL )
ptwX_free( groupedData );
769 double x1, fy1, gy1, hy1, x2, fy2, gy2, hy2, fy2p, gy2p, hy2p, xg1, xg2, sum;
770 ptwXYPoints *f = NULL, *ff, *fff = NULL, *g = NULL, *gg = NULL, *h = NULL, *hh = NULL;
805 if( ptwX_norm == NULL ) {
823 if( ( ff->length == 0 ) || ( gg->length == 0 ) || ( hh->length == 0 ) ) {
829 return( groupedData );
840 if( ( groupedData =
ptwX_new( smr, ngs ) ) == NULL )
goto Err;
841 xg1 = groupBoundaries->
points[0];
844 gy1 = g->points[0].y;
845 hy1 = h->points[0].y;
846 for( igs = 0, i = 1; igs < ngs; igs++ ) {
847 xg2 = groupBoundaries->
points[igs+1];
850 for( ; i < f->
length; i++, x1 = x2, fy1 = fy2, gy1 = gy2, hy1 = hy2 ) {
852 if( x2 > xg2 )
break;
855 gy2p = gy2 = g->points[i].y;
857 hy2p = hy2 = h->points[i].y;
859 sum += ( ( fy1 + fy2p ) * ( gy1 + gy2p ) * ( hy1 + hy2p ) + 2 * fy1 * gy1 * hy1 + 2 * fy2p * gy2p * hy2p ) * ( x2 - x1 );
864 sum /= ( xg2 - xg1 ); }
866 if( ptwX_norm->
points[igs] == 0. ) {
870 sum /= ptwX_norm->
points[igs];
873 groupedData->
points[igs] = sum / 12.;
885 return( groupedData );
896 if( groupedData != NULL )
ptwX_free( groupedData );
910 double integral = 0., sum;
917 if( ( runningIntegral =
ptwX_new( smr, ptwXY->
length ) ) == NULL )
goto Err;
919 if( ptwXY->
length == 0 )
return( runningIntegral );
922 for( i = 1; i < ptwXY->
length; i++ ) {
928 return( runningIntegral );
932 if( runningIntegral != NULL )
ptwX_free( runningIntegral );
939 void *argList,
double domainMin,
double domainMax,
int degree,
int recursionLimit,
double tolerance,
double *value ) {
941 int64_t i1, i2, n1 = ptwXY->
length;
943 double integral = 0., integral_, sign = -1., xa, xb;
955 if( domainMin == domainMax )
return(
nfu_Okay );
958 if( domainMin > domainMax ) {
960 domainMin = domainMax;
965 if( domainMax <= ptwXY->points[0].x )
return(
nfu_Okay );
967 for( i1 = 0; i1 < ( n1 - 1 ); i1++ ) {
968 if( ptwXY->
points[i1+1].
x > domainMin )
break;
970 for( i2 = n1 - 1; i2 > i1; i2-- ) {
971 if( ptwXY->
points[i2-1].
x < domainMax )
break;
973 point = &(ptwXY->
points[i1]);
975 integrateWithFunctionInfo.
degree = degree;
976 integrateWithFunctionInfo.
func = func;
977 integrateWithFunctionInfo.
argList = argList;
979 integrateWithFunctionInfo.
x2 = point->
x;
980 integrateWithFunctionInfo.
y2 = point->
y;
983 for( ; i1 < i2; i1++ ) {
984 integrateWithFunctionInfo.
x1 = integrateWithFunctionInfo.
x2;
985 integrateWithFunctionInfo.
y1 = integrateWithFunctionInfo.
y2;
987 integrateWithFunctionInfo.
x2 = point->
x;
988 integrateWithFunctionInfo.
y2 = point->
y;
990 if( xb > domainMax ) xb = domainMax;
991 status =
nf_GnG_adaptiveQuadrature( ptwXY_integrateWithFunction2, ptwXY_integrateWithFunction3, &integrateWithFunctionInfo,
992 xa, xb, recursionLimit, tolerance, &integral_, &evaluations );
997 integral += integral_;
1000 *value = sign * integral;
1008 double x2,
double *integral ) {
1019static nfu_status ptwXY_integrateWithFunction3(
double x,
double *y,
void *argList ) {
1026 integrateWithFunctionInfo->
x1, integrateWithFunctionInfo->
y1,
1027 integrateWithFunctionInfo->
x2, integrateWithFunctionInfo->
y2 ) ) ==
nfu_Okay ) {
1028 status = integrateWithFunctionInfo->
func( NULL, x, y, integrateWithFunctionInfo->
argList );
1039 int64_t i1, length = ptwXY->
length;
1040 double x1, y1, x2, y2, integral, runningIntegral1 = 0., runningIntegral2, nextCDF, dIntegral;
1041 double dx, temp, norm;
1065 if( numberOfBins < 1 ) {
1069 if( ( equalProbableBins =
ptwX_new( smr, numberOfBins ) ) == NULL )
goto Err;
1082 for( i1 = 1; i1 < length; ++i1, ++point ) {
1086 runningIntegral2 = runningIntegral1 + integral;
1087 while( index < numberOfBins ) {
1088 nextCDF = norm * index / (double) numberOfBins;
1089 if( runningIntegral2 < nextCDF )
break;
1090 dIntegral = nextCDF - runningIntegral1;
1093 temp = ( y2 - y1 ) / ( x2 - x1 );
1094 dx = 2. * dIntegral / ( y1 + sqrt( y1 * y1 + 2. * temp * dIntegral ) ); }
1096 dx = dIntegral / y1;
1102 runningIntegral1 = runningIntegral2;
1109 return( equalProbableBins );
1112 if( equalProbableBins != NULL )
ptwX_free( equalProbableBins );
nfu_status nf_Legendre_GaussianQuadrature(int degree, double x1, double x2, nf_Legendre_GaussianQuadrature_callback func, void *argList, double *integral)
nfu_status(* nf_Legendre_GaussianQuadrature_callback)(double x, double *y, void *argList)
nfu_status nf_GnG_adaptiveQuadrature(nf_GnG_adaptiveQuadrature_callback quadratureFunction, nf_Legendre_GaussianQuadrature_callback integrandFunction, void *argList, double x1, double x2, int maxDepth, double tolerance, double *integral, long *evaluations)
@ nfu_unsupportedInterpolation
@ nfu_badIntegrationInput
enum nfu_status_e nfu_status
enum ptwXY_group_normType_e ptwXY_group_normType
nfu_status(* ptwXY_createFromFunction_callback)(statusMessageReporting *smr, double x, double *y, void *argList)
@ ptwXY_group_normType_dx
@ ptwXY_group_normType_norm
ptwXYPoints * ptwXY_intersectionWith_ptwX(statusMessageReporting *smr, ptwXYPoints *ptwXY, ptwXPoints *ptwX)
nfu_status ptwXY_tweakDomainsToMutualify(statusMessageReporting *smr, ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, int epsilonFactor, double epsilon)
enum ptwXY_interpolation_e ptwXY_interpolation
@ ptwXY_interpolationFlat
@ ptwXY_interpolationLinLog
@ ptwXY_interpolationLogLog
@ ptwXY_interpolationLinLin
@ ptwXY_interpolationOther
@ ptwXY_interpolationLogLin
struct ptwXYPoints_s ptwXYPoints
nfu_status ptwXY_interpolatePoint(statusMessageReporting *smr, ptwXY_interpolation interpolation, double x, double *y, double x1, double y1, double x2, double y2)
ptwXYPoints * ptwXY_union(statusMessageReporting *smr, ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, int unionOptions)
struct ptwXYPoint_s ptwXYPoint
ptwXYPoints * ptwXY_free(ptwXYPoints *ptwXY)
nfu_status ptwXY_domainMax(statusMessageReporting *smr, ptwXYPoints *ptwXY, double *value)
nfu_status ptwXY_simpleCoalescePoints(statusMessageReporting *smr, ptwXYPoints *ptwXY)
nfu_status ptwXY_domainMin(statusMessageReporting *smr, ptwXYPoints *ptwXY, double *value)
ptwXPoints * ptwXY_equalProbableBins(statusMessageReporting *smr, ptwXYPoints *ptwXY, int numberOfBins)
nfu_status ptwXY_integrateDomainWithWeight_sqrt_x(statusMessageReporting *smr, ptwXYPoints *ptwXY, double *value)
nfu_status ptwXY_integrateWithFunction(statusMessageReporting *smr, ptwXYPoints *ptwXY, ptwXY_createFromFunction_callback func, void *argList, double domainMin, double domainMax, int degree, int recursionLimit, double tolerance, double *value)
ptwXPoints * ptwXY_runningIntegral(statusMessageReporting *smr, ptwXYPoints *ptwXY)
nfu_status ptwXY_integrateDomainWithWeight_x(statusMessageReporting *smr, ptwXYPoints *ptwXY, double *value)
ptwXPoints * ptwXY_groupTwoFunctions(statusMessageReporting *smr, ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, ptwXPoints *groupBoundaries, ptwXY_group_normType normType, ptwXPoints *ptwX_norm)
nfu_status ptwXY_integrate(statusMessageReporting *smr, ptwXYPoints *ptwXY, double domainMin, double domainMax, double *value)
nfu_status ptwXY_integrateWithWeight_sqrt_x(statusMessageReporting *smr, ptwXYPoints *ptwXY, double domainMin, double domainMax, double *value)
struct ptwXY_integrateWithFunctionInfo_s ptwXY_integrateWithFunctionInfo
nfu_status ptwXY_normalize(statusMessageReporting *smr, ptwXYPoints *ptwXY)
nfu_status ptwXY_f_integrate(statusMessageReporting *smr, ptwXY_interpolation interpolation, double x1, double y1, double x2, double y2, double *value)
ptwXPoints * ptwXY_groupThreeFunctions(statusMessageReporting *smr, ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, ptwXYPoints *ptwXY3, ptwXPoints *groupBoundaries, ptwXY_group_normType normType, ptwXPoints *ptwX_norm)
ptwXPoints * ptwXY_groupOneFunction(statusMessageReporting *smr, ptwXYPoints *ptwXY, ptwXPoints *groupBoundaries, ptwXY_group_normType normType, ptwXPoints *ptwX_norm)
nfu_status ptwXY_integrateDomain(statusMessageReporting *smr, ptwXYPoints *ptwXY, double *value)
nfu_status ptwXY_integrateWithWeight_x(statusMessageReporting *smr, ptwXYPoints *ptwXY, double domainMin, double domainMax, double *value)
int64_t ptwX_length(statusMessageReporting *smr, ptwXPoints *ptwX)
struct ptwXPoints_s ptwXPoints
ptwXPoints * ptwX_createLine(statusMessageReporting *smr, int64_t size, int64_t length, double slope, double offset)
nfu_status ptwX_setPointAtIndex(statusMessageReporting *smr, ptwXPoints *ptwX, int64_t index, double x)
ptwXPoints * ptwX_free(ptwXPoints *ptwX)
ptwXPoints * ptwX_new(statusMessageReporting *smr, int64_t size)
#define smr_setReportError2(smr, libraryID, code, fmt,...)
#define smr_setReportError2p(smr, libraryID, code, fmt)
ptwXY_interpolation interpolation
char const * interpolationString
ptwXY_interpolation interpolation
ptwXY_createFromFunction_callback func