Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
ptwXY_integration.c File Reference
#include <math.h>
#include <float.h>
#include "ptwXY.h"
#include <nf_Legendre.h>
#include <nf_integration.h>

Go to the source code of this file.

Classes

struct  ptwXY_integrateWithFunctionInfo_s

Typedefs

typedef struct ptwXY_integrateWithFunctionInfo_s ptwXY_integrateWithFunctionInfo

Functions

nfu_status ptwXY_f_integrate (statusMessageReporting *smr, ptwXY_interpolation interpolation, double x1, double y1, double x2, double y2, double *value)
nfu_status ptwXY_integrate (statusMessageReporting *smr, ptwXYPoints *ptwXY, double domainMin, double domainMax, double *value)
nfu_status ptwXY_integrateDomain (statusMessageReporting *smr, ptwXYPoints *ptwXY, double *value)
nfu_status ptwXY_normalize (statusMessageReporting *smr, ptwXYPoints *ptwXY)
nfu_status ptwXY_integrateDomainWithWeight_x (statusMessageReporting *smr, ptwXYPoints *ptwXY, double *value)
nfu_status ptwXY_integrateWithWeight_x (statusMessageReporting *smr, ptwXYPoints *ptwXY, double domainMin, double domainMax, double *value)
nfu_status ptwXY_integrateDomainWithWeight_sqrt_x (statusMessageReporting *smr, ptwXYPoints *ptwXY, double *value)
nfu_status ptwXY_integrateWithWeight_sqrt_x (statusMessageReporting *smr, ptwXYPoints *ptwXY, double domainMin, double domainMax, double *value)
ptwXPointsptwXY_groupOneFunction (statusMessageReporting *smr, ptwXYPoints *ptwXY, ptwXPoints *groupBoundaries, ptwXY_group_normType normType, ptwXPoints *ptwX_norm)
ptwXPointsptwXY_groupTwoFunctions (statusMessageReporting *smr, ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, ptwXPoints *groupBoundaries, ptwXY_group_normType normType, ptwXPoints *ptwX_norm)
ptwXPointsptwXY_groupThreeFunctions (statusMessageReporting *smr, ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, ptwXYPoints *ptwXY3, ptwXPoints *groupBoundaries, ptwXY_group_normType normType, ptwXPoints *ptwX_norm)
ptwXPointsptwXY_runningIntegral (statusMessageReporting *smr, ptwXYPoints *ptwXY)
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)
ptwXPointsptwXY_equalProbableBins (statusMessageReporting *smr, ptwXYPoints *ptwXY, int numberOfBins)

Typedef Documentation

◆ ptwXY_integrateWithFunctionInfo

Function Documentation

◆ ptwXY_equalProbableBins()

ptwXPoints * ptwXY_equalProbableBins ( statusMessageReporting * smr,
ptwXYPoints * ptwXY,
int numberOfBins )

Definition at line 1036 of file ptwXY_integration.c.

1036 {
1037
1038 int index = 1;
1039 int64_t i1, length = ptwXY->length;
1040 double x1, y1, x2, y2, integral, runningIntegral1 = 0., runningIntegral2, nextCDF, dIntegral;
1041 double dx, temp, norm;
1042 ptwXYPoint *point;
1043 ptwXPoints *equalProbableBins = NULL;
1044
1045 if( ptwXY->status != nfu_Okay ) {
1047 goto Err;
1048 }
1049
1050 switch( ptwXY->interpolation ) {
1053 break;
1054 default :
1056 "interpolation = %d not supported", ptwXY->interpolation );
1057 goto Err;
1058 }
1059
1060 if( length < 2 ) {
1061 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_tooFewPoints, "number of points = %lld < 2", length );
1062 goto Err;
1063 }
1064
1065 if( numberOfBins < 1 ) {
1066 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_badInput, "numberOfBins = %d < 1", numberOfBins );
1067 goto Err;
1068 }
1069 if( ( equalProbableBins = ptwX_new( smr, numberOfBins ) ) == NULL ) goto Err;
1070
1071 if( ptwXY_integrateDomain( smr, ptwXY, &norm ) != nfu_Okay ) goto Err;
1072 if( norm <= 0 ) {
1073 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_badNorm, "norm = %e <= 0", norm );
1074 goto Err;
1075 }
1076
1077 point = ptwXY->points;
1078 x1 = point->x;
1079 y1 = point->y;
1080 ++point;
1081 if( ptwX_setPointAtIndex( smr, equalProbableBins, 0, x1 ) != nfu_Okay ) goto Err;
1082 for( i1 = 1; i1 < length; ++i1, ++point ) {
1083 x2 = point->x;
1084 y2 = point->y;
1085 if( ptwXY_f_integrate( smr, ptwXY->interpolation, x1, y1, x2, y2, &integral ) != nfu_Okay ) goto Err;
1086 runningIntegral2 = runningIntegral1 + integral;
1087 while( index < numberOfBins ) {
1088 nextCDF = norm * index / (double) numberOfBins;
1089 if( runningIntegral2 < nextCDF ) break;
1090 dIntegral = nextCDF - runningIntegral1;
1091
1093 temp = ( y2 - y1 ) / ( x2 - x1 ); /* slope. */
1094 dx = 2. * dIntegral / ( y1 + sqrt( y1 * y1 + 2. * temp * dIntegral ) ); }
1095 else {
1096 dx = dIntegral / y1;
1097 }
1098
1099 if( ptwX_setPointAtIndex( smr, equalProbableBins, index, dx + x1 ) != nfu_Okay ) goto Err;
1100 ++index;
1101 }
1102 runningIntegral1 = runningIntegral2;
1103
1104 x1 = x2;
1105 y1 = y2;
1106 }
1107 if( ptwX_setPointAtIndex( smr, equalProbableBins, index, x2 ) != nfu_Okay ) goto Err;
1108
1109 return( equalProbableBins );
1110
1111Err:
1112 if( equalProbableBins != NULL ) ptwX_free( equalProbableBins );
1113 return( NULL );
1114}
@ nfu_unsupportedInterpolation
@ nfu_Okay
@ nfu_badSelf
@ nfu_badNorm
@ nfu_tooFewPoints
@ nfu_badInput
int nfu_SMR_libraryID
@ ptwXY_interpolationFlat
Definition ptwXY.h:38
@ ptwXY_interpolationLinLin
Definition ptwXY.h:37
struct ptwXYPoint_s ptwXYPoint
nfu_status ptwXY_f_integrate(statusMessageReporting *smr, ptwXY_interpolation interpolation, double x1, double y1, double x2, double y2, double *value)
nfu_status ptwXY_integrateDomain(statusMessageReporting *smr, ptwXYPoints *ptwXY, double *value)
struct ptwXPoints_s ptwXPoints
nfu_status ptwX_setPointAtIndex(statusMessageReporting *smr, ptwXPoints *ptwX, int64_t index, double x)
Definition ptwX_core.c:304
ptwXPoints * ptwX_free(ptwXPoints *ptwX)
Definition ptwX_core.c:213
ptwXPoints * ptwX_new(statusMessageReporting *smr, int64_t size)
Definition ptwX_core.c:22
#define smr_setReportError2(smr, libraryID, code, fmt,...)
#define smr_setReportError2p(smr, libraryID, code, fmt)
double y
Definition ptwXY.h:64
double x
Definition ptwXY.h:64
ptwXYPoint * points
Definition ptwXY.h:93
ptwXY_interpolation interpolation
Definition ptwXY.h:81
int64_t length
Definition ptwXY.h:87
nfu_status status
Definition ptwXY.h:80

