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

Go to the source code of this file.

Macros

#define minEps   5e-16

Typedefs

typedef nfu_status(* interpolation_func) (statusMessageReporting *smr, ptwXYPoints *desc, double x1, double y1, double x2, double y2, int depth)

Functions

nfu_status ptwXY_interpolatePoint (statusMessageReporting *smr, ptwXY_interpolation interpolation, double x, double *y, double x1, double y1, double x2, double y2)
ptwXYPointsptwXY_flatInterpolationToLinear (statusMessageReporting *smr, ptwXYPoints *ptwXY, double lowerEps, double upperEps)
ptwXYPointsptwXY_toOtherInterpolation (statusMessageReporting *smr, ptwXYPoints *ptwXY, ptwXY_interpolation interpolationTo, double accuracy)
ptwXYPointsptwXY_toUnitbase (statusMessageReporting *smr, ptwXYPoints *ptwXY, int scaleRange)
ptwXYPointsptwXY_fromUnitbase (statusMessageReporting *smr, ptwXYPoints *ptwXY, double domainMin, double domainMax, int scaleRange)
ptwXYPointsptwXY_unitbaseInterpolate (statusMessageReporting *smr, double w, double w1, ptwXYPoints *ptwXY1, double w2, ptwXYPoints *ptwXY2, int scaleRange)

Macro Definition Documentation

◆ minEps

#define minEps   5e-16

Typedef Documentation

◆ interpolation_func

typedef nfu_status(* interpolation_func) (statusMessageReporting *smr, ptwXYPoints *desc, double x1, double y1, double x2, double y2, int depth)

Definition at line 15 of file ptwXY_interpolation.c.

Function Documentation

◆ ptwXY_flatInterpolationToLinear()

ptwXYPoints * ptwXY_flatInterpolationToLinear ( statusMessageReporting * smr,
ptwXYPoints * ptwXY,
double lowerEps,
double upperEps )

Definition at line 100 of file ptwXY_interpolation.c.

100 {
101
102 int64_t i, length;
103 double x;
104 ptwXYPoints *n;
105 ptwXYPoint *p1 = NULL, *p2 = NULL, *p3;
106
107#define minEps 5e-16
108
109 if( ptwXY_simpleCoalescePoints( smr, ptwXY ) != nfu_Okay ) {
111 return( NULL );
112 }
113
114 if( ptwXY->interpolation != ptwXY_interpolationFlat ) {
115 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_invalidInterpolation, "Source interpolation not 'flat' but '%s'.",
116 ptwXY->interpolationString );
117 return( NULL );
118 }
119
120 if( ( lowerEps < 0 ) || ( upperEps < 0 ) || ( ( lowerEps == 0 ) && ( upperEps == 0 ) ) ) {
121 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_badInput, "Bad epsilons: lowerEps = %.17e and upperEps = %.17e.",
122 lowerEps, upperEps );
123 return( NULL );
124 }
125 if( ( lowerEps != 0 ) && ( lowerEps < minEps ) ) lowerEps = minEps;
126 if( ( upperEps != 0 ) && ( upperEps < minEps ) ) upperEps = minEps;
127
128 length = ptwXY->length * ( 1 + ( lowerEps == 0 ? 0 : 1 ) + ( lowerEps == 0 ? 0 : 1 ) );
129 if( ( n = ptwXY_new( smr, ptwXY_interpolationLinLin, NULL, ptwXY->biSectionMax, ptwXY->accuracy, length,
130 ptwXY->overflowLength, ptwXY->userFlag ) ) == NULL ) {
132 return( NULL );
133 }
134
135 p3 = ptwXY->points;
136 if( ptwXY->length > 0 ) {
137 if( ptwXY_setValueAtX( smr, n, p3->x, p3->y ) != nfu_Okay ) goto Err;
138 }
139 for( i = 0; i < ptwXY->length; i++, p3++ ) {
140 if( i > 1 ) {
141 if( lowerEps > 0 ) {
142 x = ptwXY_flatInterpolationToLinear_eps( p2->x, -lowerEps );
143 if( x > p1->x ) {
144 if( ptwXY_setValueAtX( smr, n, x, p1->y ) != nfu_Okay ) goto Err;
145 }
146 }
147 if( lowerEps == 0 ) if( ptwXY_setValueAtX( smr, n, p2->x, p1->y ) != nfu_Okay ) goto Err;
148 if( upperEps == 0 ) if( ptwXY_setValueAtX( smr, n, p2->x, p2->y ) != nfu_Okay ) goto Err;
149 if( upperEps > 0 ) {
150 x = ptwXY_flatInterpolationToLinear_eps( p2->x, upperEps );
151 if( x < p3->x ) {
152 if( ptwXY_setValueAtX( smr, n, x, p2->y ) != nfu_Okay ) goto Err;
153 }
154 }
155 }
156 p1 = p2;
157 p2 = p3;
158 }
159 if( ptwXY->length > 1 ) {
160 if( ( lowerEps != 0 ) && ( p1->y != p2->y ) ) {
161 x = ptwXY_flatInterpolationToLinear_eps( p2->x, -lowerEps );
162 if( x > p1->x ) {
163 if( ptwXY_setValueAtX( smr, n, x, p1->y ) != nfu_Okay ) goto Err;
164 }
165 }
166 if( ptwXY_setValueAtX( smr, n, p2->x, p2->y ) != nfu_Okay ) goto Err;
167 }
168
169 return( n );
170
171Err:
173 ptwXY_free( n );
174 return( NULL );
175
176#undef minEps
177}
@ nfu_invalidInterpolation
@ nfu_Okay
@ nfu_badInput
@ nfu_Error
int nfu_SMR_libraryID
nfu_status ptwXY_setValueAtX(statusMessageReporting *smr, ptwXYPoints *ptwXY, double x, double y)
@ ptwXY_interpolationFlat
Definition ptwXY.h:38
@ ptwXY_interpolationLinLin
Definition ptwXY.h:37
struct ptwXYPoints_s ptwXYPoints
ptwXYPoints * ptwXY_new(statusMessageReporting *smr, ptwXY_interpolation interpolation, char const *interpolationString, double biSectionMax, double accuracy, int64_t primarySize, int64_t secondarySize, int userFlag)
Definition ptwXY_core.c:28
struct ptwXYPoint_s ptwXYPoint
ptwXYPoints * ptwXY_free(ptwXYPoints *ptwXY)
Definition ptwXY_core.c:782
nfu_status ptwXY_simpleCoalescePoints(statusMessageReporting *smr, ptwXYPoints *ptwXY)
Definition ptwXY_core.c:734
#define minEps
#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
int userFlag
Definition ptwXY.h:83
ptwXYPoint * points
Definition ptwXY.h:93
ptwXY_interpolation interpolation
Definition ptwXY.h:81
double biSectionMax
Definition ptwXY.h:84
double accuracy
Definition ptwXY.h:85
int64_t length
Definition ptwXY.h:87
int64_t overflowLength
Definition ptwXY.h:89
char const * interpolationString
Definition ptwXY.h:82

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

