11 #if defined __cplusplus 
   19 typedef nfu_status (*
interpolation_func)( ptwXYPoints *desc, 
double x1, 
double y1, 
double x2, 
double y2, 
int depth );
 
   23 static nfu_status 
ptwXY_LogLogToLinLin( ptwXYPoints *desc, 
double x1, 
double y1, 
double x2, 
double y2, 
int depth );
 
   24 static nfu_status 
ptwXY_LinLogToLinLin( ptwXYPoints *desc, 
double x1, 
double y1, 
double x2, 
double y2, 
int depth );
 
   25 static nfu_status 
ptwXY_LogLinToLinLin( ptwXYPoints *desc, 
double x1, 
double y1, 
double x2, 
double y2, 
int depth );
 
   26 static nfu_status 
ptwXY_otherToLinLin( ptwXYPoints *desc, 
double x1, 
double y1, 
double x2, 
double y2, 
int depth );
 
   30 nfu_status 
ptwXY_interpolatePoint( ptwXY_interpolation interpolation, 
double x, 
double *y, 
double x1, 
double y1, 
double x2, 
double y2 ) {
 
   32     nfu_status status = nfu_Okay;
 
   34     if( interpolation == ptwXY_interpolationOther ) 
return( nfu_otherInterpolation );
 
   35     if( ( x1 > x2 ) || ( x < x1 ) || ( x > x2 ) ) 
return( nfu_invalidInterpolation );
 
   39         *y = 0.5 * ( y1  + y2 ); }
 
   45         switch( interpolation ) {
 
   46         case ptwXY_interpolationLinLin :
 
   47             *y = ( y1 * ( x2 - x ) + y2 * ( x - x1 ) ) / ( x2 - x1 );
 
   49         case ptwXY_interpolationLogLin :
 
   50             if( ( x <= 0. ) || ( x1 <= 0. ) || ( x2 <= 0. ) ) 
return( nfu_invalidInterpolation );
 
   51             *y = ( y1 * 
G4Log( x2 / x ) + y2 * 
G4Log( x / x1 ) ) / 
G4Log( x2 / x1 );
 
   53         case ptwXY_interpolationLinLog :
 
   54             if( ( y1 <= 0. ) || ( y2 <= 0. ) ) 
return( nfu_invalidInterpolation );
 
   55             *y = 
G4Exp( ( 
G4Log( y1 ) * ( x2 - x ) + 
G4Log( y2 ) * ( x - x1 ) ) / ( x2 - x1 ) );
 
   57         case ptwXY_interpolationLogLog :
 
   58             if( ( x <= 0. ) || ( x1 <= 0. ) || ( x2 <= 0. ) ) 
return( nfu_invalidInterpolation );
 
   59             if( ( y1 <= 0. ) || ( y2 <= 0. ) ) 
return( nfu_invalidInterpolation );
 
   62         case ptwXY_interpolationFlat :
 
   66             status = nfu_invalidInterpolation;
 
   79     ptwXYPoint *p1 = NULL, *p2 = NULL, *p3;
 
   84     *status = nfu_invalidInterpolation;
 
   85     if( ptwXY->interpolation != ptwXY_interpolationFlat ) 
return( NULL );
 
   86     *status = nfu_badInput;
 
   87     if( ( lowerEps < 0 ) || ( upperEps < 0 ) || ( ( lowerEps == 0 ) && ( upperEps == 0 ) ) ) 
return( NULL );
 
   88     if( ( lowerEps != 0 ) && ( lowerEps < 
minEps ) ) lowerEps = 
minEps;
 
   89     if( ( upperEps != 0 ) && ( upperEps < 
minEps ) ) upperEps = 
minEps;
 
   91     length = ptwXY->length * ( 1 + ( lowerEps == 0 ? 0 : 1 ) + ( lowerEps == 0 ? 0 : 1 ) );
 
   92     if( ( n = 
ptwXY_new( ptwXY_interpolationLinLin, NULL, ptwXY->biSectionMax, ptwXY->accuracy, length, ptwXY->overflowLength, status, ptwXY->userFlag ) ) == NULL ) 
return( NULL );
 
   96     for( i = 0; i < ptwXY->length; i++, p3++ ) {
 
  104             if( lowerEps == 0 ) 
if( ( *status = 
ptwXY_setValueAtX( n, p2->x, p1->y ) ) != nfu_Okay ) 
goto Err;
 
  105             if( upperEps == 0 ) 
if( ( *status = 
ptwXY_setValueAtX( n, p2->x, p2->y ) ) != nfu_Okay ) 
goto Err;
 
  116     if( ptwXY->length > 1 ) {
 
  117         if( ( lowerEps != 0 ) && ( p1->y != p2->y ) ) {
 
  142         x = ( 1 - 
eps ) * px; }
 
  144         x = ( 1 + 
eps ) * px; }
 
  160     if( ( *status = ptwXY->status ) != nfu_Okay ) 
return( NULL );
 
  161     if( ptwXY->interpolation == interpolationTo ) {
 
  165         if( interpolationTo == ptwXY_interpolationLinLin ) {
 
  166             switch( ptwXY->interpolation ) {
 
  167             case ptwXY_interpolationLogLog :
 
  169             case ptwXY_interpolationLinLog :
 
  171             case ptwXY_interpolationLogLin :
 
  173             case ptwXY_interpolationOther :
 
  176             case ptwXY_interpolationLinLin :        
 
  177             case ptwXY_interpolationFlat :
 
  182     *status = nfu_unsupportedInterpolationConversion;
 
  183     if( func == NULL ) 
return( NULL );
 
  187     if( accuracy < ptwXY->accuracy ) accuracy = ptwXY->accuracy;
 
  188     n1->accuracy = accuracy;
 
  190     n1->interpolationOtherInfo.getValueFunc = ptwXY->interpolationOtherInfo.getValueFunc;
 
  191     n1->interpolationOtherInfo.argList = ptwXY->interpolationOtherInfo.argList;
 
  193     n1->interpolationOtherInfo.getValueFunc = NULL;
 
  194     n1->interpolationOtherInfo.argList = NULL;
 
  195     if( *status != nfu_Okay ) n1 = 
ptwXY_free( n1 );
 
  205     double x1, y1, x2, y2;
 
  209     x1 = src->points[0].x;
 
  210     y1 = src->points[0].y;
 
  211     for( i = 1; i < src->length; i++ ) {
 
  212         x2 = src->points[i].x;
 
  213         y2 = src->points[i].y;
 
  214         if( ( x1 != x2 ) && ( y1 != y2 ) ) {
 
  215             if( ( status = func( desc, x1, y1, x2, y2, 0 ) ) != nfu_Okay ) 
break;
 
  225 static nfu_status 
ptwXY_LogLogToLinLin( ptwXYPoints *desc, 
double x1, 
double y1, 
double x2, 
double y2, 
int depth ) {
 
  227     nfu_status status = nfu_Okay;
 
  228     double x, y, u, u2 = x2 / x1, v2 = y2 / y1, logYXs, logXs = 
G4Log( u2 ), logYs = 
G4Log( v2 ), vLin, vLog, w;
 
  230     logYXs = logYs / logXs;
 
  232     if( depth > 16 ) 
return( nfu_Okay );
 
  233     if( std::fabs( logYXs  - 1 ) < 1e-5 ) {
 
  234         u = 0.5 * ( 1 + u2 );
 
  235         w = ( logYXs  - 1 ) * logXs;
 
  236         vLog = u * ( 1. + w * ( 1 + 0.5 * w ) ); }
 
  238         u = logYXs * ( u2 - v2 ) / ( ( 1 - logYXs ) * ( v2 - 1 ) );
 
  241     vLin = ( u2 - u + v2 * ( u - 1 ) ) / ( u2 - 1 );
 
  242     if( std::fabs( vLog - vLin ) <= ( vLog * desc->accuracy ) ) 
return( status );
 
  246     if( ( status = 
ptwXY_LogLogToLinLin( desc, x1, y1, x, y, depth + 1 ) ) != nfu_Okay ) 
return( status );
 
  252 static nfu_status 
ptwXY_LinLogToLinLin( ptwXYPoints *desc, 
double x1, 
double y1, 
double x2, 
double y2, 
int depth ) {
 
  254     nfu_status status = nfu_Okay;
 
  255     double x, y, logYs = 
G4Log( y2 / y1 ), yLinLin;
 
  257     if( depth > 16 ) 
return( nfu_Okay );
 
  258     x = ( x2 - x1 ) / ( y2 - y1 ) * ( ( y2 - y1 ) / logYs - y1 ) + x1;
 
  259     y = y1 * 
G4Exp( logYs / ( x2 - x1 ) * ( x - x1 ) );
 
  260     yLinLin = ( y1 * ( x2 - x ) + y2 * ( x - x1 ) ) / ( x2 - x1 );
 
  261     if( std::fabs( y - yLinLin ) <= ( y * desc->accuracy ) ) 
return( status );
 
  263     if( ( status = 
ptwXY_LinLogToLinLin( desc, x1, y1, x, y, depth + 1 ) ) != nfu_Okay ) 
return( status );
 
  269 static nfu_status 
ptwXY_LogLinToLinLin( ptwXYPoints *desc, 
double x1, 
double y1, 
double x2, 
double y2, 
int depth ) {
 
  271     nfu_status status = nfu_Okay;
 
  272     double x = std::sqrt( x2 * x1 ), y, logXs = 
G4Log( x2 / x1 ), yLinLin;
 
  274     if( depth > 16 ) 
return( nfu_Okay );
 
  276     x = ( y1 * x2 - y2 * x1 ) / ( y1 * logXs + ( y2 - y1 ) * ( std::log( x / x1 ) - 1 ) );
 
  278     y = ( y2 - y1 ) * 
G4Log( x / x1 ) / logXs + y1;
 
  279     yLinLin = ( y1 * ( x2 - x ) + y2 * ( x - x1 ) ) / ( x2 - x1 );
 
  280     if( std::fabs( y - yLinLin ) <= ( y * desc->accuracy ) ) 
return( status );
 
  282     if( ( status = 
ptwXY_LogLinToLinLin( desc, x1, y1, x, y, depth + 1 ) ) != nfu_Okay ) 
return( status );
 
  288 static nfu_status 
ptwXY_otherToLinLin( ptwXYPoints *desc, 
double x1, 
double y1, 
double x2, 
double y2, 
int depth ) {
 
  291     double x = 0.5 * ( x1 + x2 ), y, yLinLin;
 
  292     ptwXY_getValue_callback getValueFunc = desc->interpolationOtherInfo.getValueFunc;
 
  293     void *argList = desc->interpolationOtherInfo.argList;
 
  295     if( depth > 16 ) 
return( nfu_Okay );
 
  296     if( ( status = getValueFunc( argList, x, &y, x1, y1, x2, y2 ) ) != nfu_Okay ) 
return( status );
 
  297     yLinLin = ( y1 * ( x2 - x ) + y2 * ( x - x1 ) ) / ( x2 - x1 );
 
  298     if( std::fabs( y - yLinLin ) <= ( y * desc->accuracy ) ) 
return( status );
 
  300     if( ( status = 
ptwXY_otherToLinLin( desc, x1, y1, x, y, depth + 1 ) ) != nfu_Okay ) 
return( status );
 
  311     double xMin, xMax, dx, inverseDx;
 
  313     *status = nfu_tooFewPoints;
 
  314     if( ptwXY->length < 2 ) 
return( NULL );
 
  315     if( ( n = 
ptwXY_clone( ptwXY, status ) ) == NULL ) 
return( NULL );
 
  317     xMin = n->points[0].x;
 
  318     xMax = n->points[n->length-1].x;
 
  321     for( i = 0, p = n->points; i < n->length; i++, p++ ) {
 
  322         p->x = ( p->x - xMin ) * inverseDx;
 
  325     n->points[n->length-1].x = 1.;                          
 
  331 ptwXYPoints *
ptwXY_fromUnitbase( ptwXYPoints *ptwXY, 
double xMin, 
double xMax, nfu_status *status ) {
 
  336     double dx, inverseDx, xLast = 0.;
 
  338     *status = nfu_tooFewPoints;
 
  339     if( ptwXY->length < 2 ) 
return( NULL );
 
  340     if( ( n = 
ptwXY_clone( ptwXY, status ) ) == NULL ) 
return( NULL );
 
  345     for( i = 0, p2 = p = n->points; i < length; ++i, ++p ) {
 
  346         p2->x = p->x * dx + xMin;
 
  348             if( std::fabs( p2->x - xLast ) <= 10. * 
DBL_EPSILON * ( std::fabs( p2->x ) + std::fabs( xLast ) ) ) {
 
  353         p2->y = p->y * inverseDx;
 
  357     n->points[n->length-1].x = xMax;                          
 
  363 ptwXYPoints *
ptwXY_unitbaseInterpolate( 
double w, 
double w1, ptwXYPoints *ptwXY1, 
double w2, ptwXYPoints *ptwXY2, nfu_status *status ) {
 
  368     ptwXYPoints *n1 = NULL, *n2 = NULL, *
a = NULL, *r = NULL;
 
  370     double f, 
g, xMin, xMax;
 
  372     *status = nfu_XOutsideDomain;
 
  374         if( w < w1 ) 
return( NULL );
 
  378         if( w > w2 ) 
return( NULL );
 
  383     f = ( w - w1 ) / ( w2 - w1 );
 
  385     for( i = 0, p = n1->points; i < n1->length; i++, p++ ) p->y *= 
g;
 
  386     for( i = 0, p = n2->points; i < n2->length; i++, p++ ) p->y *= f;
 
  389     xMin = g * ptwXY1->points[0].x + f * ptwXY2->points[0].x;
 
  390     xMax = g * ptwXY1->points[ptwXY1->length-1].x + f * ptwXY2->points[ptwXY2->length-1].x;
 
  404 #if defined __cplusplus 
static G4Pow * GetInstance()
 
G4double powA(G4double A, G4double y) const 
 
std::vector< ExP01TrackerHit * > a
 
nfu_status ptwXY_simpleCoalescePoints(ptwXYPoints *ptwXY)
 
ptwXYPoints * ptwXY_free(ptwXYPoints *ptwXY)
 
static const G4double eps
 
nfu_status ptwXY_setValueAtX(ptwXYPoints *ptwXY, double x, double y)
 
static constexpr double g
 
static double ptwXY_flatInterpolationToLinear_eps(double px, double eps)
 
ptwXYPoints * ptwXY_unitbaseInterpolate(double w, double w1, ptwXYPoints *ptwXY1, double w2, ptwXYPoints *ptwXY2, nfu_status *status)
 
static nfu_status ptwXY_LogLinToLinLin(ptwXYPoints *desc, double x1, double y1, double x2, double y2, int depth)
 
static nfu_status ptwXY_LogLogToLinLin(ptwXYPoints *desc, double x1, double y1, double x2, double y2, int depth)
 
static nfu_status ptwXY_otherToLinLin(ptwXYPoints *desc, double x1, double y1, double x2, double y2, int depth)
 
ptwXYPoints * ptwXY_toOtherInterpolation(ptwXYPoints *ptwXY, ptwXY_interpolation interpolationTo, double accuracy, nfu_status *status)
 
G4double G4Log(G4double x)
 
ptwXYPoints * ptwXY_add_ptwXY(ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, nfu_status *status)
 
G4double G4Exp(G4double initial_x)
Exponential Function double precision. 
 
ptwXYPoints * ptwXY_clone(ptwXYPoints *ptwXY, nfu_status *status)
 
static nfu_status ptwXY_LinLogToLinLin(ptwXYPoints *desc, double x1, double y1, double x2, double y2, int depth)
 
ptwXYPoints * ptwXY_flatInterpolationToLinear(ptwXYPoints *ptwXY, double lowerEps, double upperEps, nfu_status *status)
 
nfu_status(* interpolation_func)(ptwXYPoints *desc, double x1, double y1, double x2, double y2, int depth)
 
ptwXYPoints * ptwXY_cloneToInterpolation(ptwXYPoints *ptwXY, ptwXY_interpolation interpolationTo, 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)
 
nfu_status ptwXY_interpolatePoint(ptwXY_interpolation interpolation, double x, double *y, double x1, double y1, double x2, double y2)
 
ptwXYPoints * ptwXY_fromUnitbase(ptwXYPoints *ptwXY, double xMin, double xMax, nfu_status *status)
 
static nfu_status ptwXY_toOtherInterpolation2(ptwXYPoints *desc, ptwXYPoints *src, interpolation_func func)
 
ptwXYPoints * ptwXY_toUnitbase(ptwXYPoints *ptwXY, nfu_status *status)