◆ ptwXY_f_integrate()

nfu_status ptwXY_f_integrate ( statusMessageReporting * smr,
ptwXY_interpolation interpolation,
double x1,
double y1,
double x2,
double y2,
double * value )

Definition at line 31 of file ptwXY_integration.c.

32 {
33
34 nfu_status status = nfu_Okay;
35 double r, _sign = 1.0;
36 double ratioX, logX, ratioY, logY, numerator;
37
38 if( x2 < x1 ) {
39 double x = x1;
40 x1 = x2;
41 x2 = x;
42 _sign = -1.;
43 }
44
45 *value = 0.;
46 switch( interpolation ) {
47 case ptwXY_interpolationLinLin : /* x linear, y linear */
48 *value = 0.5 * ( y1 + y2 ) * ( x2 - x1 );
49 break;
50 case ptwXY_interpolationLogLin : /* x linear, y log */
51 if( ( y1 <= 0. ) || ( y2 <= 0. ) ) {
53 "0 or negative values for log-y integration: y1 = %.17e, y2 = %.17e", y1, y2 );
54 status = nfu_badIntegrationInput; }
55 else {
56 r = y2 / y1;
57 if( fabs( r - 1. ) < 1e-4 ) {
58 r = r - 1.;
59 *value = y1 * ( x2 - x1 ) / ( 1. + r * ( -0.5 + r * ( 1. / 3. + r * ( -0.25 + .2 * r ) ) ) ); }
60 else {
61 *value = ( y2 - y1 ) * ( x2 - x1 ) / log( r );
62 }
63 }
64 break;
65 case ptwXY_interpolationLinLog : /* x log, y linear */
66 if( ( x1 <= 0. ) || ( x2 <= 0. ) ) {
68 "0 or negative values for log-x integration: x1 = %.17e, x2 = %.17e", x1, x2 );
69 status = nfu_badIntegrationInput; }
70 else {
71 r = x2 / x1;
72 if( fabs( r - 1. ) < 1e-4 ) {
73 r = r - 1.;
74 r = r * ( -0.5 + r * ( 1. / 3. + r * ( -0.25 + .2 * r ) ) );
75 *value = x1 * ( y2 - y1 ) * r / ( 1. + r ) + y2 * ( x2 - x1 ); }
76 else {
77 *value = ( y1 - y2 ) * ( x2 - x1 ) / log( r ) + x2 * y2 - x1 * y1;
78 }
79 }
80 break;
81 case ptwXY_interpolationLogLog : /* x log, y log */
82 ratioX = x2 / x1;
83 if( fabs( ratioX - 1. ) < 1e-4 ) {
84 ratioX -= 1.0;
85 logX = ratioX * ( 1. + ratioX * ( -0.5 + ratioX * ( 1. / 3. - 0.25 * ratioX ) ) );
86 ratioX = x2 / x1; }
87 else {
88 logX = log( ratioX );
89 }
90
91 ratioY = y2 / y1;
92 if( fabs( ratioY - 1. ) < 1e-4 ) {
93 ratioY -= 1.0;
94 logY = ratioY * ( 1. + ratioY * ( -0.5 + ratioY * ( 1. / 3. - 0.25 * ratioY ) ) );
95 ratioY = y2 / y1; }
96 else {
97 logY = log( ratioY );
98 }
99
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 ) ); }
103 else {
104 *value = y1 * x1 * numerator / ( logY / logX + 1.0 );
105 }
106 break;
107 case ptwXY_interpolationFlat : /* x ?, y flat */
108 *value = y1 * ( x2 - x1 );
109 break;
111 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_otherInterpolation, "Other interpolation not supported for integration." );
112 status = nfu_otherInterpolation;
113 }
114
115 *value *= _sign;
116
117 return( status );
118}
@ nfu_badIntegrationInput
@ nfu_otherInterpolation
enum nfu_status_e nfu_status
@ ptwXY_interpolationLinLog
Definition ptwXY.h:37
@ ptwXY_interpolationLogLog
Definition ptwXY.h:38
@ ptwXY_interpolationOther
Definition ptwXY.h:38
@ ptwXY_interpolationLogLin
Definition ptwXY.h:37

Referenced by ptwXY_equalProbableBins(), ptwXY_integrate(), and ptwXY_runningIntegral().

◆ ptwXY_groupOneFunction()

ptwXPoints * ptwXY_groupOneFunction ( statusMessageReporting * smr,
ptwXYPoints * ptwXY,
ptwXPoints * groupBoundaries,
ptwXY_group_normType normType,
ptwXPoints * ptwX_norm )

Definition at line 552 of file ptwXY_integration.c.

