Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/lend/src/ptwX_core.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 /*
  2 # <<BEGIN-copyright>>
  3 # <<END-copyright>>
  4 */
  5 
  6 #include <stdio.h>
  7 #include <stdlib.h>
  8 #include <cmath>
  9 #include <cstdlib>   //for std::abs(int)
 10 #include <float.h>
 11 
 12 #include "ptwX.h"
 13 
 14 #if defined __cplusplus
 15 namespace GIDI {
 16 using namespace GIDI;
 17 #endif
 18 
 19 static int ptwX_sort_descending( void const *p1, void const *p2 );
 20 static int ptwX_sort_ascending( void const *p1, void const *p2 );
 21 /*
 22 ************************************************************
 23 */
 24 ptwXPoints *ptwX_new( int64_t size, nfu_status *status ) {
 25 
 26     ptwXPoints *ptwX = (ptwXPoints *) nfu_calloc( sizeof( ptwXPoints ), 1 );
 27 
 28     *status = nfu_mallocError;
 29     if( ptwX == NULL ) return( NULL );
 30     ptwX_setup( ptwX, size );
 31     if( ( *status = ptwX->status ) != nfu_Okay ) ptwX = (ptwXPoints *) nfu_free( ptwX );
 32     return( ptwX );
 33 }
 34 /*
 35 ************************************************************
 36 */
 37 nfu_status ptwX_setup( ptwXPoints *ptwX, int64_t size ) {
 38 
 39     ptwX->status = nfu_Okay;
 40     ptwX->length = 0;
 41     ptwX->allocatedSize = 0;
 42     ptwX->mallocFailedSize = 0;
 43     ptwX->points = NULL;
 44     ptwX_reallocatePoints( ptwX, size, 0 );
 45     return( ptwX->status );
 46 }
 47 /*
 48 ************************************************************
 49 */
 50 ptwXPoints *ptwX_create( int64_t size, int64_t length, double const *xs, nfu_status *status ) {
 51 
 52     ptwXPoints *ptwX = ptwX_new( size, status );
 53 
 54     if( ptwX != NULL ) {
 55         if( ( *status = ptwX_setData( ptwX, length, xs ) ) != nfu_Okay ) ptwX = ptwX_free( ptwX );
 56     }
 57     return( ptwX );
 58 }
 59 /*
 60 ************************************************************
 61 */
 62 ptwXPoints *ptwX_createLine( int64_t size, int64_t length, double slope, double offset, nfu_status *status ) {
 63 
 64     int64_t i1;
 65     double *p1;
 66     ptwXPoints *ptwX;
 67 
 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;
 72     }
 73     return( ptwX );
 74 }
 75 /*
 76 ************************************************************
 77 */
 78 nfu_status ptwX_copy( ptwXPoints *dest, ptwXPoints *src ) {
 79 
 80     if( dest->status == nfu_Okay ) return( dest->status );
 81     if( src->status == nfu_Okay ) return( src->status );
 82     ptwX_clear( dest );
 83     return( ptwX_setData( dest, src->length, src->points ) );
 84 }
 85 /*
 86 ************************************************************
 87 */
 88 ptwXPoints *ptwX_clone( ptwXPoints *ptwX, nfu_status *status ) {
 89 
 90     return( ptwX_slice( ptwX, 0, ptwX->length, status ) );
 91 }
 92 /*
 93 ************************************************************
 94 */
 95 ptwXPoints *ptwX_slice( ptwXPoints *ptwX, int64_t index1, int64_t index2, nfu_status *status ) {
 96 
 97     int64_t i, j, length;
 98     ptwXPoints *n;
 99 
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 );
108     *status = n->status;
109     for( j = 0, i = index1; i < index2; i++, j++ ) n->points[j] = ptwX->points[i];
110     n->length = length;
111     return( n );
112 }
113 /*
114 ************************************************************
115 */
116 nfu_status ptwX_reallocatePoints( ptwXPoints *ptwX, int64_t size, int forceSmallerResize ) {
117 
118     if( size < ptwX_minimumSize ) size = ptwX_minimumSize;                        /* ptwX_minimumSize must be > 0 for other routines to work properly. */
119     if( size < ptwX->length ) size = ptwX->length;
120     if( size != ptwX->allocatedSize ) {
121         if( size > ptwX->allocatedSize ) {                                         /* Increase size of allocated points. */
122              ptwX->points = (double *) nfu_realloc( (size_t) size * sizeof( double ), ptwX->points ); }
123         else if( ( ptwX->allocatedSize > 2 * size ) || forceSmallerResize ) {      /* Decrease size, if at least 1/2 size reduction or if forced to. */
124             ptwX->points = (double *) nfu_realloc( (size_t) size * sizeof( double ), ptwX->points );
125         }
126         if( ptwX->points == NULL ) {
127             ptwX->mallocFailedSize = size;
128             size = 0;
129             ptwX->status = nfu_mallocError;
130         }
131         ptwX->allocatedSize = size;
132     }
133 
134     return( ptwX->status );
135 }
136 /*
137 ************************************************************
138 */
139 nfu_status ptwX_clear( ptwXPoints *ptwX ) {
140 
141     ptwX->length = 0;
142     return( ptwX->status );
143 }
144 /*
145 ************************************************************
146 */
147 nfu_status ptwX_release( ptwXPoints *ptwX ) {
148 
149     ptwX->length = 0;
150     ptwX->allocatedSize = 0;
151     ptwX->points = (double *) nfu_free( ptwX->points );
152 
153     return( nfu_Okay );
154 }
155 /*
156 ************************************************************
157 */
158 ptwXPoints *ptwX_free( ptwXPoints *ptwX ) {
159 
160     if( ptwX != NULL ) ptwX_release( ptwX );
161     return( (ptwXPoints *) nfu_free( ptwX ) );
162 }
163 /*
164 ************************************************************
165 */
166 int64_t ptwX_length( ptwXPoints *ptwX ) {
167 
168     return( ptwX->length );
169 }
170 /*
171 ************************************************************
172 */
173 nfu_status ptwX_setData( ptwXPoints *ptwX, int64_t length, double const *xs ) {
174 
175     int64_t  i;
176 
177     if( ptwX->status != nfu_Okay ) return( ptwX->status );
178 
179     if( length > ptwX->allocatedSize ) {
180         ptwX_reallocatePoints( ptwX, length, 0 );
181         if( ptwX->status != nfu_Okay ) return( ptwX->status );
182     }
183     for( i = 0; i < length; i++ ) ptwX->points[i] = xs[i];
184     ptwX->length = length;
185 
186     return( ptwX->status );
187 }
188 /*
189 ************************************************************
190 */ 
191 nfu_status ptwX_deletePoints( ptwXPoints *ptwX, int64_t i1, int64_t i2 ) {
192 
193     int64_t n = ptwX->length - ( i2 - i1 );
194 
195     if( ptwX->status != nfu_Okay ) return( ptwX->status );
196     if( ( i1 < 0 ) || ( i1 > i2 ) || ( i2 > ptwX->length ) ) return( nfu_badIndex );
197     if( i1 != i2 ) {
198         for( ; i2 < ptwX->length; i1++, i2++ ) ptwX->points[i1] = ptwX->points[i2];
199         ptwX->length = n;
200     }
201     return( ptwX->status );
202 }
203 /*
204 ************************************************************
205 */
206 double *ptwX_getPointAtIndex( ptwXPoints *ptwX, int64_t index ) {
207 
208     if( ptwX->status != nfu_Okay ) return( NULL );
209     if( ( index < 0 ) || ( index >= ptwX->length ) ) return( NULL );
210     return( &(ptwX->points[index]) );
211 }
212 /*
213 ************************************************************
214 */
215 double ptwX_getPointAtIndex_Unsafely( ptwXPoints *ptwX, int64_t index ) {
216 
217     return( ptwX->points[index] );
218 }
219 /*
220 ************************************************************
221 */
222 nfu_status ptwX_setPointAtIndex( ptwXPoints *ptwX, int64_t index, double x ) {
223 
224     nfu_status status;
225 
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 );
230     }
231     ptwX->points[index] = x;
232     if( index == ptwX->length ) ptwX->length++;
233     return( nfu_Okay );
234 }
235 /*
236 ************************************************************
237 */
238 nfu_status ptwX_insertPointsAtIndex( ptwXPoints *ptwX, int64_t index, int64_t n1, double const *xs ) {
239 
240     nfu_status status;
241     int64_t i1, i2, n1p, size = n1 + ptwX->length;
242 
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 ) {
247         if( ( status = ptwX_reallocatePoints( ptwX, size, 0 ) ) != nfu_Okay ) return( status );
248     }
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];
251     ptwX->length += n1;
252     return( nfu_Okay );
253 }
254 /*
255 ************************************************************
256 */
257 int ptwX_ascendingOrder( ptwXPoints *ptwX ) {
258 /*
259 *    Returns -1 list is descending, 1 if ascending and 0 otherwise (i.e., mixed).
260 */
261     int order = 1;
262     int64_t i;
263     double x1, x2;
264 
265     if( ptwX->length < 2 ) return( 0 );
266 
267     if( ( x1 = ptwX->points[0] ) < ( x2 = ptwX->points[1] ) ) {     /* Check for ascending order. */
268         for( i = 2; i < ptwX->length; i++ ) {
269             x1 = x2;
270             x2 = ptwX->points[i];
271             if( x2 <= x1 ) return( 0 );
272         } }
273     else {
274         if( x1 == x2 ) return( 0 );
275         order = -1;                                                 /* Check for descending order. */
276         for( i = 2; i < ptwX->length; i++ ) {
277             x1 = x2;
278             x2 = ptwX->points[i];
279             if( x1 <= x2 ) return( 0 );
280         }
281     }
282     return( order );
283 }
284 /*
285 ************************************************************
286 */
287 ptwXPoints *ptwX_fromString( char const *str, char **endCharacter, nfu_status *status ) {
288 
289     int64_t numberConverted;
290     double  *doublePtr;
291     ptwXPoints *ptwX = NULL;
292 
293     if( ( *status = nfu_stringToListOfDoubles( str, &numberConverted, &doublePtr, endCharacter ) ) != nfu_Okay ) return( NULL );
294     ptwX = ptwX_create( numberConverted, numberConverted, doublePtr, status );
295     nfu_free( doublePtr );
296     return( ptwX );
297 }
298 /*
299 ************************************************************
300 */
301 nfu_status ptwX_countOccurrences( ptwXPoints *ptwX, double value, int *count ) {
302 
303     int64_t i1;
304 
305     *count = 0;
306     for( i1 = 0; i1 < ptwX->length; i1++ ) {
307         if( ptwX->points[i1] == value ) (*count)++;
308     }
309     return( nfu_Okay );
310 }
311 /*
312 ************************************************************
313 */
314 nfu_status ptwX_reverse( ptwXPoints *ptwX ) {
315 
316     int64_t i1, i2 = ptwX->length - 1, n1 = ptwX->length / 2;
317     double tmp;
318 
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;
323     }
324     return( nfu_Okay );
325 }
326 /*
327 ************************************************************
328 */
329 nfu_status ptwX_sort( ptwXPoints *ptwX, enum ptwX_sort_order order ) {
330 
331     int (*cmp)( void const *, void const * ) = ptwX_sort_descending;
332 
333     if( order == ptwX_sort_order_ascending ) cmp = ptwX_sort_ascending;
334     qsort( ptwX->points, (size_t) ptwX->length, sizeof( ptwX->points[0] ), cmp );
335     return( nfu_Okay );
336 }
337 /*
338 ************************************************************
339 */
340 static int ptwX_sort_descending( void const *p1, void const *p2 ) { return( -ptwX_sort_ascending( p1, p2 ) ); }
341 static int ptwX_sort_ascending( void const *p1, void const *p2 ) {
342 
343     double *d1 = (double *) p1, *d2 = (double *) p2;
344 
345     if( *d1 < *d2 ) return( -1 );
346     if( *d1 == *d2 ) return( 0 );
347     return( 1 );
348 }
349 /*
350 ************************************************************
351 */
352 nfu_status ptwX_closesDifference( ptwXPoints *ptwX, double value, int64_t *index, double *difference ) {
353 
354     return( ptwX_closesDifferenceInRange( ptwX, 0, ptwX->length, value, index, difference ) );
355 }
356 /*
357 ************************************************************
358 */
359 nfu_status ptwX_closesDifferenceInRange( ptwXPoints *ptwX, int64_t i1, int64_t i2, double value, int64_t *index, double *difference ) {
360 /*
361 *   Finds the closes datum to value. If *difference is zero, datum is same as value.
362 */
363     double d1;
364 
365     *index = -1;
366     *difference = -1;
367     if( ptwX->status != nfu_Okay ) return( ptwX->status );
368     if( i1 < 0 ) i1 = 0;
369     if( i2 > ptwX->length ) i2 = ptwX->length;
370     if( i1 >= i2 ) return( nfu_Okay );
371     *index = i1;
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 ) ) {
376             *index = i1;
377             *difference = d1;
378         }
379     }
380     return( nfu_Okay );
381 }
382 /*
383 ************************************************************
384 */
385 ptwXPoints *ptwX_unique( ptwXPoints *ptwX, int order, nfu_status *status ) {
386 /*
387 *   If order < 0 order is descending, if order > 0 order is ascending, otherwise, order is the same as ptwX.
388 */
389     int64_t i1, i2, n1 = 0;
390     double x1, *p2;
391     ptwXPoints *ptwX2 = NULL;
392 
393     if( order == 0 ) {
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;
399             }
400             if( i2 == ptwX2->length ) {
401                 ptwX2->points[ptwX2->length] = x1;
402                 ptwX2->length++;
403             }
404         } }
405     else {
406         if( ( ptwX2 = ptwX_clone( ptwX, status ) ) == NULL ) return( NULL );
407         if( ( *status = ptwX_sort( ptwX2, ptwX_sort_order_ascending ) ) != nfu_Okay ) goto err;
408 
409         if( ptwX2->length > 1 ) {
410             x1 = ptwX2->points[n1];
411             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;
416                     n1++;
417                 }
418             }
419             ptwX2->length = n1;
420             if( order < 0 ) {
421                 if( ( *status = ptwX_sort( ptwX2, ptwX_sort_order_descending ) ) != nfu_Okay ) goto err;
422             }
423         }
424     }
425     return( ptwX2 );
426 
427 err:
428     if( ptwX2 != NULL ) ptwX_free( ptwX2 );
429     return( NULL );
430 }
431 /*
432 ************************************************************
433 */
434 nfu_status ptwX_abs( ptwXPoints *ptwX ) {
435 
436     int64_t i1;
437     double *p1;
438 
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 );
441     return( nfu_Okay );
442 }
443 /*
444 ************************************************************
445 */
446 nfu_status ptwX_neg( ptwXPoints *ptwX ) {
447 
448     return( ptwX_slopeOffset( ptwX, -1, 0 ) );
449 }
450 /*
451 ************************************************************
452 */
453 nfu_status ptwX_add_double( ptwXPoints *ptwX, double value ) {
454 
455     return( ptwX_slopeOffset( ptwX, 1, value ) );
456 }
457 /*
458 ************************************************************
459 */
460 nfu_status ptwX_mul_double( ptwXPoints *ptwX, double value ) {
461 
462     return( ptwX_slopeOffset( ptwX, value, 0 ) );
463 }
464 /*
465 ************************************************************
466 */
467 nfu_status ptwX_slopeOffset( ptwXPoints *ptwX, double slope, double offset ) {
468 
469     int64_t i1;
470     double *p1;
471 
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;
474     return( nfu_Okay );
475 }
476 /*
477 ************************************************************
478 */
479 nfu_status ptwX_add_ptwX( ptwXPoints *ptwX1, ptwXPoints *ptwX2 ) {
480 
481     int64_t i1;
482     double *p1 = ptwX1->points, *p2 = ptwX2->points;
483 
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 );
487 
488     for( i1 = 0; i1 < ptwX1->length; i1++, p1++, p2++ ) *p1 += *p2;
489     return( nfu_Okay );
490 }
491 /*
492 ************************************************************
493 */
494 nfu_status ptwX_sub_ptwX( ptwXPoints *ptwX1, ptwXPoints *ptwX2 ) {
495 
496     int64_t i1;
497     double *p1 = ptwX1->points, *p2 = ptwX2->points;
498 
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 );
502 
503     for( i1 = 0; i1 < ptwX1->length; i1++, p1++, p2++ ) *p1 -= *p2;
504     return( nfu_Okay );
505 }
506 /*
507 ************************************************************
508 */
509 nfu_status ptwX_xMinMax( ptwXPoints *ptwX, double *xMin, double *xMax ) {
510 
511     int64_t i1, n1 = ptwX->length;
512     *xMin = *xMax = 0;
513     double *p1 = ptwX->points;
514 
515     if( ptwX->status != nfu_Okay ) return( ptwX->status );
516     if( n1 > 0 ) {
517         *xMin = *xMax = *(p1++);
518         for( i1 = 1; i1 < n1; ++i1, ++p1 ) {
519             if( *p1 < *xMin ) *xMin = *p1;
520             if( *p1 > *xMax ) *xMax = *p1;
521         }
522     }
523     return( nfu_Okay );
524 }
525 /*
526 ************************************************************
527 */
528 nfu_status ptwX_compare( ptwXPoints *ptwX1, ptwXPoints *ptwX2, int *comparison ) {
529 
530     int64_t i1, n1 = ptwX1->length, n2 = ptwX2->length, nn = n1;
531     double *p1 = ptwX1->points, *p2 = ptwX2->points;
532 
533     *comparison = 0;
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;
539         *comparison = 1;
540         if( *p1 < *p2 ) *comparison = -1;
541         return( nfu_Okay );
542     }
543     if( n1 < n2 ) {
544         *comparison = -1; }
545     else if( n1 > n2 ) {
546         *comparison = 1;
547     }
548     return( nfu_Okay );
549 }
550 /*
551 ************************************************************
552 */
553 int ptwX_close( ptwXPoints *ptwX1, ptwXPoints *ptwX2, int epsilonFactor, double epsilon, nfu_status *status ) {
554 
555     int64_t i1, n1 = ptwX1->length;
556     double larger;
557     double *p1 = ptwX1->points, *p2 = ptwX2->points;
558 
559     epsilon = std::fabs( epsilon ) + std::abs( epsilonFactor ) * DBL_EPSILON;
560 
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 );
567 
568     *status = nfu_Okay;
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 ) );
573     }
574     return( 0 );
575 }
576 
577 #if defined __cplusplus
578 }
579 #endif
580