Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
ptwXY_core.c
Go to the documentation of this file.
1/*
2# <<BEGIN-copyright>>
3# Copyright 2019, Lawrence Livermore National Security, LLC.
4# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
5# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
6# SPDX-License-Identifier: MIT
7# <<END-copyright>>
8*/
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <math.h>
13
14#include "ptwXY.h"
15
16/* Need to change these when conversion to Fudge3 is complete. */
17static char const linLinInterpolationString[] = "lin-lin";
18static char const logLinInterpolationString[] = "log-lin";
19static char const linLogInterpolationString[] = "lin-log";
20static char const logLogInterpolationString[] = "log-log";
21static char const flatInterpolationString[] = "flat";
22
23static nfu_status ptwXY_mergeFrom( statusMessageReporting *smr, ptwXYPoints *ptwXY, int incY, int length, double *xs, double *ys );
24static void ptwXY_initialOverflowPoint( ptwXYOverflowPoint *overflowPoint, ptwXYOverflowPoint *prior, ptwXYOverflowPoint *next );
25/*
26************************************************************
27*/
28ptwXYPoints *ptwXY_new( statusMessageReporting *smr, ptwXY_interpolation interpolation, char const *interpolationString,
29 double biSectionMax, double accuracy, int64_t primarySize, int64_t secondarySize, int userFlag ) {
30
31 ptwXYPoints *ptwXY = (ptwXYPoints *) smr_malloc2( smr, sizeof( ptwXYPoints ), 1, "ptwXY" );
32
33 if( ptwXY == NULL ) return( NULL );
34 if( ptwXY_initialize( smr, ptwXY, interpolation, interpolationString, biSectionMax, accuracy, primarySize, secondarySize, userFlag ) != nfu_Okay ) {
36 smr_freeMemory2( ptwXY );
37 }
38 return( ptwXY );
39}
40
41/*
42************************************************************
43*/
44ptwXYPoints *ptwXY_new2( statusMessageReporting *smr, ptwXY_interpolation interpolation, int64_t primarySize, int64_t secondarySize ) {
45
46 char const *interpolationString = ptwXY_interpolationToString( interpolation );
47
48 return( ptwXY_new( smr, interpolation, interpolationString, 12, 1e-3, primarySize, secondarySize, 0 ) );
49}
50/*
51************************************************************
52*/
54 char const *interpolationString, double biSectionMax, double accuracy, int64_t primarySize, int64_t secondarySize,
55 int userFlag ) {
56
57 ptwXY->status = nfu_Okay;
58 ptwXY->interpolation = interpolation;
59 ptwXY->interpolationString = NULL;
60 switch( interpolation ) {
62 ptwXY->interpolationString = linLinInterpolationString; break;
64 ptwXY->interpolationString = logLinInterpolationString; break;
66 ptwXY->interpolationString = linLogInterpolationString; break;
68 ptwXY->interpolationString = logLogInterpolationString; break;
70 ptwXY->interpolationString = flatInterpolationString; break;
71 case ptwXY_interpolationOther : /* For ptwXY_interpolationOther, interpolationString must be defined. */
72 if( interpolationString == NULL ) {
74 "Invalid other interplation. interpolationString is NULL, it must be a defined string" );
75 ptwXY->status = nfu_Error; }
76 else {
77 if( ( ptwXY->interpolationString = smr_allocateCopyString2( smr, interpolationString, "interpolationString" ) ) == NULL )
78 ptwXY->status = nfu_Error;
79 }
80 }
81 ptwXY->userFlag = 0;
82 ptwXY_setUserFlag( ptwXY, userFlag );
84 ptwXY_setBiSectionMax( ptwXY, biSectionMax );
86 ptwXY_setAccuracy( ptwXY, accuracy );
87
88 ptwXY->length = 0;
89 ptwXY->allocatedSize = 0;
90 ptwXY->overflowLength = 0;
91 ptwXY->overflowAllocatedSize = 0;
92 ptwXY->mallocFailedSize = 0;
93
94 ptwXY_initialOverflowPoint( &(ptwXY->overflowHeader), &(ptwXY->overflowHeader), &(ptwXY->overflowHeader) );
95
96 ptwXY->points = NULL;
97 ptwXY->overflowPoints = NULL;
98
99 if( ptwXY_reallocatePoints( smr, ptwXY, primarySize, 0 ) == nfu_Okay )
100 ptwXY_reallocateOverflowPoints( smr, ptwXY, secondarySize );
101 if( ptwXY->status != nfu_Okay ) {
103 ptwXY_release( smr, ptwXY );
104 }
105 return( ptwXY->status );
106}
107/*
108************************************************************
109*/
110ptwXYPoints *ptwXY_create( statusMessageReporting *smr, ptwXY_interpolation interpolation, char const *interpolationString,
111 double biSectionMax, double accuracy, int64_t primarySize, int64_t secondarySize, int64_t length, double const *xy,
112 int userFlag ) {
113
114 ptwXYPoints *ptwXY;
115
116 if( primarySize < length ) primarySize = length;
117 if( ( ptwXY = ptwXY_new( smr, interpolation, interpolationString, biSectionMax, accuracy, primarySize,
118 secondarySize, userFlag ) ) != NULL ) {
119 if( ptwXY_setXYData( smr, ptwXY, length, xy ) != nfu_Okay ) ptwXY = ptwXY_free( ptwXY );
120 }
121
122 if( ptwXY == NULL ) smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_Error, "Via." );
123 return( ptwXY );
124}
125/*
126************************************************************
127*/
129 int64_t primarySize, int64_t secondarySize, int64_t length, double const *xy, int userFlag ) {
130
131 char const *interpolationString = ptwXY_interpolationToString( interpolation );
132
133 return( ptwXY_create( smr, interpolation, interpolationString, 12, 1e-3, primarySize, secondarySize, length, xy, userFlag ) );
134}
135/*
136************************************************************
137*/
138ptwXYPoints *ptwXY_createFrom_Xs_Ys( statusMessageReporting *smr, ptwXY_interpolation interpolation, char const *interpolationString,
139 double biSectionMax, double accuracy, int64_t primarySize, int64_t secondarySize, int64_t length, double const *Xs,
140 double const *Ys, int userFlag ) {
141
142 int i;
143 ptwXYPoints *ptwXY;
144
145 if( primarySize < length ) primarySize = length;
146 if( ( ptwXY = ptwXY_new( smr, interpolation, interpolationString, biSectionMax, accuracy, primarySize,
147 secondarySize, userFlag ) ) != NULL ) {
148 for( i = 0; i < length; i++ ) {
149 ptwXY->points[i].x = Xs[i];
150 ptwXY->points[i].y = Ys[i];
151 }
152 ptwXY->length = length;
153 }
154
155 if( ptwXY == NULL ) smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_Error, "Via." );
156 return( ptwXY );
157}
158/*
159************************************************************
160*/
162 int64_t secondarySize, int64_t length, double const *Xs, double const *Ys, int userFlag ) {
163
164 char const *interpolationString = ptwXY_interpolationToString( interpolation );
165
166 return( ptwXY_createFrom_Xs_Ys( smr, interpolation, interpolationString, 12, 1e-3, primarySize, secondarySize, length, Xs, Ys, userFlag ) );
167}
168/*
169************************************************************
170*/
172
173 int64_t i, nonOverflowLength;
174 ptwXYPoint *pointFrom, *pointTo;
175 ptwXYOverflowPoint *o, *overflowHeader = &(src->overflowHeader);
176
177 if( dest->status != nfu_Okay ) {
178 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Invalid destination." );
179 return( dest->status );
180 }
181 if( src->status != nfu_Okay ) {
182 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Invalid source." );
183 return( src->status );
184 }
185
186 nonOverflowLength = ptwXY_getNonOverflowLength( smr, src ); /* No need to check return value. */
187
188 if( ptwXY_clear( smr, dest ) != nfu_Okay ) {
190 return( dest->status );
191 }
193 if( dest->interpolationString != NULL ) {
194 dest->interpolationString = (char const *) smr_freeMemory2( dest->interpolationString );
195 }
196 }
197 dest->interpolation = ptwXY_interpolationLinLin; /* This and prior lines are in case interpolation is 'other' and ptwXY_reallocatePoints fails. */
198 if( dest->allocatedSize < src->length ) {
199 if( ptwXY_reallocatePoints( smr, dest, src->length, 0 ) != nfu_Okay ) {
201 return( dest->status );
202 }
203 }
204 if( dest->status != nfu_Okay ) return( dest->status );
205 dest->interpolation = src->interpolation;
207 if( src->interpolationString != NULL ) {
208 if( ( dest->interpolationString = smr_allocateCopyString2( smr, src->interpolationString, "interpolationString" ) ) == NULL ) {
210 return( dest->status = nfu_Error );
211 }
212 } }
213 else {
215 }
216 dest->userFlag = src->userFlag;
217 dest->biSectionMax = src->biSectionMax;
218 dest->accuracy = src->accuracy;
220 pointFrom = src->points;
221 o = src->overflowHeader.next;
222 pointTo = dest->points;
223 i = 0;
224 while( o != overflowHeader ) {
225 if( i < nonOverflowLength ) {
226 if( pointFrom->x < o->point.x ) {
227 *pointTo = *pointFrom;
228 i++;
229 pointFrom++; }
230 else {
231 *pointTo = o->point;
232 o = o->next;
233 } }
234 else {
235 *pointTo = o->point;
236 o = o->next;
237 }
238 pointTo++;
239 }
240 for( ; i < nonOverflowLength; i++, pointFrom++, pointTo++ ) *pointTo = *pointFrom;
241 dest->length = src->length;
242 return( dest->status );
243}
244/*
245************************************************************
246*/
248
249 int64_t i, nonOverflowLength;
250 ptwXYPoint *pointFrom, *pointTo;
251 ptwXYOverflowPoint *o, *overflowHeader = &(src->overflowHeader);
252
253 if( dest->status != nfu_Okay ) {
254 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Invalid destination." );
255 return( dest->status );
256 }
257 if( src->status != nfu_Okay ) {
258 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Invalid source." );
259 return( src->status );
260 }
261
262 nonOverflowLength = ptwXY_getNonOverflowLength( smr, src ); /* No need to check return value. */
263
264 if( ptwXY_clear( smr, dest ) != nfu_Okay ) {
266 return( dest->status );
267 }
268
269 if( dest->allocatedSize < src->length ) {
270 if( ptwXY_reallocatePoints( smr, dest, src->length, 0 ) != nfu_Okay ) {
272 return( dest->status );
273 }
274 }
275 pointFrom = src->points;
276 o = src->overflowHeader.next;
277 pointTo = dest->points;
278 i = 0;
279 while( o != overflowHeader ) {
280 if( i < nonOverflowLength ) {
281 if( pointFrom->x < o->point.x ) {
282 *pointTo = *pointFrom;
283 i++;
284 pointFrom++; }
285 else {
286 *pointTo = o->point;
287 o = o->next;
288 } }
289 else {
290 *pointTo = o->point;
291 o = o->next;
292 }
293 pointTo++;
294 }
295 for( ; i < nonOverflowLength; i++, pointFrom++, pointTo++ ) *pointTo = *pointFrom;
296 dest->length = src->length;
297 return( dest->status );
298}
299/*
300************************************************************
301*/
303
304 ptwXYPoints *ptwXY2 = ptwXY_slice( smr, ptwXY, 0, ptwXY->length, ptwXY->overflowAllocatedSize );
305
306 if( ptwXY2 == NULL ) smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_Error, "Via." );
307 return( ptwXY2 );
308}
309/*
310************************************************************
311*/
313
314 int64_t length = ptwXY->length;
315 ptwXYPoints *ptwXY2 = NULL;
316 ptwXYPoint *pointsFrom, *pointsTo;
318
319 if( ptwXY->status != nfu_Okay ) {
320 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Invalid source." );
321 return( NULL );
322 }
323
324 ptwXY2 = ptwXY_new( smr, ptwXY->interpolation, ptwXY->interpolationString,
325 ptwXY->biSectionMax, ptwXY->accuracy, length, ptwXY->overflowAllocatedSize, ptwXY->userFlag );
326 if( ptwXY2 == NULL ) smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_Error, "Via." );
327
328 pointsFrom = &(ptwXY->points[ptwXY_getNonOverflowLength( smr, ptwXY ) - 1]);
329 pointsTo = &(ptwXY2->points[length - 1]);
330 while( last != &(ptwXY->overflowHeader) ) {
331 if( ( pointsFrom >= ptwXY->points ) && ( pointsFrom->x > last->point.x ) ) {
332 *pointsTo = *pointsFrom;
333 --pointsFrom; }
334 else {
335 *pointsTo = last->point;
336 last = last->prior;
337 }
338 --pointsTo;
339 }
340
341 for( ; pointsFrom >= ptwXY->points; --pointsFrom, --pointsTo ) *pointsTo = *pointsFrom;
342 ptwXY2->length = length;
343
344 return( ptwXY2 );
345}
346/*
347************************************************************
348*/
350
351 ptwXYPoints *n1;
352
353 if( ptwXY->status != nfu_Okay ) {
354 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Invalid source." );
355 return( NULL );
356 }
357
358/* Other interpolation should probably be allowed. */
359 if( interpolationTo == ptwXY_interpolationOther ) {
360 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_otherInterpolation, "Other interpolation not allowed." );
361 return( NULL );
362 }
363 if( ( n1 = ptwXY_clone( smr, ptwXY ) ) == NULL ) {
365 else {
367 n1->interpolation = interpolationTo;
368 switch( interpolationTo ) {
370 n1->interpolationString = linLinInterpolationString; break;
372 n1->interpolationString = logLinInterpolationString; break;
374 n1->interpolationString = linLogInterpolationString; break;
376 n1->interpolationString = logLogInterpolationString; break;
378 n1->interpolationString = flatInterpolationString; break;
379 case ptwXY_interpolationOther : /* Does not happen, but needed to stop compilers from complaining. */
380 break;
381 }
382 }
383 return( n1 );
384}
385/*
386************************************************************
387*/
388ptwXYPoints *ptwXY_slice( statusMessageReporting *smr, ptwXYPoints *ptwXY, int64_t index1, int64_t index2, int64_t secondarySize ) {
389
390 int64_t i, length;
391 ptwXYPoints *n;
392
393 if( ptwXY->status != nfu_Okay ) {
394 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Invalid source." );
395 return( NULL );
396 }
397
398 if( ( index1 < 0 ) || ( index2 < index1 ) || ( index2 > ptwXY->length ) ) {
399 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_badIndex, "Indices = %d, %d out of bounds: length = %d",
400 (int) index1, (int) index2, (int) ptwXY->length );
401 return( NULL );
402 }
403
404 length = index2 - index1;
405 if( ptwXY_simpleCoalescePoints( smr, ptwXY ) != nfu_Okay ) {
407 return( NULL );
408 }
409 if( ( n = ptwXY_new( smr, ptwXY->interpolation, ptwXY->interpolationString, ptwXY->biSectionMax,
410 ptwXY->accuracy, length, secondarySize, ptwXY->userFlag ) ) == NULL ) {
412 return( NULL );
413 }
414
415 for( i = index1; i < index2; i++ ) n->points[i - index1] = ptwXY->points[i];
416 n->length = length;
417 return( n );
418}
419/*
420************************************************************
421*/
422ptwXYPoints *ptwXY_domainSlice( statusMessageReporting *smr, ptwXYPoints *ptwXY, double domainMin, double domainMax,
423 int64_t secondarySize, int fill ) {
424
425 int64_t i, i1, i2;
426 double y, _domainMin, _domainMax;
427 ptwXYPoints *n = NULL;
428
429 if( ptwXY->status != nfu_Okay ) {
430 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Invalid source." );
431 return( NULL );
432 }
433
434 if( ptwXY_domainMin( smr, ptwXY, &_domainMin ) != nfu_Okay ) {
436 return( NULL );
437 }
438 if( ptwXY_domainMax( smr, ptwXY, &_domainMax ) != nfu_Okay ) {
440 return( NULL );
441 }
442
443 if( ( ptwXY->length == 0 ) || ( _domainMin >= domainMax ) || ( _domainMax <= domainMin ) ) {
444 if( ( n = ptwXY_new( smr, ptwXY->interpolation, ptwXY->interpolationString, ptwXY->biSectionMax,
445 ptwXY->accuracy, 0, secondarySize, ptwXY->userFlag ) ) == NULL ) {
447 } }
448 else {
449 if( ( n = ptwXY_clone( smr, ptwXY ) ) == NULL ) {
451 return( NULL );
452 }
453 if( ( n->points[0].x < domainMin ) || ( n->points[n->length - 1].x > domainMax ) ) {
454 if( fill && ( n->points[n->length - 1].x > domainMax ) ) {
455 if( ptwXY_getValueAtX( smr, n, domainMax, &y ) != nfu_Okay ) goto Err;
456 if( ptwXY_setValueAtX( smr, n, domainMax, y ) != nfu_Okay ) goto Err;
457 }
458 if( fill && ( n->points[0].x < domainMin ) ) {
459 if( ptwXY_getValueAtX( smr, n, domainMin, &y ) != nfu_Okay ) goto Err;
460 if( ptwXY_setValueAtX( smr, n, domainMin, y ) != nfu_Okay ) goto Err;
461 }
462 if( ptwXY_coalescePoints( smr, n, n->length + n->overflowAllocatedSize, NULL, 0 ) != nfu_Okay ) goto Err;
463 for( i1 = 0; i1 < n->length; i1++ ) if( n->points[i1].x >= domainMin ) break;
464 for( i2 = n->length - 1; i2 > 0; i2-- ) if( n->points[i2].x <= domainMax ) break;
465 i2++;
466 if( i1 > 0 ) {
467 for( i = i1; i < i2; i++ ) n->points[i- i1] = n->points[i];
468 }
469 n->length = i2 - i1;
470 }
471 }
472 return( n );
473
474Err:
476 if( n != NULL ) ptwXY_free( n );
477 return( NULL );
478}
479/*
480************************************************************
481*/
482ptwXYPoints *ptwXY_domainMinSlice( statusMessageReporting *smr, ptwXYPoints *ptwXY, double domainMin, int64_t secondarySize, int fill ) {
483
484 double domainMax = 1.1 * domainMin + 1;
485 ptwXYPoints *ptwXY2;
486
487 if( domainMin < 0 ) domainMax = 0.9 * domainMin + 1;
488 if( ptwXY->length > 0 ) {
489 if( ptwXY_domainMax( smr, ptwXY, &domainMax ) != nfu_Okay )
491 }
492 if( ( ptwXY2 = ptwXY_domainSlice( smr, ptwXY, domainMin, domainMax, secondarySize, fill ) ) == NULL )
494 return( ptwXY2 );
495}
496/*
497************************************************************
498*/
499ptwXYPoints *ptwXY_domainMaxSlice( statusMessageReporting *smr, ptwXYPoints *ptwXY, double domainMax, int64_t secondarySize, int fill ) {
500
501 double domainMin = 0.9 * domainMax - 1;
502 ptwXYPoints *ptwXY2;
503
504 if( domainMax < 0 ) domainMin = 1.1 * domainMax - 1;
505 if( ptwXY->length > 0 ) {
506 if( ptwXY_domainMin( smr, ptwXY, &domainMin ) != nfu_Okay ) {
508 return( NULL );
509 }
510 }
511 if( ( ptwXY2 = ptwXY_domainSlice( smr, ptwXY, domainMin, domainMax, secondarySize, fill ) ) == NULL )
513 return( ptwXY2 );
514}
515/*
516************************************************************
517*/
519
520 return( ptwXY->interpolation );
521}
522/*
523************************************************************
524*/
526
527 return( ptwXY->interpolationString );
528}
529/*
530************************************************************
531*/
532nfu_status ptwXY_setInterpolationString( ptwXYPoints *ptwXY, char const *interpolationString ) {
533
534 ptwXY_interpolation interpolation = ptwXY_stringToInterpolation( interpolationString );
535
536 if( interpolation == ptwXY_interpolationOther ) return( nfu_invalidInterpolation );
537
538 ptwXY->interpolation = interpolation;
539 ptwXY->interpolationString = ptwXY_interpolationToString( interpolation );
540 return( nfu_Okay );
541}
542/*
543************************************************************
544*/
546
547 return( ptwXY->status );
548}
549/*
550************************************************************
551*/
553
554 return( ptwXY->userFlag );
555}
556/*
557************************************************************
558*/
559void ptwXY_setUserFlag( ptwXYPoints *ptwXY, int userFlag ) {
560
561 ptwXY->userFlag = userFlag;
562}
563/*
564************************************************************
565*/
567
568 return( ptwXY->accuracy );
569}
570/*
571************************************************************
572*/
573double ptwXY_setAccuracy( ptwXYPoints *ptwXY, double accuracy ) {
574
575 accuracy = ptwXY_limitAccuracy( accuracy );
576 ptwXY->accuracy = accuracy;
577 return( ptwXY->accuracy );
578}
579/*
580************************************************************
581*/
583
584 return( ptwXY->biSectionMax );
585}
586/*
587************************************************************
588*/
589double ptwXY_setBiSectionMax( ptwXYPoints *ptwXY, double biSectionMax ) {
590
591 if( biSectionMax < 0 ) {
592 biSectionMax = 0; }
593 else if( biSectionMax > ptwXY_maxBiSectionMax ) {
594 biSectionMax = ptwXY_maxBiSectionMax;
595 }
596 ptwXY->biSectionMax = biSectionMax;
597 return( ptwXY->biSectionMax );
598}
599/*
600************************************************************
601*/
602nfu_status ptwXY_reallocatePoints( statusMessageReporting *smr, ptwXYPoints *ptwXY, int64_t size, int forceSmallerResize ) {
603/*
604* This is for allocating/reallocating the primary data memory.
605*/
606 if( ptwXY->status != nfu_Okay ) {
607 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Invalid source." );
608 return( ptwXY->status );
609 }
610
611 if( size < ptwXY_minimumSize ) size = ptwXY_minimumSize; /* ptwXY_minimumSize must be > 0. */
612 if( size < ptwXY->length ) size = ptwXY->length;
613 if( size != ptwXY->allocatedSize ) {
614 if( size > ptwXY->allocatedSize ) { /* Increase size of allocated points. */
615 ptwXY->points = (ptwXYPoint *) smr_realloc2( smr, ptwXY->points, (size_t) size * sizeof( ptwXYPoint ), "ptwXY->points" ); }
616 else if( ( ptwXY->allocatedSize > 2 * size ) || forceSmallerResize ) { /* Decrease size, if at least 1/2 size reduction or if forced to. */
617 ptwXY->points = (ptwXYPoint *) smr_realloc2( smr, ptwXY->points, (size_t) size * sizeof( ptwXYPoint ), "ptwXY->points" ); }
618 else {
619 size = ptwXY->allocatedSize; /* Size is < ptwXY->allocatedSize, but realloc not called. */
620 }
621 if( ptwXY->points == NULL ) {
622 ptwXY->length = 0;
623 ptwXY->mallocFailedSize = size;
624 size = 0;
625 ptwXY->status = nfu_mallocError;
626 }
627 ptwXY->allocatedSize = size;
628 }
629 return( ptwXY->status );
630}
631/*
632************************************************************
633*/
635/*
636* This is for allocating/reallocating the secondary data memory.
637*/
638 if( ptwXY->status != nfu_Okay ) {
639 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Invalid source." );
640 return( ptwXY->status );
641 }
642
643 if( size < ptwXY_minimumOverflowSize ) size = ptwXY_minimumOverflowSize; /* ptwXY_minimumOverflowSize must be > 0. */
644 if( size < ptwXY->overflowLength ) {
645 if( ptwXY_coalescePoints( smr, ptwXY, ptwXY->length + ptwXY->overflowAllocatedSize, NULL, 0 ) != nfu_Okay ) {
647 return( ptwXY->status );
648 }
649 }
650 if( size != ptwXY->overflowAllocatedSize ) {
652 (size_t) size * sizeof( ptwXYOverflowPoint ), "ptwXY->overflowPoints" );
653 if( ptwXY->overflowPoints == NULL ) {
654 ptwXY->length = 0;
655 ptwXY->overflowLength = 0;
656 ptwXY->mallocFailedSize = size;
657 size = 0;
658 ptwXY->status = nfu_mallocError;
659 }
660 }
661 ptwXY->overflowAllocatedSize = size;
662 return( ptwXY->status );
663}
664/*
665************************************************************
666*/
668 ptwXYPoint *newPoint, int forceSmallerResize ) {
669
670 int addNewPoint;
671 int64_t length = ptwXY->length + ( ( newPoint != NULL ) ? 1 : 0 );
673 ptwXYPoint *pointsFrom, *pointsTo;
674
675 if( ptwXY->status != nfu_Okay ) {
676 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Invalid source." );
677 return( ptwXY->status );
678 }
679 if( ptwXY->overflowLength == 0 ) return( nfu_Okay );
680
681 if( size < length ) size = length;
682 if( size > ptwXY->allocatedSize ) {
683 if( ptwXY_reallocatePoints( smr, ptwXY, size, forceSmallerResize ) != nfu_Okay ) {
685 return( ptwXY->status );
686 }
687 }
688 pointsFrom = &(ptwXY->points[ptwXY_getNonOverflowLength( smr, ptwXY ) - 1]);
689 pointsTo = &(ptwXY->points[length - 1]);
690 while( last != &(ptwXY->overflowHeader) ) {
691 addNewPoint = 0;
692 if( newPoint != NULL ) {
693 if( ( pointsFrom >= ptwXY->points ) && ( pointsFrom->x > last->point.x ) ) {
694 if( newPoint->x > pointsFrom->x ) addNewPoint = 1; }
695 else {
696 if( newPoint->x > last->point.x ) addNewPoint = 1;
697 }
698 if( addNewPoint == 1 ) {
699 *pointsTo = *newPoint;
700 newPoint = NULL;
701 }
702 }
703 if( addNewPoint == 0 ) {
704 if( ( pointsFrom >= ptwXY->points ) && ( pointsFrom->x > last->point.x ) ) {
705 *pointsTo = *pointsFrom;
706 pointsFrom--; }
707 else {
708 *pointsTo = last->point;
709 last = last->prior;
710 }
711 }
712 pointsTo--;
713 }
714 while( ( newPoint != NULL ) && ( pointsFrom >= ptwXY->points ) ) {
715 if( newPoint->x > pointsFrom->x ) {
716 *pointsTo = *newPoint;
717 newPoint = NULL; }
718 else {
719 *pointsTo = *pointsFrom;
720 pointsFrom--;
721 }
722 pointsTo--;
723 }
724 if( newPoint != NULL ) *pointsTo = *newPoint;
725 ptwXY->overflowHeader.prior = &(ptwXY->overflowHeader);
726 ptwXY->overflowHeader.next = &(ptwXY->overflowHeader);
727 ptwXY->length = length;
728 ptwXY->overflowLength = 0;
729 return( nfu_Okay );
730}
731/*
732************************************************************
733*/
735
736 if( ptwXY_coalescePoints( smr, ptwXY, ptwXY->length, NULL, 0 ) != nfu_Okay )
738 return( ptwXY->status );
739}
740/*
741************************************************************
742*/
744
745 if( ptwXY->status != nfu_Okay ) {
746 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Invalid source." );
747 return( ptwXY->status );
748 }
749
750 ptwXY->length = 0;
751 ptwXY->overflowLength = 0;
752 ptwXY->overflowHeader.prior = &(ptwXY->overflowHeader);
753 ptwXY->overflowHeader.next = &(ptwXY->overflowHeader);
754 return( nfu_Okay );
755}
756/*
757************************************************************
758*/
760/*
761* Note, this routine does not free ptwXY (i.e., it does not undo all of ptwXY_new).
762*/
763
765 if( ptwXY->interpolationString != NULL )
766 ptwXY->interpolationString = (char const *) smr_freeMemory2( ptwXY->interpolationString );
767 }
769 ptwXY->length = 0;
770 ptwXY->allocatedSize = 0;
771 ptwXY->points = (ptwXYPoint *) smr_freeMemory2( ptwXY->points );
772
773 ptwXY->overflowLength = 0;
774 ptwXY->overflowAllocatedSize = 0;
776
777 return( nfu_Okay );
778}
779/*
780************************************************************
781*/
783
784 if( ptwXY != NULL ) {
785 ptwXY_release( NULL, ptwXY );
786 smr_freeMemory2( ptwXY );
787 }
788 return( (ptwXYPoints *) NULL );
789}
790/*
791************************************************************
792*/
794
795 if( ptwXY->status != nfu_Okay ) {
796 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Invalid source." );
797 return( -ptwXY->status );
798 }
799
800 return( ptwXY->length );
801}
802/*
803************************************************************
804*/
806
807 if( ptwXY->status != nfu_Okay ) {
808 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Invalid source." );
809 return( -ptwXY->status );
810 }
811
812 return( ptwXY->length - ptwXY->overflowLength );
813}
814
815/*
816************************************************************
817*/
818nfu_status ptwXY_startIndex( statusMessageReporting *a_smr, ptwXYPoints *a_ptwXY, double a_x, int64_t *a_startIndex, int64_t *a_length ) {
819/*
820 Sets *a_startIndex to -2 if a_x < domainMin, -1 if a_x > domainMax, otherwise to the lowest index in a_ptwXY->points
821where a_x >= a_ptwXY->points[*a_startIndex]. The logic below guarantees that *a_startIndex < (*a_length - 1 ). For example, if
822a_x == domainMax, then *a_startIndex = *a_length - 2, or the next to the last point.
823*/
824
825 int64_t lower = 0, mid, upper;
826 ptwXYPoint *point;
827 *a_length = ptwXY_length( NULL, a_ptwXY );
828
829 if( ptwXY_simpleCoalescePoints( a_smr, a_ptwXY ) != nfu_Okay ) {
831 return( a_ptwXY->status );
832 }
833
834 if( *a_length < 2 ) {
835 smr_setReportError2( a_smr, nfu_SMR_libraryID, nfu_tooFewPoints, "number of points = %lld < 2", *a_length );
836 return( nfu_tooFewPoints );
837 }
838
839 *a_startIndex = -2;
840 point = &a_ptwXY->points[lower];
841 if( a_x < point->x ) return( nfu_Okay );
842
843 upper = *a_length - 1;
844 *a_startIndex = -1;
845 point = &a_ptwXY->points[upper];
846 if( a_x > point->x ) return( nfu_Okay );
847
848 while( 1 ) {
849 mid = ( lower + upper ) >> 1;
850 if( mid == lower ) break;
851 point = &a_ptwXY->points[mid];
852 if( a_x < point->x ) {
853 upper = mid; }
854 else {
855 lower = mid;
856 }
857 }
858
859 *a_startIndex = mid;
860 return( nfu_Okay );
861}
862
863/*
864************************************************************
865*/
866nfu_status ptwXY_setXYData( statusMessageReporting *smr, ptwXYPoints *ptwXY, int64_t length, double const *xy ) {
867
868 int64_t index;
869 ptwXYPoint *p;
870 double const *d = xy;
871 double priorX = 0.;
872
873 if( ptwXY->status != nfu_Okay ) {
874 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Invalid source." );
875 return( ptwXY->status );
876 }
877
878 if( length > ptwXY->allocatedSize ) {
879 if( ptwXY_reallocatePoints( smr, ptwXY, length, 0 ) != nfu_Okay ) {
881 return( ptwXY->status );
882 }
883 }
884 for( index = 0, p = ptwXY->points; index < length; index++, p++ ) {
885 if( index != 0 ) {
886 if( *d <= priorX ) {
888 "X value at index = %d of %.17e is <= prior value of %.17e", (int) index, *d, priorX );
889 ptwXY->status = nfu_XNotAscending;
890 length = 0;
891 break;
892 }
893 }
894 priorX = *d;
895 p->x = *(d++);
896 p->y = *(d++);
897 }
898 ptwXY->overflowHeader.next = &(ptwXY->overflowHeader);
899 ptwXY->overflowHeader.prior = &(ptwXY->overflowHeader);
900 ptwXY->overflowLength = 0;
901 ptwXY->length = length;
902 return( ptwXY->status );
903}
904/*
905************************************************************
906*/
908 double const *x, double const *y ) {
909
910 int64_t i;
911 ptwXYPoint *p;
912 double xOld = 0.;
913
914 if( ptwXY_clear( smr, ptwXY ) != nfu_Okay ) {
916 return( ptwXY->status );
917 }
918
919 if( length > ptwXY->allocatedSize ) {
920 if( ptwXY_reallocatePoints( smr, ptwXY, length, 0 ) != nfu_Okay ) {
922 return( ptwXY->status );
923 }
924 }
925 for( i = 0, p = ptwXY->points; i < length; i++, p++, x++, y++ ) {
926 if( i != 0 ) {
927 if( *x <= xOld ) {
928 ptwXY->status = nfu_XNotAscending;
929 length = 0;
930 break;
931 }
932 }
933 xOld = *x;
934 p->x = *x;
935 p->y = *y;
936 }
937 ptwXY->length = length;
938 return( ptwXY->status );
939}
940/*
941************************************************************
942*/
943nfu_status ptwXY_deletePoints( statusMessageReporting *smr, ptwXYPoints *ptwXY, int64_t i1, int64_t i2 ) {
944
945 int64_t n = ptwXY->length - ( i2 - i1 );
946
947 if( ptwXY_simpleCoalescePoints( smr, ptwXY ) != nfu_Okay ) {
949 return( ptwXY->status );
950 }
951
952 if( ( i1 < 0 ) || ( i2 < i1 ) || ( i2 > ptwXY->length ) ) {
953 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_badIndex, "Indices = %d, %d out of bounds: length = %d",
954 (int) i1, (int) i2, (int) ptwXY->length );
955 return( ptwXY->status = nfu_badIndex );
956 }
957
958 if( i1 != i2 ) {
959 for( ; i2 < ptwXY->length; i1++, i2++ ) ptwXY->points[i1] = ptwXY->points[i2];
960 ptwXY->length = n;
961 }
962 return( ptwXY->status );
963}
964/*
965************************************************************
966*/
968
969 int64_t i1, length = ptwXY->length;
970
971 *index = -1;
972
973 if( ptwXY->status != nfu_Okay ) {
974 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Invalid source." );
975 return( ptwXY->status );
976 }
977
978 if( ptwXY_simpleCoalescePoints( smr, ptwXY ) != nfu_Okay ) {
980 return( ptwXY->status );
981 }
982
983 if( x < ptwXY->points[0].x ) return( nfu_Okay );
984 if( x > ptwXY->points[length-1].x ) return( nfu_Okay );
985 for( i1 = 1; i1 < length; ++i1 ) {
986 if( x < ptwXY->points[i1].x ) break;
987 }
988 *index = i1 - 1;
989 return( ptwXY->status );
990}
991/*
992************************************************************
993*/
995
996 if( ptwXY->status != nfu_Okay ) {
997 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Invalid source." );
998 return( NULL );
999 }
1000
1001 if( ( index < 0 ) || ( index >= ptwXY->length ) ) return( NULL );
1002 return( ptwXY_getPointAtIndex_Unsafely( ptwXY, index ) );
1003}
1004/*
1005************************************************************
1006*/
1008
1009 int64_t i;
1010 ptwXYOverflowPoint *overflowPoint;
1011
1012 for( overflowPoint = ptwXY->overflowHeader.next, i = 0; overflowPoint != &(ptwXY->overflowHeader); overflowPoint = overflowPoint->next, i++ ) {
1013 if( overflowPoint->index == index ) return( &(overflowPoint->point) );
1014 if( overflowPoint->index > index ) break;
1015 }
1016 return( &(ptwXY->points[index - i]) );
1017}
1018/*
1019************************************************************
1020*/
1021nfu_status ptwXY_getXYPairAtIndex( statusMessageReporting *smr, ptwXYPoints *ptwXY, int64_t index, double *x, double *y ) {
1022
1023 ptwXYPoint *p = ptwXY_getPointAtIndex( smr, ptwXY, index );
1024
1025 if( p == NULL ) {
1027 return( ptwXY->status );
1028 }
1029 *x = p->x;
1030 *y = p->y;
1031 return( nfu_Okay );
1032}
1033/*
1034************************************************************
1035*/
1037 ptwXYOverflowPoint *lessThanEqualXPoint, ptwXYOverflowPoint *greaterThanXPoint ) {
1038
1039 int closeIsEqual;
1040 ptwXYPoint *closePoint;
1041 ptwXY_lessEqualGreaterX lessEqualGreaterX;
1042
1043 if( ptwXY->status != nfu_Okay ) {
1044 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Invalid source." );
1046 }
1047
1048 lessEqualGreaterX = ptwXY_getPointsAroundX_closeIsEqual( smr, ptwXY, x, lessThanEqualXPoint, greaterThanXPoint,
1049 0, &closeIsEqual, &closePoint );
1050 if( lessEqualGreaterX == ptwXY_lessEqualGreaterX_Error ) smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_Error, "Via." );
1051 return( lessEqualGreaterX );
1052}
1053/*
1054************************************************************
1055*/
1057 ptwXYOverflowPoint *lessThanEqualXPoint, ptwXYOverflowPoint *greaterThanXPoint, double eps, int *closeIsEqual,
1058 ptwXYPoint **closePoint ) {
1059
1060 int64_t overflowIndex, nonOverflowLength = ptwXY_getNonOverflowLength( smr, ptwXY );
1061 int64_t indexMin, indexMid, indexMax;
1062 ptwXY_dataFrom domainMinFrom, domainMaxFrom;
1063 double domainMin, domainMax;
1064 ptwXYOverflowPoint *overflowPoint, *overflowHeader = &(ptwXY->overflowHeader);
1066 ptwXYPoint *lowerPoint = NULL, *upperPoint = NULL;
1067
1068 if( nonOverflowLength < 0 ) {
1071 }
1072
1073 *closeIsEqual = 0;
1074 if( ptwXY->length == 0 ) return( status );
1075
1076 if( ptwXY_domainMinAndFrom( smr, ptwXY, &domainMinFrom, &domainMin ) != nfu_Okay ) {
1079 }
1080
1081 if( ptwXY_domainMaxAndFrom( smr, ptwXY, &domainMaxFrom, &domainMax ) != nfu_Okay ) {
1084 }
1085
1086 ptwXY_initialOverflowPoint( lessThanEqualXPoint, overflowHeader, NULL );
1087 ptwXY_initialOverflowPoint( greaterThanXPoint, overflowHeader, NULL );
1088 if( x < domainMin ) {
1090 if( domainMinFrom == ptwXY_dataFrom_Points ) {
1091 greaterThanXPoint->prior = overflowHeader;
1092 greaterThanXPoint->index = 0;
1093 greaterThanXPoint->point = ptwXY->points[0];
1094 *closePoint = &(ptwXY->points[0]); }
1095 else {
1096 *greaterThanXPoint = *(overflowHeader->next);
1097 *closePoint = &(overflowHeader->next->point);
1098 } }
1099 else if( x > domainMax ) {
1101 if( domainMaxFrom == ptwXY_dataFrom_Points ) {
1102 lessThanEqualXPoint->prior = overflowHeader->prior;
1103 lessThanEqualXPoint->index = nonOverflowLength - 1;
1104 lessThanEqualXPoint->point = ptwXY->points[lessThanEqualXPoint->index];
1105 *closePoint = &(ptwXY->points[lessThanEqualXPoint->index]); }
1106 else {
1107 *lessThanEqualXPoint = *(overflowHeader->prior);
1108 *closePoint = &(overflowHeader->prior->point);
1109 } }
1110 else { /* domainMin <= x <= domainMax */
1111 status = ptwXY_lessEqualGreaterX_between; /* Default for this condition, can only be between or equal. */
1112 for( overflowPoint = overflowHeader->next, overflowIndex = 0; overflowPoint != overflowHeader;
1113 overflowPoint = overflowPoint->next, overflowIndex++ ) if( overflowPoint->point.x > x ) break;
1114 overflowPoint = overflowPoint->prior;
1115 if( ( overflowPoint != overflowHeader ) && ( overflowPoint->point.x == x ) ) {
1117 *lessThanEqualXPoint = *overflowPoint; }
1118 else if( ptwXY->length == 1 ) { /* If here and length = 1, then ptwXY->points[0].x == x. */
1120 lessThanEqualXPoint->index = 0;
1121 lessThanEqualXPoint->point = ptwXY->points[0]; }
1122 else { /* ptwXY->length > 1 */
1123 indexMin = 0;
1124 indexMax = nonOverflowLength - 1;
1125 indexMid = ( indexMin + indexMax ) >> 1;
1126 while( ( indexMin != indexMid ) && ( indexMid != indexMax ) ) {
1127 if( ptwXY->points[indexMid].x > x ) {
1128 indexMax = indexMid; }
1129 else {
1130 indexMin = indexMid;
1131 }
1132 indexMid = ( indexMin + indexMax ) >> 1;
1133 }
1134 if( ptwXY->points[indexMin].x == x ) {
1136 lessThanEqualXPoint->index = indexMin;
1137 lessThanEqualXPoint->point = ptwXY->points[indexMin]; }
1138 else if( ptwXY->points[indexMax].x == x ) {
1140 lessThanEqualXPoint->index = indexMax;
1141 lessThanEqualXPoint->point = ptwXY->points[indexMax]; }
1142 else {
1143 if( ptwXY->points[indexMin].x > x ) indexMax = 0;
1144 if( ptwXY->points[indexMax].x < x ) indexMin = indexMax;
1145 if( ( overflowPoint == overflowHeader ) || /* x < domainMin of overflow points. */
1146 ( ( ptwXY->points[indexMin].x > overflowPoint->point.x ) && ( ptwXY->points[indexMin].x < x ) ) ) {
1147 if( overflowPoint != overflowHeader ) lessThanEqualXPoint->prior = overflowPoint;
1148 lowerPoint = &(ptwXY->points[indexMin]);
1149 lessThanEqualXPoint->index = indexMin;
1150 lessThanEqualXPoint->point = ptwXY->points[indexMin]; }
1151 else {
1152 lowerPoint = &(overflowPoint->point);
1153 *lessThanEqualXPoint = *overflowPoint;
1154 }
1155 if( ( overflowPoint->next == overflowHeader ) || /* x > domainMax of overflow points. */
1156 ( ( ptwXY->points[indexMax].x < overflowPoint->next->point.x ) && ( ptwXY->points[indexMax].x > x ) ) ) {
1157 upperPoint = &(ptwXY->points[indexMax]);
1158 greaterThanXPoint->index = indexMax;
1159 greaterThanXPoint->point = ptwXY->points[indexMax]; }
1160 else {
1161 upperPoint = &(overflowPoint->next->point);
1162 *greaterThanXPoint = *(overflowPoint->next);
1163 }
1164 }
1165 }
1166 }
1167
1168 if( eps > 0 ) {
1169 double absX = fabs( x );
1170
1171 if( status == ptwXY_lessEqualGreaterX_lessThan ) {
1172 if( absX < fabs( greaterThanXPoint->point.x ) ) absX = fabs( greaterThanXPoint->point.x );
1173 if( ( greaterThanXPoint->point.x - x ) < eps * absX ) *closeIsEqual = 1; }
1174 else if( status == ptwXY_lessEqualGreaterX_greater ) {
1175 if( absX < fabs( lessThanEqualXPoint->point.x ) ) absX = fabs( lessThanEqualXPoint->point.x );
1176 if( ( x - lessThanEqualXPoint->point.x ) < eps * absX ) *closeIsEqual = -1; }
1177 else if( status == ptwXY_lessEqualGreaterX_between ) {
1178 if( ( x - lessThanEqualXPoint->point.x ) < ( greaterThanXPoint->point.x - x ) ) { /* x is closer to lower point. */
1179 *closePoint = lowerPoint;
1180 if( absX < fabs( lessThanEqualXPoint->point.x ) ) absX = fabs( lessThanEqualXPoint->point.x );
1181 if( ( x - lessThanEqualXPoint->point.x ) < eps * absX ) *closeIsEqual = -1; }
1182 else { /* x is closer to upper point. */
1183 *closePoint = upperPoint;
1184 if( absX < fabs( greaterThanXPoint->point.x ) ) absX = fabs( greaterThanXPoint->point.x );
1185 if( ( greaterThanXPoint->point.x - x ) < eps * absX ) *closeIsEqual = 1;
1186 } }
1187 else if( status == ptwXY_lessEqualGreaterX_equal ) {
1188 *closeIsEqual = 1;
1189 }
1190 }
1191 return( status );
1192}
1193/*
1194************************************************************
1195*/
1197
1199 ptwXYOverflowPoint lessThanEqualXPoint, greaterThanXPoint;
1200 ptwXY_lessEqualGreaterX legx = ptwXY_getPointsAroundX( smr, ptwXY, x, &lessThanEqualXPoint, &greaterThanXPoint );
1201
1202 *y = 0.;
1203 switch( legx ) {
1206 return( ptwXY->status );
1210 break;
1212 status = nfu_Okay;
1213 *y = lessThanEqualXPoint.point.y;
1214 break;
1216 status = ptwXY_interpolatePoint( smr, ptwXY->interpolation, x, y, lessThanEqualXPoint.point.x, lessThanEqualXPoint.point.y,
1217 greaterThanXPoint.point.x, greaterThanXPoint.point.y );
1218 break;
1219 }
1220 return( status );
1221}
1222/*
1223************************************************************
1224*/
1226
1227 if( ptwXY_setValueAtX_overrideIfClose( smr, ptwXY, x, y, 0., 0 ) != nfu_Okay )
1229 return( ptwXY->status );
1230}
1231/*
1232************************************************************
1233*/
1235 double eps, int override ) {
1236
1237 int closeIsEqual;
1238 int64_t nonOverflowLength = ptwXY_getNonOverflowLength( smr, ptwXY ), i;
1240 ptwXYPoint *point = NULL, newPoint = { x, y };
1241 ptwXYOverflowPoint *overflowPoint, *p, *overflowHeader = &(ptwXY->overflowHeader);
1242 ptwXYOverflowPoint lessThanEqualXPoint, greaterThanXPoint;
1243 ptwXYPoint *closePoint;
1244
1245 if( nonOverflowLength < 0 ) {
1247 return( nfu_Error );
1248 }
1249
1250 legx = ptwXY_getPointsAroundX_closeIsEqual( smr, ptwXY, x, &lessThanEqualXPoint, &greaterThanXPoint, eps, &closeIsEqual, &closePoint );
1251 switch( legx ) {
1254 return( nfu_Error );
1258 if( closeIsEqual ) {
1259 if( !override ) return( nfu_Okay );
1260 point = closePoint;
1262 x = point->x; }
1263 else {
1264 if( ( legx == ptwXY_lessEqualGreaterX_greater ) && ( nonOverflowLength < ptwXY->allocatedSize ) ) {
1265 point = &(ptwXY->points[nonOverflowLength]); }
1266 else {
1267 if( ptwXY->overflowLength == ptwXY->overflowAllocatedSize ) {
1268 if( ptwXY_coalescePoints( smr, ptwXY, ptwXY->length + ptwXY->overflowAllocatedSize, &newPoint, 0 ) != nfu_Okay )
1270 return( ptwXY->status );
1271 }
1272 overflowPoint = &(ptwXY->overflowPoints[ptwXY->overflowLength]);
1273 if( legx == ptwXY_lessEqualGreaterX_lessThan ) {
1274 overflowPoint->prior = greaterThanXPoint.prior;
1275 overflowPoint->index = 0; }
1276 else { /* Between or greater and must go in overflow area. */
1277 if( legx == ptwXY_lessEqualGreaterX_greater ) {
1278 overflowPoint->prior = overflowHeader->prior;
1279 overflowPoint->index = ptwXY->length; }
1280 else {
1281 overflowPoint->prior = lessThanEqualXPoint.prior;
1282 if( lessThanEqualXPoint.next != NULL ) {
1283 if( lessThanEqualXPoint.point.x < x )
1284 overflowPoint->prior = lessThanEqualXPoint.prior->next;
1285 i = 1; }
1286 else {
1287 for( p = overflowHeader->next, i = 1; p != overflowHeader; p = p->next, i++ )
1288 if( p->point.x > x ) break;
1289 }
1290 overflowPoint->index = lessThanEqualXPoint.index + i;
1291 }
1292 }
1293 overflowPoint->next = overflowPoint->prior->next;
1294 overflowPoint->prior->next = overflowPoint;
1295 overflowPoint->next->prior = overflowPoint;
1296 point = &(overflowPoint->point);
1297 for( overflowPoint = overflowPoint->next; overflowPoint != overflowHeader; overflowPoint = overflowPoint->next ) {
1298 overflowPoint->index++;
1299 }
1300 ptwXY->overflowLength++;
1301 }
1302 }
1303 break;
1305 point = ptwXY->points; /* ptwXY_minimumSize must be > 0 so there is always space here. */
1306 break;
1308 if( closeIsEqual && !override ) return( nfu_Okay );
1309 if( lessThanEqualXPoint.next == NULL ) {
1310 point = &(ptwXY->points[lessThanEqualXPoint.index]); }
1311 else {
1312 point = &(lessThanEqualXPoint.prior->next->point);
1313 }
1314 break;
1315 }
1316
1317 point->x = x;
1318 point->y = y;
1319 if( legx != ptwXY_lessEqualGreaterX_equal ) ptwXY->length++;
1320 return( nfu_Okay );
1321}
1322/*
1323************************************************************
1324*/
1325nfu_status ptwXY_mergeFromXsAndYs( statusMessageReporting *smr, ptwXYPoints *ptwXY, int length, double *xs, double *ys ) {
1326
1327 if( ptwXY_mergeFrom( smr, ptwXY, 1, length, xs, ys ) != nfu_Okay )
1329 return( ptwXY->status );
1330}
1331/*
1332************************************************************
1333*/
1334nfu_status ptwXY_mergeFromXYs( statusMessageReporting *smr, ptwXYPoints *ptwXY, int length, double *xys ) {
1335
1336 int i;
1337 double *xs, *p1, *p2;
1338
1339 if( length == 0 ) return( nfu_Okay );
1340 if( length < 0 ) {
1341 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_badInput, "Negative length = %d.", length );
1342 return( nfu_badInput );
1343 }
1344
1345 if( ( xs = (double *) smr_malloc2( smr, length * sizeof( double ), 0, "xs" ) ) == NULL ) return( nfu_mallocError );
1346 for( i = 0, p1 = xs, p2 = xys; i < length; i++, p1++, p2 += 2 ) *p1 = *p2;
1347 if( ptwXY_mergeFrom( smr, ptwXY, 2, length, xs, xys ) != nfu_Okay )
1349 smr_freeMemory2( xs );
1350
1351 return( ptwXY->status );
1352}
1353/*
1354************************************************************
1355*/
1356static nfu_status ptwXY_mergeFrom( statusMessageReporting *smr, ptwXYPoints *ptwXY, int incY, int length, double *xs, double *ys ) {
1357
1358 int i1, j1, n1 = 0;
1359 double *p1, priorX;
1360 ptwXYPoint *point1, *point2;
1361
1362 if( ptwXY->status != nfu_Okay ) {
1363 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Invalid source." );
1364 return( ptwXY->status );
1365 }
1366
1367 if( length == 0 ) return( nfu_Okay );
1368 if( length < 0 ) {
1369 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_badInput, "Negative length = %d.", length );
1370 return( nfu_badInput );
1371 }
1372
1373 if( ptwXY_simpleCoalescePoints( smr, ptwXY ) != nfu_Okay ) {
1375 return( ptwXY->status );
1376 }
1377
1378 if( xs[0] < 0 ) {
1379 priorX = 1.1 * xs[0]; }
1380 else {
1381 priorX = 0.9 * xs[0] - 1;
1382 }
1383 for( i1 = 0, p1 = xs; i1 < length; ++i1, ++p1 ) {
1384 if( *p1 <= priorX ) return( nfu_XNotAscending );
1385 priorX = *p1;
1386 }
1387
1388 for( i1 = 0, p1 = xs, j1 = 0; i1 < length; ++i1, ++p1 ) { /* Count the number of x-values same in xs and ptwXY. */
1389 for( ; j1 < ptwXY->length; ++j1 ) {
1390 if( *p1 <= ptwXY->points[j1].x ) break;
1391 }
1392 if( j1 == ptwXY->length ) break; /* Completed all ptwXY points. */
1393 if( *p1 == ptwXY->points[j1].x ) ++n1;
1394 }
1395 n1 = length + (int) ptwXY->length - n1;
1396
1397 if( ptwXY_reallocatePoints( smr, ptwXY, n1, 0 ) != nfu_Okay ) {
1399 n1 = 0; }
1400 else {
1401 point1 = &(ptwXY->points[n1-1]); /* Go backwards through arrays. */
1402 point2 = &(ptwXY->points[ptwXY->length-1]);
1403 p1 = &(xs[length-1]);
1404 for( i1 = length - 1, j1 = (int) ptwXY->length - 1; ( i1 >= 0 ) && ( j1 >= 0 ); --point1 ) {
1405 if( *p1 >= point2->x ) {
1406 point1->x = *p1;
1407 point1->y = ys[i1];
1408 if( *p1 == point2->x ) {
1409 --point2;
1410 --j1;
1411 }
1412 --p1;
1413 --i1; }
1414 else {
1415 *point1 = *point2;
1416 --point2;
1417 --j1;
1418 }
1419 }
1420 for( ; i1 >= 0; --i1, --p1, --point1 ) {
1421 point1->x = *p1;
1422 point1->y = ys[i1];
1423 }
1424 }
1425 ptwXY->length = n1;
1426
1427 return( ptwXY->status );
1428}
1429/*
1430************************************************************
1431*/
1433
1434 int64_t nonOverflowLength = ptwXY_getNonOverflowLength( smr, ptwXY );
1435 ptwXY_dataFrom dataFrom;
1436
1437 if( nonOverflowLength < 0 ) {
1439 return( nfu_Error );
1440 }
1441
1442 if( ptwXY->length != 0 ) {
1443 double domainMax;
1444 nfu_status status;
1445
1446 if( ( status = ptwXY_domainMaxAndFrom( smr, ptwXY, &dataFrom, &domainMax ) ) != nfu_Okay ) {
1448 return( status );
1449 }
1450 if( domainMax >= x ) {
1451 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_XNotAscending, "domainMax = %17.e >= x = %.17e", domainMax, x );
1452 return( ptwXY->status = nfu_XNotAscending );
1453 }
1454 }
1455
1456 if( nonOverflowLength < ptwXY->allocatedSize ) { /* Room at end of points. Also handles the case when length = 0. */
1457 ptwXY->points[nonOverflowLength].x = x;
1458 ptwXY->points[nonOverflowLength].y = y; }
1459 else {
1460 if( ptwXY->overflowLength == ptwXY->overflowAllocatedSize ) {
1461 ptwXYPoint newPoint = { x, y };
1462 if( ptwXY_coalescePoints( smr, ptwXY, ptwXY->length + ptwXY->overflowAllocatedSize, &newPoint, 0 ) != nfu_Okay ) {
1464 return( ptwXY->status ); } }
1465 else { /* Add to end of overflow. */
1466 ptwXYOverflowPoint *overflowPoint = &(ptwXY->overflowPoints[ptwXY->overflowLength]);
1467
1468 overflowPoint->prior = ptwXY->overflowHeader.prior;
1469 overflowPoint->next = overflowPoint->prior->next;
1470 overflowPoint->index = ptwXY->length;
1471 overflowPoint->prior->next = overflowPoint;
1472 overflowPoint->next->prior = overflowPoint;
1473 overflowPoint->point.x = x;
1474 overflowPoint->point.y = y;
1475 ptwXY->overflowLength++;
1476 }
1477 }
1478 ptwXY->length++;
1479 return( nfu_Okay );
1480}
1481/*
1482************************************************************
1483*/
1484nfu_status ptwXY_setXYPairAtIndex( statusMessageReporting *smr, ptwXYPoints *ptwXY, int64_t index, double x, double y ) {
1485
1486 int64_t i, ip1;
1487 ptwXYOverflowPoint *overflowPoint, *pm1, *pp1;
1488
1489 if( ptwXY->status != nfu_Okay ) {
1490 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Invalid source." );
1491 return( ptwXY->status );
1492 }
1493
1494 if( ( index < 0 ) || ( index >= ptwXY->length ) ) {
1495 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_badIndex, "Index = %d, out of bounds: length = %d",
1496 (int) index, (int) ptwXY->length );
1497 return( ptwXY->status = nfu_badIndex );
1498 }
1499
1500 for( overflowPoint = ptwXY->overflowHeader.next, i = 0; overflowPoint != &(ptwXY->overflowHeader); overflowPoint = overflowPoint->next, i++ ) {
1501 if( overflowPoint->index >= index ) break;
1502 }
1503 ip1 = i;
1504 pm1 = pp1 = overflowPoint;
1505 if( overflowPoint->index == index ) { /* Note, if overflowPoint is header, then its index = -1. */
1506 pp1 = overflowPoint->next;
1507 ip1++;
1508 }
1509 if( ( pp1 != &(ptwXY->overflowHeader) ) && ( pp1->index == ( index + 1 ) ) ) { /* This if and else check that x < element[index+1]'s x values. */
1510 if( pp1->point.x <= x ) return( nfu_badIndexForX ); }
1511 else {
1512 if( ( ( index + 1 ) < ptwXY->length ) && ( ptwXY->points[index + 1 - ip1].x <= x ) ) return( nfu_badIndexForX );
1513 }
1514 if( overflowPoint != &(ptwXY->overflowHeader) ) pm1 = overflowPoint->prior;
1515 if( ( pm1 != &(ptwXY->overflowHeader) ) && ( pm1->index == ( index - 1 ) ) ) { /* This if and else check that x > element[index-1]'s x values. */
1516 if( pm1->point.x >= x ) return( nfu_badIndexForX ); }
1517 else {
1518 if( ( ( index - 1 ) >= 0 ) && ( ptwXY->points[index - 1 - i].x >= x ) ) return( nfu_badIndexForX );
1519 }
1520 if( ( overflowPoint != &(ptwXY->overflowHeader) ) && ( overflowPoint->index == index ) ) {
1521 overflowPoint->point.x = x;
1522 overflowPoint->point.y = y; }
1523 else {
1524 index -= i;
1525 ptwXY->points[index].x = x;
1526 ptwXY->points[index].y = y;
1527 }
1528 return( nfu_Okay );
1529}
1530/*
1531************************************************************
1532*/
1533nfu_status ptwXY_getSlopeAtX( statusMessageReporting *smr, ptwXYPoints *ptwXY, double x, const char side, double *slope ) {
1534
1535 nfu_status status = nfu_Okay;
1536 ptwXYOverflowPoint lessThanEqualXPoint = { NULL, NULL, 0, {0.0, 0.0}}, greaterThanXPoint;
1537 ptwXY_lessEqualGreaterX legx = ptwXY_getPointsAroundX( smr, ptwXY, x, &lessThanEqualXPoint, &greaterThanXPoint );
1538 ptwXYPoint *point;
1539 greaterThanXPoint = lessThanEqualXPoint; /* Done to stop a compiler from complaining. */
1540
1541 *slope = 0.;
1542
1543 if( ptwXY->status != nfu_Okay ) {
1544 smr_setReportError2p( smr, nfu_SMR_libraryID, nfu_badSelf, "Invalid source." );
1545 return( ptwXY->status );
1546 }
1547 if( ( side != '-' ) && ( side != '+' ) ) {
1548 smr_setReportError2( smr, nfu_SMR_libraryID, nfu_badSelf, "Invalid side = '%c'.", side );
1549 return( nfu_badInput );
1550 }
1551
1552 switch( legx ) {
1555 return( nfu_Error );
1559 status = nfu_XOutsideDomain;
1560 break;
1562 *slope = ( greaterThanXPoint.point.y - lessThanEqualXPoint.point.y ) /
1563 ( greaterThanXPoint.point.x - lessThanEqualXPoint.point.x );
1564 break;
1566 if( side == '-' ) {
1567 if( lessThanEqualXPoint.index == 0 ) {
1568 status = nfu_XOutsideDomain; }
1569 else {
1570 point = ptwXY_getPointAtIndex_Unsafely( ptwXY, lessThanEqualXPoint.index - 1 );
1571 *slope = ( lessThanEqualXPoint.point.y - point->y ) / ( lessThanEqualXPoint.point.x - point->x );
1572 } }
1573 else {
1574 if( lessThanEqualXPoint.index == ( ptwXY->length - 1 ) ) {
1575 status = nfu_XOutsideDomain; }
1576 else {
1577 point = ptwXY_getPointAtIndex_Unsafely( ptwXY, lessThanEqualXPoint.index + 1 );
1578 *slope = ( point->y - lessThanEqualXPoint.point.y ) / ( point->x - lessThanEqualXPoint.point.x );
1579 }
1580 }
1581 }
1582
1583 return( status );
1584}
1585/*
1586************************************************************
1587*/
1589
1590 int64_t nonOverflowLength = ptwXY_getNonOverflowLength( smr, ptwXY );
1591
1592 *domainMin = 0;
1593 *dataFrom = ptwXY_dataFrom_Unknown;
1594
1595 if( nonOverflowLength < 0 ) {
1597 return( nfu_Error );
1598 }
1599
1600 if( ptwXY->overflowLength > 0 ) {
1601 *dataFrom = ptwXY_dataFrom_Overflow;
1602 *domainMin = ptwXY->overflowHeader.next->point.x;
1603 if( nonOverflowLength >= 0 ) {
1604 if( *domainMin > ptwXY->points[0].x ) {
1605 *dataFrom = ptwXY_dataFrom_Points;
1606 *domainMin = ptwXY->points[0].x;
1607 }
1608 } }
1609 else if( nonOverflowLength > 0 ) {
1610 *dataFrom = ptwXY_dataFrom_Points;
1611 *domainMin = ptwXY->points[0].x; }
1612 else {
1613 return( nfu_empty );
1614 }
1615 return( nfu_Okay );
1616}
1617/*
1618************************************************************
1619*/
1621
1622 ptwXY_dataFrom dataFrom;
1623 nfu_status status;
1624
1625 if( ( status = ptwXY_domainMinAndFrom( smr, ptwXY, &dataFrom, domainMin ) ) != nfu_Okay ) {
1626 if( status == nfu_empty ) return( status );
1628 return( nfu_Error );
1629 }
1630
1631 return( nfu_Okay );
1632}
1633/*
1634************************************************************
1635*/
1637
1638 int64_t nonOverflowLength = ptwXY_getNonOverflowLength( smr, ptwXY );
1639
1640 *domainMax = 0;
1641 *dataFrom = ptwXY_dataFrom_Unknown;
1642
1643 if( nonOverflowLength < 0 ) {
1645 return( nfu_Error );
1646 }
1647
1648 if( ptwXY->overflowLength > 0 ) {
1649 *dataFrom = ptwXY_dataFrom_Overflow;
1650 *domainMax = ptwXY->overflowHeader.prior->point.x;
1651 if( ( nonOverflowLength > 0 ) ) {
1652 if( *domainMax < ptwXY->points[nonOverflowLength-1].x ) {
1653 *dataFrom = ptwXY_dataFrom_Points;
1654 *domainMax = ptwXY->points[nonOverflowLength-1].x;
1655 }
1656 } }
1657 else if( ptwXY->length > 0 ) {
1658 *dataFrom = ptwXY_dataFrom_Points;
1659 *domainMax = ptwXY->points[nonOverflowLength-1].x; }
1660 else {
1661 return( nfu_empty );
1662 }
1663 return( nfu_Okay );
1664}
1665/*
1666************************************************************
1667*/
1669
1670 ptwXY_dataFrom dataFrom;
1671 nfu_status status;
1672
1673 if( ( status = ptwXY_domainMaxAndFrom( smr, ptwXY, &dataFrom, domainMax ) ) != nfu_Okay ) {
1674 if( status == nfu_empty ) return( status );
1676 return( nfu_Error );
1677 }
1678 return( nfu_Okay );
1679}
1680/*
1681************************************************************
1682*/
1683nfu_status ptwXY_range( statusMessageReporting *smr, ptwXYPoints *ptwXY, double *rangeMin, double *rangeMax ) {
1684
1685 int64_t i, nonOverflowLength = ptwXY_getNonOverflowLength( smr, ptwXY );
1686 ptwXYPoint *p = ptwXY->points;
1687 ptwXYOverflowPoint *overflowPoint = ptwXY->overflowHeader.next;
1688
1689 *rangeMin = *rangeMax = 0.;
1690
1691 if( nonOverflowLength < 0 ) {
1693 return( nfu_Error );
1694 }
1695
1696 if( ptwXY->length == 0 ) return( nfu_empty );
1697 if( nonOverflowLength > 0 ) {
1698 *rangeMin = *rangeMax = p->y;
1699 for( i = 1, p++; i < nonOverflowLength; i++, p++ ) {
1700 *rangeMin = ( ( *rangeMin < p->y ) ? *rangeMin : p->y );
1701 *rangeMax = ( ( *rangeMax > p->y ) ? *rangeMax : p->y );
1702 } }
1703 else {
1704 *rangeMin = *rangeMax = overflowPoint->point.y;
1705 }
1706 for( ; overflowPoint != &(ptwXY->overflowHeader); overflowPoint = overflowPoint->next ) {
1707 *rangeMin = ( ( *rangeMin < overflowPoint->point.y ) ? *rangeMin : overflowPoint->point.y );
1708 *rangeMax = ( ( *rangeMax < overflowPoint->point.y ) ? *rangeMax : overflowPoint->point.y );
1709 }
1710 return( nfu_Okay );
1711}
1712/*
1713************************************************************
1714*/
1716
1717 int64_t i, nonOverflowLength = ptwXY_getNonOverflowLength( smr, ptwXY );
1718 ptwXYPoint *p = ptwXY->points;
1719 ptwXYOverflowPoint *overflowPoint = ptwXY->overflowHeader.next;
1720
1721 *rangeMin = 0.;
1722
1723 if( nonOverflowLength < 0 ) {
1725 return( nfu_Error );
1726 }
1727
1728 if( ptwXY->length == 0 ) return( nfu_empty );
1729 if( nonOverflowLength > 0 ) {
1730 *rangeMin = p->y;
1731 for( i = 1, p++; i < nonOverflowLength; i++, p++ ) *rangeMin = ( ( *rangeMin < p->y ) ? *rangeMin : p->y ); }
1732 else {
1733 *rangeMin = overflowPoint->point.y;
1734 }
1735 for( ; overflowPoint != &(ptwXY->overflowHeader); overflowPoint = overflowPoint->next )
1736 *rangeMin = ( ( *rangeMin < overflowPoint->point.y ) ? *rangeMin : overflowPoint->point.y );
1737 return( nfu_Okay );
1738}
1739/*
1740************************************************************
1741*/
1743
1744 int64_t i, nonOverflowLength = ptwXY_getNonOverflowLength( smr, ptwXY );
1745 ptwXYPoint *p = ptwXY->points;
1746 ptwXYOverflowPoint *overflowPoint = ptwXY->overflowHeader.next;
1747
1748 *rangeMax = 0.;
1749
1750 if( nonOverflowLength < 0 ) {
1752 return( nfu_Error );
1753 }
1754
1755 if( ptwXY->length == 0 ) return( nfu_empty );
1756 if( nonOverflowLength > 0 ) {
1757 *rangeMax = p->y;
1758 for( i = 1, p++; i < nonOverflowLength; i++, p++ ) *rangeMax = ( ( *rangeMax > p->y ) ? *rangeMax : p->y ); }
1759 else {
1760 *rangeMax = overflowPoint->point.y;
1761 }
1762 for( ; overflowPoint != &(ptwXY->overflowHeader); overflowPoint = overflowPoint->next )
1763 *rangeMax = ( ( *rangeMax > overflowPoint->point.y ) ? *rangeMax : overflowPoint->point.y );
1764 return( nfu_Okay );
1765}
1766/*
1767************************************************************
1768*/
1769static void ptwXY_initialOverflowPoint( ptwXYOverflowPoint *overflowPoint, ptwXYOverflowPoint *prior, ptwXYOverflowPoint *next ) {
1770
1771 overflowPoint->prior = prior;
1772 overflowPoint->next = next;
1773 overflowPoint->index = -1;
1774 overflowPoint->point.x = 0.;
1775 overflowPoint->point.y = 0.;
1776}
1777/*
1778************************************************************
1779*/
1781
1782 switch( interpolation ) {
1783 case ptwXY_interpolationLinLin : return( linLinInterpolationString );
1784 case ptwXY_interpolationLogLin : return( logLinInterpolationString );
1785 case ptwXY_interpolationLinLog : return( linLogInterpolationString );
1786 case ptwXY_interpolationLogLog : return( logLogInterpolationString );
1787 case ptwXY_interpolationFlat : return( flatInterpolationString );
1788 default :
1789 break;
1790 }
1791 return( NULL );
1792}
1793/*
1794************************************************************
1795*/
1796ptwXY_interpolation ptwXY_stringToInterpolation( char const *interpolationString ) {
1797
1798 if( strcmp( interpolationString, "" ) == 0 ) return( ptwXY_interpolationLinLin );
1799 if( strcmp( interpolationString, linLinInterpolationString ) == 0 ) return( ptwXY_interpolationLinLin );
1800 if( strcmp( interpolationString, logLinInterpolationString ) == 0 ) return( ptwXY_interpolationLogLin );
1801 if( strcmp( interpolationString, linLogInterpolationString ) == 0 ) return( ptwXY_interpolationLinLog );
1802 if( strcmp( interpolationString, logLogInterpolationString ) == 0 ) return( ptwXY_interpolationLogLog );
1803 if( strcmp( interpolationString, flatInterpolationString ) == 0 ) return( ptwXY_interpolationFlat );
1804 return( ptwXY_interpolationOther );
1805}
@ nfu_XNotAscending
@ nfu_invalidInterpolation
@ nfu_Okay
@ nfu_badSelf
@ nfu_mallocError
@ nfu_XOutsideDomain
@ nfu_badIndex
@ nfu_tooFewPoints
@ nfu_badInput
@ nfu_badIndexForX
@ nfu_Error
@ nfu_empty
@ nfu_otherInterpolation
enum nfu_status_e nfu_status
int nfu_SMR_libraryID
#define ptwXY_minAccuracy
Definition ptwXY.h:26
double ptwXY_limitAccuracy(double accuracy)
Definition ptwXY_misc.c:28
enum ptwXY_lessEqualGreaterX_e ptwXY_lessEqualGreaterX
enum ptwXY_dataFrom_e ptwXY_dataFrom
struct ptwXYOverflowPoint_s ptwXYOverflowPoint
enum ptwXY_interpolation_e ptwXY_interpolation
@ ptwXY_interpolationFlat
Definition ptwXY.h:38
@ ptwXY_interpolationLinLog
Definition ptwXY.h:37
@ ptwXY_interpolationLogLog
Definition ptwXY.h:38
@ ptwXY_interpolationLinLin
Definition ptwXY.h:37
@ ptwXY_interpolationOther
Definition ptwXY.h:38
@ ptwXY_interpolationLogLin
Definition ptwXY.h:37
struct ptwXYPoints_s ptwXYPoints
#define ptwXY_maxBiSectionMax
Definition ptwXY.h:25
#define ptwXY_minimumSize
Definition ptwXY.h:23
nfu_status ptwXY_interpolatePoint(statusMessageReporting *smr, ptwXY_interpolation interpolation, double x, double *y, double x1, double y1, double x2, double y2)
@ ptwXY_lessEqualGreaterX_equal
Definition ptwXY.h:59
@ ptwXY_lessEqualGreaterX_Error
Definition ptwXY.h:60
@ ptwXY_lessEqualGreaterX_empty
Definition ptwXY.h:59
@ ptwXY_lessEqualGreaterX_between
Definition ptwXY.h:60
@ ptwXY_lessEqualGreaterX_lessThan
Definition ptwXY.h:59
@ ptwXY_lessEqualGreaterX_greater
Definition ptwXY.h:60
struct ptwXYPoint_s ptwXYPoint
#define ptwXY_minimumOverflowSize
Definition ptwXY.h:24
@ ptwXY_dataFrom_Overflow
Definition ptwXY.h:30
@ ptwXY_dataFrom_Points
Definition ptwXY.h:30
@ ptwXY_dataFrom_Unknown
Definition ptwXY.h:30
nfu_status ptwXY_setInterpolationString(ptwXYPoints *ptwXY, char const *interpolationString)
Definition ptwXY_core.c:532
nfu_status ptwXY_domainMax(statusMessageReporting *smr, ptwXYPoints *ptwXY, double *domainMax)
nfu_status ptwXY_deletePoints(statusMessageReporting *smr, ptwXYPoints *ptwXY, int64_t i1, int64_t i2)
Definition ptwXY_core.c:943
ptwXYPoints * ptwXY_domainSlice(statusMessageReporting *smr, ptwXYPoints *ptwXY, double domainMin, double domainMax, int64_t secondarySize, int fill)
Definition ptwXY_core.c:422
nfu_status ptwXY_mergeFromXsAndYs(statusMessageReporting *smr, ptwXYPoints *ptwXY, int length, double *xs, double *ys)
double ptwXY_getAccuracy(ptwXYPoints *ptwXY)
Definition ptwXY_core.c:566
nfu_status ptwXY_setValueAtX(statusMessageReporting *smr, ptwXYPoints *ptwXY, double x, double y)
ptwXY_interpolation ptwXY_getInterpolation(ptwXYPoints *ptwXY)
Definition ptwXY_core.c:518
double ptwXY_setAccuracy(ptwXYPoints *ptwXY, double accuracy)
Definition ptwXY_core.c:573
nfu_status ptwXY_initialize(statusMessageReporting *smr, ptwXYPoints *ptwXY, ptwXY_interpolation interpolation, char const *interpolationString, double biSectionMax, double accuracy, int64_t primarySize, int64_t secondarySize, int userFlag)
Definition ptwXY_core.c:53
ptwXYPoints * ptwXY_clone2(statusMessageReporting *smr, ptwXYPoints const *ptwXY)
Definition ptwXY_core.c:312
int ptwXY_getUserFlag(ptwXYPoints *ptwXY)
Definition ptwXY_core.c:552
nfu_status ptwXY_startIndex(statusMessageReporting *a_smr, ptwXYPoints *a_ptwXY, double a_x, int64_t *a_startIndex, int64_t *a_length)
Definition ptwXY_core.c:818
char const * ptwXY_interpolationToString(ptwXY_interpolation interpolation)
nfu_status ptwXY_release(statusMessageReporting *smr, ptwXYPoints *ptwXY)
Definition ptwXY_core.c:759
int64_t ptwXY_getNonOverflowLength(statusMessageReporting *smr, ptwXYPoints const *ptwXY)
Definition ptwXY_core.c:805
ptwXYPoints * ptwXY_clone(statusMessageReporting *smr, ptwXYPoints *ptwXY)
Definition ptwXY_core.c:302
void ptwXY_setUserFlag(ptwXYPoints *ptwXY, int userFlag)
Definition ptwXY_core.c:559
nfu_status ptwXY_coalescePoints(statusMessageReporting *smr, ptwXYPoints *ptwXY, int64_t size, ptwXYPoint *newPoint, int forceSmallerResize)
Definition ptwXY_core.c:667
nfu_status ptwXY_getLowerIndexBoundingX(statusMessageReporting *smr, ptwXYPoints *ptwXY, double x, int64_t *index)
Definition ptwXY_core.c:967
ptwXYPoints * ptwXY_createFrom_Xs_Ys2(statusMessageReporting *smr, ptwXY_interpolation interpolation, int64_t primarySize, int64_t secondarySize, int64_t length, double const *Xs, double const *Ys, int userFlag)
Definition ptwXY_core.c:161
nfu_status ptwXY_range(statusMessageReporting *smr, ptwXYPoints *ptwXY, double *rangeMin, double *rangeMax)
nfu_status ptwXY_domainMaxAndFrom(statusMessageReporting *smr, ptwXYPoints *ptwXY, ptwXY_dataFrom *dataFrom, double *domainMax)
ptwXY_lessEqualGreaterX ptwXY_getPointsAroundX(statusMessageReporting *smr, ptwXYPoints *ptwXY, double x, ptwXYOverflowPoint *lessThanEqualXPoint, ptwXYOverflowPoint *greaterThanXPoint)
nfu_status ptwXY_reallocateOverflowPoints(statusMessageReporting *smr, ptwXYPoints *ptwXY, int64_t size)
Definition ptwXY_core.c:634
ptwXYPoints * ptwXY_new2(statusMessageReporting *smr, ptwXY_interpolation interpolation, int64_t primarySize, int64_t secondarySize)
Definition ptwXY_core.c:44
ptwXYPoints * ptwXY_cloneToInterpolation(statusMessageReporting *smr, ptwXYPoints *ptwXY, ptwXY_interpolation interpolationTo)
Definition ptwXY_core.c:349
nfu_status ptwXY_domainMinAndFrom(statusMessageReporting *smr, ptwXYPoints *ptwXY, ptwXY_dataFrom *dataFrom, double *domainMin)
ptwXY_lessEqualGreaterX ptwXY_getPointsAroundX_closeIsEqual(statusMessageReporting *smr, ptwXYPoints *ptwXY, double x, ptwXYOverflowPoint *lessThanEqualXPoint, ptwXYOverflowPoint *greaterThanXPoint, double eps, int *closeIsEqual, ptwXYPoint **closePoint)
nfu_status ptwXY_mergeFromXYs(statusMessageReporting *smr, ptwXYPoints *ptwXY, int length, double *xys)
char const * ptwXY_getInterpolationString(ptwXYPoints *ptwXY)
Definition ptwXY_core.c:525
nfu_status ptwXY_rangeMax(statusMessageReporting *smr, ptwXYPoints *ptwXY, double *rangeMax)
nfu_status ptwXY_setXYPairAtIndex(statusMessageReporting *smr, ptwXYPoints *ptwXY, int64_t index, double x, double y)
ptwXYPoints * ptwXY_domainMinSlice(statusMessageReporting *smr, ptwXYPoints *ptwXY, double domainMin, int64_t secondarySize, int fill)
Definition ptwXY_core.c:482
nfu_status ptwXY_getXYPairAtIndex(statusMessageReporting *smr, ptwXYPoints *ptwXY, int64_t index, double *x, double *y)
nfu_status ptwXY_getSlopeAtX(statusMessageReporting *smr, ptwXYPoints *ptwXY, double x, const char side, double *slope)
ptwXYPoints * ptwXY_createFrom_Xs_Ys(statusMessageReporting *smr, ptwXY_interpolation interpolation, char const *interpolationString, double biSectionMax, double accuracy, int64_t primarySize, int64_t secondarySize, int64_t length, double const *Xs, double const *Ys, int userFlag)
Definition ptwXY_core.c:138
ptwXYPoints * ptwXY_domainMaxSlice(statusMessageReporting *smr, ptwXYPoints *ptwXY, double domainMax, int64_t secondarySize, int fill)
Definition ptwXY_core.c:499
nfu_status ptwXY_clear(statusMessageReporting *smr, ptwXYPoints *ptwXY)
Definition ptwXY_core.c:743
double ptwXY_getBiSectionMax(ptwXYPoints *ptwXY)
Definition ptwXY_core.c:582
nfu_status ptwXY_getStatus(ptwXYPoints *ptwXY)
Definition ptwXY_core.c:545
ptwXYPoints * ptwXY_new(statusMessageReporting *smr, ptwXY_interpolation interpolation, char const *interpolationString, double biSectionMax, double accuracy, int64_t primarySize, int64_t secondarySize, int userFlag)
Definition ptwXY_core.c:28
nfu_status ptwXY_appendXY(statusMessageReporting *smr, ptwXYPoints *ptwXY, double x, double y)
ptwXYPoints * ptwXY_create2(statusMessageReporting *smr, ptwXY_interpolation interpolation, int64_t primarySize, int64_t secondarySize, int64_t length, double const *xy, int userFlag)
Definition ptwXY_core.c:128
int64_t ptwXY_length(statusMessageReporting *smr, ptwXYPoints *ptwXY)
Definition ptwXY_core.c:793
nfu_status ptwXY_copy(statusMessageReporting *smr, ptwXYPoints *dest, ptwXYPoints *src)
Definition ptwXY_core.c:171
nfu_status ptwXY_reallocatePoints(statusMessageReporting *smr, ptwXYPoints *ptwXY, int64_t size, int forceSmallerResize)
Definition ptwXY_core.c:602
ptwXY_interpolation ptwXY_stringToInterpolation(char const *interpolationString)
nfu_status ptwXY_setXYData(statusMessageReporting *smr, ptwXYPoints *ptwXY, int64_t length, double const *xy)
Definition ptwXY_core.c:866
ptwXYPoints * ptwXY_free(ptwXYPoints *ptwXY)
Definition ptwXY_core.c:782
ptwXYPoints * ptwXY_slice(statusMessageReporting *smr, ptwXYPoints *ptwXY, int64_t index1, int64_t index2, int64_t secondarySize)
Definition ptwXY_core.c:388
nfu_status ptwXY_rangeMin(statusMessageReporting *smr, ptwXYPoints *ptwXY, double *rangeMin)
ptwXYPoint * ptwXY_getPointAtIndex_Unsafely(ptwXYPoints const *ptwXY, int64_t index)
nfu_status ptwXY_domainMin(statusMessageReporting *smr, ptwXYPoints *ptwXY, double *domainMin)
ptwXYPoints * ptwXY_create(statusMessageReporting *smr, ptwXY_interpolation interpolation, char const *interpolationString, double biSectionMax, double accuracy, int64_t primarySize, int64_t secondarySize, int64_t length, double const *xy, int userFlag)
Definition ptwXY_core.c:110
ptwXYPoint * ptwXY_getPointAtIndex(statusMessageReporting *smr, ptwXYPoints *ptwXY, int64_t index)
Definition ptwXY_core.c:994
double ptwXY_setBiSectionMax(ptwXYPoints *ptwXY, double biSectionMax)
Definition ptwXY_core.c:589
nfu_status ptwXY_getValueAtX(statusMessageReporting *smr, ptwXYPoints *ptwXY, double x, double *y)
nfu_status ptwXY_simpleCoalescePoints(statusMessageReporting *smr, ptwXYPoints *ptwXY)
Definition ptwXY_core.c:734
nfu_status ptwXY_setValueAtX_overrideIfClose(statusMessageReporting *smr, ptwXYPoints *ptwXY, double x, double y, double eps, int override)
nfu_status ptwXY_copyPointsOnly(statusMessageReporting *smr, ptwXYPoints *dest, ptwXYPoints *src)
Definition ptwXY_core.c:247
nfu_status ptwXY_setXYDataFromXsAndYs(statusMessageReporting *smr, ptwXYPoints *ptwXY, int64_t length, double const *x, double const *y)
Definition ptwXY_core.c:907
#define smr_setReportError2(smr, libraryID, code, fmt,...)
#define smr_setReportError2p(smr, libraryID, code, fmt)
#define smr_realloc2(smr, old, size, forItem)
#define smr_freeMemory2(p)
#define smr_allocateCopyString2(smr, s, forItem)
#define smr_malloc2(smr, size, zero, forItem)
struct ptwXYOverflowPoint_s * next
Definition ptwXY.h:73
struct ptwXYOverflowPoint_s * prior
Definition ptwXY.h:72
ptwXYPoint point
Definition ptwXY.h:75
double y
Definition ptwXY.h:64
double x
Definition ptwXY.h:64
double minFractional_dx
Definition ptwXY.h:86
ptwXYOverflowPoint overflowHeader
Definition ptwXY.h:92
int userFlag
Definition ptwXY.h:83
ptwXYPoint * points
Definition ptwXY.h:93
ptwXY_interpolation interpolation
Definition ptwXY.h:81
double biSectionMax
Definition ptwXY.h:84
double accuracy
Definition ptwXY.h:85
int64_t length
Definition ptwXY.h:87
int64_t overflowLength
Definition ptwXY.h:89
int64_t overflowAllocatedSize
Definition ptwXY.h:90
nfu_status status
Definition ptwXY.h:80
ptwXYOverflowPoint * overflowPoints
Definition ptwXY.h:94
int64_t mallocFailedSize
Definition ptwXY.h:91
int64_t allocatedSize
Definition ptwXY.h:88
char const * interpolationString
Definition ptwXY.h:82