553 {
554
555 int64_t i, igs, ngs;
556 double x1, y1, x2, y2, y2p, xg1, xg2, sum;
557 ptwXYPoints *f;
558 ptwXPoints *groupedData = NULL;
559
560 if( ptwXY_simpleCoalescePoints( smr, ptwXY ) != nfu_Okay ) {
562 return( NULL );
563 }
564 if( groupBoundaries->status != nfu_Okay ) {
565 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Via: groupBoundaries." );
566 return( NULL );
567 }
569 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_otherInterpolation, "Other interpolation not supported for integration." );
570 return( NULL );
571 }
572
573 ngs = ptwX_length( smr, groupBoundaries ) - 1;
574 if( normType == ptwXY_group_normType_norm ) {
575 if( ptwX_norm == NULL ) {
576 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badNorm, "Norm function required but is NULL." );
577 return( NULL );
578 }
579 if( ptwX_norm->status != nfu_Okay ) {
581 return( NULL );
582 }
583 if( ptwX_length( smr, ptwX_norm ) != ngs ) {
584 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_badNorm, "Norm length = %d but there are %d groups.",
585 (int) ptwX_length( NULL, ptwX_norm ), (int) ngs );
586 return( NULL );
587 }
588 }
589
590 if( ( f = ptwXY_intersectionWith_ptwX( smr, ptwXY, groupBoundaries ) ) == NULL ) {
592 return( NULL );
593 }
594 if( f->length == 0 ) {
595 groupedData = ptwX_createLine( smr, ngs, ngs, 0, 0 );
596 if( groupedData == NULL ) smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_Error, "Via." );
597 return( groupedData );
598 }
599
600 if( ( groupedData = ptwX_new( smr, ngs ) ) == NULL ) goto Err;
601 xg1 = groupBoundaries->points[0];
602 x1 = f->points[0].x;
603 y1 = f->points[0].y;
604 for( igs = 0, i = 1; igs < ngs; igs++ ) {
605 xg2 = groupBoundaries->points[igs+1];
606 sum = 0;
607 if( xg2 > x1 ) {
608 for( ; i < f->length; i++, x1 = x2, y1 = y2 ) {
609 x2 = f->points[i].x;
610 if( x2 > xg2 ) break;
611 y2p = y2 = f->points[i].y;
612 if( f->interpolation == ptwXY_interpolationFlat ) y2p = y1;
613 sum += ( y1 + y2p ) * ( x2 - x1 );
614 }
615 }
616 if( sum != 0. ) {
617 if( normType == ptwXY_group_normType_dx ) {
618 sum /= ( xg2 - xg1 ); }
619 else if( normType == ptwXY_group_normType_norm ) {
620 if( ptwX_norm->points[igs] == 0. ) {
621 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_divByZero, "Divide by 0. Norm at index %d is 0.", (int) igs );
622 goto Err;
623 }
624 sum /= ptwX_norm->points[igs];
625 }
626 }
627 groupedData->points[igs] = 0.5 * sum;
628 groupedData->length++;
629 xg1 = xg2;
630 }
631
632 ptwXY_free( f );
633 return( groupedData );
634
635Err:
637 ptwXY_free( f );
638 if( groupedData != NULL ) ptwX_free( groupedData );
639 return( NULL );
640}
@ nfu_Error
@ nfu_divByZero
@ ptwXY_group_normType_dx
Definition ptwXY.h:31
@ ptwXY_group_normType_norm
Definition ptwXY.h:31
ptwXYPoints * ptwXY_intersectionWith_ptwX(statusMessageReporting *smr, ptwXYPoints *ptwXY, ptwXPoints *ptwX)
struct ptwXYPoints_s ptwXYPoints
ptwXYPoints * ptwXY_free(ptwXYPoints *ptwXY)
Definition ptwXY_core.c:782
nfu_status ptwXY_simpleCoalescePoints(statusMessageReporting *smr, ptwXYPoints *ptwXY)
Definition ptwXY_core.c:734
int64_t ptwX_length(statusMessageReporting *smr, ptwXPoints *ptwX)
Definition ptwX_core.c:222
ptwXPoints * ptwX_createLine(statusMessageReporting *smr, int64_t size, int64_t length, double slope, double offset)
Definition ptwX_core.c:71
nfu_status status
Definition ptwX.h:28
int64_t length
Definition ptwX.h:29
double * points
Definition ptwX.h:32

Referenced by GIDI::multiGroupXYs1d(), and GIDI::Transporting::Flux::process().

◆ ptwXY_groupThreeFunctions()

ptwXPoints * ptwXY_groupThreeFunctions ( statusMessageReporting * smr,
ptwXYPoints * ptwXY1,
ptwXYPoints * ptwXY2,
ptwXYPoints * ptwXY3,
ptwXPoints * groupBoundaries,
ptwXY_group_normType normType,
ptwXPoints * ptwX_norm )

Definition at line 764 of file ptwXY_integration.c.

