11 #if defined __cplusplus 
   16 static double ptwXY_mod2( 
double v, 
double m, 
int pythonMod );
 
   17 static nfu_status 
ptwXY_mul2_s_ptwXY( ptwXYPoints *
n, ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, 
double x1, 
double y1, 
double x2, 
double y2, 
int level );
 
   18 static nfu_status 
ptwXY_div_s_ptwXY( ptwXYPoints *
n, ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, 
double x1, 
double y1, 
double x2, 
double y2, 
 
   19     int level, 
int isNAN1, 
int isNAN2 );
 
   20 static ptwXYPoints *
ptwXY_div_ptwXY_forFlats( ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, nfu_status *status, 
int safeDivide );
 
   29     ptwXYOverflowPoint *o, *overflowHeader = &(ptwXY->overflowHeader);
 
   31     if( ptwXY->status != nfu_Okay ) 
return( ptwXY->status );
 
   33     for( i = 0, p = ptwXY->points; i < nonOverflowLength; i++, p++ ) p->y = slope * p->y + offset;
 
   34     for( o = overflowHeader->next; o != overflowHeader; o = o->next ) o->point.y = slope * o->point.y + offset; 
 
   35     return( ptwXY->status );
 
   47         ptwXY->status = nfu_divByZero; }
 
   51     return( ptwXY->status );
 
   60     ptwXYOverflowPoint *o, *overflowHeader = &(ptwXY->overflowHeader);
 
   62     if( ptwXY->status != nfu_Okay ) 
return( ptwXY->status );
 
   63     if( ptwXY->interpolation == ptwXY_interpolationOther ) 
return( nfu_otherInterpolation );
 
   65     for( i = 0, p = ptwXY->points; i < nonOverflowLength; i++, p++ ) 
if( p->y == 0. ) ptwXY->status = nfu_divByZero;
 
   66     for( o = overflowHeader->next; o != overflowHeader; o = o->next ) 