◆ ptwXY_fromUnitbase()

ptwXYPoints * ptwXY_fromUnitbase ( statusMessageReporting * smr,
ptwXYPoints * ptwXY,
double domainMin,
double domainMax,
int scaleRange )

Definition at line 403 of file ptwXY_interpolation.c.

404 {
405
406 int64_t i, length;
407 ptwXYPoints *n;
408 ptwXYPoint *p, *p2;
409 double dx, inverseDx, xLast = 0.;
410
411 if( ptwXY->length < 2 ) {
412 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_tooFewPoints, "Too few points %d", (int) ptwXY->length );
413 return( NULL );
414 }
415 if( ( n = ptwXY_clone( smr, ptwXY ) ) == NULL ) {
417 return( NULL );
418 }
419
420 dx = domainMax - domainMin;
421 inverseDx = 1. / dx;
422 length = n->length;
423 for( i = 0, p2 = p = n->points; i < length; ++i, ++p ) {
424 p2->x = p->x * dx + domainMin;
425 if( i > 0 ) {
426 if( fabs( p2->x - xLast ) <= 10. * DBL_EPSILON * ( fabs( p2->x ) + fabs( xLast ) ) ) {
427 --(n->length);
428 continue;
429 }
430 }
431 if( scaleRange ) p2->y = p->y * inverseDx;
432 xLast = p2->x;
433 ++p2;
434 }
435 n->points[n->length-1].x = domainMax; /* Make sure last point is realy domainMax. */
436 return( n );
437}
@ nfu_tooFewPoints
ptwXYPoints * ptwXY_clone(statusMessageReporting *smr, ptwXYPoints *ptwXY)
Definition ptwXY_core.c:302
#define DBL_EPSILON
Definition templates.hh:66

Referenced by ptwXY_unitbaseInterpolate().

◆ ptwXY_interpolatePoint()

nfu_status ptwXY_interpolatePoint ( statusMessageReporting * smr,
ptwXY_interpolation interpolation,
double x,
double * y,
double x1,
double y1,
double x2,
double y2 )

Definition at line 30 of file ptwXY_interpolation.c.