765 {
766
767 int64_t i, igs, ngs;
768 nfu_status status = nfu_Okay;
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;
771 ptwXPoints *groupedData = NULL;
772
773 if( ptwXY_simpleCoalescePoints( smr, ptwXY1 ) != nfu_Okay ) {
774 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_Error, "Via: source1." );
775 return( NULL );
776 }
777 if( ptwXY_simpleCoalescePoints( smr, ptwXY2 ) != nfu_Okay ) {
778 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_Error, "Via: source2." );
779 return( NULL );
780 }
781 if( ptwXY_simpleCoalescePoints( smr, ptwXY3 ) != nfu_Okay ) {
782 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_Error, "Via: source3." );
783 return( NULL );
784 }
785 if( groupBoundaries->status != nfu_Okay ) {
786 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Via: groupBoundaries." );
787 return( NULL );
788 }
789
790 if( ptwXY1->interpolation == ptwXY_interpolationOther ) {
791 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_otherInterpolation, "Other interpolation not supported for integration: source1." );
792 return( NULL );
793 }
794 if( ptwXY2->interpolation == ptwXY_interpolationOther ) {
795 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_otherInterpolation, "Other interpolation not supported for integration: source2." );
796 return( NULL );
797 }
798 if( ptwXY3->interpolation == ptwXY_interpolationOther ) {
799 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_otherInterpolation, "Other interpolation not supported for integration: source3." );
800 return( NULL );
801 }
802
803 ngs = ptwX_length( smr, groupBoundaries ) - 1;
804 if( normType == ptwXY_group_normType_norm ) {
805 if( ptwX_norm == NULL ) {
806 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badNorm, "Norm function required but is NULL." );
807 return( NULL );
808 }
809 if( ptwX_norm->status != nfu_Okay ) {
811 return( NULL );
812 }
813 if( ptwX_length( smr, ptwX_norm ) != ngs ) {
814 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_badNorm, "Norm length = %d but there are %d groups.",
815 (int) ptwX_length( NULL, ptwX_norm ), (int) ngs );
816 return( NULL );
817 }
818 }
819
820 if( ( ff = ptwXY_intersectionWith_ptwX( smr, ptwXY1, groupBoundaries ) ) == NULL ) goto Err;
821 if( ( gg = ptwXY_intersectionWith_ptwX( smr, ptwXY2, groupBoundaries ) ) == NULL ) goto Err;
822 if( ( hh = ptwXY_intersectionWith_ptwX( smr, ptwXY3, groupBoundaries ) ) == NULL ) goto Err;
823 if( ( ff->length == 0 ) || ( gg->length == 0 ) || ( hh->length == 0 ) ) {
824 ptwXY_free( ff );
825 ptwXY_free( gg );
826 ptwXY_free( hh );
827 groupedData = ptwX_createLine( smr, ngs, ngs, 0, 0 );
828 if( groupedData == NULL ) smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_Error, "Via." );
829 return( groupedData );
830 }
831
832 if( ( status = ptwXY_tweakDomainsToMutualify( smr, ff, gg, 4, 0 ) ) != nfu_Okay ) goto Err2;
833 if( ( status = ptwXY_tweakDomainsToMutualify( smr, ff, hh, 4, 0 ) ) != nfu_Okay ) goto Err2;
834 if( ( status = ptwXY_tweakDomainsToMutualify( smr, gg, hh, 4, 0 ) ) != nfu_Okay ) goto Err2;
835 if( ( fff = ptwXY_union( smr, ff, gg, ptwXY_union_fill ) ) == NULL ) goto Err;
836 if( ( h = ptwXY_union( smr, hh, fff, ptwXY_union_fill ) ) == NULL ) goto Err;
837 if( ( f = ptwXY_union( smr, fff, h, ptwXY_union_fill ) ) == NULL ) goto Err;
838 if( ( g = ptwXY_union( smr, gg, h, ptwXY_union_fill ) ) == NULL ) goto Err;
839
840 if( ( groupedData = ptwX_new( smr, ngs ) ) == NULL ) goto Err;
841 xg1 = groupBoundaries->points[0];
842 x1 = f->points[0].x;
843 fy1 = f->points[0].y;
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];
848 sum = 0;
849 if( xg2 > x1 ) {
850 for( ; i < f->length; i++, x1 = x2, fy1 = fy2, gy1 = gy2, hy1 = hy2 ) {
851 x2 = f->points[i].x;
852 if( x2 > xg2 ) break;
853 fy2p = fy2 = f->points[i].y;
854 if( f->interpolation == ptwXY_interpolationFlat ) fy2p = fy1;
855 gy2p = gy2 = g->points[i].y;
856 if( g->interpolation == ptwXY_interpolationFlat ) gy2p = gy1;
857 hy2p = hy2 = h->points[i].y;
858 if( h->interpolation == ptwXY_interpolationFlat ) hy2p = hy1;
859 sum += ( ( fy1 + fy2p ) * ( gy1 + gy2p ) * ( hy1 + hy2p ) + 2 * fy1 * gy1 * hy1 + 2 * fy2p * gy2p * hy2p ) * ( x2 - x1 );
860 }
861 }
862 if( sum != 0. ) {
863 if( normType == ptwXY_group_normType_dx ) {
864 sum /= ( xg2 - xg1 ); }
865 else if( normType == ptwXY_group_normType_norm ) {
866 if( ptwX_norm->points[igs] == 0. ) {
867 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_divByZero, "Divide by 0. Norm at index %d is 0.", (int) igs );
868 goto Err;
869 }
870 sum /= ptwX_norm->points[igs];
871 }
872 }
873 groupedData->points[igs] = sum / 12.;
874 groupedData->length++;
875 xg1 = xg2;
876 }
877
878 ptwXY_free( f );
879 ptwXY_free( g );
880 ptwXY_free( h );
881 ptwXY_free( ff );
882 ptwXY_free( gg );
883 ptwXY_free( hh );
884 ptwXY_free( fff );
885 return( groupedData );
886
887Err:
889 if( fff != NULL ) ptwXY_free( fff );
890 if( ff != NULL ) ptwXY_free( ff );
891 if( gg != NULL ) ptwXY_free( gg );
892 if( hh != NULL ) ptwXY_free( hh );
893 if( f != NULL ) ptwXY_free( f );
894 if( g != NULL ) ptwXY_free( g );
895 if( h != NULL ) ptwXY_free( h );
896 if( groupedData != NULL ) ptwX_free( groupedData );
897 return( NULL );
898
899Err2:
900 smr_setReportError2p( smr, nfu_SMR_libraryID, status, "ptwXY_tweakDomainsToMutualify failed: most likely functions cannot be mutualified by tweaking." );
901 goto Err;
902}
nfu_status ptwXY_tweakDomainsToMutualify(statusMessageReporting *smr, ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, int epsilonFactor, double epsilon)
#define ptwXY_union_fill
Definition ptwXY.h:34
ptwXYPoints * ptwXY_union(statusMessageReporting *smr, ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, int unionOptions)

Referenced by GIDI::multiGroupTwoXYs1ds().

◆ ptwXY_groupTwoFunctions()

ptwXPoints * ptwXY_groupTwoFunctions ( statusMessageReporting * smr,
ptwXYPoints * ptwXY1,
ptwXYPoints * ptwXY2,
ptwXPoints * groupBoundaries,
ptwXY_group_normType normType,
ptwXPoints * ptwX_norm )

Definition at line 644 of file ptwXY_integration.c.

