12 #if defined __cplusplus
30 double accuracy, int64_t primarySize, int64_t secondarySize,
nfu_status *status,
int userFlag ) {
35 if( ptwXY == NULL )
return( NULL );
36 ptwXY_setup( ptwXY, interpolation, interpolationOtherInfo, biSectionMax, accuracy, primarySize,
37 secondarySize, userFlag );
47 double biSectionMax,
double accuracy, int64_t primarySize, int64_t secondarySize,
int userFlag ) {
56 switch( interpolation ) {
68 if( interpolationOtherInfo == NULL ) {
109 double biSectionMax,
double accuracy, int64_t primarySize, int64_t secondarySize, int64_t length,
double const *xy,
114 if( primarySize < length ) primarySize = length;
115 if( ( ptwXY =
ptwXY_new( interpolation, interpolationOtherInfo, biSectionMax, accuracy, primarySize,
116 secondarySize, status, userFlag ) ) != NULL ) {
127 double biSectionMax,
double accuracy, int64_t primarySize, int64_t secondarySize, int64_t length,
double const *Xs,
128 double const *Ys,
nfu_status *status,
int userFlag ) {
133 if( primarySize < length ) primarySize = length;
134 if( ( ptwXY =
ptwXY_new( interpolation, interpolationOtherInfo, biSectionMax, accuracy, primarySize,
135 secondarySize, status, userFlag ) ) != NULL ) {
136 for( i = 0; i < length; i++ ) {
185 while( o != overflowHeader ) {
186 if( i < nonOverflowLength ) {
187 if( pointFrom->
x < o->
point.
x ) {
188 *pointTo = *pointFrom;
201 for( ; i < nonOverflowLength; i++, pointFrom++, pointTo++ ) *pointTo = *pointFrom;
223 if( ( n1 =
ptwXY_clone( ptwXY, status ) ) != NULL ) {
226 switch( interpolationTo ) {
257 if( index2 < index1 )
return( NULL );
258 if( index1 < 0 ) index1 = 0;
261 length = index2 - index1;
264 ptwXY->
accuracy, length, secondarySize, status, ptwXY->
userFlag ) ) == NULL )
return( NULL );
267 for( i = index1; i < index2; i++ ) n->
points[i - index1] = ptwXY->
points[i];
286 if( ( n =
ptwXY_clone( ptwXY, status ) ) == NULL )
return( NULL );
292 if( fill && ( n->
points[0].
x < xMin ) ) {
297 for( i1 = 0; i1 < n->
length; i1++ )
if( n->
points[i1].
x >= xMin )
break;
298 for( i2 = n->
length - 1; i2 > 0; i2-- )
if( n->
points[i2].
x <= xMax )
break;
301 for( i = i1; i < i2; i++ ) n->
points[i- i1] = n->
points[i];
317 double xMax = 1.1 * xMin + 1;
319 if( xMin < 0 ) xMax = 0.9 * xMin + 1;
321 return(
ptwXY_xSlice( ptwXY, xMin, xMax, secondarySize, fill, status ) );
328 double xMin = 0.9 * xMax - 1;
330 if( xMax < 0 ) xMin = 1.1 * xMax - 1;
332 return(
ptwXY_xSlice( ptwXY, xMin, xMax, secondarySize, fill, status ) );
382 if( accuracy < ptwXY->accuracy ) accuracy = ptwXY->
accuracy;
383 if( accuracy > 1 ) accuracy = 1.;
399 if( biSectionMax < 0 ) {
417 if( size < ptwXY->length ) size = ptwXY->
length;
421 else if( ( ptwXY->
allocatedSize > 2 * size ) || forceSmallerResize ) {
426 if( ptwXY->
points == NULL ) {
472 int64_t length = ptwXY->
length + ( ( newPoint != NULL ) ? 1 : 0 );
479 if( size < length ) size = length;
484 pointsTo = &(ptwXY->
points[length - 1]);
487 if( newPoint != NULL ) {
488 if( ( pointsFrom >= ptwXY->
points ) && ( pointsFrom->
x > last->
point.
x ) ) {
489 if( newPoint->
x > pointsFrom->
x ) addNewPoint = 1; }
491 if( newPoint->
x > last->
point.
x ) addNewPoint = 1;
493 if( addNewPoint == 1 ) {
494 *pointsTo = *newPoint;
498 if( addNewPoint == 0 ) {
499 if( ( pointsFrom >= ptwXY->
points ) && ( pointsFrom->
x > last->
point.
x ) ) {
500 *pointsTo = *pointsFrom;
503 *pointsTo = last->
point;
509 while( ( newPoint != NULL ) && ( pointsFrom >= ptwXY->
points ) ) {
510 if( newPoint->
x > pointsFrom->
x ) {
511 *pointsTo = *newPoint;
514 *pointsTo = *pointsFrom;
519 if( newPoint != NULL ) *pointsTo = *newPoint;
602 double const *
d = xy;
607 if( status !=
nfu_Okay )
return( status );
609 for( i = 0, p = ptwXY->
points; i < length; i++, p++ ) {
626 return( ptwXY->
status = status );
642 for( i = 0, p = ptwXY->
points; i < length; i++, p++, x++, y++ ) {
662 int64_t
n = ptwXY->
length - ( i2 - i1 );
678 if( ( index < 0 ) || ( index >= ptwXY->
length ) )
return( NULL );
690 if( overflowPoint->
index == index )
return( &(overflowPoint->
point) );
691 if( overflowPoint->
index > index )
break;
693 return( &(ptwXY->
points[index - i]) );
724 int64_t indexMin, indexMid, indexMax;
729 ptwXYPoint *lowerPoint = NULL, *upperPoint = NULL;
733 if( ptwXY->
length != 0 ) {
737 greaterThanXPoint->
prior = overflowHeader;
738 greaterThanXPoint->
index = 0;
740 *closePoint = &(ptwXY->
points[0]); }
742 *greaterThanXPoint = *(overflowHeader->
next);
743 *closePoint = &(overflowHeader->
next->
point);
745 else if( x > xMax ) {
748 lessThanEqualXPoint->
prior = overflowHeader->
prior;
749 lessThanEqualXPoint->
index = nonOverflowLength - 1;
751 *closePoint = &(ptwXY->
points[lessThanEqualXPoint->
index]); }
753 *lessThanEqualXPoint = *(overflowHeader->
prior);
754 *closePoint = &(overflowHeader->
prior->
point);
758 for( overflowPoint = overflowHeader->
next, overflowIndex = 0; overflowPoint != overflowHeader;
759 overflowPoint = overflowPoint->
next, overflowIndex++ )
if( overflowPoint->
point.
x > x )
break;
760 overflowPoint = overflowPoint->
prior;
761 if( ( overflowPoint != overflowHeader ) && ( overflowPoint->
point.
x ==
x ) ) {
763 *lessThanEqualXPoint = *overflowPoint; }
764 else if( ptwXY->
length == 1 ) {
766 lessThanEqualXPoint->
index = 0;
770 indexMax = nonOverflowLength - 1;
771 indexMid = ( indexMin + indexMax ) >> 1;
772 while( ( indexMin != indexMid ) && ( indexMid != indexMax ) ) {
773 if( ptwXY->
points[indexMid].
x > x ) {
774 indexMax = indexMid; }
778 indexMid = ( indexMin + indexMax ) >> 1;
780 if( ptwXY->
points[indexMin].
x == x ) {
782 lessThanEqualXPoint->
index = indexMin;
783 lessThanEqualXPoint->
point = ptwXY->
points[indexMin]; }
784 else if( ptwXY->
points[indexMax].
x == x ) {
786 lessThanEqualXPoint->
index = indexMax;
787 lessThanEqualXPoint->
point = ptwXY->
points[indexMax]; }
789 if( ptwXY->
points[indexMin].
x > x ) indexMax = 0;
790 if( ptwXY->
points[indexMax].
x < x ) indexMin = indexMax;
791 if( ( overflowPoint == overflowHeader ) ||
792 ( ( ptwXY->
points[indexMin].
x > overflowPoint->
point.
x ) && ( ptwXY->
points[indexMin].
x < x ) ) ) {
793 if( overflowPoint != overflowHeader ) lessThanEqualXPoint->
prior = overflowPoint;
794 lowerPoint = &(ptwXY->
points[indexMin]);
795 lessThanEqualXPoint->
index = indexMin;
796 lessThanEqualXPoint->
point = ptwXY->
points[indexMin]; }
798 lowerPoint = &(overflowPoint->
point);
799 *lessThanEqualXPoint = *overflowPoint;
801 if( ( overflowPoint->
next == overflowHeader ) ||
803 upperPoint = &(ptwXY->
points[indexMax]);
804 greaterThanXPoint->
index = indexMax;
805 greaterThanXPoint->
point = ptwXY->
points[indexMax]; }
807 upperPoint = &(overflowPoint->
next->
point);
808 *greaterThanXPoint = *(overflowPoint->
next);
817 double absX = std::fabs( x );
820 if( absX < std::fabs( greaterThanXPoint->
point.
x ) ) absX = std::fabs( greaterThanXPoint->
point.
x );
821 if( ( greaterThanXPoint->
point.
x - x ) < eps * absX ) *closeIsEqual = 1; }
823 if( absX < std::fabs( lessThanEqualXPoint->
point.
x ) ) absX = std::fabs( lessThanEqualXPoint->
point.
x );
824 if( ( x - lessThanEqualXPoint->
point.
x ) < eps * absX ) *closeIsEqual = -1; }
826 if( ( x - lessThanEqualXPoint->
point.
x ) < ( greaterThanXPoint->
point.
x - x ) ) {
827 *closePoint = lowerPoint;
828 if( absX < std::fabs( lessThanEqualXPoint->
point.
x ) ) absX = std::fabs( lessThanEqualXPoint->
point.
x );
829 if( ( x - lessThanEqualXPoint->
point.
x ) < eps * absX ) *closeIsEqual = -1; }
831 *closePoint = upperPoint;
832 if( absX < std::fabs( greaterThanXPoint->
point.
x ) ) absX = std::fabs( greaterThanXPoint->
point.
x );
833 if( ( greaterThanXPoint->
point.
x - x ) < eps * absX ) *closeIsEqual = 1;
859 *y = lessThanEqualXPoint.
point.
y;
902 if( !
override )
return( status );
908 point = &(ptwXY->
points[nonOverflowLength]); }
914 overflowPoint->
prior = greaterThanXPoint.
prior;
915 overflowPoint->
index = 0; }
921 overflowPoint->
prior = lessThanEqualXPoint.
prior;
922 if( lessThanEqualXPoint.
next != NULL ) {
923 if( lessThanEqualXPoint.
point.
x < x )
927 for( p = overflowHeader->
next, i = 1; p != overflowHeader; p = p->
next, i++ )
928 if( p->
point.
x > x )
break;
930 overflowPoint->
index = lessThanEqualXPoint.
index + i;
934 overflowPoint->
prior->
next = overflowPoint;
935 overflowPoint->
next->
prior = overflowPoint;
936 point = &(overflowPoint->
point);
937 for( overflowPoint = overflowPoint->
next; overflowPoint != overflowHeader; overflowPoint = overflowPoint->
next ) {
938 overflowPoint->
index++;
948 if( closeIsEqual && !
override )
return( status );
949 if( lessThanEqualXPoint.
next == NULL ) {
950 point = &(ptwXY->
points[lessThanEqualXPoint.
index]); }
976 double *xs, *p1, *p2;
980 if( length == 0 )
return(
nfu_Okay );
982 for( i = 0, p1 = xs, p2 = xys; i < length; i++, p1++, p2 += 2 ) *p1 = *p2;
994 double *sortedXs, *p1, *p2;
999 if( length == 0 )
return(
nfu_Okay );
1006 for( i = 0, p1 = sortedXs, p2 = xs; i < length; i++, p1++, p2++ ) *p1 = *p2;
1011 for( i = 0, p1 = sortedXs, j = 0, n = 0; i < length; i++, p1++, n++ ) {
1012 for( ; j < ptwXY->
length; j++, n++ ) {
1013 if( *p1 <= ptwXY->points[j].
x )
break;
1015 if( j == ptwXY->
length )
break;
1017 n += (
int) ( ( length - i ) + ( ptwXY->
length - j ) );
1020 point1 = &(ptwXY->
points[n-1]);
1021 point2 = &(ptwXY->
points[length-1]);
1022 for( i = 0, j = 0, p1 = &(sortedXs[length-1]); ( i < length ) && ( j < length ) && ( n > 0 ); n--, point1-- ) {
1023 if( *p1 >= point2->
x ) {
1025 point1->
y = ys[(
int)(p1 - xs)];
1026 if( *p1 >= point2->
x ) {
1038 for( ; i < length; i++, p1--, point1-- ) {
1040 point1->
y = ys[(
int)(p1 - xs)];
1042 for( ; j < length; j++, point1--, point2-- ) *point1 = *point2;
1053 double d1 = *((
double *) x1p),
d2 = *((
double *) x2p);
1055 if( d1 <
d2 )
return( -1 );
1056 if( d1 ==
d2 )
return( 0 );
1067 if( ptwXY->
length != 0 ) {
1072 if( nonOverflowLength < ptwXY->allocatedSize ) {
1073 ptwXY->
points[nonOverflowLength].
x =
x;
1074 ptwXY->
points[nonOverflowLength].
y =
y; }
1085 overflowPoint->
prior->
next = overflowPoint;
1086 overflowPoint->
next->
prior = overflowPoint;
1107 if( overflowPoint->
index >= index )
break;
1110 pm1 = pp1 = overflowPoint;
1111 if( overflowPoint->
index == index ) {
1112 pp1 = overflowPoint->
next;
1126 if( ( overflowPoint != &(ptwXY->
overflowHeader) ) && ( overflowPoint->
index == index ) ) {
1147 if( ( side !=
'-' ) && ( side !=
'+' ) )
return(
nfu_badInput );
1156 *slope = ( greaterThanXPoint.
point.
y - lessThanEqualXPoint.
point.
y ) /
1157 ( greaterThanXPoint.
point.
x - lessThanEqualXPoint.
point.
x );
1161 if( lessThanEqualXPoint.
index == 0 ) {
1165 *slope = ( lessThanEqualXPoint.
point.
y - point->
y ) / ( lessThanEqualXPoint.
point.
x - point->
x );
1168 if( lessThanEqualXPoint.
index == ( ptwXY->
length - 1 ) ) {
1172 *slope = ( point->
y - lessThanEqualXPoint.
point.
y ) / ( point->
x - lessThanEqualXPoint.
point.
x );
1191 if( nonOverflowLength >= 0 ) {
1192 if( xMin > ptwXY->
points[0].
x ) {
1197 else if( nonOverflowLength > 0 ) {
1224 if( ( nonOverflowLength > 0 ) ) {
1225 if( xMax < ptwXY->points[nonOverflowLength-1].
x ) {
1227 xMax = ptwXY->
points[nonOverflowLength-1].
x;
1230 else if( ptwXY->
length > 0 ) {
1232 xMax = ptwXY->
points[nonOverflowLength-1].
x;
1255 if( ptwXY->
length == 0 )
return( 0. );
1258 for( i = 1, p++; i <
n; i++, p++ ) yMin = ( ( yMin < p->
y ) ? yMin : p->
y ); }
1260 yMin = overflowPoint->
point.
y;
1262 for( ; overflowPoint != &(ptwXY->
overflowHeader); overflowPoint = overflowPoint->
next )
1263 yMin = ( ( yMin < overflowPoint->point.y ) ? yMin : overflowPoint->
point.
y );
1276 if( ptwXY->
length == 0 )
return( 0. );
1279 for( i = 1, p++; i < n; i++, p++ ) yMax = ( ( yMax > p->
y ) ? yMax : p->
y ); }
1281 yMax = overflowPoint->
point.
y;
1283 for( ; overflowPoint != &(ptwXY->
overflowHeader); overflowPoint = overflowPoint->
next )
1284 yMax = ( ( yMax > overflowPoint->
point.
y ) ? yMax : overflowPoint->
point.
y );
1292 overflowPoint->
prior = prior;
1293 overflowPoint->
next = next;
1294 overflowPoint->
index = -1;
1295 overflowPoint->
point.
x = 0.;
1296 overflowPoint->
point.
y = 0.;
1299 #if defined __cplusplus
nfu_status ptwXY_release(ptwXYPoints *ptwXY)
nfu_status ptwXY_getSlopeAtX(ptwXYPoints *ptwXY, double x, const char side, double *slope)
ptwXYOverflowPoint * overflowPoints
enum ptwXY_dataFrom_e ptwXY_dataFrom
ptwXYPoints * ptwXY_xSlice(ptwXYPoints *ptwXY, double xMin, double xMax, int64_t secondarySize, int fill, nfu_status *status)
ptwXYPoints * ptwXY_new(ptwXY_interpolation interpolation, ptwXY_interpolationOtherInfo const *interpolationOtherInfo, double biSectionMax, double accuracy, int64_t primarySize, int64_t secondarySize, nfu_status *status, int userFlag)
#define ptwXY_minimumSize
ptwXYPoints * ptwXY_createFrom_Xs_Ys(ptwXY_interpolation interpolation, ptwXY_interpolationOtherInfo const *interpolationOtherInfo, double biSectionMax, double accuracy, int64_t primarySize, int64_t secondarySize, int64_t length, double const *Xs, double const *Ys, nfu_status *status, int userFlag)
double ptwXY_getAccuracy(ptwXYPoints *ptwXY)
ptwXYPoints * ptwXY_clone(ptwXYPoints *ptwXY, nfu_status *status)
static nfu_status ptwXY_mergeFrom(ptwXYPoints *ptwXY, int incY, int length, double *xs, double *ys)
int64_t ptwXY_length(ptwXYPoints *ptwXY)
enum ptwXY_interpolation_e ptwXY_interpolation
int ptwXY_getUserFlag(ptwXYPoints *ptwXY)
ptwXY_lessEqualGreaterX ptwXY_getPointsAroundX(ptwXYPoints *ptwXY, double x, ptwXYOverflowPoint *lessThanEqualXPoint, ptwXYOverflowPoint *greaterThanXPoint)
double ptwXY_setBiSectionMax(ptwXYPoints *ptwXY, double biSectionMax)
int64_t ptwXY_getNonOverflowLength(ptwXYPoints const *ptwXY)
double ptwXY_getXMax(ptwXYPoints *ptwXY)
char const * ptwXY_getInterpolationString(ptwXYPoints *ptwXY)
nfu_status ptwXY_setXYDataFromXsAndYs(ptwXYPoints *ptwXY, int64_t length, double const *x, double const *y)
struct ptwXYOverflowPoint_s ptwXYOverflowPoint
struct ptwXYOverflowPoint_s * next
double ptwXY_getXMaxAndFrom(ptwXYPoints *ptwXY, ptwXY_dataFrom *dataFrom)
nfu_status ptwXY_setXYData(ptwXYPoints *ptwXY, int64_t length, double const *xy)
nfu_status ptwXY_clear(ptwXYPoints *ptwXY)
#define ptwXY_maxBiSectionMax
void * nfu_calloc(size_t size, size_t n)
nfu_status ptwXY_coalescePoints(ptwXYPoints *ptwXY, int64_t size, ptwXYPoint *newPoint, int forceSmallerResize)
nfu_status ptwXY_copy(ptwXYPoints *dest, ptwXYPoints *src)
nfu_status ptwXY_mergeFromXYs(ptwXYPoints *ptwXY, int length, double *xys)
static char const flatInterpolationString[]
static char const linLinInterpolationString[]
ptwXYPoints * ptwXY_xMaxSlice(ptwXYPoints *ptwXY, double xMax, int64_t secondarySize, int fill, nfu_status *status)
struct ptwXYPoint_s ptwXYPoint
nfu_status ptwXY_setValueAtX_overrideIfClose(ptwXYPoints *ptwXY, double x, double y, double eps, int override)
double ptwXY_getBiSectionMax(ptwXYPoints *ptwXY)
ptwXY_lessEqualGreaterX ptwXY_getPointsAroundX_closeIsEqual(ptwXYPoints *ptwXY, double x, ptwXYOverflowPoint *lessThanEqualXPoint, ptwXYOverflowPoint *greaterThanXPoint, double eps, int *closeIsEqual, ptwXYPoint **closePoint)
ptwXY_interpolationOtherInfo interpolationOtherInfo
nfu_status ptwXY_reallocatePoints(ptwXYPoints *ptwXY, int64_t size, int forceSmallerResize)
enum nfu_status_e nfu_status
typedef int(XMLCALL *XML_NotStandaloneHandler)(void *userData)
nfu_status ptwXY_getValueAtX(ptwXYPoints *ptwXY, double x, double *y)
char const * interpolationString
ptwXYPoints * ptwXY_slice(ptwXYPoints *ptwXY, int64_t index1, int64_t index2, int64_t secondarySize, nfu_status *status)
double ptwXY_getXMinAndFrom(ptwXYPoints *ptwXY, ptwXY_dataFrom *dataFrom)
ptwXY_interpolation interpolation
ptwXYPoints * ptwXY_cloneToInterpolation(ptwXYPoints *ptwXY, ptwXY_interpolation interpolationTo, nfu_status *status)
nfu_status ptwXY_mergeFromXsAndYs(ptwXYPoints *ptwXY, int length, double *xs, double *ys)
static void ptwXY_initialOverflowPoint(ptwXYOverflowPoint *overflowPoint, ptwXYOverflowPoint *prior, ptwXYOverflowPoint *next)
ptwXYPoint * ptwXY_getPointAtIndex(ptwXYPoints *ptwXY, int64_t index)
nfu_status ptwXY_setXYPairAtIndex(ptwXYPoints *ptwXY, int64_t index, double x, double y)
ptwXYPoint * ptwXY_getPointAtIndex_Unsafely(ptwXYPoints *ptwXY, int64_t index)
static char const logLinInterpolationString[]
double ptwXY_getYMin(ptwXYPoints *ptwXY)
nfu_status ptwXY_appendXY(ptwXYPoints *ptwXY, double x, double y)
nfu_status ptwXY_getXYPairAtIndex(ptwXYPoints *ptwXY, int64_t index, double *x, double *y)
ptwXYPoints * ptwXY_free(ptwXYPoints *ptwXY)
double ptwXY_getYMax(ptwXYPoints *ptwXY)
static int ptwXY_mergeCompareFunction(void const *x1p, void const *x2p)
static char const logLogInterpolationString[]
ptwXYPoints * ptwXY_create(ptwXY_interpolation interpolation, ptwXY_interpolationOtherInfo const *interpolationOtherInfo, double biSectionMax, double accuracy, int64_t primarySize, int64_t secondarySize, int64_t length, double const *xy, nfu_status *status, int userFlag)
nfu_status ptwXY_reallocateOverflowPoints(ptwXYPoints *ptwXY, int64_t size)
nfu_status ptwXY_simpleCoalescePoints(ptwXYPoints *ptwXY)
nfu_status ptwXY_setup(ptwXYPoints *ptwXY, ptwXY_interpolation interpolation, ptwXY_interpolationOtherInfo const *interpolationOtherInfo, double biSectionMax, double accuracy, int64_t primarySize, int64_t secondarySize, int userFlag)
enum ptwXY_lessEqualGreaterX_e ptwXY_lessEqualGreaterX
void * nfu_realloc(size_t size, void *old)
ptwXYPoints * ptwXY_xMinSlice(ptwXYPoints *ptwXY, double xMin, int64_t secondarySize, int fill, nfu_status *status)
static const G4double eps
struct ptwXYOverflowPoint_s * prior
void ptwXY_setUserFlag(ptwXYPoints *ptwXY, int userFlag)
ptwXY_getValue_callback getValueFunc
int64_t overflowAllocatedSize
nfu_status ptwXY_interpolatePoint(ptwXY_interpolation interpolation, double x, double *y, double x1, double y1, double x2, double y2)
#define ptwXY_minAccuracy
nfu_status ptwXY_deletePoints(ptwXYPoints *ptwXY, int64_t i1, int64_t i2)
void * nfu_malloc(size_t size)
#define ptwXY_minimumOverflowSize
double ptwXY_getXMin(ptwXYPoints *ptwXY)
nfu_status ptwXY_setValueAtX(ptwXYPoints *ptwXY, double x, double y)
static char const linLogInterpolationString[]
ptwXY_interpolation ptwXY_getInterpolation(ptwXYPoints *ptwXY)
nfu_status ptwXY_getStatus(ptwXYPoints *ptwXY)
double ptwXY_setAccuracy(ptwXYPoints *ptwXY, double accuracy)
ptwXYOverflowPoint overflowHeader