16static double ptwXY_thicken_linear_dx(
int sectionSubdivideMax,
double dDomainMax,
double x1,
double x2 );
27 double x2, y2, _rangeMin, _rangeMax;
47 if( _rangeMax < rangeMin ) i = 1;
48 if( _rangeMin > rangeMax ) i = 1;
57 ptwXY1->
points[0].
y = rangeMin; }
58 else if( y2 > rangeMax ) {
67 for( i = 0; i < n; i++ ) {
73 if( points->
y > rangeMin ) {
74 if( ptwXY_clip2( smr, clipped, rangeMin, points->
x, points->
y, x2, y2 ) !=
nfu_Okay )
goto Err;
79 for( i++; i < n; i++ )
if( !( ptwXY1->
points[i].
y < rangeMin ) )
break;
83 if( ptwXY_clip2( smr, clipped, rangeMin, ptwXY1->
points[i-1].
x, ptwXY1->
points[i-1].
y, x2, y2 ) !=
nfu_Okay )
goto Err;
85 if( ptwXY_clip2( smr, clipped, rangeMax, ptwXY1->
points[i-1].
x, ptwXY1->
points[i-1].
y, x2, y2 ) !=
nfu_Okay )
goto Err;
87 else if( j != n - 1 ) {
91 else if( y2 > rangeMax ) {
94 if( points->
y < rangeMax ) {
95 if( ptwXY_clip2( smr, clipped, rangeMax, points->
x, points->
y, x2, y2 ) !=
nfu_Okay )
goto Err;
100 for( i++; i < n; i++ )
if( !( ptwXY1->
points[i].
y > rangeMax ) )
break;
104 if( ptwXY_clip2( smr, clipped, rangeMax, ptwXY1->
points[i-1].
x, ptwXY1->
points[i-1].
y, x2, y2 ) !=
nfu_Okay )
goto Err;
105 if( y2 < rangeMin ) {
106 if( ptwXY_clip2( smr, clipped, rangeMin, ptwXY1->
points[i-1].
x, ptwXY1->
points[i-1].
y, x2, y2 ) !=
nfu_Okay )
goto Err;
108 else if( j != n - 1 ) {
142 x = ( y - y1 ) * ( x2 - x1 ) / ( y2 - y1 ) + x1;
150 return( clipped->
status );
156 double dDomainMax,
double fDomainMax ) {
158 double x1, x2 = 0., y1, y2 = 0., fx = 1.1, x, dx, dxp, lfx, y;
159 int64_t i, notFirstPass = 0;
160 int nfx, nDone, doLinear;
166 if( ( sectionSubdivideMax < 1 ) || ( dDomainMax < 0. ) || ( fDomainMax < 1. ) ) {
168 "ptwXY_thicken: One or more of the following not satisfied: sectionSubdivideMax = %d > 0, dDomainMax = %e >= 0.0, fDomainMax = %e >= 1.0",
169 sectionSubdivideMax, dDomainMax, fDomainMax );
177 for( i = ptwXY1->
length - 1; i >= 0; i-- ) {
181 dx = ptwXY_thicken_linear_dx( sectionSubdivideMax, dDomainMax, x1, x2 );
189 if( fDomainMax == 1. ) {
190 nfx = sectionSubdivideMax; }
192 nfx = ( (int) ( lfx / log( fDomainMax ) ) ) + 1;
193 if( nfx > sectionSubdivideMax ) nfx = sectionSubdivideMax;
195 if( nfx > 0 ) fx = exp( lfx / nfx );
197 if( dx < ( fx - 1 ) * x1 ) doLinear = 1; }
209 dx = ptwXY_thicken_linear_dx( sectionSubdivideMax - nDone, dDomainMax, x, x2 );
210 if( dx <= ( fx - 1 ) * x ) {
215 dxp = ( fx - 1. ) * x;
218 if( ( x2 - x ) < 0.05 * fabs( dxp ) )
break;
239static double ptwXY_thicken_linear_dx(
int sectionSubdivideMax,
double dDomainMax,
double x1,
double x2 ) {
242 double dx = x2 - x1, dndx;
244 if( dDomainMax == 0. ) {
245 dx = ( x2 - x1 ) / sectionSubdivideMax; }
247 dndx = dx / dDomainMax;
249 if( ( dndx - ndx ) > 1e-6 ) ndx++;
250 if( ndx > sectionSubdivideMax ) ndx = sectionSubdivideMax;
251 if( ndx > 0 ) dx /= ndx;
261 int64_t i, j, length = ptwXY1->
length;
263 double y1, y2, y3, accuracyNew;
267 if( ( thinned =
ptwXY_clone( smr, ptwXY1 ) ) == NULL )
283 accuracyNew = accuracy;
284 if( accuracyNew < ptwXY1->accuracy ) accuracyNew = ptwXY1->
accuracy;
294 for( i = 2, j = 1; i < length; i++ ) {
296 if( ( y1 != y2 ) || ( y2 != y3 ) ) {
305 length = thinned->
length = j;
306 if( ( thin = (
char *)
smr_malloc2( smr, (
size_t) length, 1,
"thin" ) ) == NULL )
goto Err2;
307 if( ptwXY_thin2( smr, thinned, thin, accuracy, 0, length - 1 ) !=
nfu_Okay )
goto Err1;
308 for( j = 1; j < length; j++ )
if( thin[j] != 0 )
break;
309 for( i = j + 1; i < length; i++ ) {
334 double y, s, dRange, dRangeMax = 0., dRangeR, dRangeRMax = 0;
338 if( i1 + 1 >= i2 )
return(
nfu_Okay );
339 for( i = i1 + 1; i < i2; i++ ) {
342 return( thinned->
status );
344 s = 0.5 * ( fabs( y ) + fabs( thinned->
points[i].
y ) );
345 dRange = fabs( y - thinned->
points[i].
y );
347 if( s != 0 ) dRangeR = dRange / s;
348 if( ( dRangeR > dRangeRMax ) || ( ( dRangeR >= 0.9999 * dRangeRMax ) && ( dRange > dRangeMax ) ) ) {
350 if( dRange > dRangeMax ) dRangeMax = dRange;
351 if( dRangeR > dRangeRMax ) dRangeRMax = dRangeR;
354 if( dRangeRMax < accuracy ) {
355 for( i = i1 + 1; i < i2; i++ ) thin[i] = 1; }
357 if( ( status = ptwXY_thin2( smr, thinned, thin, accuracy, i1, iMax ) ) !=
nfu_Okay )
return( status );
358 status = ptwXY_thin2( smr, thinned, thin, accuracy, iMax, i2 );
369 int64_t i1, i2, length = ptwXY1->
length, lengthm1 = length - 1, thinnedLength = 0;
372 double x1, x2, x3, dx, y2, half_epsilon = 0.5 *
epsilon;
390 if( ( ptwXY1->
points[length-1].
x - ptwXY1->
points[0].
x ) < half_epsilon * ( fabs( ptwXY1->
points[0].
x ) + fabs( ptwXY1->
points[0].
x ) ) ) {
409 *points = ptwXY1->
points[0];
414 for( i1 = 1; i1 < lengthm1; i1 = i2 ) {
415 for( i2 = i1; i2 < length; ++i2 ) {
417 if( ( x3 - x1 ) >= half_epsilon * ( fabs( x1 ) + fabs( x3 ) ) )
break;
424 if( ( x3 - x1 ) > (
epsilon * ( fabs( x1 ) + fabs( x3 ) ) ) ) {
434 if( i2 == length )
break;
447 x3 = ptwXY1->
points[lengthm1].
x;
448 x2 = thinned->
points[thinnedLength-1].
x;
449 if( ( x3 - x2 ) < ( half_epsilon * ( fabs( x2 ) + fabs( x3 ) ) ) ) {
452 x1 = thinned->
points[thinnedLength-1].
x;
453 if( ( x3 - x1 ) > (
epsilon * ( fabs( x1 ) + fabs( x2 ) ) ) ) {
468 points->
y = ptwXY1->
points[lengthm1].
y;
470 thinned->
length = thinnedLength;
493 for( i1 = 0; i1 < ptwXY->
length; i1++ ) {
494 if( ptwXY->
points[i1].
y != 0 )
break;
497 for( i2 = ptwXY->
length - 1; i2 >= 0; i2-- ) {
498 if( ptwXY->
points[i2].
y != 0 )
break;
501 if( i2 < ptwXY->length ) i2++;
504 for( i = i1; i < i2; i++ ) ptwXY->
points[i - i1] = ptwXY->
points[i];
506 ptwXY->
length = i2 - i1; }
519 int64_t overflowSize, i, i1 = 0, i2 = 0, n1 = ptwXY1->
length, n2 = ptwXY2->
length, length;
522 double x1 = 0., x2 = 0., y1 = 0., y2 = 0., y, biSectionMax, accuracy;
544 if( ( n1 == 1 ) || ( n2 == 1 ) ) {
546 "Too few point in one of the sources: len( source1 ) = %d, len( source2 ) = %d", (
int) n1, (
int) n2 );
555 if( fillWithFirst ) {
556 if( i1 < ( ptwXY1->
length - 1 ) ) {
591 length = ( n1 - i1 ) + ( n2 - i2 );
594 if( biSectionMax < ptwXY2->biSectionMax ) biSectionMax = ptwXY2->
biSectionMax;
596 if( accuracy < ptwXY2->accuracy ) accuracy = ptwXY2->
accuracy;
603 for( i = 0; ( i1 < n1 ) && ( i2 < n2 ); i++ ) {
606 n->points[i].x = ptwXY1->
points[i1].
x;
607 if( fillWithFirst ) {
609 if( i1 < ( ptwXY1->
length - 1 ) ) {
622 n->points[i].x = ptwXY2->
points[i2].
x;
623 if( fillWithFirst && ( ( y1 != 0. ) || ( y2 != 0. ) ) ) {
636 for( ; i1 < n1; i1++, i++ ) {
637 n->points[i].x = ptwXY1->
points[i1].
x;
638 if( fillWithFirst ) y = ptwXY1->
points[i1].
y;
641 for( ; i2 < n2; i2++, i++ ) {
642 n->points[i].x = ptwXY2->
points[i2].
x;
643 if( fillWithFirst && trim && ( n->points[i].x <= x2 ) ) {
667 double yScale,
double yOffset ) {
669 int64_t i1, length = ptwXY->
length;
688 for( i1 = 0, p1 = ptwXY->
points; i1 < length; i1++, p1++ ) {
689 p1->
x = xScale * p1->
x + xOffset;
690 p1->
y = yScale * p1->
y + yOffset;
694 int64_t length_2 = length / 2;
697 for( i1 = 0, p1 = ptwXY->
points, p2 = &(ptwXY->
points[length-1]); i1 < length_2; i1++ ) {
710 int skipLastPoint ) {
726 double offsetXYMin, offsetXYMax, slopeXYMin, slopeXYMax, domainMin, domainMax, domainMinXY, domainMaxXY;
727 ptwXYPoints *ptwXY2 = NULL, *offsetXY2 = NULL, *slopeXY2 = NULL;
751 if( ( offsetXYMin != slopeXYMin ) || ( offsetXYMax != slopeXYMax ) ) {
761 if( ( domainMinXY >= offsetXYMax ) || ( domainMaxXY <= offsetXYMin ) )
return(
nfu_Okay );
763 domainMin = ( domainMinXY > offsetXYMin ? domainMinXY : offsetXYMin );
764 domainMax = ( domainMaxXY < offsetXYMax ? domainMaxXY : offsetXYMax );
766 if( ( domainMinXY == offsetXYMin ) && ( domainMaxXY == offsetXYMax ) ) {
768 offsetXY2 = offsetXY;
769 slopeXY2 = slopeXY; }
771 if( ( ptwXY2 =
ptwXY_domainSlice( smr, ptwXY, domainMin, domainMax, 0, 1 ) ) == NULL ) {
776 if( ( offsetXY2 =
ptwXY_domainSlice( smr, offsetXY, domainMin, domainMax, 0, 1 ) ) == NULL ) {
781 if( ( slopeXY2 =
ptwXY_domainSlice( smr, slopeXY, domainMin, domainMax, 0, 1 ) ) == NULL ) {
795 if( skipLastPoint != 0 ) addXY->points[addXY->length-1].y = ptwXY2->
points[ptwXY2->
length-1].
y;
797 if( domainMin > domainMinXY ) {
798 for( i1 = 0, p1 = ptwXY2->
points; i1 < ptwXY2->length; i1++, p1++ ) {
799 if( p1->
x >= domainMin )
break;
804 if( domainMax < domainMaxXY ) {
805 for( i1 = 0, p1 = ptwXY2->
points; i1 < ptwXY2->length; i1++, p1++ )
if( p1->
x > domainMax )
break;
806 for( ; i1 < ptwXY2->
length; i1++, p1++ ) {
814 if( offsetXY2 != offsetXY )
ptwXY_free( offsetXY2 );
815 if( slopeXY2 != slopeXY )
ptwXY_free( slopeXY2 );
G4double epsilon(G4double density, G4double temperature)
@ nfu_invalidInterpolation
enum nfu_status_e nfu_status
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)
double ptwXY_limitAccuracy(double accuracy)
ptwXYPoints * ptwXY_clone(statusMessageReporting *smr, ptwXYPoints *ptwXY)
nfu_status ptwXY_range(statusMessageReporting *smr, ptwXYPoints *ptwXY, double *rangeMin, double *rangeMax)
@ ptwXY_interpolationFlat
@ ptwXY_interpolationOther
ptwXYPoints * ptwXY_mul2_ptwXY(statusMessageReporting *smr, ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2)
struct ptwXYPoints_s ptwXYPoints
nfu_status ptwXY_clear(statusMessageReporting *smr, ptwXYPoints *ptwXY)
#define ptwXY_minimumSize
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)
#define ptwXY_sectionSubdivideMax
nfu_status ptwXY_copy(statusMessageReporting *smr, ptwXYPoints *dest, ptwXYPoints *src)
#define ptwXY_union_mergeClosePoints
struct ptwXYPoint_s ptwXYPoint
nfu_status ptwXY_mergeClosePoints(statusMessageReporting *smr, ptwXYPoints *ptwXY, double epsilon)
ptwXYPoints * ptwXY_free(ptwXYPoints *ptwXY)
ptwXYPoint * ptwXY_getPointAtIndex_Unsafely(ptwXYPoints const *ptwXY, int64_t index)
nfu_status ptwXY_domainMax(statusMessageReporting *smr, ptwXYPoints *ptwXY, double *value)
nfu_status ptwXY_getValueAtX(statusMessageReporting *smr, ptwXYPoints *ptwXY, double x, double *y)
nfu_status ptwXY_simpleCoalescePoints(statusMessageReporting *smr, ptwXYPoints *ptwXY)
nfu_status ptwXY_domainMin(statusMessageReporting *smr, ptwXYPoints *ptwXY, double *value)
nfu_status ptwXY_trim(statusMessageReporting *smr, ptwXYPoints *ptwXY)
nfu_status ptwXY_scaleOffsetXAndY(statusMessageReporting *smr, ptwXYPoints *ptwXY, double xScale, double xOffset, double yScale, double yOffset)
nfu_status ptwXY_scaleAndOffsetDomainWith_ptwXYs(statusMessageReporting *smr, ptwXYPoints *ptwXY, ptwXYPoints *offsetXY, ptwXYPoints *slopeXY, int skipLastPoint)
nfu_status ptwXY_clip(statusMessageReporting *smr, ptwXYPoints *ptwXY1, double rangeMin, double rangeMax)
ptwXYPoints * ptwXY_thinDomain(statusMessageReporting *smr, ptwXYPoints *ptwXY1, double epsilon)
ptwXYPoints * ptwXY_thin(statusMessageReporting *smr, ptwXYPoints *ptwXY1, double accuracy)
nfu_status ptwXY_thicken(statusMessageReporting *smr, ptwXYPoints *ptwXY1, int sectionSubdivideMax, double dDomainMax, double fDomainMax)
ptwXYPoints * ptwXY_union(statusMessageReporting *smr, ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, int unionOptions)
#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
int64_t overflowAllocatedSize
char const * interpolationString