17 double x2,
double y2,
int addX1Point );
32 if( ( xArray =
ptwX_new( smr, n ) ) == NULL ) {
36 for( i = 0; i < n; i++ ) xArray->
points[i] = ptwXY->
points[i].
x;
63 if( ( nXY == 1 ) || ( nX == 1 ) ) {
68 if( ( nXY == 0 ) || ( nX == 0 ) ) {
69 if( ( Ys =
ptwX_new( smr, 0 ) ) == NULL ) {
76 point1 = &ptwXY->
points[0];
77 point2 = &ptwXY->
points[nXY-1];
79 for( iX = 0; iX < nX; ++iX ) {
80 if( Xs->
points[iX] >= point1->
x )
break;
84 for( iX = 0; iX < nX; ++iX ) {
85 if( Xs->
points[iX] > point2->
x )
break;
90 if( ( Ys =
ptwX_new( smr, nX - iX ) ) == NULL ) {
94 if( nX - iX < 2 )
return( Ys );
96 for( iXY = 1; iXY < nXY; ++iXY ) {
97 point2 = &ptwXY->
points[iXY];
98 if( point2->
x >= Xs->
points[iX] )
break;
102 for( ; iXY < nXY; ++iXY ) {
103 point2 = &ptwXY->
points[iXY];
106 double xValue = Xs->
points[iX], yValue;
108 if( xValue > point2->
x )
break;
132 double *a_results,
double a_scaleFractor ) {
134 int64_t
offset, startIndex, length, length_m1;
135 double x1, x2, y1, y2;
138 double xValue, yValue;
140 if( a_offset < 0 ) a_offset = 0;
141 if( a_offset >= a_length )
return(
nfu_Okay );
145 if( status !=
nfu_Okay )
return( status );
146 if( startIndex < 0 ) {
147 if( startIndex == -2 ) {
148 if( a_Xs[a_length-1] >= a_ptwXY->
points[0].
x ) startIndex = 0;
150 if( startIndex < 0 )
return(
nfu_Okay );
153 length_m1 = length - 1;
154 point = &a_ptwXY->
points[startIndex];
157 while( startIndex < length_m1 ) {
159 point = &a_ptwXY->
points[startIndex];
166 if( xValue < x1 )
continue;
167 if( xValue > x2 )
break;
173 a_results[
offset] += a_scaleFractor * yValue;
190 double xm, xp, dx, y, x1, y1, x2, y2, sign;
212 if( lowerEps != 0. ) {
213 if( fabs( lowerEps ) <
minEps ) {
215 if( lowerEps < 0. ) sign = -1;
227 dx = fabs( x1 * lowerEps );
228 if( x1 == 0 ) dx = fabs( lowerEps );
231 if( ( xp + dx ) < x2 ) {
241 if( ( xm < 0. ) && ( x1 >= 0. ) && positiveXOnly ) {
246 return( ptwXY->
status = status );
253 if( upperEps != 0. ) {
254 if( fabs( upperEps ) <
minEps ) {
256 if( upperEps < 0. ) sign = -1;
268 dx = fabs( x2 * upperEps );
269 if( x2 == 0 ) dx = fabs( upperEps );
272 if( ( xm - dx ) > x1 ) {
284 return( ptwXY->
status = status );
299 int64_t i, i1, j, k, n = ptwXY->
length;
303 if( n < 2 )
return( ptwXY->
status );
312 for( i1 = 1, p2++; i1 < ( n - 1 ); i1++, p2++ ) {
313 if( ( p2->
x - x ) > 0.5 *
epsilon * ( fabs( x ) + fabs( p2->
x ) ) )
break;
316 for( i = i1, p1 = &(ptwXY->
points[1]); i < n; i++, p1++, p2++ ) *p1 = *p2;
320 p1 = &(ptwXY->
points[n-1]);
322 for( i1 = n - 2, p1--; i1 > 0; i1--, p1-- ) {
323 if( x - p1->
x > 0.5 *
epsilon * ( fabs( x ) + fabs( p1->
x ) ) )
break;
325 if( i1 != ( n - 2 ) ) {
327 n = ptwXY->
length = i1 + 2;
330 for( i = 1; i < n - 1; i++ ) {
334 for( j = i + 1, p2 = &(ptwXY->
points[i+1]); j < n - 1; j++, p2++ ) {
335 if( ( p2->
x - p1->
x ) > 0.5 *
epsilon * ( fabs( p2->
x ) + fabs( p1->
x ) ) )
break;
339 if( ( k = ( j - i ) ) > 1 ) {
342 for( p1 = &(ptwXY->
points[i+1]); j < n; j++, p1++, p2++ ) *p1 = *p2;
355 int64_t i, i1, i2, lengthX =
ptwX_length( smr, ptwX );
356 double x, y, domainMin, domainMax;
379 if( ptwXY->
length == 0 )
return( n );
380 domainMin = ptwXY->
points[0].
x;
383 if( ( domainMin >= ptwX->
points[lengthX-1] ) || ( domainMax <= ptwX->points[0] ) ) {
388 for( i = 0; i < lengthX; i++ ) {
390 if( x <= domainMin )
continue;
391 if( x >= domainMax )
break;
401 if( x > n->points[i1].x ) {
402 for( ; i1 < n->length; i1++ ) {
403 if( n->points[i1].x == x )
break;
407 x = ptwX->
points[lengthX - 1];
408 if( x < n->points[i2].x ) {
409 for( ; i2 > i1; i2-- ) {
410 if( n->points[i2].x == x )
break;
417 for( i = i1; i < i2; i++ ) n->points[i - i1] = n->points[i];
456 if( xy1->
x < xy2->
x ) {
458 else if( xy1->
x > xy2->
x ) {
465 if( xy1->
x < xy2->
x ) {
467 else if( xy1->
x > xy2->
x ) {
478 int epsilonFactor,
double epsilon ) {
505 if( xy1->
x < xy2->
x ) {
507 sum = fabs( xy1->
x ) + fabs( xy2->
x );
508 diff = fabs( xy2->
x - xy1->
x );
515 else if( xy1->
x > xy2->
x ) {
517 sum = fabs( xy1->
x ) + fabs( xy2->
x );
518 diff = fabs( xy2->
x - xy1->
x );
530 if( xy1->
x < xy2->
x ) {
532 sum = fabs( xy1->
x ) + fabs( xy2->
x );
533 diff = fabs( xy2->
x - xy1->
x );
540 else if( xy1->
x > xy2->
x ) {
542 sum = fabs( xy1->
x ) + fabs( xy2->
x );
543 diff = fabs( xy2->
x - xy1->
x );
559 int positiveXOnly1,
ptwXYPoints *ptwXY2,
double lowerEps2,
double upperEps2,
int positiveXOnly2 ) {
598 if( xy1->
x < xy2->
x ) {
603 if( lowerEps2 == 0 ) {
606 if( ( xy2->
x - xy1->
x ) < lowerEps2 * ( fabs( xy1->
x ) + fabs( xy2->
x ) ) ) {
613 else if( xy1->
x > xy2->
x ) {
618 if( lowerEps1 == 0 ) {
621 if( ( xy1->
x - xy2->
x ) < lowerEps1 * ( fabs( xy1->
x ) + fabs( xy2->
x ) ) ) {
629 lowerEps1 = lowerEps2 = 0.;
635 if( xy1->
x < xy2->
x ) {
640 if( upperEps1 == 0 ) {
643 if( ( xy2->
x - xy1->
x ) < upperEps1 * ( fabs( xy1->
x ) + fabs( xy2->
x ) ) ) {
650 else if( xy1->
x > xy2->
x ) {
655 if( upperEps2 == 0 ) {
658 if( ( xy1->
x - xy2->
x ) < upperEps2 * ( fabs( xy1->
x ) + fabs( xy2->
x ) ) ) {
666 upperEps1 = upperEps2 = 0.;
669 if( ( lowerEps1 != 0. ) || ( upperEps1 != 0. ) ) {
675 if( ( lowerEps2 != 0. ) || ( upperEps2 != 0. ) ) {
685 if( code1 == 1 ) strcat( str,
" lowerEps1" );
686 if( code1 == -1 ) strcat( str,
" lowerEps2" );
687 if( code2 == 1 ) strcat( str,
" upperEps2" );
688 if( code2 == -1 ) strcat( str,
" upperEps1" );
690 "The following inputs are 0 and must be a non 0 value: %s.", str );
700 int64_t allocatedSize, int64_t *numberOfPoints,
double *xys ) {
711 if( index1 < 0 ) index1 = 0;
713 if( index2 < index1 ) index2 = index1;
714 *numberOfPoints = index2 - index1;
717 for( i = index1, pointFrom = ptwXY->
points; i < index2; i++, pointFrom++ ) {
718 *(d++) = pointFrom->
x;
719 *(d++) = pointFrom->
y;
739 if( ( *xs = (
double *)
smr_malloc2( smr, (
size_t) length *
sizeof(
double ), 0,
"xs" ) ) == NULL ) {
743 if( ( *ys = (
double *)
smr_malloc2( smr, (
size_t) length *
sizeof(
double ), 0,
"ys" ) ) == NULL ) {
749 for( i1 = 0, pointFrom = ptwXY->
points, xps = *xs, yps = *ys; i1 < length; ++i1, ++pointFrom, ++xps, ++yps ) {
765 "X-values not ascend: x1 = %.17e, x2 = %.17e", x1, x2 );
788 double x1, y1, x2, y2, accuracy2, rangeMin = 1e-10;
791 if( accuracy < 1e-5 ) accuracy = 1e-5;
792 if( accuracy > 1e-1 ) accuracy = 1e-1;
798 accuracy2 = accuracy = gaussian->
accuracy;
799 if( accuracy2 > 5e-3 ) accuracy2 = 5e-3;
801 x1 = -sqrt( -2. * log( rangeMin ) );
804 y2 = exp( -0.5 * x2 * x2 );
806 gaussian->
accuracy = 20 * accuracy2;
807 if( ptwXY_createGaussianCenteredSigma1_2( smr, gaussian, x1, y1, x2, y2, 1 ) !=
nfu_Okay )
goto Err;
811 y2 = exp( -0.5 * x2 * x2 );
813 if( ptwXY_createGaussianCenteredSigma1_2( smr, gaussian, x1, y1, x2, y2, 1 ) !=
nfu_Okay )
goto Err;
817 y2 = exp( -0.5 * x2 * x2 );
819 if( ptwXY_createGaussianCenteredSigma1_2( smr, gaussian, x1, y1, x2, y2, 1 ) !=
nfu_Okay )
goto Err;
823 y2 = exp( -0.5 * x2 * x2 );
824 if( ptwXY_createGaussianCenteredSigma1_2( smr, gaussian, x1, y1, x2, y2, 1 ) !=
nfu_Okay )
goto Err;
830 for( i = 0, pm = pp - 2; i < n; i++, pp++, pm-- ) {
834 gaussian->
length = 2 * n + 1;
847 double x1,
double y1,
double x2,
double y2,
int addX1Point ) {
851 double x = 0.5 * ( x1 + x2 );
852 double y = exp( -0.5 * x * x ), rangeMin = ( y1 * ( x2 - x ) + y2 * ( x - x1 ) ) / ( x2 - x1 );
854 if( fabs( y - rangeMin ) > y * ptwXY->
accuracy ) morePoints = 1;
855 if( morePoints && ( status = ptwXY_createGaussianCenteredSigma1_2( smr, ptwXY, x, y, x2, y2, 0 ) ) !=
nfu_Okay )
return( status );
857 if( morePoints && ( status = ptwXY_createGaussianCenteredSigma1_2( smr, ptwXY, x1, y1, x, y, 0 ) ) !=
nfu_Okay )
return( status );
865 double amplitude,
double domainMin,
double domainMax,
double dullEps ) {
876 for( i = 0, point = gaussian->
points; i < gaussian->length; i++, point++ ) {
877 point->
x = point->
x * sigma + xCenter;
878 point->
y *= amplitude;
880 if( ( gaussian->
points[0].
x < domainMin ) || ( gaussian->
points[gaussian->
length - 1].
x > domainMax ) ) {
881 if( ( sliced =
ptwXY_domainSlice( smr, gaussian, domainMin, domainMax, 10, 1 ) ) == NULL )
goto Err;
G4double epsilon(G4double density, G4double temperature)
G4ThreadLocal T * G4GeomSplitter< T >::offset
@ nfu_invalidInterpolation
enum nfu_status_e nfu_status
#define ptwXY_minAccuracy
ptwXYPoints * ptwXY_domainSlice(statusMessageReporting *smr, ptwXYPoints *ptwXY, double domainMin, double domainMax, int64_t secondarySize, int fill)
nfu_status ptwXY_setValueAtX(statusMessageReporting *smr, ptwXYPoints *ptwXY, double x, double y)
ptwXY_interpolation ptwXY_getInterpolation(ptwXYPoints *ptwXY)
nfu_status ptwXY_startIndex(statusMessageReporting *a_smr, ptwXYPoints *a_ptwXY, double a_x, int64_t *a_startIndex, int64_t *a_length)
ptwXYPoints * ptwXY_clone(statusMessageReporting *smr, ptwXYPoints *ptwXY)
nfu_status ptwXY_coalescePoints(statusMessageReporting *smr, ptwXYPoints *ptwXY, int64_t size, ptwXYPoint *newPoint, int forceSmallerResize)
enum ptwXY_interpolation_e ptwXY_interpolation
@ ptwXY_interpolationFlat
@ ptwXY_interpolationLinLin
@ ptwXY_interpolationOther
struct ptwXYPoints_s ptwXYPoints
#define ptwXY_maxBiSectionMax
nfu_status ptwXY_interpolatePoint(statusMessageReporting *smr, ptwXY_interpolation interpolation, double x, double *y, double x1, double y1, double x2, double y2)
ptwXYPoints * ptwXY_new(statusMessageReporting *smr, ptwXY_interpolation interpolation, char const *interpolationString, double biSectionMax, double accuracy, int64_t primarySize, int64_t secondarySize, int userFlag)
int64_t ptwXY_length(statusMessageReporting *smr, ptwXYPoints *ptwXY)
struct ptwXYPoint_s ptwXYPoint
ptwXYPoints * ptwXY_free(ptwXYPoints *ptwXY)
ptwXYPoint * ptwXY_getPointAtIndex_Unsafely(ptwXYPoints const *ptwXY, int64_t index)
nfu_status ptwXY_getValueAtX(statusMessageReporting *smr, ptwXYPoints *ptwXY, double x, double *y)
nfu_status ptwXY_simpleCoalescePoints(statusMessageReporting *smr, ptwXYPoints *ptwXY)
nfu_status ptwXY_dullEdges(statusMessageReporting *smr, ptwXYPoints *ptwXY, double lowerEps, double upperEps, int positiveXOnly)
nfu_status ptwXY_valuesToC_XsAndYs(statusMessageReporting *smr, ptwXYPoints *ptwXY, double **xs, double **ys)
nfu_status ptwXY_copyToC_XY(statusMessageReporting *smr, ptwXYPoints *ptwXY, int64_t index1, int64_t index2, int64_t allocatedSize, int64_t *numberOfPoints, double *xys)
ptwXYPoints * ptwXY_createGaussianCenteredSigma1(statusMessageReporting *smr, double accuracy)
ptwXYPoints * ptwXY_intersectionWith_ptwX(statusMessageReporting *smr, ptwXYPoints *ptwXY, ptwXPoints *ptwX)
nfu_status ptwXY_tweakDomainsToMutualify(statusMessageReporting *smr, ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, int epsilonFactor, double epsilon)
ptwXPoints * ptwXY_getXArray(statusMessageReporting *smr, ptwXYPoints *ptwXY)
nfu_status ptwXY_areDomainsMutual(statusMessageReporting *smr, ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2)
nfu_status ptwXY_mutualifyDomains(statusMessageReporting *smr, ptwXYPoints *ptwXY1, double lowerEps1, double upperEps1, int positiveXOnly1, ptwXYPoints *ptwXY2, double lowerEps2, double upperEps2, int positiveXOnly2)
nfu_status ptwXY_mapToXsAndAdd(statusMessageReporting *a_smr, ptwXYPoints *a_ptwXY, int64_t a_offset, int64_t a_length, double const *a_Xs, double *a_results, double a_scaleFractor)
nfu_status ptwXY_mergeClosePoints(statusMessageReporting *smr, ptwXYPoints *ptwXY, double epsilon)
ptwXYPoints * ptwXY_valueTo_ptwXY(statusMessageReporting *smr, double x1, double x2, double y)
ptwXYPoints * ptwXY_createGaussian(statusMessageReporting *smr, double accuracy, double xCenter, double sigma, double amplitude, double domainMin, double domainMax, double dullEps)
ptwXPoints * ptwXY_ysMappedToXs(statusMessageReporting *smr, ptwXYPoints *ptwXY, ptwXPoints *Xs, int64_t *offset)
int64_t ptwX_length(statusMessageReporting *smr, ptwXPoints *ptwX)
struct ptwXPoints_s ptwXPoints
nfu_status ptwX_setPointAtIndex(statusMessageReporting *smr, ptwXPoints *ptwX, int64_t index, double x)
ptwXPoints * ptwX_free(ptwXPoints *ptwX)
ptwXPoints * ptwX_new(statusMessageReporting *smr, int64_t size)
#define smr_setReportError2(smr, libraryID, code, fmt,...)
#define smr_setReportError2p(smr, libraryID, code, fmt)
#define smr_freeMemory2(p)
#define smr_malloc2(smr, size, zero, forItem)
ptwXY_interpolation interpolation