Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
ptwXY_integration.cc
Go to the documentation of this file.
1/*
2# <<BEGIN-copyright>>
3# <<END-copyright>>
4*/
5
6#include <cmath>
7#include <float.h>
8
9#include "ptwXY.h"
10#include <nf_Legendre.h>
11#include <nf_integration.h>
12
13#if defined __cplusplus
14#include "G4Log.hh"
15#include "G4Pow.hh"
16namespace GIDI {
17using namespace GIDI;
18#endif
19
21 int degree;
23 void *argList;
25 double x1, x2, y1, y2;
27
28static nfu_status ptwXY_integrateWithFunction2( nf_Legendre_GaussianQuadrature_callback integrandFunction, void *argList, double x1,
29 double x2, double *integral );
30static nfu_status ptwXY_integrateWithFunction3( double x, double *y, void *argList );
31/*
32************************************************************
33*/
34nfu_status ptwXY_f_integrate( ptwXY_interpolation interpolation, double x1, double y1, double x2, double y2, double *value ) {
35
36 nfu_status status = nfu_Okay;
37 double r;
38
39 *value = 0.;
40 switch( interpolation ) {
41 case ptwXY_interpolationLinLin : /* x linear, y linear */
42 *value = 0.5 * ( y1 + y2 ) * ( x2 - x1 );
43 break;
44 case ptwXY_interpolationLinLog : /* x linear, y log */
45 if( ( y1 <= 0. ) || ( y2 <= 0. ) ) {
46 status = nfu_badIntegrationInput; }
47 else {
48 r = y2 / y1;
49 if( std::fabs( r - 1. ) < 1e-4 ) {
50 r = r - 1.;
51 *value = y1 * ( x2 - x1 ) / ( 1. + r * ( -0.5 + r * ( 1. / 3. + r * ( -0.25 + .2 * r ) ) ) ); }
52 else {
53 *value = ( y2 - y1 ) * ( x2 - x1 ) / G4Log( r );
54 }
55 }
56 break;
57 case ptwXY_interpolationLogLin : /* x log, y linear */
58 if( ( x1 <= 0. ) || ( x2 <= 0. ) ) {
59 status = nfu_badIntegrationInput; }
60 else {
61 r = x2 / x1;
62 if( std::fabs( r - 1. ) < 1e-4 ) {
63 r = r - 1.;
64 r = r * ( -0.5 + r * ( 1. / 3. + r * ( -0.25 + .2 * r ) ) );
65 *value = x1 * ( y2 - y1 ) * r / ( 1. + r ) + y2 * ( x2 - x1 ); }
66 else {
67 *value = ( y1 - y2 ) * ( x2 - x1 ) / G4Log( r ) + x2 * y2 - x1 * y1;
68 }
69 }
70 break;
71 case ptwXY_interpolationLogLog : /* x log, y log */
72 if( ( x1 <= 0. ) || ( x2 <= 0. ) || ( y1 <= 0. ) || ( y2 <= 0. ) ) {
73 status = nfu_badIntegrationInput; }
74 else {
75 int i, n;
76 double a, z, lx, ly, s, f;
77
78 r = y2 / y1;
79 if( std::fabs( r - 1. ) < 1e-4 ) {
80 ly = ( y2 - y1 ) / y1;
81 ly = ly * ( 1. + ly * ( -0.5 + ly * ( 1. / 3. - 0.25 * ly ) ) ); }
82 else {
83 ly = G4Log( r );
84 }
85 r = x2 / x1;
86 if( std::fabs( r - 1. ) < 1e-4 ) {
87 lx = ( x2 - x1 ) / x1;
88 lx = lx * ( 1 + lx * ( -0.5 + lx * ( 1. / 3. - 0.25 * lx ) ) ); }
89 else {
90 lx = G4Log( r );
91 }
92 a = ly / lx;
93 if( std::fabs( r - 1. ) < 1e-3 ) {
94 z = ( x2 - x1 ) / x1;
95 n = (int) a;
96 if( n > 10 ) n = 12;
97 if( n < 4 ) n = 6;
98 a = a - n + 1;
99 f = n + 1.;
100 for( i = 0, s = 0.; i < n; i++, a++, f-- ) s = ( 1. + s ) * a * z / f;
101 *value = y1 * ( x2 - x1 ) * ( 1. + s ); }
102 else {
103 *value = y1 * x1 * ( G4Pow::GetInstance()->powA( r, a + 1. ) - 1. ) / ( a + 1. );
104 }
105 }
106 break;
107 case ptwXY_interpolationFlat : /* x ?, y flat */
108 *value = y1 * ( x2 - x1 );
109 break;
111 status = nfu_otherInterpolation;
112 }
113 return( status );
114}
115/*
116************************************************************
117*/
118double ptwXY_integrate( ptwXYPoints *ptwXY, double xMin, double xMax, nfu_status *status ) {
119
120 int64_t i, n = ptwXY->length;
121 double sum = 0., dSum, x, y, x1, x2, y1, y2, _sign = 1.;
122 ptwXYPoint *point;
123
124 if( ( *status = ptwXY->status ) != nfu_Okay ) return( 0. );
125 *status = nfu_otherInterpolation;
126 if( ptwXY->interpolation == ptwXY_interpolationOther ) return( 0. );
127
128 if( xMax < xMin ) {
129 x = xMin;
130 xMin = xMax;
131 xMax = x;
132 _sign = -1.;
133 }
134 if( n < 2 ) return( 0. );
135
136 if( ( *status = ptwXY_simpleCoalescePoints( ptwXY ) ) != nfu_Okay ) return( 0. );
137 for( i = 0, point = ptwXY->points; i < n; i++, point++ ) {
138 if( point->x >= xMin ) break;
139 }
140 if( i == n ) return( 0. );
141 x2 = point->x;
142 y2 = point->y;
143 if( i > 0 ) {
144 if( x2 > xMin ) {
145 x1 = point[-1].x;
146 y1 = point[-1].y;
147 if( ( *status = ptwXY_interpolatePoint( ptwXY->interpolation, xMin, &y, x1, y1, x2, y2 ) ) != nfu_Okay ) return( 0. );
148 if( x2 > xMax ) {
149 double yMax;
150
151 if( ( *status = ptwXY_interpolatePoint( ptwXY->interpolation, xMax, &yMax, x1, y1, x2, y2 ) ) != nfu_Okay ) return( 0. );
152 if( ( *status = ptwXY_f_integrate( ptwXY->interpolation, xMin, y, xMax, yMax, &sum ) ) != nfu_Okay ) return( 0. );
153 return( sum ); }
154 else {
155 if( ( *status = ptwXY_f_integrate( ptwXY->interpolation, xMin, y, x2, y2, &sum ) ) != nfu_Okay ) return( 0. );
156 }
157 }
158 }
159 i++;
160 point++;
161 for( ; i < n; i++, point++ ) {
162 x1 = x2;
163 y1 = y2;
164 x2 = point->x;
165 y2 = point->y;
166 if( x2 > xMax ) {
167 if( ( *status = ptwXY_interpolatePoint( ptwXY->interpolation, xMax, &y, x1, y1, x2, y2 ) ) != nfu_Okay ) return( 0. );
168 if( ( *status = ptwXY_f_integrate( ptwXY->interpolation, x1, y1, xMax, y, &dSum ) ) != nfu_Okay ) return( 0. );
169 sum += dSum;
170 break;
171 }
172 if( ( *status = ptwXY_f_integrate( ptwXY->interpolation, x1, y1, x2, y2, &dSum ) ) != nfu_Okay ) return( 0. );
173 sum += dSum;
174 }
175
176 return( _sign * sum );
177}
178/*
179************************************************************
180*/
182
183 if( ( *status = ptwXY->status ) != nfu_Okay ) return( 0. );
184 if( ptwXY->length > 0 ) return( ptwXY_integrate( ptwXY, ptwXY_getXMin( ptwXY ), ptwXY_getXMax( ptwXY ), status ) );
185 return( 0. );
186}
187/*
188************************************************************
189*/
191/*
192* This function assumes ptwXY_integrateDomain checks status and coalesces the points.
193*/
194
195 int64_t i;
196 nfu_status status;
197 double sum = ptwXY_integrateDomain( ptwXY, &status );
198
199 if( status != nfu_Okay ) return( status );
200 if( sum == 0. ) {
201 status = nfu_badNorm; }
202 else {
203 for( i = 0; i < ptwXY->length; i++ ) ptwXY->points[i].y /= sum;
204 }
205 return( status );
206}
207/*
208************************************************************
209*/
211
212 if( ( *status = ptwXY->status ) != nfu_Okay ) return( 0. );
213 if( ptwXY->length < 2 ) return( 0. );
214 return( ptwXY_integrateWithWeight_x( ptwXY, ptwXY_getXMin( ptwXY ), ptwXY_getXMax( ptwXY ), status ) );
215}
216/*
217************************************************************
218*/
219double ptwXY_integrateWithWeight_x( ptwXYPoints *ptwXY, double xMin, double xMax, nfu_status *status ) {
220
221 int64_t i, n = ptwXY->length;
222 double sum = 0., x, y, x1, x2, y1, y2, _sign = 1.;
223 ptwXYPoint *point;
224
225 if( ( *status = ptwXY->status ) != nfu_Okay ) return( 0. );
227 if( ( ptwXY->interpolation != ptwXY_interpolationLinLin ) &&
228 ( ptwXY->interpolation != ptwXY_interpolationFlat ) ) return( 0. );
229
230 if( n < 2 ) return( 0. );
231 if( xMax < xMin ) {
232 x = xMin;
233 xMin = xMax;
234 xMax = x;
235 _sign = -1.;
236 }
237
238 if( ( *status = ptwXY_simpleCoalescePoints( ptwXY ) ) != nfu_Okay ) return( 0. );
239 for( i = 0, point = ptwXY->points; i < n; ++i, ++point ) {
240 if( point->x >= xMin ) break;
241 }
242 if( i == n ) return( 0. );
243 x2 = point->x;
244 y2 = point->y;
245 if( i > 0 ) {
246 if( x2 > xMin ) {
247 if( ( *status = ptwXY_interpolatePoint( ptwXY->interpolation, xMin, &y, point[-1].x, point[-1].y, x2, y2 ) ) != nfu_Okay ) return( 0. );
248 x2 = xMin;
249 y2 = y;
250 --i;
251 --point;
252 }
253 }
254 ++i;
255 ++point;
256 for( ; i < n; ++i, ++point ) {
257 x1 = x2;
258 y1 = y2;
259 x2 = point->x;
260 y2 = point->y;
261 if( x2 > xMax ) {
262 if( ( *status = ptwXY_interpolatePoint( ptwXY->interpolation, xMax, &y, x1, y1, x2, y2 ) ) != nfu_Okay ) return( 0. );
263 x2 = xMax;
264 y2 = y;
265 }
266 switch( ptwXY->interpolation ) {
268 sum += ( x2 - x1 ) * y1 * 3 * ( x1 + x2 );
269 break;
271 sum += ( x2 - x1 ) * ( y1 * ( 2 * x1 + x2 ) + y2 * ( x1 + 2 * x2 ) );
272 break;
273 default : /* Only to stop compilers from complaining. */
274 break;
275 }
276 if( x2 == xMax ) break;
277 }
278
279 return( _sign * sum / 6 );
280}
281/*
282************************************************************
283*/
285
286 if( ( *status = ptwXY->status ) != nfu_Okay ) return( 0. );
287 if( ptwXY->length < 2 ) return( 0. );
288 return( ptwXY_integrateWithWeight_sqrt_x( ptwXY, ptwXY_getXMin( ptwXY ), ptwXY_getXMax( ptwXY ), status ) );
289}
290/*
291************************************************************
292*/
293double ptwXY_integrateWithWeight_sqrt_x( ptwXYPoints *ptwXY, double xMin, double xMax, nfu_status *status ) {
294
295 int64_t i, n = ptwXY->length;
296 double sum = 0., x, y, x1, x2, y1, y2, _sign = 1., sqrt_x1, sqrt_x2, inv_apb, c;
297 ptwXYPoint *point;
298
299 if( ( *status = ptwXY->status ) != nfu_Okay ) return( 0. );
301 if( ( ptwXY->interpolation != ptwXY_interpolationLinLin ) &&
302 ( ptwXY->interpolation != ptwXY_interpolationFlat ) ) return( 0. );
303
304 if( n < 2 ) return( 0. );
305 if( xMax < xMin ) {
306 x = xMin;
307 xMin = xMax;
308 xMax = x;
309 _sign = -1.;
310 }
311
312 if( ( *status = ptwXY_simpleCoalescePoints( ptwXY ) ) != nfu_Okay ) return( 0. );
313 for( i = 0, point = ptwXY->points; i < n; ++i, ++point ) {
314 if( point->x >= xMin ) break;
315 }
316 if( i == n ) return( 0. );
317 x2 = point->x;
318 y2 = point->y;
319 if( i > 0 ) {
320 if( x2 > xMin ) {
321 if( ( *status = ptwXY_interpolatePoint( ptwXY->interpolation, xMin, &y, point[-1].x, point[-1].y, x2, y2 ) ) != nfu_Okay ) return( 0. );
322 x2 = xMin;
323 y2 = y;
324 --i;
325 --point;
326 }
327 }
328 ++i;
329 ++point;
330 sqrt_x2 = std::sqrt( x2 );
331 for( ; i < n; ++i, ++point ) {
332 x1 = x2;
333 y1 = y2;
334 sqrt_x1 = sqrt_x2;
335 x2 = point->x;
336 y2 = point->y;
337 if( x2 > xMax ) {
338 if( ( *status = ptwXY_interpolatePoint( ptwXY->interpolation, xMax, &y, x1, y1, x2, y2 ) ) != nfu_Okay ) return( 0. );
339 x2 = xMax;
340 y2 = y;
341 }
342 sqrt_x2 = std::sqrt( x2 );
343 inv_apb = sqrt_x1 + sqrt_x2;
344 c = 2. * ( sqrt_x1 * sqrt_x2 + x1 + x2 );
345 switch( ptwXY->interpolation ) {
347 sum += ( sqrt_x2 - sqrt_x1 ) * y1 * 2.5 * c;
348 break;
350 sum += ( sqrt_x2 - sqrt_x1 ) * ( y1 * ( c + x1 * ( 1. + sqrt_x2 / inv_apb ) ) + y2 * ( c + x2 * ( 1. + sqrt_x1 / inv_apb ) ) );
351 break;
352 default : /* Only to stop compilers from complaining. */
353 break;
354 }
355 if( x2 == xMax ) break;
356 }
357
358 return( 2. / 15. * _sign * sum );
359}
360/*
361************************************************************
362*/
363ptwXPoints *ptwXY_groupOneFunction( ptwXYPoints *ptwXY, ptwXPoints *groupBoundaries, ptwXY_group_normType normType, ptwXPoints *ptwX_norm, nfu_status *status ) {
364
365 int64_t i, igs, ngs;
366 double x1, y1, x2, y2, y2p, xg1, xg2, sum;
367 ptwXYPoints *f;
368 ptwXPoints *groupedData = NULL;
369
370 if( ( *status = ptwXY_simpleCoalescePoints( ptwXY ) ) != nfu_Okay ) return( NULL );
371 if( ( *status = groupBoundaries->status ) != nfu_Okay ) return( NULL );
372 *status = nfu_otherInterpolation;
373 if( ptwXY->interpolation == ptwXY_interpolationOther ) return( NULL );
374
375 ngs = ptwX_length( groupBoundaries ) - 1;
376 if( normType == ptwXY_group_normType_norm ) {
377 if( ptwX_norm == NULL ) {
378 *status = nfu_badNorm;
379 return( NULL );
380 }
381 *status = ptwX_norm->status;
382 if( ptwX_norm->status != nfu_Okay ) return( NULL );
383 if( ptwX_length( ptwX_norm ) != ngs ) {
384 *status = nfu_badNorm;
385 return( NULL );
386 }
387 }
388
389 if( ( f = ptwXY_intersectionWith_ptwX( ptwXY, groupBoundaries, status ) ) == NULL ) return( NULL );
390 if( f->length == 0 ) return( ptwX_createLine( ngs, ngs, 0, 0, status ) );
391
392 if( ( groupedData = ptwX_new( ngs, status ) ) == NULL ) goto err;
393 xg1 = groupBoundaries->points[0];
394 x1 = f->points[0].x;
395 y1 = f->points[0].y;
396 for( igs = 0, i = 1; igs < ngs; igs++ ) {
397 xg2 = groupBoundaries->points[igs+1];
398 sum = 0;
399 if( xg2 > x1 ) {
400 for( ; i < f->length; i++, x1 = x2, y1 = y2 ) {
401 x2 = f->points[i].x;
402 if( x2 > xg2 ) break;
403 y2p = y2 = f->points[i].y;
404 if( f->interpolation == ptwXY_interpolationFlat ) y2p = y1;
405 sum += ( y1 + y2p ) * ( x2 - x1 );
406 }
407 }
408 if( sum != 0. ) {
409 if( normType == ptwXY_group_normType_dx ) {
410 sum /= ( xg2 - xg1 ); }
411 else if( normType == ptwXY_group_normType_norm ) {
412 if( ptwX_norm->points[igs] == 0. ) {
413 *status = nfu_divByZero;
414 goto err;
415 }
416 sum /= ptwX_norm->points[igs];
417 }
418 }
419 groupedData->points[igs] = 0.5 * sum;
420 groupedData->length++;
421 xg1 = xg2;
422 }
423
424 ptwXY_free( f );
425 return( groupedData );
426
427err:
428 ptwXY_free( f );
429 if( groupedData != NULL ) ptwX_free( groupedData );
430 return( NULL );
431}
432/*
433************************************************************
434*/
436 ptwXPoints *ptwX_norm, nfu_status *status ) {
437
438 int64_t i, igs, ngs;
439 double x1, fy1, gy1, x2, fy2, gy2, fy2p, gy2p, xg1, xg2, sum;
440 ptwXYPoints *f = NULL, *ff, *g = NULL, *gg = NULL;
441 ptwXPoints *groupedData = NULL;
442
443 if( ( *status = ptwXY_simpleCoalescePoints( ptwXY1 ) ) != nfu_Okay ) return( NULL );
444 if( ( *status = ptwXY_simpleCoalescePoints( ptwXY2 ) ) != nfu_Okay ) return( NULL );
445 if( ( *status = groupBoundaries->status ) != nfu_Okay ) return( NULL );
446 *status = nfu_otherInterpolation;
447 if( ptwXY1->interpolation == ptwXY_interpolationOther ) return( NULL );
448 if( ptwXY2->interpolation == ptwXY_interpolationOther ) return( NULL );
449
450 ngs = ptwX_length( groupBoundaries ) - 1;
451 if( normType == ptwXY_group_normType_norm ) {
452 if( ptwX_norm == NULL ) {
453 *status = nfu_badNorm;
454 return( NULL );
455 }
456 if( ( *status = ptwX_norm->status ) != nfu_Okay ) return( NULL );
457 if( ptwX_length( ptwX_norm ) != ngs ) {
458 *status = nfu_badNorm;
459 return( NULL );
460 }
461 }
462
463 if( ( ff = ptwXY_intersectionWith_ptwX( ptwXY1, groupBoundaries, status ) ) == NULL ) return( NULL );
464 if( ( gg = ptwXY_intersectionWith_ptwX( ptwXY2, groupBoundaries, status ) ) == NULL ) goto err;
465 if( ( ff->length == 0 ) || ( gg->length == 0 ) ) {
466 ptwXY_free( ff );
467 ptwXY_free( gg );
468 return( ptwX_createLine( ngs, ngs, 0, 0, status ) );
469 }
470
471 if( ( *status = ptwXY_tweakDomainsToMutualify( ff, gg, 4, 0 ) ) != nfu_Okay ) goto err;
472 if( ( f = ptwXY_union( ff, gg, status, ptwXY_union_fill ) ) == NULL ) goto err;
473 if( ( g = ptwXY_union( gg, f, status, ptwXY_union_fill ) ) == NULL ) goto err;
474
475 if( ( groupedData = ptwX_new( ngs, status ) ) == NULL ) goto err;
476 xg1 = groupBoundaries->points[0];
477 x1 = f->points[0].x;
478 fy1 = f->points[0].y;
479 gy1 = g->points[0].y;
480 for( igs = 0, i = 1; igs < ngs; igs++ ) {
481 xg2 = groupBoundaries->points[igs+1];
482 sum = 0;
483 if( xg2 > x1 ) {
484 for( ; i < f->length; i++, x1 = x2, fy1 = fy2, gy1 = gy2 ) {
485 x2 = f->points[i].x;
486 if( x2 > xg2 ) break;
487 fy2p = fy2 = f->points[i].y;
488 if( f->interpolation == ptwXY_interpolationFlat ) fy2p = fy1;
489 gy2p = gy2 = g->points[i].y;
490 if( g->interpolation == ptwXY_interpolationFlat ) gy2p = gy1;
491 sum += ( ( fy1 + fy2p ) * ( gy1 + gy2p ) + fy1 * gy1 + fy2p * gy2p ) * ( x2 - x1 );
492 }
493 }
494 if( sum != 0. ) {
495 if( normType == ptwXY_group_normType_dx ) {
496 sum /= ( xg2 - xg1 ); }
497 else if( normType == ptwXY_group_normType_norm ) {
498 if( ptwX_norm->points[igs] == 0. ) {
499 *status = nfu_divByZero;
500 goto err;
501 }
502 sum /= ptwX_norm->points[igs];
503 }
504 }
505 groupedData->points[igs] = sum / 6.;
506 groupedData->length++;
507 xg1 = xg2;
508 }
509
510 ptwXY_free( f );
511 ptwXY_free( g );
512 ptwXY_free( ff );
513 ptwXY_free( gg );
514 return( groupedData );
515
516err:
517 ptwXY_free( ff );
518 if( gg != NULL ) ptwXY_free( gg );
519 // Coverity #63063
520 if( f != NULL ) ptwXY_free( f );
521 if( g != NULL ) ptwXY_free( g );
522 if( groupedData != NULL ) ptwX_free( groupedData );
523 return( NULL );
524}
525/*
526************************************************************
527*/
529 ptwXY_group_normType normType, ptwXPoints *ptwX_norm, nfu_status *status ) {
530
531 int64_t i, igs, ngs;
532 double x1, fy1, gy1, hy1, x2, fy2, gy2, hy2, fy2p, gy2p, hy2p, xg1, xg2, sum;
533 ptwXYPoints *f = NULL, *ff, *fff = NULL, *g = NULL, *gg = NULL, *h = NULL, *hh = NULL;
534 ptwXPoints *groupedData = NULL;
535
536 if( ( *status = ptwXY_simpleCoalescePoints( ptwXY1 ) ) != nfu_Okay ) return( NULL );
537 if( ( *status = ptwXY_simpleCoalescePoints( ptwXY2 ) ) != nfu_Okay ) return( NULL );
538 if( ( *status = ptwXY_simpleCoalescePoints( ptwXY3 ) ) != nfu_Okay ) return( NULL );
539 if( ( *status = groupBoundaries->status ) != nfu_Okay ) return( NULL );
540 *status = nfu_otherInterpolation;
541 if( ptwXY1->interpolation == ptwXY_interpolationOther ) return( NULL );
542 if( ptwXY2->interpolation == ptwXY_interpolationOther ) return( NULL );
543 if( ptwXY3->interpolation == ptwXY_interpolationOther ) return( NULL );
544
545 ngs = ptwX_length( groupBoundaries ) - 1;
546 if( normType == ptwXY_group_normType_norm ) {
547 if( ptwX_norm == NULL ) {
548 *status = nfu_badNorm;
549 return( NULL );
550 }
551 if( ( *status = ptwX_norm->status ) != nfu_Okay ) return( NULL );
552 if( ptwX_length( ptwX_norm ) != ngs ) {
553 *status = nfu_badNorm;
554 return( NULL );
555 }
556 }
557
558 if( ( ff = ptwXY_intersectionWith_ptwX( ptwXY1, groupBoundaries, status ) ) == NULL ) return( NULL );
559 if( ( gg = ptwXY_intersectionWith_ptwX( ptwXY2, groupBoundaries, status ) ) == NULL ) goto err;
560 if( ( hh = ptwXY_intersectionWith_ptwX( ptwXY3, groupBoundaries, status ) ) == NULL ) goto err;
561 if( ( ff->length == 0 ) || ( gg->length == 0 ) || ( hh->length == 0 ) ) return( ptwX_createLine( ngs, ngs, 0, 0, status ) );
562
563 if( ( *status = ptwXY_tweakDomainsToMutualify( ff, gg, 4, 0 ) ) != nfu_Okay ) goto err;
564 if( ( *status = ptwXY_tweakDomainsToMutualify( ff, hh, 4, 0 ) ) != nfu_Okay ) goto err;
565 if( ( *status = ptwXY_tweakDomainsToMutualify( gg, hh, 4, 0 ) ) != nfu_Okay ) goto err;
566 if( ( fff = ptwXY_union( ff, gg, status, ptwXY_union_fill ) ) == NULL ) goto err;
567 if( ( h = ptwXY_union( hh, fff, status, ptwXY_union_fill ) ) == NULL ) goto err;
568 if( ( f = ptwXY_union( fff, h, status, ptwXY_union_fill ) ) == NULL ) goto err;
569 if( ( g = ptwXY_union( gg, h, status, ptwXY_union_fill ) ) == NULL ) goto err;
570
571 if( ( groupedData = ptwX_new( ngs, status ) ) == NULL ) goto err;
572 xg1 = groupBoundaries->points[0];
573 x1 = f->points[0].x;
574 fy1 = f->points[0].y;
575 gy1 = g->points[0].y;
576 hy1 = h->points[0].y;
577 for( igs = 0, i = 1; igs < ngs; igs++ ) {
578 xg2 = groupBoundaries->points[igs+1];
579 sum = 0;
580 if( xg2 > x1 ) {
581 for( ; i < f->length; i++, x1 = x2, fy1 = fy2, gy1 = gy2, hy1 = hy2 ) {
582 x2 = f->points[i].x;
583 if( x2 > xg2 ) break;
584 fy2p = fy2 = f->points[i].y;
585 if( f->interpolation == ptwXY_interpolationFlat ) fy2p = fy1;
586 gy2p = gy2 = g->points[i].y;
587 if( g->interpolation == ptwXY_interpolationFlat ) gy2p = gy1;
588 hy2p = hy2 = h->points[i].y;
589 if( h->interpolation == ptwXY_interpolationFlat ) hy2p = hy1;
590 sum += ( ( fy1 + fy2p ) * ( gy1 + gy2p ) * ( hy1 + hy2p ) + 2 * fy1 * gy1 * hy1 + 2 * fy2p * gy2p * hy2p ) * ( x2 - x1 );
591 }
592 }
593 if( sum != 0. ) {
594 if( normType == ptwXY_group_normType_dx ) {
595 sum /= ( xg2 - xg1 ); }
596 else if( normType == ptwXY_group_normType_norm ) {
597 if( ptwX_norm->points[igs] == 0. ) {
598 *status = nfu_divByZero;
599 goto err;
600 }
601 sum /= ptwX_norm->points[igs];
602 }
603 }
604 groupedData->points[igs] = sum / 12.;
605 groupedData->length++;
606 xg1 = xg2;
607 }
608
609 ptwXY_free( f );
610 ptwXY_free( g );
611 ptwXY_free( h );
612 ptwXY_free( ff );
613 ptwXY_free( gg );
614 ptwXY_free( hh );
615 ptwXY_free( fff );
616 return( groupedData );
617
618err:
619 ptwXY_free( ff );
620 if( fff != NULL ) ptwXY_free( fff );
621 if( gg != NULL ) ptwXY_free( gg );
622 if( hh != NULL ) ptwXY_free( hh );
623 if( f != NULL ) ptwXY_free( f );
624 if( g != NULL ) ptwXY_free( g );
625 if( h != NULL ) ptwXY_free( h );
626 if( groupedData != NULL ) ptwX_free( groupedData );
627 return( NULL );
628}
629/*
630************************************************************
631*/
633
634 int i;
635 ptwXPoints *runningIntegral = NULL;
636 double integral = 0., sum;
637
638 if( ( *status = ptwXY_simpleCoalescePoints( ptwXY ) ) != nfu_Okay ) return( NULL );
639 if( ( runningIntegral = ptwX_new( ptwXY->length, status ) ) == NULL ) goto err;
640
641 if( ( *status = ptwX_setPointAtIndex( runningIntegral, 0, 0. ) ) != nfu_Okay ) goto err;
642 for( i = 1; i < ptwXY->length; i++ ) {
643 if( ( *status = ptwXY_f_integrate( ptwXY->interpolation, ptwXY->points[i-1].x, ptwXY->points[i-1].y,
644 ptwXY->points[i].x, ptwXY->points[i].y, &sum ) ) != nfu_Okay ) goto err;
645 integral += sum;
646 if( ( *status = ptwX_setPointAtIndex( runningIntegral, i, integral ) ) != nfu_Okay ) goto err;
647 }
648 return( runningIntegral );
649
650err:
651 if( runningIntegral != NULL ) ptwX_free( runningIntegral );
652 return( NULL );
653}
654/*
655************************************************************
656*/
658 double xMin, double xMax, int degree, int recursionLimit, double tolerance, nfu_status *status ) {
659
660 int64_t i1, i2, n1 = ptwXY->length;
661 long evaluations;
662 double integral = 0., integral_, sign = -1., xa, xb;
663 ptwXY_integrateWithFunctionInfo integrateWithFunctionInfo;
664 ptwXYPoint *point;
665
666 if( ( *status = ptwXY->status ) != nfu_Okay ) return( 0. );
667
668 if( xMin == xMax ) return( 0. );
669 if( n1 < 2 ) return( 0. );
670
672
673 if( xMin > xMax ) {
674 sign = xMin;
675 xMin = xMax;
676 xMax = sign;
677 sign = -1.;
678 }
679 if( xMin >= ptwXY->points[n1-1].x ) return( 0. );
680 if( xMax <= ptwXY->points[0].x ) return( 0. );
681
682 for( i1 = 0; i1 < ( n1 - 1 ); i1++ ) {
683 if( ptwXY->points[i1+1].x > xMin ) break;
684 }
685 for( i2 = n1 - 1; i2 > i1; i2-- ) {
686 if( ptwXY->points[i2-1].x < xMax ) break;
687 }
688 point = &(ptwXY->points[i1]);
689
690 integrateWithFunctionInfo.degree = degree;
691 integrateWithFunctionInfo.func = func;
692 integrateWithFunctionInfo.argList = argList;
693 integrateWithFunctionInfo.interpolation = ptwXY->interpolation;
694 integrateWithFunctionInfo.x2 = point->x;
695 integrateWithFunctionInfo.y2 = point->y;
696
697 xa = xMin;
698 for( ; i1 < i2; i1++ ) {
699 integrateWithFunctionInfo.x1 = integrateWithFunctionInfo.x2;
700 integrateWithFunctionInfo.y1 = integrateWithFunctionInfo.y2;
701 ++point;
702 integrateWithFunctionInfo.x2 = point->x;
703 integrateWithFunctionInfo.y2 = point->y;
704 xb = point->x;
705 if( xb > xMax ) xb = xMax;
706 *status = nf_GnG_adaptiveQuadrature( ptwXY_integrateWithFunction2, ptwXY_integrateWithFunction3, &integrateWithFunctionInfo,
707 xa, xb, recursionLimit, tolerance, &integral_, &evaluations );
708 if( *status != nfu_Okay ) return( 0. );
709 integral += integral_;
710 xa = xb;
711 }
712
713 return( integral );
714}
715/*
716************************************************************
717*/
718static nfu_status ptwXY_integrateWithFunction2( nf_Legendre_GaussianQuadrature_callback integrandFunction, void *argList, double x1,
719 double x2, double *integral ) {
720
721 ptwXY_integrateWithFunctionInfo *integrateWithFunctionInfo = (ptwXY_integrateWithFunctionInfo *) argList;
722 nfu_status status;
723
724 status = nf_Legendre_GaussianQuadrature( integrateWithFunctionInfo->degree, x1, x2, integrandFunction, argList, integral );
725 return( status );
726}
727/*
728************************************************************
729*/
730static nfu_status ptwXY_integrateWithFunction3( double x, double *y, void *argList ) {
731
732 double yf;
733 ptwXY_integrateWithFunctionInfo *integrateWithFunctionInfo = (ptwXY_integrateWithFunctionInfo *) argList;
734 nfu_status status;
735
736 if( ( status = ptwXY_interpolatePoint( integrateWithFunctionInfo->interpolation, x, &yf,
737 integrateWithFunctionInfo->x1, integrateWithFunctionInfo->y1,
738 integrateWithFunctionInfo->x2, integrateWithFunctionInfo->y2 ) ) == nfu_Okay ) {
739 status = integrateWithFunctionInfo->func( x, y, integrateWithFunctionInfo->argList );
740 *y *= yf;
741 }
742 return( status );
743}
744
745#if defined __cplusplus
746}
747#endif
G4double G4Log(G4double x)
Definition: G4Log.hh:227
static G4Pow * GetInstance()
Definition: G4Pow.cc:41
G4double powA(G4double A, G4double y) const
Definition: G4Pow.hh:230
nfu_status nf_Legendre_GaussianQuadrature(int degree, double x1, double x2, nf_Legendre_GaussianQuadrature_callback func, void *argList, double *integral)
nfu_status(* nf_Legendre_GaussianQuadrature_callback)(double x, double *y, void *argList)
Definition: nf_Legendre.h:29
nfu_status nf_GnG_adaptiveQuadrature(nf_GnG_adaptiveQuadrature_callback quadratureFunction, nf_Legendre_GaussianQuadrature_callback integrandFunction, void *argList, double x1, double x2, int maxDepth, double tolerance, double *integral, long *evaluations)
@ nfu_unsupportedInterpolation
Definition: nf_utilities.h:28
@ nfu_Okay
Definition: nf_utilities.h:25
@ nfu_badNorm
Definition: nf_utilities.h:29
@ nfu_badIntegrationInput
Definition: nf_utilities.h:29
@ nfu_divByZero
Definition: nf_utilities.h:27
@ nfu_otherInterpolation
Definition: nf_utilities.h:29
enum nfu_status_e nfu_status
ptwXPoints * ptwXY_groupOneFunction(ptwXYPoints *ptwXY, ptwXPoints *groupBoundaries, ptwXY_group_normType normType, ptwXPoints *ptwX_norm, nfu_status *status)
ptwXPoints * ptwXY_groupThreeFunctions(ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, ptwXYPoints *ptwXY3, ptwXPoints *groupBoundaries, ptwXY_group_normType normType, ptwXPoints *ptwX_norm, nfu_status *status)
enum ptwXY_group_normType_e ptwXY_group_normType
ptwXYPoints * ptwXY_union(ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, nfu_status *status, int unionOptions)
@ ptwXY_group_normType_dx
Definition: ptwXY.h:28
@ ptwXY_group_normType_norm
Definition: ptwXY.h:28
nfu_status ptwXY_simpleCoalescePoints(ptwXYPoints *ptwXY)
Definition: ptwXY_core.cc:529
nfu_status ptwXY_tweakDomainsToMutualify(ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, int epsilonFactor, double epsilon)
ptwXYPoints * ptwXY_intersectionWith_ptwX(ptwXYPoints *ptwXY, ptwXPoints *ptwX, nfu_status *status)
enum ptwXY_interpolation_e ptwXY_interpolation
@ ptwXY_interpolationFlat
Definition: ptwXY.h:36
@ ptwXY_interpolationLinLog
Definition: ptwXY.h:35
@ ptwXY_interpolationLogLog
Definition: ptwXY.h:35
@ ptwXY_interpolationLinLin
Definition: ptwXY.h:35
@ ptwXY_interpolationOther
Definition: ptwXY.h:36
@ ptwXY_interpolationLogLin
Definition: ptwXY.h:35
double ptwXY_integrateDomainWithWeight_sqrt_x(ptwXYPoints *ptwXY, nfu_status *status)
ptwXPoints * ptwXY_runningIntegral(ptwXYPoints *ptwXY, nfu_status *status)
nfu_status ptwXY_normalize(ptwXYPoints *ptwXY1)
double ptwXY_integrateWithWeight_x(ptwXYPoints *ptwXY, double xMin, double xMax, nfu_status *status)
#define ptwXY_union_fill
Definition: ptwXY.h:31
double ptwXY_getXMin(ptwXYPoints *ptwXY)
Definition: ptwXY_core.cc:1206
ptwXPoints * ptwXY_groupTwoFunctions(ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, ptwXPoints *groupBoundaries, ptwXY_group_normType normType, ptwXPoints *ptwX_norm, nfu_status *status)
ptwXYPoints * ptwXY_free(ptwXYPoints *ptwXY)
Definition: ptwXY_core.cc:574
double ptwXY_integrateWithWeight_sqrt_x(ptwXYPoints *ptwXY, double xMin, double xMax, nfu_status *status)
double ptwXY_integrate(ptwXYPoints *ptwXY, double xMin, double xMax, nfu_status *status)
double ptwXY_integrateDomain(ptwXYPoints *ptwXY, nfu_status *status)
double ptwXY_getXMax(ptwXYPoints *ptwXY)
Definition: ptwXY_core.cc:1239
nfu_status(* ptwXY_createFromFunction_callback)(double x, double *y, void *argList)
Definition: ptwXY.h:65
nfu_status ptwXY_interpolatePoint(ptwXY_interpolation interpolation, double x, double *y, double x1, double y1, double x2, double y2)
double ptwXY_integrateDomainWithWeight_x(ptwXYPoints *ptwXY, nfu_status *status)
nfu_status ptwXY_f_integrate(ptwXY_interpolation interpolation, double x1, double y1, double x2, double y2, double *value)
double ptwXY_integrateWithFunction(ptwXYPoints *ptwXY, ptwXY_createFromFunction_callback func, void *argList, double xMin, double xMax, int degree, int recursionLimit, double tolerance, nfu_status *status)
struct ptwXY_integrateWithFunctionInfo_s ptwXY_integrateWithFunctionInfo
ptwXPoints * ptwX_new(int64_t size, nfu_status *status)
Definition: ptwX_core.cc:24
ptwXPoints * ptwX_createLine(int64_t size, int64_t length, double slope, double offset, nfu_status *status)
Definition: ptwX_core.cc:62
nfu_status ptwX_setPointAtIndex(ptwXPoints *ptwX, int64_t index, double x)
Definition: ptwX_core.cc:222
ptwXPoints * ptwX_free(ptwXPoints *ptwX)
Definition: ptwX_core.cc:158
int64_t ptwX_length(ptwXPoints *ptwX)
Definition: ptwX_core.cc:166
nfu_status status
Definition: ptwX.h:25
int64_t length
Definition: ptwX.h:26
double * points
Definition: ptwX.h:29
double y
Definition: ptwXY.h:62
double x
Definition: ptwXY.h:62
ptwXYPoint * points
Definition: ptwXY.h:99
ptwXY_interpolation interpolation
Definition: ptwXY.h:87
int64_t length
Definition: ptwXY.h:93
nfu_status status
Definition: ptwXY.h:85
ptwXY_createFromFunction_callback func