645 {
646
647 int64_t i, igs, ngs;
648 nfu_status status = nfu_Okay;
649 double x1, fy1, gy1, x2, fy2, gy2, fy2p, gy2p, xg1, xg2, sum;
650 ptwXYPoints *f = NULL, *ff, *g = NULL, *gg = NULL;
651 ptwXPoints *groupedData = NULL;
652
653 if( ptwXY_simpleCoalescePoints( smr, ptwXY1 ) != nfu_Okay ) {
654 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_Error, "Via: source1." );
655 return( NULL );
656 }
657 if( ptwXY_simpleCoalescePoints( smr, ptwXY2 ) != nfu_Okay ) {
658 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_Error, "Via: source2." );
659 return( NULL );
660 }
661 if( groupBoundaries->status != nfu_Okay ) {
662 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Via: groupBoundaries." );
663 return( NULL );
664 }
665
666 if( ptwXY1->interpolation == ptwXY_interpolationOther ) {
668 "Other interpolation not supported for integration: source1." );
669 return( NULL );
670 }
671 if( ptwXY2->interpolation == ptwXY_interpolationOther ) {
673 "Other interpolation not supported for integration: source2." );
674 return( NULL );
675 }
676
677 ngs = ptwX_length( smr, groupBoundaries ) - 1;
678 if( normType == ptwXY_group_normType_norm ) {
679 if( ptwX_norm == NULL ) {
680 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badNorm, "Norm function required but is NULL." );
681 return( NULL );
682 }
683 if( ptwX_norm->status != nfu_Okay ) {
685 return( NULL );
686 }
687 if( ptwX_length( smr, ptwX_norm ) != ngs ) {
688 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_badNorm, "Norm length = %d but there are %d groups.",
689 (int) ptwX_length( NULL, ptwX_norm ), (int) ngs );
690 return( NULL );
691 }
692 }
693
694 if( ( ff = ptwXY_intersectionWith_ptwX( smr, ptwXY1, groupBoundaries ) ) == NULL ) goto Err;
695 if( ( gg = ptwXY_intersectionWith_ptwX( smr, ptwXY2, groupBoundaries ) ) == NULL ) goto Err;
696 if( ( ff->length == 0 ) || ( gg->length == 0 ) ) {
697 ptwXY_free( ff );
698 ptwXY_free( gg );
699 groupedData = ptwX_createLine( smr, ngs, ngs, 0, 0 );
700 if( groupedData == NULL ) smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_Error, "Via." );
701 return( groupedData );
702 }
703
704 if( ( status = ptwXY_tweakDomainsToMutualify( smr, ff, gg, 4, 0 ) ) != nfu_Okay ) {
705 smr_setReportError2p( smr, nfu_SMR_libraryID, status, "ptwXY_tweakDomainsToMutualify failed: most likely functions cannot be mutualified by tweaking." );
706 goto Err;
707 }
708 if( ( f = ptwXY_union( smr, ff, gg, ptwXY_union_fill ) ) == NULL ) goto Err;
709 if( ( g = ptwXY_union( smr, gg, f, ptwXY_union_fill ) ) == NULL ) goto Err;
710
711 if( ( groupedData = ptwX_new( smr, ngs ) ) == NULL ) goto Err;
712 xg1 = groupBoundaries->points[0];
713 x1 = f->points[0].x;
714 fy1 = f->points[0].y;
715 gy1 = g->points[0].y;
716 for( igs = 0, i = 1; igs < ngs; igs++ ) {
717 xg2 = groupBoundaries->points[igs+1];
718 sum = 0;
719 if( xg2 > x1 ) {
720 for( ; i < f->length; i++, x1 = x2, fy1 = fy2, gy1 = gy2 ) {
721 x2 = f->points[i].x;
722 if( x2 > xg2 ) break;
723 fy2p = fy2 = f->points[i].y;
724 if( f->interpolation == ptwXY_interpolationFlat ) fy2p = fy1;
725 gy2p = gy2 = g->points[i].y;
726 if( g->interpolation == ptwXY_interpolationFlat ) gy2p = gy1;
727 sum += ( ( fy1 + fy2p ) * ( gy1 + gy2p ) + fy1 * gy1 + fy2p * gy2p ) * ( x2 - x1 );
728 }
729 }
730 if( sum != 0. ) {
731 if( normType == ptwXY_group_normType_dx ) {
732 sum /= ( xg2 - xg1 ); }
733 else if( normType == ptwXY_group_normType_norm ) {
734 if( ptwX_norm->points[igs] == 0. ) {
735 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_divByZero, "Divide by 0. Norm at index %d is 0.", (int) igs );
736 goto Err;
737 }
738 sum /= ptwX_norm->points[igs];
739 }
740 }
741 groupedData->points[igs] = sum / 6.;
742 groupedData->length++;
743 xg1 = xg2;
744 }
745
746 ptwXY_free( f );
747 ptwXY_free( g );
748 ptwXY_free( ff );
749 ptwXY_free( gg );
750 return( groupedData );
751
752Err:
754 if( ff != NULL ) ptwXY_free( ff );
755 if( gg != NULL ) ptwXY_free( gg );
756 if( f != NULL ) ptwXY_free( f );
757 if( g != NULL ) ptwXY_free( g );
758 if( groupedData != NULL ) ptwX_free( groupedData );
759 return( NULL );
760}

Referenced by GIDI::multiGroupXYs1d().

◆ ptwXY_integrate()

nfu_status ptwXY_integrate ( statusMessageReporting * smr,
ptwXYPoints * ptwXY,
double domainMin,
double domainMax,
double * value )

Definition at line 122 of file ptwXY_integration.c.

122 {
123
124 int64_t i, n = ptwXY->length;
125 double dSum, x, y, x1, x2, y1, y2, _sign = 1.;
126 ptwXYPoint *point;
127 nfu_status status;
128
129 *value = 0.;
130
131 if( ptwXY->status != nfu_Okay ) {
133 return( nfu_badSelf );
134 }
136 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_otherInterpolation, "Other interpolation not supported for integration." );
137 return( nfu_otherInterpolation );
138 }
139
140 if( n < 2 ) return( nfu_Okay );
141
142 if( domainMax < domainMin ) {
143 x = domainMin;
144 domainMin = domainMax;
145 domainMax = x;
146 _sign = -1.;
147 }
148
149 if( ( status = ptwXY_simpleCoalescePoints( smr, ptwXY ) ) != nfu_Okay ) {
151 return( status );
152 }
153
154 for( i = 0, point = ptwXY->points; i < n; i++, point++ ) {
155 if( point->x >= domainMin ) break;
156 }
157 if( i == n ) return( nfu_Okay );
158
159 x2 = point->x;
160 y2 = point->y;
161 if( i > 0 ) {
162 if( x2 > domainMin ) {
163 x1 = point[-1].x;
164 y1 = point[-1].y;
165 if( ( status = ptwXY_interpolatePoint( smr, ptwXY->interpolation, domainMin, &y, x1, y1, x2, y2 ) ) != nfu_Okay ) {
167 return( status );
168 }
169 if( x2 > domainMax ) {
170 double rangeMax;
171
172 if( ( status = ptwXY_interpolatePoint( smr, ptwXY->interpolation, domainMax, &rangeMax, x1, y1, x2, y2 ) ) == nfu_Okay ) {
173 status = ptwXY_f_integrate( smr, ptwXY->interpolation, domainMin, y, domainMax, rangeMax, value );
174 }
175 if( status != nfu_Okay ) smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Via." );
176 return( status ); }
177 else {
178 if( ( status = ptwXY_f_integrate( smr, ptwXY->interpolation, domainMin, y, x2, y2, value ) ) != nfu_Okay ) {
180 return( status );
181 }
182 }
183 }
184 }
185 i++;
186 point++;
187 for( ; i < n; i++, point++ ) {
188 x1 = x2;
189 y1 = y2;
190 x2 = point->x;
191 y2 = point->y;
192 if( x2 > domainMax ) {
193 if( ( status = ptwXY_interpolatePoint( smr, ptwXY->interpolation, domainMax, &y, x1, y1, x2, y2 ) ) != nfu_Okay ) {
195 return( status );
196 }
197 if( ( status = ptwXY_f_integrate( smr, ptwXY->interpolation, x1, y1, domainMax, y, &dSum ) ) != nfu_Okay ) {
199 return( status );
200 }
201 *value += dSum;
202 break;
203 }
204 if( ( status = ptwXY_f_integrate( smr, ptwXY->interpolation, x1, y1, x2, y2, &dSum ) ) != nfu_Okay ) {
206 return( status );
207 }
208 *value += dSum;
209 }
210
211 *value *= _sign;
212
213 return( nfu_Okay );
214}
nfu_status ptwXY_interpolatePoint(statusMessageReporting *smr, ptwXY_interpolation interpolation, double x, double *y, double x1, double y1, double x2, double y2)

