12 #if defined __cplusplus 
   29     if( ( *status = ptwXY->status ) != nfu_Okay ) 
return( NULL );
 
   33     if( ( xArray = 
ptwX_new( n, status ) ) == NULL ) 
return( NULL );
 
   34     for( i = 0; i < 
n; i++ ) xArray->points[i] = ptwXY->points[i].x;
 
   42 nfu_status 
ptwXY_dullEdges( ptwXYPoints *ptwXY, 
double lowerEps, 
double upperEps, 
int positiveXOnly ) {
 
   47     double xm, xp, dx, y, x1, y1, x2, y2, 
sign;
 
   52     if( ( status = ptwXY->status ) != nfu_Okay ) 
return( status );
 
   53     if( ptwXY->interpolation == ptwXY_interpolationFlat ) 
return( nfu_invalidInterpolation );
 
   54     if( ptwXY->interpolation == ptwXY_interpolationOther ) 
return( nfu_otherInterpolation );
 
   56     if( ptwXY->length < 2 ) 
return( nfu_Okay );
 
   58     if( lowerEps != 0. ) {
 
   59         if( std::fabs( lowerEps ) < 
minEps ) {
 
   61             if( lowerEps < 0. ) sign = -1;
 
   73             dx = std::fabs( x1 * lowerEps );
 
   74             if( x1 == 0 ) dx = std::fabs( lowerEps );
 
   77             if( ( xp + dx ) < x2 ) {
 
   78                 if( ( status = 
ptwXY_getValueAtX( ptwXY, xp, &y ) ) != nfu_Okay ) 
return( status );
 
   79                 if( ( status = 
ptwXY_setValueAtX( ptwXY, xp,  y ) ) != nfu_Okay ) 
return( status ); }
 
   85                 if( ( status = 
ptwXY_setValueAtX( ptwXY, x1, 0. ) ) != nfu_Okay ) 
return( status ); }
 
   87                 if( ( xm < 0. ) && ( x1 >= 0. ) && positiveXOnly ) {
 
   88                     if( ( status = 
ptwXY_setValueAtX( ptwXY, x1, 0. ) ) != nfu_Okay ) 
return( status ); }
 
   90                     if( ( status = 
ptwXY_setValueAtX( ptwXY, xm, 0. ) ) != nfu_Okay ) 
return( status );
 
   91                     if( ( status = 
ptwXY_interpolatePoint( ptwXY->interpolation, x1, &y, xm, 0., xp, y )  ) != nfu_Okay ) 
return( status );
 
   92                     if( ( status = 
ptwXY_setValueAtX( ptwXY, x1, y ) ) != nfu_Okay ) 
return( status );
 
   98     if( upperEps != 0. ) {
 
   99         if( std::fabs( upperEps ) < 
minEps ) {
 
  101             if( upperEps < 0. ) sign = -1;
 
  113             dx = std::fabs( x2 * upperEps );
 
  114             if( x2 == 0 ) dx = std::fabs( upperEps );
 
  117             if( ( xm - dx ) > x1 ) {
 
  118                 if( ( status = 
ptwXY_getValueAtX( ptwXY, xm, &y ) ) != nfu_Okay ) 
return( status );
 
  119                 if( ( status = 
ptwXY_setValueAtX( ptwXY, xm,  y ) ) != nfu_Okay ) 
return( status ); }
 
  125                 if( ( status = 
ptwXY_setValueAtX( ptwXY, x2, 0. ) ) != nfu_Okay ) 
return( status ); }
 
  127                 if( ( status = 
ptwXY_setValueAtX( ptwXY, xp, 0. ) ) != nfu_Okay ) 
return( status );
 
  128                 if( ( status = 
ptwXY_interpolatePoint( ptwXY->interpolation, x2, &y, xm, y, xp, 0. )  ) != nfu_Okay ) 
return( status );
 
  129                 if( ( status = 
ptwXY_setValueAtX( ptwXY, x2, y ) ) != nfu_Okay ) 
return( status );
 
  134     return( ptwXY->status );
 
  143     int64_t i, i1, j, k, 
n = ptwXY->length;
 
  147     if( n < 2 ) 
return( ptwXY->status );
 
  153     for( i1 = 1, p2++; i1 < ( n - 1 ); i1++, p2++ ) {                 
 
  154         if( ( p2->x - x ) > 0.5 * epsilon * ( std::fabs( x ) + std::fabs( p2->x ) ) ) 
break;
 
  157         for( i = i1, p1 = &(ptwXY->points[1]); i < 
n; i++, p1++, p2++ ) *p1 = *p2;
 
  158         n = ptwXY->length = ptwXY->length - i1 + 1;
 
  161     p1 = &(ptwXY->points[n-1]);
 
  163     for( i1 = n - 2, p1--; i1 > 0; i1--, p1-- ) {            
 
  164         if( x - p1->x > 0.5 * epsilon * ( std::fabs( x ) + std::fabs( p1->x ) ) ) 
break;
 
  166     if( i1 != ( n - 2 ) ) {
 
  167         ptwXY->points[i1 + 1] = ptwXY->points[n - 1];
 
  168         n = ptwXY->length = i1 + 2;
 
  171     for( i = 1; i < n - 1; i++ ) {
 
  172         p1 = &(ptwXY->points[i]);
 
  175         for( j = i + 1, p2 = &(ptwXY->points[i+1]); j < n - 1; j++, p2++ ) {
 
  176             if( ( p2->x - p1->x ) > 0.5 * epsilon * ( std::fabs( p2->x ) + std::fabs( p1->x ) ) ) 
break;
 
  180         if( ( k = ( j - i ) ) > 1 ) {
 
  183             for( p1 = &(ptwXY->points[i+1]); j < 
n; j++, p1++, p2++ ) *p1 = *p2;
 
  189     return( ptwXY->status );
 
  197     double x, y, xMin, xMax;
 
  198     ptwXYPoints *
n = NULL;
 
  200     if( ( *status = ptwXY->status ) != nfu_Okay ) 
return( NULL );
 
  201     if( ( *status = ptwX->status ) != nfu_Okay ) 
return( NULL );
 
  203     *status = nfu_otherInterpolation;
 
  204     if( ptwXY->interpolation == ptwXY_interpolationOther ) 
return( NULL );
 
  205     if( ( n = 
ptwXY_clone( ptwXY, status ) ) == NULL ) 
return( NULL );
 
  206     if( ptwXY->length == 0 ) 
return( n );
 
  207     xMin = ptwXY->points[0].x;
 
  208     xMax = ptwXY->points[ptwXY->length - 1].x;
 
  210     if( ( xMin >= ptwX->points[lengthX-1] ) || ( xMax <= ptwX->points[0] ) ) {  
 
  215     for( i = 0; i < lengthX; i++ ) {        
 
  217         if( x <= xMin ) 
continue;
 
  218         if( x >= xMax ) 
break;
 
  228         if( x > n->points[i1].x ) {
 
  229             for( ; i1 < n->length; i1++ ) {
 
  230                 if( n->points[i1].x == x ) 
break;
 
  234         x = ptwX->points[lengthX - 1];
 
  235         if( x < n->points[i2].x ) {
 
  236             for( ; i2 > i1; i2-- ) {
 
  237                 if( n->points[i2].x == x ) 
break;
 
  244         for( i = i1; i < i2; i++ ) n->points[i - i1] = n->points[i];
 
  260     int64_t n1 = ptwXY1->length, n2 = ptwXY2->length;
 
  261     ptwXYPoint *xy1, *xy2;
 
  263     if( ( status = ptwXY1->status ) != nfu_Okay ) 
return( status );
 
  264     if( ( status = ptwXY2->status ) != nfu_Okay ) 
return( status );
 
  265     if( n1 == 0 ) 
return( nfu_empty );
 
  266     if( n2 == 0 ) 
return( nfu_empty );
 
  268         status = nfu_tooFewPoints; }
 
  270         status = nfu_tooFewPoints; }
 
  274         if( xy1->x < xy2->x ) {
 
  275             if( xy2->y != 0. ) status = nfu_domainsNotMutual; }
 
  276         else if( xy1->x > xy2->x ) {
 
  277             if( xy1->y != 0. ) status = nfu_domainsNotMutual;
 
  280         if( status == nfu_Okay ) {
 
  283             if( xy1->x < xy2->x ) {
 
  284                 if( xy1->y != 0. ) status = nfu_domainsNotMutual; }
 
  285             else if( xy1->x > xy2->x ) {
 
  286                 if( xy2->y != 0. ) status = nfu_domainsNotMutual;
 
  298     int64_t n1 = ptwXY1->length, n2 = ptwXY2->length;
 
  300     ptwXYPoint *xy1, *xy2;
 
  302     epsilon = std::fabs( epsilon ) + std::fabs( epsilonFactor * 
DBL_EPSILON );
 
  304     if( ( status = ptwXY1->status ) != nfu_Okay ) 
return( status );
 
  305     if( ( status = ptwXY2->status ) != nfu_Okay ) 
return( status );
 
  306     if( n1 == 0 ) 
return( nfu_empty );
 
  307     if( n2 == 0 ) 
return( nfu_empty );
 
  309         status = nfu_tooFewPoints; }
 
  311         status = nfu_tooFewPoints; }
 
  315         if( xy1->x < xy2->x ) {
 
  317                 sum = std::fabs( xy1->x ) + std::fabs( xy2->x );
 
  318                 diff = std::fabs( xy2->x - xy1->x );
 
  319                 if( diff > epsilon * sum ) {
 
  320                     status = nfu_domainsNotMutual; }
 
  325         else if( xy1->x > xy2->x ) {
 
  327                 sum = std::fabs( xy1->x ) + std::fabs( xy2->x );
 
  328                 diff = std::fabs( xy2->x - xy1->x );
 
  329                 if( diff > epsilon * sum ) {
 
  330                     status = nfu_domainsNotMutual; }
 
  337         if( status == nfu_Okay ) {
 
  340             if( xy1->x < xy2->x ) {
 
  342                     sum = std::fabs( xy1->x ) + std::fabs( xy2->x );
 
  343                     diff = std::fabs( xy2->x - xy1->x );
 
  344                     if( diff > epsilon * sum ) {
 
  345                         status = nfu_domainsNotMutual; }
 
  350             else if( xy1->x > xy2->x ) {
 
  352                     sum = std::fabs( xy1->x ) + std::fabs( xy2->x );
 
  353                     diff = std::fabs( xy2->x - xy1->x );
 
  354                     if( diff > epsilon * sum ) {
 
  355                         status = nfu_domainsNotMutual; }
 
  369                                           ptwXYPoints *ptwXY2, 
double lowerEps2, 
double upperEps2, 
int positiveXOnly2 ) {
 
  372     int64_t n1 = ptwXY1->length, n2 = ptwXY2->length;
 
  373     ptwXYPoint *xy1, *xy2;
 
  379     case nfu_domainsNotMutual :
 
  385     if( ptwXY1->interpolation == ptwXY_interpolationOther ) 
return( nfu_otherInterpolation );
 
  386     if( ptwXY2->interpolation == ptwXY_interpolationOther ) 
return( nfu_otherInterpolation );
 
  387     if( ptwXY1->interpolation == ptwXY_interpolationFlat ) 
return( nfu_invalidInterpolation );
 
  388     if( ptwXY2->interpolation == ptwXY_interpolationFlat ) 
return( nfu_invalidInterpolation );
 
  392     if( xy1->x < xy2->x ) {
 
  394         if( xy2->y == 0. ) lowerEps2 = 0.; }
 
  395     else if( xy1->x > xy2->x ) {
 
  397         if( xy1->y == 0. ) lowerEps1 = 0.; }
 
  399         lowerEps1 = lowerEps2 = 0.;
 
  404     if( xy1->x < xy2->x ) {
 
  406         if( xy1->y == 0. ) upperEps1 = 0.; }
 
  407     else if( xy1->x > xy2->x ) {
 
  409         if( xy2->y == 0. ) upperEps2 = 0.; }
 
  411         upperEps1 = upperEps2 = 0.;
 
  414     if( ( lowerEps1 != 0. ) || ( upperEps1 != 0. ) ) 
 
  415         if( ( status = 
ptwXY_dullEdges( ptwXY1, lowerEps1, upperEps1, positiveXOnly1 ) ) != nfu_Okay ) 
return( status );
 
  416     if( ( lowerEps2 != 0. ) || ( upperEps2 != 0. ) ) 
 
  417         if( ( status = 
ptwXY_dullEdges( ptwXY2, lowerEps2, upperEps2, positiveXOnly2 ) ) != nfu_Okay ) 
return( status );
 
  424 nfu_status 
ptwXY_copyToC_XY( ptwXYPoints *ptwXY, int64_t index1, int64_t index2, int64_t allocatedSize, int64_t *numberOfPoints, 
double *xys ) {
 
  429     ptwXYPoint *pointFrom;
 
  431     if( ptwXY->status != nfu_Okay ) 
return( ptwXY->status );
 
  434     if( index1 < 0 ) index1 = 0;
 
  435     if( index2 > ptwXY->length ) index2 = ptwXY->length;
 
  436     if( index2 < index1 ) index2 = index1;
 
  437     *numberOfPoints = index2 - index1;
 
  438     if( allocatedSize < ( index2 - index1 ) ) 
return( nfu_insufficientMemory );
 
  440     for( i = index1, pointFrom = ptwXY->points; i < index2; i++, pointFrom++ ) {
 
  441         *(d++) = pointFrom->x;
 
  442         *(d++) = pointFrom->y;
 
  454     ptwXYPoint *pointFrom;
 
  457     if( ptwXY->status != nfu_Okay ) 
return( ptwXY->status );
 
  460     if( ( *xs = (
double *) malloc( length * 
sizeof( 
double ) ) ) == NULL ) 
return( nfu_mallocError );
 
  461     if( ( *ys = (
double *) malloc( length * 
sizeof( 
double ) ) ) == NULL ) {
 
  464         return( nfu_mallocError );
 
  467     for( i1 = 0, pointFrom = ptwXY->points, xps = *xs, yps = *ys; i1 < length; ++i1, ++pointFrom, ++xps, ++yps ) {
 
  481     *status = nfu_XNotAscending;
 
  482     if( x1 >= x2 ) 
return( NULL );
 
  484     if( ( n = 
ptwXY_new( ptwXY_interpolationLinLin, NULL, ptwXY_maxBiSectionMax, ptwXY_minAccuracy, 2, 0, status, 0 ) ) == NULL ) 
return( NULL );
 
  496     double x1, y1, x2, y2, accuracy2, yMin = 1e-10;
 
  497     ptwXYPoints *gaussian;
 
  499     if( accuracy < 1e-5 ) accuracy = 1e-5;
 
  500     if( accuracy > 1e-1 ) accuracy = 1e-1;
 
  501     if( ( gaussian = 
ptwXY_new( ptwXY_interpolationLinLin, NULL, 1., accuracy, 200, 100, status, 0 ) ) == NULL ) 
return( NULL );
 
  502     accuracy2 = accuracy = gaussian->accuracy;
 
  503     if( accuracy2 > 5e-3 ) accuracy2 = 5e-3;
 
  505     x1 = -std::sqrt( -2. * 
G4Log( yMin ) );
 
  508     y2 = 
G4Exp( -0.5 * x2 * x2 );
 
  510     gaussian->accuracy = 20 * accuracy2;
 
  515     y2 = 
G4Exp( -0.5 * x2 * x2 );
 
  516     gaussian->accuracy = 5 * accuracy2;
 
  521     y2 = 
G4Exp( -0.5 * x2 * x2 );
 
  522     gaussian->accuracy = accuracy;
 
  527     y2 = 
G4Exp( -0.5 * x2 * x2 );
 
  530     n = gaussian->length;
 
  533     pp = &(gaussian->points[gaussian->length]);
 
  534     for( i = 0, pm = pp - 2; i < 
n; i++, pp++, pm-- ) {
 
  538     gaussian->length = 2 * n + 1;
 
  551     nfu_status status = nfu_Okay;
 
  553     double x = 0.5 * ( x1 + x2 );
 
  554     double y = 
G4Exp( -x * x / 2 ), yMin = ( y1 * ( x2 - 
x ) + y2 * ( x - x1 ) ) / ( x2 - x1 );
 
  556     if( std::fabs( y - yMin ) > y * ptwXY->accuracy ) morePoints = 1;
 
  558     if( ( status = 
ptwXY_setValueAtX( ptwXY, x, y ) ) != nfu_Okay ) 
return( status );
 
  566 ptwXYPoints *
ptwXY_createGaussian( 
double accuracy, 
double xCenter, 
double sigma, 
double amplitude, 
double xMin, 
double xMax, 
 
  567         double , nfu_status *status ) {
 
  570     ptwXYPoints *gaussian, *sliced;
 
  574     for( i = 0, point = gaussian->points; i < gaussian->length; i++, point++ ) {
 
  575         point->x = point->x * sigma + xCenter;
 
  576         point->y *= amplitude;
 
  578     if( ( gaussian->points[0].x < xMin ) || ( gaussian->points[gaussian->length - 1].x > xMax ) ) {
 
  579         if( ( sliced = 
ptwXY_xSlice( gaussian, xMin, xMax, 10, 1, status ) ) == NULL ) 
goto Err;
 
  591 #if defined __cplusplus 
ptwXYPoints * ptwXY_intersectionWith_ptwX(ptwXYPoints *ptwXY, ptwXPoints *ptwX, nfu_status *status)
 
ptwXPoints * ptwXY_getXArray(ptwXYPoints *ptwXY, nfu_status *status)
 
nfu_status ptwXY_mergeClosePoints(ptwXYPoints *ptwXY, double epsilon)
 
int64_t ptwXY_length(ptwXYPoints *ptwXY)
 
nfu_status ptwXY_areDomainsMutual(ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2)
 
ptwXYPoints * ptwXY_createGaussian(double accuracy, double xCenter, double sigma, double amplitude, double xMin, double xMax, double, nfu_status *status)
 
nfu_status ptwXY_valueTo_ptwXAndY(ptwXYPoints *ptwXY, double **xs, double **ys)
 
nfu_status ptwXY_simpleCoalescePoints(ptwXYPoints *ptwXY)
 
ptwXYPoints * ptwXY_free(ptwXYPoints *ptwXY)
 
nfu_status ptwXY_mutualifyDomains(ptwXYPoints *ptwXY1, double lowerEps1, double upperEps1, int positiveXOnly1, ptwXYPoints *ptwXY2, double lowerEps2, double upperEps2, int positiveXOnly2)
 
nfu_status ptwXY_setValueAtX(ptwXYPoints *ptwXY, double x, double y)
 
ptwXYPoints * ptwXY_valueTo_ptwXY(double x1, double x2, double y, nfu_status *status)
 
ptwXPoints * ptwX_new(int64_t size, nfu_status *status)
 
ptwXYPoints * ptwXY_createGaussianCenteredSigma1(double accuracy, nfu_status *status)
 
nfu_status ptwXY_coalescePoints(ptwXYPoints *ptwXY, int64_t size, ptwXYPoint *newPoint, int forceSmallerResize)
 
ptwXYPoints * ptwXY_xSlice(ptwXYPoints *ptwXY, double xMin, double xMax, int64_t secondarySize, int fill, nfu_status *status)
 
G4double G4Log(G4double x)
 
G4double G4Exp(G4double initial_x)
Exponential Function double precision. 
 
ptwXYPoints * ptwXY_clone(ptwXYPoints *ptwXY, nfu_status *status)
 
int64_t ptwX_length(ptwXPoints *ptwX)
 
ptwXYPoint * ptwXY_getPointAtIndex_Unsafely(ptwXYPoints *ptwXY, int64_t index)
 
nfu_status ptwXY_getValueAtX(ptwXYPoints *ptwXY, double x, double *y)
 
const G4double x[NPOINTSGL]
 
static nfu_status ptwXY_createGaussianCenteredSigma1_2(ptwXYPoints *ptwXY, double x1, double y1, double x2, double y2, int addX1Point)
 
nfu_status ptwXY_tweakDomainsToMutualify(ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, int epsilonFactor, double epsilon)
 
nfu_status ptwXY_dullEdges(ptwXYPoints *ptwXY, double lowerEps, double upperEps, int positiveXOnly)
 
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)
 
G4int sign(const T t)
A simple sign function that allows us to port fortran code to c++ more easily. 
 
double epsilon(double density, double temperature)
 
nfu_status ptwXY_copyToC_XY(ptwXYPoints *ptwXY, int64_t index1, int64_t index2, int64_t allocatedSize, int64_t *numberOfPoints, double *xys)