31 {
32
33 nfu_status status = nfu_Okay;
34
35 if( interpolation == ptwXY_interpolationOther ) {
36 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_otherInterpolation, "Other interpolation not allow." );
37 return( nfu_otherInterpolation );
38 }
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 );
43 }
44 if( y1 == y2 ) {
45 *y = y1; }
46 else if( x1 == x2 ) {
47 *y = 0.5 * ( y1 + y2 ); }
48 else if( x == x1 ) {
49 *y = y1; }
50 else if( x == x2 ) {
51 *y = y2; }
52 else {
53 switch( interpolation ) {
55 *y = ( y1 * ( x2 - x ) + y2 * ( x - x1 ) ) / ( x2 - x1 );
56 break;
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 );
62 }
63 *y = ( y1 * log( x2 / x ) + y2 * log( x / x1 ) ) / log( x2 / x1 );
64 break;
66 if( ( y1 <= 0. ) || ( y2 <= 0. ) ) {
68 "For log(y), some y-values less than equal to 0, y1 = %.17e, y2 = %.17e.", y1, y2 );
70 }
71 *y = exp( ( log( y1 ) * ( x2 - x ) + log( y2 ) * ( x - x1 ) ) / ( x2 - x1 ) );
72 break;
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 );
78 }
79 if( ( y1 <= 0. ) || ( y2 <= 0. ) ) {
81 "For log(y), some y-values less than equal to 0, y1 = %.17e, y2 = %.17e.", y1, y2 );
83 }
84 *y = exp( ( log( y1 ) * log( x2 / x ) + log( y2 ) * log( x / x1 ) ) / log( x2 / x1 ) );
85 break;
87 *y = y1;
88 break;
89 default :
91 "Invalid interpolation token = %d.", interpolation );
93 }
94 }
95 return( status );
96}
@ 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_dullEdges(), ptwXY_getValueAtX(), ptwXY_integrate(), ptwXY_integrateWithWeight_sqrt_x(), ptwXY_integrateWithWeight_x(), ptwXY_mapToXsAndAdd(), ptwXY_thicken(), ptwXY_union(), ptwXY_ysMappedToXs(), and GIDI::Functions::XYs1d::ysMappedToXs().

◆ ptwXY_toOtherInterpolation()

ptwXYPoints * ptwXY_toOtherInterpolation ( statusMessageReporting * smr,
ptwXYPoints * ptwXY,
ptwXY_interpolation interpolationTo,
double accuracy )

Definition at line 197 of file ptwXY_interpolation.c.

198 {
199/*
200* This function only works when 'ptwXY->interpolation == interpolationTo' or when interpolationTo is ptwXY_interpolationLinLin.
201*/
202 int i1, logX = 0, logY = 0;
203 ptwXYPoints *n1;
204 interpolation_func func = NULL;
205
206 if( ptwXY->status != nfu_Okay ) {
207 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Invalid source." );
208 return( NULL );
209 }
210
211 if( ptwXY->interpolation == interpolationTo ) {
212 if( ( n1 = ptwXY_clone( smr, ptwXY ) ) == NULL ) smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_Error, "Via." );
213 return( n1 ); }
214 else {
215 if( interpolationTo == ptwXY_interpolationLinLin ) {
216 switch( ptwXY->interpolation ) {
218 logX = logY = 1;
219 func = ptwXY_LogLogToLinLin; break;
221 logY = 1;
222 func = ptwXY_LogLinToLinLin; break;
224 logX = 1;
225 func = ptwXY_LinLogToLinLin; break;
226 case ptwXY_interpolationLinLin : /* Stops compilers from complaining. */
229 break;
230 }
231 }
232 }
233 if( func == NULL ) {
235 "Interpolation conversion from '%s' to %d not supported.", ptwXY->interpolationString, interpolationTo );
236 return( NULL );
237 }
238
239 if( ( logX != 0 ) || ( logY != 0 ) ) {
240 ptwXYPoint *point;
241
242 if( ptwXY_simpleCoalescePoints( smr, ptwXY ) != nfu_Okay ) {
244 return( NULL );
245 }
246
247 for( i1 = 0, point = ptwXY->points; i1 < ptwXY->length; ++i1, ++point ) {
248 if( ( logX != 0 ) && ( point->x <= 0 ) ) {
249 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_badLogValue, "At index %d x-value %.16e for log <= 0.",
250 (int) i1, point->x );
251 return( NULL );
252 }
253 if( ( logY != 0 ) && ( point->y <= 0 ) ) {
254 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_badLogValue, "At index %d y-value %.16e for log <= 0.",
255 (int) i1, point->y );
256 return( NULL );
257 }
258 }
259 }
260
261 if( ( n1 = ptwXY_cloneToInterpolation( smr, ptwXY, interpolationTo ) ) == NULL ) {
263 return( NULL );
264 }
265 n1->accuracy = ptwXY_limitAccuracy( accuracy );
266
267 if( ptwXY_toOtherInterpolation2( smr, n1, ptwXY, func ) != nfu_Okay ) {
269 n1 = ptwXY_free( n1 ); }
270 else {
271 if( n1->accuracy < ptwXY->accuracy ) n1->accuracy = ptwXY->accuracy;
272 }
273 return( n1 );
274}
@ nfu_badSelf
@ nfu_badLogValue
@ nfu_unsupportedInterpolationConversion
double ptwXY_limitAccuracy(double accuracy)
Definition ptwXY_misc.c:28
ptwXYPoints * ptwXY_cloneToInterpolation(statusMessageReporting *smr, ptwXYPoints *ptwXY, ptwXY_interpolation interpolationTo)
Definition ptwXY_core.c:349
nfu_status(* interpolation_func)(statusMessageReporting *smr, ptwXYPoints *desc, double x1, double y1, double x2, double y2, int depth)
nfu_status status
Definition ptwXY.h:80

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