Referenced by GIDI::Functions::XYs1d::integrate(), and ptwXY_integrateDomain().

◆ ptwXY_integrateDomain()

nfu_status ptwXY_integrateDomain ( statusMessageReporting * smr,
ptwXYPoints * ptwXY,
double * value )

Definition at line 218 of file ptwXY_integration.c.

218 {
219
220 nfu_status status = nfu_Okay;
221
222 *value = 0;
223
224 if( ptwXY->status != nfu_Okay ) {
226 return( nfu_badSelf );
227 }
228
229 if( ptwXY->length > 0 ) {
230 double domainMin, domainMax;
231
232 if( ptwXY_domainMin( smr, ptwXY, &domainMin ) != nfu_Okay ) smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Via." );
233 if( ptwXY_domainMax( smr, ptwXY, &domainMax ) != nfu_Okay ) smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Via." );
234 if( ( status = ptwXY_integrate( smr, ptwXY, domainMin, domainMax, value ) ) != nfu_Okay )
236 }
237 return( status );
238}
nfu_status ptwXY_domainMax(statusMessageReporting *smr, ptwXYPoints *ptwXY, double *value)
nfu_status ptwXY_domainMin(statusMessageReporting *smr, ptwXYPoints *ptwXY, double *value)
nfu_status ptwXY_integrate(statusMessageReporting *smr, ptwXYPoints *ptwXY, double domainMin, double domainMax, double *value)

Referenced by GIDI::Functions::XYs1d::normalize(), ptwXY_equalProbableBins(), and ptwXY_normalize().

◆ ptwXY_integrateDomainWithWeight_sqrt_x()

nfu_status ptwXY_integrateDomainWithWeight_sqrt_x ( statusMessageReporting * smr,
ptwXYPoints * ptwXY,
double * value )

Definition at line 436 of file ptwXY_integration.c.

436 {
437
438 nfu_status status;
439 double domainMin, domainMax;
440
441 *value = 0.;
442
443 if( ptwXY->status != nfu_Okay ) {
445 return( nfu_badSelf );
446 }
447
448 if( ptwXY->length < 2 ) return( nfu_Okay );
449
450 if( ptwXY_domainMin( smr, ptwXY, &domainMin ) != nfu_Okay ) smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Via." );
451 if( ptwXY_domainMax( smr, ptwXY, &domainMax ) != nfu_Okay ) smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Via." );
452 if( ( status = ptwXY_integrateWithWeight_sqrt_x( smr, ptwXY, domainMin, domainMax, value ) ) != nfu_Okay )
454 return( status );
455}
nfu_status ptwXY_integrateWithWeight_sqrt_x(statusMessageReporting *smr, ptwXYPoints *ptwXY, double domainMin, double domainMax, double *value)

◆ ptwXY_integrateDomainWithWeight_x()

nfu_status ptwXY_integrateDomainWithWeight_x ( statusMessageReporting * smr,
ptwXYPoints * ptwXY,
double * value )

Definition at line 271 of file ptwXY_integration.c.

271 {
272
273 nfu_status status = nfu_Okay;
274 double domainMin, domainMax;
275
276 *value = 0.;
277
278 if( ptwXY->status != nfu_Okay ) {
280 return( nfu_badSelf );
281 }
282
283 if( ptwXY->length < 2 ) return( nfu_Okay );
284
285 if( ptwXY_domainMin( smr, ptwXY, &domainMin ) != nfu_Okay ) smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Via." );
286 if( ptwXY_domainMax( smr, ptwXY, &domainMax ) != nfu_Okay ) smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Via." );
287 if( ( status = ptwXY_integrateWithWeight_x( smr, ptwXY, domainMin, domainMax, value ) ) != nfu_Okay )
289 return( status );
290}
nfu_status ptwXY_integrateWithWeight_x(statusMessageReporting *smr, ptwXYPoints *ptwXY, double domainMin, double domainMax, double *value)

◆ ptwXY_integrateWithFunction()

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 )

Definition at line 938 of file ptwXY_integration.c.

