14 #if defined __cplusplus
24 ptwXPoints *
ptwX_new( int64_t size, nfu_status *status ) {
26 ptwXPoints *ptwX = (ptwXPoints *)
nfu_calloc(
sizeof( ptwXPoints ), 1 );
28 *status = nfu_mallocError;
29 if( ptwX == NULL )
return( NULL );
31 if( ( *status = ptwX->status ) != nfu_Okay ) ptwX = (ptwXPoints *)
nfu_free( ptwX );
37 nfu_status
ptwX_setup( ptwXPoints *ptwX, int64_t size ) {
39 ptwX->status = nfu_Okay;
41 ptwX->allocatedSize = 0;
42 ptwX->mallocFailedSize = 0;
45 return( ptwX->status );
50 ptwXPoints *
ptwX_create( int64_t size, int64_t length,
double const *xs, nfu_status *status ) {
52 ptwXPoints *ptwX =
ptwX_new( size, status );
62 ptwXPoints *
ptwX_createLine( int64_t size, int64_t length,
double slope,
double offset, nfu_status *status ) {
68 if( size < length ) size = length;
69 if( ( ptwX =
ptwX_new( size, status ) ) != NULL ) {
70 for( i1 = 0, p1 = ptwX->points; i1 < length; i1++, p1++ ) *p1 = slope * i1 + offset;
71 ptwX->length = length;
78 nfu_status
ptwX_copy( ptwXPoints *dest, ptwXPoints *src ) {
80 if( dest->status == nfu_Okay )
return( dest->status );
81 if( src->status == nfu_Okay )
return( src->status );
83 return(
ptwX_setData( dest, src->length, src->points ) );
88 ptwXPoints *
ptwX_clone( ptwXPoints *ptwX, nfu_status *status ) {
90 return(
ptwX_slice( ptwX, 0, ptwX->length, status ) );
95 ptwXPoints *
ptwX_slice( ptwXPoints *ptwX, int64_t index1, int64_t index2, nfu_status *status ) {
100 *status = nfu_badSelf;
101 if( ptwX->status != nfu_Okay )
return( NULL );
102 *status = nfu_badIndex;
103 if( index1 < 0 )
return( NULL );
104 if( index2 < index1 )
return( NULL );
105 if( index2 > ptwX->length )
return( NULL );
106 length = ( index2 - index1 );
107 if( ( n =
ptwX_new( length, status ) ) == NULL )
return( n );
109 for( j = 0, i = index1; i < index2; i++, j++ ) n->points[j] = ptwX->points[i];
118 if( size < ptwX_minimumSize ) size = ptwX_minimumSize;
119 if( size < ptwX->length ) size = ptwX->length;
120 if( size != ptwX->allocatedSize ) {
121 if( size > ptwX->allocatedSize ) {
122 ptwX->points = (
double *)
nfu_realloc( (
size_t) size *
sizeof( double ), ptwX->points ); }
123 else if( ( ptwX->allocatedSize > 2 * size ) || forceSmallerResize ) {
124 ptwX->points = (
double *)
nfu_realloc( (
size_t) size *
sizeof( double ), ptwX->points );
126 if( ptwX->points == NULL ) {
127 ptwX->mallocFailedSize = size;
129 ptwX->status = nfu_mallocError;
131 ptwX->allocatedSize = size;
134 return( ptwX->status );
142 return( ptwX->status );
150 ptwX->allocatedSize = 0;
151 ptwX->points = (
double *)
nfu_free( ptwX->points );
161 return( (ptwXPoints *)
nfu_free( ptwX ) );
168 return( ptwX->length );
173 nfu_status
ptwX_setData( ptwXPoints *ptwX, int64_t length,
double const *xs ) {
177 if( ptwX->status != nfu_Okay )
return( ptwX->status );
179 if( length > ptwX->allocatedSize ) {
181 if( ptwX->status != nfu_Okay )
return( ptwX->status );
183 for( i = 0; i < length; i++ ) ptwX->points[i] = xs[i];
184 ptwX->length = length;
186 return( ptwX->status );
193 int64_t
n = ptwX->length - ( i2 - i1 );
195 if( ptwX->status != nfu_Okay )
return( ptwX->status );
196 if( ( i1 < 0 ) || ( i1 > i2 ) || ( i2 > ptwX->length ) )
return( nfu_badIndex );
198 for( ; i2 < ptwX->length; i1++, i2++ ) ptwX->points[i1] = ptwX->points[i2];
201 return( ptwX->status );
208 if( ptwX->status != nfu_Okay )
return( NULL );
209 if( ( index < 0 ) || ( index >= ptwX->length ) )
return( NULL );
210 return( &(ptwX->points[index]) );
217 return( ptwX->points[index] );
226 if( ptwX->status != nfu_Okay )
return( ptwX->status );
227 if( ( index < 0 ) || ( index > ptwX->length ) )
return( nfu_badIndex );
228 if( index == ptwX->allocatedSize ) {
229 if( ( status =
ptwX_reallocatePoints( ptwX, ptwX->allocatedSize + 10, 0 ) ) != nfu_Okay )
return( status );
231 ptwX->points[index] =
x;
232 if( index == ptwX->length ) ptwX->length++;
241 int64_t i1, i2, n1p, size = n1 + ptwX->length;
243 if( ptwX->status != nfu_Okay )
return( ptwX->status );
244 if( n1 < 1 )
return( nfu_Okay );
245 if( ( index < 0 ) || ( index > ptwX->length ) )
return( nfu_badIndex );
246 if( size > ptwX->allocatedSize ) {
249 for( i1 = ptwX->length - 1, i2 = size - 1, n1p = ptwX->length - index + 1; n1p > 0; i1--, i2--, n1p-- ) ptwX->points[i2] = ptwX->points[i1];
250 for( i1 = 0, i2 = index; i1 < n1; i1++, i2++ ) ptwX->points[i2] = xs[i1];
265 if( ptwX->length < 2 )
return( 0 );
267 if( ( x1 = ptwX->points[0] ) < ( x2 = ptwX->points[1] ) ) {
268 for( i = 2; i < ptwX->length; i++ ) {
270 x2 = ptwX->points[i];
271 if( x2 <= x1 )
return( 0 );
274 if( x1 == x2 )
return( 0 );
276 for( i = 2; i < ptwX->length; i++ ) {
278 x2 = ptwX->points[i];
279 if( x1 <= x2 )
return( 0 );
287 ptwXPoints *
ptwX_fromString(
char const *str,
char **endCharacter, nfu_status *status ) {
289 int64_t numberConverted;
291 ptwXPoints *ptwX = NULL;
293 if( ( *status =
nfu_stringToListOfDoubles( str, &numberConverted, &doublePtr, endCharacter ) ) != nfu_Okay )
return( NULL );
294 ptwX =
ptwX_create( numberConverted, numberConverted, doublePtr, status );
306 for( i1 = 0; i1 < ptwX->length; i1++ ) {
307 if( ptwX->points[i1] == value ) (*count)++;
316 int64_t i1, i2 = ptwX->length - 1, n1 = ptwX->length / 2;
319 for( i1 = 0; i1 < n1; i1++, i2-- ) {
320 tmp = ptwX->points[i1];
321 ptwX->points[i1] = ptwX->points[i2];
322 ptwX->points[i2] = tmp;
329 nfu_status
ptwX_sort( ptwXPoints *ptwX,
enum ptwX_sort_order order ) {
334 qsort( ptwX->points, (
size_t) ptwX->length,
sizeof( ptwX->points[0] ), cmp );
343 double *
d1 = (
double *) p1, *
d2 = (
double *) p2;
345 if( *d1 < *
d2 )
return( -1 );
346 if( *d1 == *
d2 )
return( 0 );
367 if( ptwX->status != nfu_Okay )
return( ptwX->status );
369 if( i2 > ptwX->length ) i2 = ptwX->length;
370 if( i1 >= i2 )
return( nfu_Okay );
372 *difference = value - ptwX->points[i1];
373 for( i1++; i1 < i2; i1++ ) {
374 d1 = value - ptwX->points[i1];
375 if( std::fabs( *difference ) > std::fabs( d1 ) ) {
385 ptwXPoints *
ptwX_unique( ptwXPoints *ptwX,
int order, nfu_status *status ) {
389 int64_t i1, i2, n1 = 0;
391 ptwXPoints *ptwX2 = NULL;
394 if( ( ptwX2 =
ptwX_new( ptwX->length, status ) ) == NULL )
return( NULL );
395 for( i1 = 0; i1 < ptwX->length; i1++ ) {
396 x1 = ptwX->points[i1];
397 for( i2 = 0, p2 = ptwX2->points; i2 < ptwX2->length; i2++, p2++ ) {
398 if( *p2 == x1 )
break;
400 if( i2 == ptwX2->length ) {
401 ptwX2->points[ptwX2->length] = x1;
406 if( ( ptwX2 =
ptwX_clone( ptwX, status ) ) == NULL )
return( NULL );
407 if( ( *status =
ptwX_sort( ptwX2, ptwX_sort_order_ascending ) ) != nfu_Okay )
goto err;
409 if( ptwX2->length > 1 ) {
410 x1 = ptwX2->points[n1];
412 for( i1 = 1; i1 < ptwX2->length; i1++ ) {
413 if( x1 != ptwX2->points[i1] ) {
414 x1 = ptwX2->points[i1];
415 ptwX2->points[n1] = x1;
421 if( ( *status =
ptwX_sort( ptwX2, ptwX_sort_order_descending ) ) != nfu_Okay )
goto err;
439 if( ptwX->status != nfu_Okay )
return( ptwX->status );
440 for( i1 = 0, p1 = ptwX->points; i1 < ptwX->length; i1++, p1++ ) *p1 = std::fabs( *p1 );
472 if( ptwX->status != nfu_Okay )
return( ptwX->status );
473 for( i1 = 0, p1 = ptwX->points; i1 < ptwX->length; i1++, p1++ ) *p1 = slope * *p1 + offset;
482 double *p1 = ptwX1->points, *p2 = ptwX2->points;
484 if( ptwX1->status != nfu_Okay )
return( ptwX1->status );
485 if( ptwX2->status != nfu_Okay )
return( ptwX2->status );
486 if( ptwX1->length != ptwX2->length )
return( nfu_domainsNotMutual );
488 for( i1 = 0; i1 < ptwX1->length; i1++, p1++, p2++ ) *p1 += *p2;
497 double *p1 = ptwX1->points, *p2 = ptwX2->points;
499 if( ptwX1->status != nfu_Okay )
return( ptwX1->status );
500 if( ptwX2->status != nfu_Okay )
return( ptwX2->status );
501 if( ptwX1->length != ptwX2->length )
return( nfu_domainsNotMutual );
503 for( i1 = 0; i1 < ptwX1->length; i1++, p1++, p2++ ) *p1 -= *p2;
509 nfu_status
ptwX_xMinMax( ptwXPoints *ptwX,
double *xMin,
double *xMax ) {
511 int64_t i1, n1 = ptwX->length;
513 double *p1 = ptwX->points;
515 if( ptwX->status != nfu_Okay )
return( ptwX->status );
517 *xMin = *xMax = *(p1++);
518 for( i1 = 1; i1 < n1; ++i1, ++p1 ) {
519 if( *p1 < *xMin ) *xMin = *p1;
520 if( *p1 > *xMax ) *xMax = *p1;
528 nfu_status
ptwX_compare( ptwXPoints *ptwX1, ptwXPoints *ptwX2,
int *comparison ) {
530 int64_t i1, n1 = ptwX1->length, n2 = ptwX2->length,
nn = n1;
531 double *p1 = ptwX1->points, *p2 = ptwX2->points;
534 if( ptwX1->status != nfu_Okay )
return( ptwX1->status );
535 if( ptwX2->status != nfu_Okay )
return( ptwX2->status );
536 if(
nn > n2 )
nn = n2;
537 for( i1 = 0; i1 <
nn; i1++, p1++, p2++ ) {
538 if( *p1 == *p2 )
continue;
540 if( *p1 < *p2 ) *comparison = -1;
553 int ptwX_close( ptwXPoints *ptwX1, ptwXPoints *ptwX2,
int epsilonFactor,
double epsilon, nfu_status *status ) {
555 int64_t i1, n1 = ptwX1->length;
557 double *p1 = ptwX1->points, *p2 = ptwX2->points;
559 epsilon = std::fabs( epsilon ) + std::abs( epsilonFactor ) *
DBL_EPSILON;
561 *status = ptwX1->status;
562 if( ptwX1->status != nfu_Okay )
return( -1 );
563 *status = ptwX2->status;
564 if( ptwX2->status != nfu_Okay )
return( -1 );
565 *status = nfu_domainsNotMutual;
566 if( n1 != ptwX2->length )
return( -1 );
569 for( i1 = 0; i1 < n1; i1++, p1++, p2++ ) {
570 larger = std::fabs( *p1 );
571 if( std::fabs( *p2 ) > larger ) larger = std::fabs( *p2 );
572 if( std::fabs( *p2 - *p1 ) > epsilon * larger )
return( (
int) ( i1 + 1 ) );
577 #if defined __cplusplus
nfu_status ptwX_slopeOffset(ptwXPoints *ptwX, double slope, double offset)
void * nfu_realloc(size_t size, void *old)
nfu_status ptwX_copy(ptwXPoints *dest, ptwXPoints *src)
int ptwX_ascendingOrder(ptwXPoints *ptwX)
nfu_status ptwX_setPointAtIndex(ptwXPoints *ptwX, int64_t index, double x)
nfu_status ptwX_add_ptwX(ptwXPoints *ptwX1, ptwXPoints *ptwX2)
ptwXPoints * ptwX_clone(ptwXPoints *ptwX, nfu_status *status)
nfu_status ptwX_clear(ptwXPoints *ptwX)
static int ptwX_sort_descending(void const *p1, void const *p2)
ptwXPoints * ptwX_create(int64_t size, int64_t length, double const *xs, nfu_status *status)
nfu_status ptwX_xMinMax(ptwXPoints *ptwX, double *xMin, double *xMax)
int ptwX_close(ptwXPoints *ptwX1, ptwXPoints *ptwX2, int epsilonFactor, double epsilon, nfu_status *status)
nfu_status nfu_stringToListOfDoubles(char const *str, int64_t *numberConverted, double **doublePtr, char **endCharacter)
nfu_status ptwX_insertPointsAtIndex(ptwXPoints *ptwX, int64_t index, int64_t n1, double const *xs)
double ptwX_getPointAtIndex_Unsafely(ptwXPoints *ptwX, int64_t index)
nfu_status ptwX_mul_double(ptwXPoints *ptwX, double value)
ptwXPoints * ptwX_new(int64_t size, nfu_status *status)
nfu_status ptwX_sort(ptwXPoints *ptwX, enum ptwX_sort_order order)
nfu_status ptwX_sub_ptwX(ptwXPoints *ptwX1, ptwXPoints *ptwX2)
nfu_status ptwX_deletePoints(ptwXPoints *ptwX, int64_t i1, int64_t i2)
ptwXPoints * ptwX_createLine(int64_t size, int64_t length, double slope, double offset, nfu_status *status)
ptwXPoints * ptwX_free(ptwXPoints *ptwX)
double * ptwX_getPointAtIndex(ptwXPoints *ptwX, int64_t index)
ptwXPoints * ptwX_fromString(char const *str, char **endCharacter, nfu_status *status)
nfu_status ptwX_neg(ptwXPoints *ptwX)
nfu_status ptwX_closesDifference(ptwXPoints *ptwX, double value, int64_t *index, double *difference)
nfu_status ptwX_add_double(ptwXPoints *ptwX, double value)
int64_t ptwX_length(ptwXPoints *ptwX)
nfu_status ptwX_closesDifferenceInRange(ptwXPoints *ptwX, int64_t i1, int64_t i2, double value, int64_t *index, double *difference)
nfu_status ptwX_countOccurrences(ptwXPoints *ptwX, double value, int *count)
nfu_status ptwX_compare(ptwXPoints *ptwX1, ptwXPoints *ptwX2, int *comparison)
nfu_status ptwX_reallocatePoints(ptwXPoints *ptwX, int64_t size, int forceSmallerResize)
const G4double x[NPOINTSGL]
nfu_status ptwX_setup(ptwXPoints *ptwX, int64_t size)
static int ptwX_sort_ascending(void const *p1, void const *p2)
nfu_status ptwX_reverse(ptwXPoints *ptwX)
ptwXPoints * ptwX_slice(ptwXPoints *ptwX, int64_t index1, int64_t index2, nfu_status *status)
ptwXPoints * ptwX_unique(ptwXPoints *ptwX, int order, nfu_status *status)
nfu_status ptwX_setData(ptwXPoints *ptwX, int64_t length, double const *xs)
double epsilon(double density, double temperature)
void * nfu_calloc(size_t size, size_t n)
nfu_status ptwX_release(ptwXPoints *ptwX)
nfu_status ptwX_abs(ptwXPoints *ptwX)