◆ ptwXY_toUnitbase()

ptwXYPoints * ptwXY_toUnitbase ( statusMessageReporting * smr,
ptwXYPoints * ptwXY,
int scaleRange )

Definition at line 373 of file ptwXY_interpolation.c.

373 {
374
375 int64_t i;
376 ptwXYPoints *n;
377 ptwXYPoint *p;
378 double domainMin, domainMax, dx, inverseDx;
379
380 if( ptwXY->length < 2 ) {
381 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_tooFewPoints, "Too few points %d", (int) ptwXY->length );
382 return( NULL );
383 }
384 if( ( n = ptwXY_clone( smr, ptwXY ) ) == NULL ) {
386 return( NULL );
387 }
388
389 domainMin = n->points[0].x;
390 domainMax = n->points[n->length-1].x;
391 dx = domainMax - domainMin;
392 inverseDx = 1. / dx;
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;
396 }
397 n->points[n->length-1].x = 1.; /* Make sure last point is realy 1. */
398 return( n );
399}

Referenced by ptwXY_unitbaseInterpolate().

◆ ptwXY_unitbaseInterpolate()

ptwXYPoints * ptwXY_unitbaseInterpolate ( statusMessageReporting * smr,
double w,
double w1,
ptwXYPoints * ptwXY1,
double w2,
ptwXYPoints * ptwXY2,
int scaleRange )

Definition at line 441 of file ptwXY_interpolation.c.

442 {
443/*
444* Should we not be checking the interpolation members???????
445*/
446 int64_t i;
447 ptwXYPoints *n1 = NULL, *n2 = NULL, *a = NULL, *r = NULL;
448 ptwXYPoint *p;
449 double f, g, domainMin, domainMax;
450
451 if( ( w < w1 ) || ( w > w2 ) ) {
452 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_XOutsideDomain, "W value outside w-domain: (%.15e, %.15e)",
453 w1, w2 );
454 return( NULL );
455 }
456 if( w == w1 ) {
457 if( ( n1 = ptwXY_clone( smr, ptwXY1 ) ) == NULL ) smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_Error, "Via (source1)." );
458 return( n1 );
459 }
460 if( w == w2 ) {
461 if( ( n1 = ptwXY_clone( smr, ptwXY2 ) ) == NULL ) smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_Error, "Via (source2)." );
462 return( n1 );
463 }
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 );
467 g = 1. - f;
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;
470 if( ( a = ptwXY_add_ptwXY( smr, n1, n2 ) ) == NULL ) goto Err;
471
472 domainMin = g * ptwXY1->points[0].x + f * ptwXY2->points[0].x;
473 domainMax = g * ptwXY1->points[ptwXY1->length-1].x + f * ptwXY2->points[ptwXY2->length-1].x;
474 if( ( r = ptwXY_fromUnitbase( smr, a, domainMin, domainMax, scaleRange ) ) == NULL ) goto Err;
475 ptwXY_free( n1 );
476 ptwXY_free( n2 );
477 ptwXY_free( a );
478 return( r );
479
480Err:
482 if( n1 != NULL ) ptwXY_free( n1 );
483 if( n2 != NULL ) ptwXY_free( n2 );
484 if( a != NULL ) ptwXY_free( a );
485 return( NULL );
486}
@ nfu_XOutsideDomain
ptwXYPoints * ptwXY_add_ptwXY(statusMessageReporting *smr, ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2)
ptwXYPoints * ptwXY_toUnitbase(statusMessageReporting *smr, ptwXYPoints *ptwXY, int scaleRange)
ptwXYPoints * ptwXY_fromUnitbase(statusMessageReporting *smr, ptwXYPoints *ptwXY, double domainMin, double domainMax, int scaleRange)