939 {
940
941 int64_t i1, i2, n1 = ptwXY->length;
942 long evaluations;
943 double integral = 0., integral_, sign = -1., xa, xb;
944 ptwXY_integrateWithFunctionInfo integrateWithFunctionInfo;
945 ptwXYPoint *point;
946 nfu_status status;
947
948 *value = 0;
949
950 if( ptwXY_simpleCoalescePoints( smr, ptwXY ) != nfu_Okay ) {
952 return( nfu_Error );
953 }
954
955 if( domainMin == domainMax ) return( nfu_Okay );
956 if( n1 < 2 ) return( nfu_Okay );
957
958 if( domainMin > domainMax ) {
959 sign = domainMin;
960 domainMin = domainMax;
961 domainMax = sign;
962 sign = -1.;
963 }
964 if( domainMin >= ptwXY->points[n1-1].x ) return( nfu_Okay );
965 if( domainMax <= ptwXY->points[0].x ) return( nfu_Okay );
966
967 for( i1 = 0; i1 < ( n1 - 1 ); i1++ ) {
968 if( ptwXY->points[i1+1].x > domainMin ) break;
969 }
970 for( i2 = n1 - 1; i2 > i1; i2-- ) {
971 if( ptwXY->points[i2-1].x < domainMax ) break;
972 }
973 point = &(ptwXY->points[i1]);
974
975 integrateWithFunctionInfo.degree = degree;
976 integrateWithFunctionInfo.func = func;
977 integrateWithFunctionInfo.argList = argList;
978 integrateWithFunctionInfo.interpolation = ptwXY->interpolation;
979 integrateWithFunctionInfo.x2 = point->x;
980 integrateWithFunctionInfo.y2 = point->y;
981
982 xa = domainMin;
983 for( ; i1 < i2; i1++ ) {
984 integrateWithFunctionInfo.x1 = integrateWithFunctionInfo.x2;
985 integrateWithFunctionInfo.y1 = integrateWithFunctionInfo.y2;
986 ++point;
987 integrateWithFunctionInfo.x2 = point->x;
988 integrateWithFunctionInfo.y2 = point->y;
989 xb = point->x;
990 if( xb > domainMax ) xb = domainMax;
991 status = nf_GnG_adaptiveQuadrature( ptwXY_integrateWithFunction2, ptwXY_integrateWithFunction3, &integrateWithFunctionInfo,
992 xa, xb, recursionLimit, tolerance, &integral_, &evaluations );
993 if( status != nfu_Okay ) {
994 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_Error, "Via. Error from nf_GnG_adaptiveQuadrature." );
995 return( status );
996 }
997 integral += integral_;
998 xa = xb;
999 }
1000 *value = sign * integral;
1001
1002 return( nfu_Okay );
1003}
G4int sign(const T t)
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)
struct ptwXY_integrateWithFunctionInfo_s ptwXY_integrateWithFunctionInfo
ptwXY_createFromFunction_callback func

◆ ptwXY_integrateWithWeight_sqrt_x()

nfu_status ptwXY_integrateWithWeight_sqrt_x ( statusMessageReporting * smr,
ptwXYPoints * ptwXY,
double domainMin,
double domainMax,
double * value )

Definition at line 459 of file ptwXY_integration.c.

460 {
461
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;
464 ptwXYPoint *point;
465 nfu_status status;
466
467 *value = 0.;
468
469 if( ptwXY->status != nfu_Okay ) {
471 return( nfu_badSelf );
472 }
473
474 if( ( ptwXY->interpolation != ptwXY_interpolationLinLin ) &&
475 ( ptwXY->interpolation != ptwXY_interpolationFlat ) ) {
477 "Unsupported interpolation = '%s'", ptwXY->interpolationString );
479 }
480
481 if( n < 2 ) return( nfu_Okay );
482 if( domainMax < domainMin ) {
483 x = domainMin;
484 domainMin = domainMax;
485 domainMax = x;
486 _sign = -1.;
487 }
488
489 if( ptwXY_simpleCoalescePoints( smr, ptwXY ) != nfu_Okay ) {
491 return( nfu_Error );
492 }
493
494 for( i = 0, point = ptwXY->points; i < n; ++i, ++point ) {
495 if( point->x >= domainMin ) break;
496 }
497 if( i == n ) return( nfu_Okay );
498 x2 = point->x;
499 y2 = point->y;
500 if( i > 0 ) {
501 if( x2 > domainMin ) {
502 if( ( status = ptwXY_interpolatePoint( smr, ptwXY->interpolation, domainMin, &y, point[-1].x, point[-1].y, x2, y2 ) ) != nfu_Okay ) {
504 return( status );
505 }
506 x2 = domainMin;
507 y2 = y;
508 --i;
509 --point;
510 }
511 }
512 ++i;
513 ++point;
514 sqrt_x2 = sqrt( x2 );
515 for( ; i < n; ++i, ++point ) {
516 x1 = x2;
517 y1 = y2;
518 sqrt_x1 = sqrt_x2;
519 x2 = point->x;
520 y2 = point->y;
521 if( x2 > domainMax ) {
522 if( ( status = ptwXY_interpolatePoint( smr, ptwXY->interpolation, domainMax, &y, x1, y1, x2, y2 ) ) != nfu_Okay ) {
524 return( status );
525 }
526 x2 = domainMax;
527 y2 = y;
528 }
529 sqrt_x2 = sqrt( x2 );
530 inv_apb = sqrt_x1 + sqrt_x2;
531 c = 2. * ( sqrt_x1 * sqrt_x2 + x1 + x2 );
532 switch( ptwXY->interpolation ) {
534 sum += ( sqrt_x2 - sqrt_x1 ) * y1 * 2.5 * c;
535 break;
537 sum += ( sqrt_x2 - sqrt_x1 ) * ( y1 * ( c + x1 * ( 1. + sqrt_x2 / inv_apb ) ) + y2 * ( c + x2 * ( 1. + sqrt_x1 / inv_apb ) ) );
538 break;
539 default : /* Only to stop compilers from complaining. */
540 break;
541 }
542 if( x2 == domainMax ) break;
543 }
544
545 *value = 2. / 15. * _sign * sum;
546
547 return( nfu_Okay );
548}
char const * interpolationString
Definition ptwXY.h:82

Referenced by ptwXY_integrateDomainWithWeight_sqrt_x().

◆ ptwXY_integrateWithWeight_x()

nfu_status ptwXY_integrateWithWeight_x ( statusMessageReporting * smr,
ptwXYPoints * ptwXY,
double domainMin,
double domainMax,
double * value )

Definition at line 294 of file ptwXY_integration.c.

