16 double x2,
double y2,
int depth );
18static double ptwXY_flatInterpolationToLinear_eps(
double px,
double eps );
22 double x2,
double y2,
int depth );
24 double x2,
double y2,
int depth );
26 double x2,
double y2,
int depth );
31 double x1,
double y1,
double x2,
double y2 ) {
39 if( ( x1 > x2 ) || ( x < x1 ) || ( x > x2 ) ) {
41 "Interpolation point.x = %.17e not between function points x1 = %.17e and x2 = %.17e.", x, x1, x2 );
47 *y = 0.5 * ( y1 + y2 ); }
53 switch( interpolation ) {
55 *y = ( y1 * ( x2 - x ) + y2 * ( x - x1 ) ) / ( x2 - x1 );
58 if( ( x <= 0. ) || ( x1 <= 0. ) || ( x2 <= 0. ) ) {
60 "For log(x), some x-values less than equal to 0, x1 = %.17e, x = %.17e, x2 = %.17e.", x1, x, x2 );
63 *y = ( y1 * log( x2 / x ) + y2 * log( x / x1 ) ) / log( x2 / x1 );
66 if( ( y1 <= 0. ) || ( y2 <= 0. ) ) {
68 "For log(y), some y-values less than equal to 0, y1 = %.17e, y2 = %.17e.", y1, y2 );
71 *y = exp( ( log( y1 ) * ( x2 - x ) + log( y2 ) * ( x - x1 ) ) / ( x2 - x1 ) );
74 if( ( x <= 0. ) || ( x1 <= 0. ) || ( x2 <= 0. ) ) {
76 "For log(x), some x-values less than equal to 0, x1 = %.17e, x = %.17e, x2 = %.17e.", x1, x, x2 );
79 if( ( y1 <= 0. ) || ( y2 <= 0. ) ) {
81 "For log(y), some y-values less than equal to 0, y1 = %.17e, y2 = %.17e.", y1, y2 );
84 *y = exp( ( log( y1 ) * log( x2 / x ) + log( y2 ) * log( x / x1 ) ) / log( x2 / x1 ) );
91 "Invalid interpolation token = %d.", interpolation );
120 if( ( lowerEps < 0 ) || ( upperEps < 0 ) || ( ( lowerEps == 0 ) && ( upperEps == 0 ) ) ) {
122 lowerEps, upperEps );
125 if( ( lowerEps != 0 ) && ( lowerEps <
minEps ) ) lowerEps =
minEps;
126 if( ( upperEps != 0 ) && ( upperEps <
minEps ) ) upperEps =
minEps;
128 length = ptwXY->
length * ( 1 + ( lowerEps == 0 ? 0 : 1 ) + ( lowerEps == 0 ? 0 : 1 ) );
139 for( i = 0; i < ptwXY->
length; i++, p3++ ) {
142 x = ptwXY_flatInterpolationToLinear_eps( p2->x, -lowerEps );
150 x = ptwXY_flatInterpolationToLinear_eps( p2->x, upperEps );
160 if( ( lowerEps != 0 ) && ( p1->
y != p2->y ) ) {
161 x = ptwXY_flatInterpolationToLinear_eps( p2->x, -lowerEps );
181static double ptwXY_flatInterpolationToLinear_eps(
double px,
double eps ) {
186 x = ( 1 - eps ) * px; }
188 x = ( 1 + eps ) * px; }
202 int i1, logX = 0, logY = 0;
219 func = ptwXY_LogLogToLinLin;
break;
222 func = ptwXY_LogLinToLinLin;
break;
225 func = ptwXY_LinLogToLinLin;
break;
235 "Interpolation conversion from '%s' to %d not supported.", ptwXY->
interpolationString, interpolationTo );
239 if( ( logX != 0 ) || ( logY != 0 ) ) {
247 for( i1 = 0, point = ptwXY->
points; i1 < ptwXY->length; ++i1, ++point ) {
248 if( ( logX != 0 ) && ( point->
x <= 0 ) ) {
250 (
int) i1, point->
x );
253 if( ( logY != 0 ) && ( point->
y <= 0 ) ) {
255 (
int) i1, point->
y );
267 if( ptwXY_toOtherInterpolation2( smr, n1, ptwXY, func ) !=
nfu_Okay ) {
283 double x1, y1, x2, y2;
289 for( i1 = 1; i1 < src->
length; i1++ ) {
292 if( ( x1 != x2 ) && ( y1 != y2 ) ) {
293 if( ( status = func( smr, desc, x1, y1, x2, y2, 0 ) ) !=
nfu_Okay )
break;
304 double x2,
double y2,
int depth ) {
307 double x, y, u, u2 = x2 / x1, v2 = y2 / y1, logYXs, logXs = log( u2 ), logYs = log( v2 ), vLin, vLog, w;
309 logYXs = logYs / logXs;
312 if( fabs( logYXs - 1 ) < 1e-5 ) {
313 u = 0.5 * ( 1 + u2 );
314 w = ( logYXs - 1 ) * logXs;
315 vLog = u * ( 1. + w * ( 1 + 0.5 * w ) ); }
320 u = logYXs * ( u2 - v2 ) / ( ( 1 - logYXs ) * ( v2 - 1 ) );
322 vLog = pow( u, logYXs );
324 vLin = ( u2 - u + v2 * ( u - 1 ) ) / ( u2 - 1 );
325 if( fabs( vLog - vLin ) <= ( vLog * desc->
accuracy ) )
return( status );
329 if( ( status = ptwXY_LogLogToLinLin( smr, desc, x1, y1, x, y, depth + 1 ) ) !=
nfu_Okay )
return( status );
330 return( ptwXY_LogLogToLinLin( smr, desc, x, y, x2, y2, depth + 1 ) );
336 double x1,
double y1,
double x2,
double y2,
int depth ) {
339 double x, y, logYs = log( y2 / y1 ), yLinLin;
342 x = ( x2 - x1 ) / ( y2 - y1 ) * ( ( y2 - y1 ) / logYs - y1 ) + x1;
343 y = y1 * exp( logYs / ( x2 - x1 ) * ( x - x1 ) );
344 yLinLin = ( y1 * ( x2 - x ) + y2 * ( x - x1 ) ) / ( x2 - x1 );
345 if( fabs( y - yLinLin ) <= ( y * desc->
accuracy ) )
return( status );
347 if( ( status = ptwXY_LogLinToLinLin( smr, desc, x1, y1, x, y, depth + 1 ) ) !=
nfu_Okay )
return( status );
348 return( ptwXY_LogLinToLinLin( smr, desc, x, y, x2, y2, depth + 1 ) );
354 double x2,
double y2,
int depth ) {
357 double x = sqrt( x2 * x1 ), y, logXs = log( x2 / x1 ), yLinLin;
361 x = ( y1 * x2 - y2 * x1 ) / ( y1 * logXs + ( y2 - y1 ) * ( log( x / x1 ) - 1 ) );
363 y = ( y2 - y1 ) * log( x / x1 ) / logXs + y1;
364 yLinLin = ( y1 * ( x2 - x ) + y2 * ( x - x1 ) ) / ( x2 - x1 );
365 if( fabs( y - yLinLin ) <= fabs( y * desc->
accuracy ) )
return( status );
367 if( ( status = ptwXY_LinLogToLinLin( smr, desc, x1, y1, x, y, depth + 1 ) ) !=
nfu_Okay )
return( status );
368 return( ptwXY_LinLogToLinLin( smr, desc, x, y, x2, y2, depth + 1 ) );
378 double domainMin, domainMax, dx, inverseDx;
389 domainMin = n->points[0].x;
390 domainMax = n->points[n->length-1].x;
391 dx = domainMax - domainMin;
393 for( i = 0, p = n->points; i < n->length; i++, p++ ) {
394 p->
x = ( p->
x - domainMin ) * inverseDx;
395 if( scaleRange ) p->
y = p->
y * dx;
397 n->points[n->length-1].x = 1.;
409 double dx, inverseDx, xLast = 0.;
420 dx = domainMax - domainMin;
423 for( i = 0, p2 = p = n->points; i < length; ++i, ++p ) {
424 p2->
x = p->
x * dx + domainMin;
426 if( fabs( p2->
x - xLast ) <= 10. *
DBL_EPSILON * ( fabs( p2->
x ) + fabs( xLast ) ) ) {
431 if( scaleRange ) p2->
y = p->
y * inverseDx;
435 n->points[n->length-1].x = domainMax;
447 ptwXYPoints *n1 = NULL, *n2 = NULL, *a = NULL, *r = NULL;
449 double f, g, domainMin, domainMax;
451 if( ( w < w1 ) || ( w > w2 ) ) {
464 if( ( n1 =
ptwXY_toUnitbase( smr, ptwXY1, scaleRange ) ) == NULL )
goto Err;
465 if( ( n2 =
ptwXY_toUnitbase( smr, ptwXY2, scaleRange ) ) == NULL )
goto Err;
466 f = ( w - w1 ) / ( w2 - w1 );
468 for( i = 0, p = n1->
points; i < n1->length; i++, p++ ) p->
y *= g;
469 for( i = 0, p = n2->points; i < n2->length; i++, p++ ) p->
y *= f;
474 if( ( r =
ptwXY_fromUnitbase( smr, a, domainMin, domainMax, scaleRange ) ) == NULL )
goto Err;
@ nfu_invalidInterpolation
@ nfu_unsupportedInterpolationConversion
enum nfu_status_e nfu_status
nfu_status ptwXY_setValueAtX(statusMessageReporting *smr, ptwXYPoints *ptwXY, double x, double y)
double ptwXY_limitAccuracy(double accuracy)
ptwXYPoints * ptwXY_clone(statusMessageReporting *smr, ptwXYPoints *ptwXY)
ptwXYPoints * ptwXY_add_ptwXY(statusMessageReporting *smr, ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2)
ptwXYPoints * ptwXY_cloneToInterpolation(statusMessageReporting *smr, ptwXYPoints *ptwXY, ptwXY_interpolation interpolationTo)
enum ptwXY_interpolation_e ptwXY_interpolation
@ ptwXY_interpolationFlat
@ ptwXY_interpolationLinLog
@ ptwXY_interpolationLogLog
@ ptwXY_interpolationLinLin
@ ptwXY_interpolationOther
@ ptwXY_interpolationLogLin
struct ptwXYPoints_s ptwXYPoints
#define ptwXY_maxBiSectionMax
ptwXYPoints * ptwXY_new(statusMessageReporting *smr, ptwXY_interpolation interpolation, char const *interpolationString, double biSectionMax, double accuracy, int64_t primarySize, int64_t secondarySize, int userFlag)
struct ptwXYPoint_s ptwXYPoint
ptwXYPoints * ptwXY_free(ptwXYPoints *ptwXY)
nfu_status ptwXY_simpleCoalescePoints(statusMessageReporting *smr, ptwXYPoints *ptwXY)
ptwXYPoints * ptwXY_unitbaseInterpolate(statusMessageReporting *smr, double w, double w1, ptwXYPoints *ptwXY1, double w2, ptwXYPoints *ptwXY2, int scaleRange)
nfu_status(* interpolation_func)(statusMessageReporting *smr, ptwXYPoints *desc, double x1, double y1, double x2, double y2, int depth)
ptwXYPoints * ptwXY_toOtherInterpolation(statusMessageReporting *smr, ptwXYPoints *ptwXY, ptwXY_interpolation interpolationTo, double accuracy)
nfu_status ptwXY_interpolatePoint(statusMessageReporting *smr, ptwXY_interpolation interpolation, double x, double *y, double x1, double y1, double x2, double y2)
ptwXYPoints * ptwXY_toUnitbase(statusMessageReporting *smr, ptwXYPoints *ptwXY, int scaleRange)
ptwXYPoints * ptwXY_fromUnitbase(statusMessageReporting *smr, ptwXYPoints *ptwXY, double domainMin, double domainMax, int scaleRange)
ptwXYPoints * ptwXY_flatInterpolationToLinear(statusMessageReporting *smr, ptwXYPoints *ptwXY, double lowerEps, double upperEps)
#define smr_setReportError2(smr, libraryID, code, fmt,...)
#define smr_setReportError2p(smr, libraryID, code, fmt)
ptwXY_interpolation interpolation
char const * interpolationString