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;
264 ptwXY->
accuracy, length, secondarySize, status, ptwXY->
userFlag ) ) == NULL )
return( NULL );
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 ) {
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