295 {
296
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;
299 ptwXYPoint *point;
300 nfu_status status;
301
302 *value = 0.;
303
304 if( ptwXY->status != nfu_Okay ) {
306 return( nfu_badSelf );
307 }
308
310 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_unsupportedInterpolation, "Unsupported interpolation = '%s'", ptwXY->interpolationString );
312 }
313
314 if( n < 2 ) return( nfu_Okay );
315
316 if( domainMax < domainMin ) {
317 x = domainMin;
318 domainMin = domainMax;
319 domainMax = x;
320 _sign = -1.;
321 }
322
323 if( ptwXY_simpleCoalescePoints( smr, ptwXY ) != nfu_Okay ) {
325 return( nfu_Error );
326 }
327
328 for( i = 0, point = ptwXY->points; i < n; ++i, ++point ) {
329 if( point->x >= domainMin ) break;
330 }
331 if( i == n ) return( nfu_Okay );
332
333 x2 = point->x;
334 y2 = point->y;
335 if( i > 0 ) {
336 if( x2 > domainMin ) {
337 if( ( status = ptwXY_interpolatePoint( smr, ptwXY->interpolation, domainMin, &y, point[-1].x, point[-1].y, x2, y2 ) ) != nfu_Okay ) {
339 return( status );
340 }
341 x2 = domainMin;
342 y2 = y;
343 --i;
344 --point;
345 }
346 }
347 ++i;
348 ++point;
349 for( ; i < n; ++i, ++point ) {
350 x1 = x2;
351 y1 = y2;
352 x2 = point->x;
353 y2 = point->y;
354 if( x2 > domainMax ) {
355 if( ( status = ptwXY_interpolatePoint( smr, ptwXY->interpolation, domainMax, &y, x1, y1, x2, y2 ) ) != nfu_Okay ) {
357 return( status );
358 }
359 x2 = domainMax;
360 y2 = y;
361 }
362 switch( ptwXY->interpolation ) {
364 sum += 0.5 * ( x2 - x1 ) * y1 * ( x1 + x2 );
365 break;
367 sum += ( x2 - x1 ) * ( y1 * ( 2 * x1 + x2 ) + y2 * ( x1 + 2 * x2 ) ) / 6.;
368 break;
370 ratioY = y2 / y1;
371 dx = x2 - x1;
372 dy = y2 - y1;
373 if( fabs( ratioY - 1 ) < 1e-3 ) {
374 double sum2 = 0.0;
375
376 ratioY -= 1.0;
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;
380 }
381 else {
382 invLog = 1.0 / log( ratioY );
383 sum += dx * invLog * ( dx * ( y2 - dy * invLog ) + x1 * dy );
384 }
385 break;
387 sum += 0.5 * ( x2 - x1 ) * y1 * ( x1 + x2 );
388 ratioX = x2 / x1;
389 if( fabs( ratioX - 1 ) < 1e-3 ) {
390 ratioX -= 1.0;
391 sum += 0.5 * ( y2 - y1 ) * x1 * ( x2 - x1 ) * ( 1.0 + ratioX * ( 5.0 + ratioX * ratioX * ( 1.0 + ratioX ) / 30.0 ) / 6.0 ); }
392 else {
393 logX = log( ratioX );
394 sum += 0.25 * ( y2 - y1 ) * x1 * x1 * ( 1.0 + ratioX * ratioX * ( 2.0 * logX - 1.0 ) ) / logX;
395 }
396 break;
398 ratioX = x2 / x1;
399 if( fabs( ratioX - 1. ) < 1e-4 ) {
400 ratioX -= 1.0;
401 logX = ratioX * ( 1. + ratioX * ( -0.5 + ratioX * ( 1. / 3. - 0.25 * ratioX ) ) );
402 ratioX = x2 / x1; }
403 else {
404 logX = log( ratioX );
405 }
406
407 ratioY = y2 / y1;
408 if( fabs( ratioY - 1. ) < 1e-4 ) {
409 ratioY -= 1.0;
410 logY = ratioY * ( 1. + ratioY * ( -0.5 + ratioY * ( 1. / 3. - 0.25 * ratioY ) ) );
411 ratioY = y2 / y1; }
412 else {
413 logY = log( ratioY );
414 }
415
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 ) ); }
419 else {
420 sum += y1 * x1 * x1 * numerator / ( logY / logX + 2.0 );
421 }
422 break;
423 default : /* Only to stop compilers from complaining. */
424 break;
425 }
426 if( x2 == domainMax ) break;
427 }
428
429 *value = _sign * sum;
430
431 return( nfu_Okay );
432}

Referenced by ptwXY_integrateDomainWithWeight_x().

◆ ptwXY_normalize()

nfu_status ptwXY_normalize ( statusMessageReporting * smr,
ptwXYPoints * ptwXY )

Definition at line 242 of file ptwXY_integration.c.

242 {
243/*
244* This function assumes ptwXY_integrateDomain coalesces the points.
245*/
246 int64_t i1;
247 nfu_status status = nfu_Okay;
248 double sum;
249
250 if( status != nfu_Okay ) {
252 return( nfu_badSelf );
253 }
254
255 if( ( status = ptwXY_integrateDomain( smr, ptwXY, &sum ) ) != nfu_Okay ) {
257 return( status );
258 }
259
260 if( sum == 0. ) {
261 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badNorm, "Cannot normalize curve with 0 norm." );
262 status = nfu_badNorm; }
263 else {
264 for( i1 = 0; i1 < ptwXY->length; i1++ ) ptwXY->points[i1].y /= sum;
265 }
266 return( status );
267}

Referenced by GIDI::Functions::XYs1d::normalize().

◆ ptwXY_runningIntegral()

ptwXPoints * ptwXY_runningIntegral ( statusMessageReporting * smr,
ptwXYPoints * ptwXY )

Definition at line 906 of file ptwXY_integration.c.

906 {
907
908 int i;
909 ptwXPoints *runningIntegral = NULL;
910 double integral = 0., sum;
911
912 if( ptwXY_simpleCoalescePoints( smr, ptwXY ) != nfu_Okay ) {
914 return( NULL );
915 }
916
917 if( ( runningIntegral = ptwX_new( smr, ptwXY->length ) ) == NULL ) goto Err;
918
919 if( ptwXY->length == 0 ) return( runningIntegral );
920
921 if( ptwX_setPointAtIndex( smr, runningIntegral, 0, 0. ) != nfu_Okay ) goto Err;
922 for( i = 1; i < ptwXY->length; i++ ) {
923 if( ptwXY_f_integrate( smr, ptwXY->interpolation, ptwXY->points[i-1].x, ptwXY->points[i-1].y,
924 ptwXY->points[i].x, ptwXY->points[i].y, &sum ) != nfu_Okay ) goto Err;
925 integral += sum;
926 if( ptwX_setPointAtIndex( smr, runningIntegral, i, integral ) != nfu_Okay ) goto Err;
927 }
928 return( runningIntegral );
929
930Err:
932 if( runningIntegral != NULL ) ptwX_free( runningIntegral );
933 return( NULL );
934}

Referenced by GIDI::Functions::XYs1d::toXs_pdf_cdf1d().