if( o->point.y == 0. ) ptwXY->status = nfu_divByZero;
 
   67     if( ptwXY->status != nfu_divByZero ) {
 
   68         for( i = 0, p = ptwXY->points; i < nonOverflowLength; i++, p++ ) p->y = value / p->y;
 
   69         for( o = overflowHeader->next; o != overflowHeader; o = o->next ) o->point.y = value / o->point.y; 
 
   71     return( ptwXY->status );
 
   76 nfu_status 
ptwXY_mod( ptwXYPoints *ptwXY, 
double m, 
int pythonMod ) { 
 
   80     ptwXYOverflowPoint *o, *overflowHeader = &(ptwXY->overflowHeader);
 
   82     if( ptwXY->status != nfu_Okay ) 
return( ptwXY->status );
 
   83     if( m == 0 ) 
return( ptwXY->status = nfu_divByZero );
 
   85     for( i = 0, p = ptwXY->points; i < nonOverflowLength; i++, p++ ) p->y = 
ptwXY_mod2( p->y, m, pythonMod );
 
   86     for( o = overflowHeader->next; o != overflowHeader; o = o->next ) o->point.y = 
ptwXY_mod2( o->point.y, m, pythonMod );
 
   87     return( ptwXY->status );
 
   92 static double ptwXY_mod2( 
double v, 
double m, 
int pythonMod ) {
 
   94     double r = std::fmod( std::fabs( v ), std::fabs( m ) );
 
   97         if( ( v * m ) < 0. ) r = std::fabs( m ) - std::fabs( r );
 
   98         if( m < 0. ) r *= -1.; }
 
  100         if( v < 0. ) r *= -1.;
 
  108 ptwXYPoints *
ptwXY_binary_ptwXY( ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, 
double v1, 
double v2, 
double v1v2, nfu_status *status ) {
 
  111     int unionOptions = ptwXY_union_fill | ptwXY_union_mergeClosePoints;
 
  116     *status = nfu_otherInterpolation;
 
  117     if( ptwXY1->interpolation == ptwXY_interpolationOther ) 
return( NULL );
 
  118     if( ptwXY2->interpolation == ptwXY_interpolationOther ) 
return( NULL );
 
  120     if( ( ptwXY1->interpolation == ptwXY_interpolationFlat ) || ( ptwXY2->interpolation == ptwXY_interpolationFlat ) ) {
 
  121         *status = nfu_invalidInterpolation;
 
  122         if( ( ptwXY1->interpolation != ptwXY2->interpolation ) ) 
return( NULL );
 
  124     if( ( n = 
ptwXY_union( ptwXY1, ptwXY2, status, unionOptions ) ) != NULL ) {
 
  125         for( i = 0, p = n->points; i < n->length; i++, p++ ) {
 
  127             p->y = v1 * p->y + v2 * y + v1v2 * y * p->y;
 
  138 ptwXYPoints *
ptwXY_add_ptwXY( ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, nfu_status *status ) {
 
  142     if( ptwXY1->length == 0 ) {
 
  144     else if( ptwXY2->length == 0 ) {
 
  154 ptwXYPoints *
ptwXY_sub_ptwXY( ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, nfu_status *status ) {
 
  158     if( ptwXY1->length == 0 ) {
 
  161     else if( ptwXY2->length == 0 ) {
 
  171 ptwXYPoints *
ptwXY_mul_ptwXY( ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, nfu_status *status ) {
 
  175     if( ptwXY1->length == 0 ) {
 
  177     else if( ptwXY2->length == 0 ) {
 
  187 ptwXYPoints *
ptwXY_mul2_ptwXY( ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, nfu_status *status ) {
 
  190     ptwXYPoints *
n = NULL;
 
  192     double x1, y1, x2, y2, u1, u2, v1, v2, xz1 = 0, xz2 = 0, 
x;
 
  194     *status = nfu_otherInterpolation;
 
  195     if( ptwXY1->interpolation == ptwXY_interpolationOther ) 
return( NULL );
 
  196     if( ptwXY2->interpolation == ptwXY_interpolationOther ) 
return( NULL );
 
  197     if( ( n = 
ptwXY_mul_ptwXY( ptwXY1, ptwXY2, status ) ) == NULL ) 
return( n );
 
  198     if( ptwXY1->interpolation == ptwXY_interpolationFlat ) 
return( n );
 
  199     if( ptwXY2->interpolation == ptwXY_interpolationFlat ) 
return( n );
 
  200     length = n->length - 1;
 
  202         x2 = n->points[length].x;
 
  203         for( i = length - 1; i >= 0; i-- ) {             
 
  211                 xz1 = ( u1 * x2 - u2 * x1 ) / ( u1 - u2 );
 
  216                 xz2 = ( v1 * x2 - v2 * x1 ) / ( v1 - v2 );
 
  221                 x = 0.5 * ( xz1 + xz2 );
 
  231         x2 = n->points[n->length-1].x;
 
  232         y2 = n->points[n->length-1].y;
 
  233         for( i = n->length - 2; i >= 0; i-- ) {             
 
  236             if( ( *status = 
ptwXY_mul2_s_ptwXY( n, ptwXY1, ptwXY2, x1, y1, x2, y2, 0 ) ) != nfu_Okay ) 
goto Err;
 
  251 static nfu_status 
ptwXY_mul2_s_ptwXY( ptwXYPoints *
n, ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, 
double x1, 
double y1, 
double x2, 
double y2, 
int level ) {
 
  254     double u1, u2, v1, v2, 
x, y, yp, dx, 
a1, 
a2;
 
  256     if( ( x2 - x1 ) < ClosestAllowXFactor * 
DBL_EPSILON * ( std::fabs( x1 ) + std::fabs( x2 ) ) ) 
return( nfu_Okay );
 
  257     if( level >= n->biSectionMax ) 
return( nfu_Okay );
 
  263     if( ( u1 == u2 ) || ( v1 == v2 ) ) 
return( nfu_Okay );
 
  265     if( y1 == 0 ) a1 = 0.;                                  
 
  267     if( y2 == 0 ) a2 = 0.;                                  
 
  268     if( ( a1 == 0. ) || ( a2 == 0. ) ) {                    
 
  269         x = 0.5 * ( x1 + x2 ); }
 
  271         if( ( a1 * a2 < 0. ) ) 
return( nfu_Okay );  
 
  272         a1 = std::sqrt( std::fabs( a1 ) );
 
  273         a2 = std::sqrt( std::fabs( a2 ) );
 
  274         x = ( a2 * x1 + a1 * x2 ) / ( a2 + a1 );
 
  277     yp = ( u1 * v1 * ( x2 - 
x ) + u2 * v2 * ( x - x1 ) ) / dx;
 
  278     y = ( u1 * ( x2 - 
x ) + u2 * ( x - x1 ) ) * ( v1 * ( x2 - x ) + v2 * ( x - x1 ) ) / ( dx * dx );
 
  279     if( std::fabs( y - yp ) < std::fabs( y * n->accuracy ) ) 
return( nfu_Okay );
 
  281     if( ( status = 
ptwXY_mul2_s_ptwXY( n, ptwXY1, ptwXY2, x, y, x2, y2, level ) ) != nfu_Okay ) 
return( status );
 
  288 ptwXYPoints *
ptwXY_div_ptwXY( ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, nfu_status *status, 
int safeDivide ) {
 
  291     int64_t i, j, k, zeros = 0, length, iYs;
 
  292     double x1, x2, y1, y2, u1, u2, v1, v2, y, xz, nan = 
nfu_getNAN( ), s1, s2;
 
  293     ptwXYPoints *
n = NULL;
 
  298     *status = nfu_otherInterpolation;
 
  299     if( ptwXY1->interpolation == ptwXY_interpolationOther ) 
return( NULL );
 
  300     if( ptwXY2->interpolation == ptwXY_interpolationOther ) 
return( NULL );
 
  301     if( ( ptwXY1->interpolation == ptwXY_interpolationFlat ) || ( ptwXY1->interpolation == ptwXY_interpolationFlat ) )
 
  305     if( ( n = 
ptwXY_union( ptwXY1, ptwXY2, status, ptwXY_union_fill | ptwXY_union_mergeClosePoints ) ) != NULL ) {
 
  306         for( i = 0, p = n->points; i < n->length; i++, p++ ) {
 
  315                             if( *status != nfu_XOutsideDomain ) 
goto Err;
 
  318                         if( ( *status = 
ptwXY_getSlopeAtX( ptwXY2, p->x, 
'-', &s2 ) ) != nfu_Okay ) 
goto Err;
 
  326                     if( i < ( n->length - 1 ) ) {
 
  328                             if( *status != nfu_XOutsideDomain ) 
goto Err;
 
  331                         if( ( *status = 
ptwXY_getSlopeAtX( ptwXY2, p->x, 
'+', &s2 ) ) != nfu_Okay ) 
goto Err;
 
  339                     p->y = ( y1 + y2 ) / iYs; 
 
  343                         *status = nfu_divByZero;
 
  353         length = n->length - 1;
 
  355             x2 = n->points[length].x;
 
  356             for( i = length - 1; i >= 0; i-- ) {             
 
  363                     xz = ( u1 * x2 - u2 * x1 ) / ( u1 - u2 );
 
  368                         *status = nfu_divByZero;
 
  372                     xz = ( v1 * x2 - v2 * x1 ) / ( v1 - v2 );
 
  379             x2 = n->points[n->length-1].x;
 
  380             y2 = n->points[n->length-1].y;
 
  382             for( i = n->length - 2; i >= 0; i-- ) {             
 
  386                 if( !isNAN1 || !isNAN2 ) {
 
  387                     if( ( *status = 
ptwXY_div_s_ptwXY( n, ptwXY1, ptwXY2, x1, y1, x2, y2, 0, isNAN1, isNAN2 ) ) != nfu_Okay ) 
goto Err;
 
  396                 for( i = 0; i < n->length; i++ ) 
if( !
nfu_isNAN( n->points[i].y ) ) 
break;
 
  398                     if( i == n->length ) {                              
 
  400                         for( i = 0; i < n->length; i++ ) n->points[i].y = 0.; }
 
  402                          n->points[0].y = 2. * n->points[i].y;
 
  406                 for( i = n->length - 1; i > 0; i-- ) 
if( !
nfu_isNAN( n->points[i].y ) ) 
break;
 
  407                 if( 
nfu_isNAN( n->points[n->length - 1].y ) ) {         
 
  408                     n->points[n->length - 1].y = 2. * n->points[i].y;
 
  412                     for( i = 0; i < n->length; i++ ) 
if( 
nfu_isNAN( n->points[i].y ) ) 
break;
 
  413                     for( k = i + 1, j = i; k < n->length; k++ ) {
 
  414                     if( 
nfu_isNAN( n->points[k].y ) ) 
continue;
 
  415                         n->points[j] = n->points[k];
 
  432 static nfu_status 
ptwXY_div_s_ptwXY( ptwXYPoints *
n, ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, 
double x1, 
double y1, 
double x2, 
double y2, 
 
  433         int level, 
int isNAN1, 
int isNAN2 ) {
 
  436     double u1, u2, v1, v2, v, 
x, y, yp, dx, 
a1, 
a2;
 
  438     if( ( x2 - x1 ) < ClosestAllowXFactor * 
DBL_EPSILON * ( std::fabs( x1 ) + std::fabs( x2 ) ) ) 
return( nfu_Okay );
 
  439     if( level >= n->biSectionMax ) 
return( nfu_Okay );
 
  443     if( ( status = 
ptwXY_getValueAtX( ptwXY2, x1, &v1 ) ) != nfu_Okay ) 
return( status );
 
  444     if( ( status = 
ptwXY_getValueAtX( ptwXY2, x2, &v2 ) ) != nfu_Okay ) 
return( status );
 
  446         x = 0.5 * ( x1 + x2 );
 
  448         if( ( status = 
ptwXY_getValueAtX( ptwXY2, x, &v1 ) ) != nfu_Okay ) 
return( status );
 
  451         x = 0.5 * ( x1 + x2 );
 
  453         if( ( status = 
ptwXY_getValueAtX( ptwXY2, x, &v2 ) ) != nfu_Okay ) 
return( status );
 
  456         if( ( u1 == u2 ) || ( v1 == v2 ) ) 
return( nfu_Okay );
 
  457         if( ( y1 == 0. ) || ( y2 == 0. ) ) {                    
 
  458             x = 0.5 * ( x1 + x2 ); }
 
  460             if( ( u1 * u2 < 0. ) ) 
return( nfu_Okay );  
 
  461             a1 = std::sqrt( std::fabs( u1 ) );
 
  462             a2 = std::sqrt( std::fabs( u2 ) );
 
  463             x = ( a2 * x1 + a1 * x2 ) / ( a2 + a1 );
 
  466         v = v1 * ( x2 - 
x ) + v2 * ( x - x1 );
 
  467         if( ( v1 == 0. ) || ( v2 == 0. ) || ( v == 0. ) ) 
return( nfu_Okay );     
 
  468         yp = ( u1 / v1 * ( x2 - 
x ) + u2 / v2 * ( x - x1 ) ) / dx;
 
  469         y = ( u1 * ( x2 - 
x ) + u2 * ( x - x1 ) ) / v;
 
  470         if( std::fabs( y - yp ) < std::fabs( y * n->accuracy ) ) 
return( nfu_Okay );
 
  473     if( ( status = 
ptwXY_div_s_ptwXY( n, ptwXY1, ptwXY2, x, y, x2, y2, level, 0, isNAN2 ) ) != nfu_Okay ) 
return( status );
 
  483     ptwXYPoints *
n = NULL;
 
  487     *status = nfu_invalidInterpolation;
 
  488     if( ptwXY1->interpolation != ptwXY_interpolationFlat ) 
return( NULL );
 
  489     if( ptwXY2->interpolation != ptwXY_interpolationFlat ) 
return( NULL );
 
  490     if( ( n = 
ptwXY_union( ptwXY1, ptwXY2, status, ptwXY_union_fill | ptwXY_union_mergeClosePoints ) ) != NULL ) {
 
  491         for( i = 0, p = n->points; i < n->length; i++, p++ ) {
 
  494                 if( ( safeDivide ) && ( p->y == 0 ) ) {
 
  495                     *status = nfu_divByZero;
 
  516     if( status == nfu_XOutsideDomain ) status = nfu_Okay;
 
  520 #if defined __cplusplus 
nfu_status ptwXY_neg(ptwXYPoints *ptwXY)
 
nfu_status ptwXY_areDomainsMutual(ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2)
 
int64_t ptwXY_getNonOverflowLength(ptwXYPoints const *ptwXY)
 
static ptwXYPoints * ptwXY_div_ptwXY_forFlats(ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, nfu_status *status, int safeDivide)
 
nfu_status ptwXY_add_double(ptwXYPoints *ptwXY, double value)
 
ptwXYPoints * ptwXY_mul2_ptwXY(ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, nfu_status *status)
 
nfu_status ptwXY_simpleCoalescePoints(ptwXYPoints *ptwXY)
 
nfu_status ptwXY_sub_fromDouble(ptwXYPoints *ptwXY, double value)
 
static double ptwXY_mod2(double v, double m, int pythonMod)
 
ptwXYPoints * ptwXY_free(ptwXYPoints *ptwXY)
 
nfu_status ptwXY_mul_double(ptwXYPoints *ptwXY, double value)
 
nfu_status ptwXY_getSlopeAtX(ptwXYPoints *ptwXY, double x, const char side, double *slope)
 
nfu_status ptwXY_setValueAtX(ptwXYPoints *ptwXY, double x, double y)
 
nfu_status ptwXY_sub_doubleFrom(ptwXYPoints *ptwXY, double value)
 
nfu_status ptwXY_div_doubleFrom(ptwXYPoints *ptwXY, double value)
 
static nfu_status ptwXY_getValueAtX_ignore_XOutsideDomainError(ptwXYPoints *ptwXY1, double x, double *y)
 
ptwXYPoints * ptwXY_mul_ptwXY(ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, nfu_status *status)
 
static nfu_status ptwXY_div_s_ptwXY(ptwXYPoints *n, ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, double x1, double y1, double x2, double y2, int level, int isNAN1, int isNAN2)
 
nfu_status ptwXY_div_fromDouble(ptwXYPoints *ptwXY, double value)
 
ptwXYPoints * ptwXY_add_ptwXY(ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, nfu_status *status)
 
ptwXYPoints * ptwXY_clone(ptwXYPoints *ptwXY, nfu_status *status)
 
void ptwXY_update_biSectionMax(ptwXYPoints *ptwXY1, double oldLength)
 
nfu_status ptwXY_getValueAtX(ptwXYPoints *ptwXY, double x, double *y)
 
const G4double x[NPOINTSGL]
 
ptwXYPoints * ptwXY_union(ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, nfu_status *status, int unionOptions)
 
nfu_status ptwXY_slopeOffset(ptwXYPoints *ptwXY, double slope, double offset)
 
ptwXYPoints * ptwXY_sub_ptwXY(ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, nfu_status *status)
 
nfu_status ptwXY_mod(ptwXYPoints *ptwXY, double m, int pythonMod)
 
static nfu_status ptwXY_mul2_s_ptwXY(ptwXYPoints *n, ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, double x1, double y1, double x2, double y2, int level)
 
ptwXYPoints * ptwXY_binary_ptwXY(ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, double v1, double v2, double v1v2, nfu_status *status)
 
ptwXYPoints * ptwXY_div_ptwXY(ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, nfu_status *status, int safeDivide)