Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
GIDI_XYs1d.cc
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 <LUPI.hpp>
11#include <GIDI.hpp>
12#include <HAPI.hpp>
13#include <sstream>
14
15static void mutualifyDomains( ptwXYPoints const *a_lhs, ptwXYPoints const *a_rhs, ptwXYPoints **ptwXY1, ptwXYPoints **ptwXY2 );
16
17namespace GIDI {
18
19namespace Functions {
20
21/*! \class XYs1d
22 * Class to store GNDS <**XYs1d**> node.
23 */
24
25/* *********************************************************************************************************//**
26 * Constructor an empty XYs1d instance.
27 *
28 ***********************************************************************************************************/
29
32
33 double dummy[2];
34
35 m_ptwXY = ptwXY_create2( nullptr, interpolation( ), 0, 0, 0, dummy, 0 );
36}
37
38/* *********************************************************************************************************//**
39 * Constructor that creates an empty instance.
40 *
41 * @param a_axes [in] The axes to copy for *this*.
42 * @param a_interpolation [in] The interpolation along the outer most independent axis and the dependent axis.
43 * @param a_index [in] Currently not used.
44 * @param a_outerDomainValue [in] If embedded in a higher dimensional function, the value of the domain of the next higher dimension.
45 * @return
46 ***********************************************************************************************************/
47
48XYs1d::XYs1d( Axes const &a_axes, ptwXY_interpolation a_interpolation, int a_index, double a_outerDomainValue ) :
49 Function1dForm( GIDI_XYs1dChars, FormType::XYs1d, a_axes, a_interpolation, a_index, a_outerDomainValue ) {
50
51 double dummy[2];
52
53 m_ptwXY = ptwXY_create2( nullptr, a_interpolation, 0, 0, 0, dummy, 0 );
54}
55
56/* *********************************************************************************************************//**
57 * Constructor that create an instance from a list of doubles via **a_values** which must have an even number of values.
58 *
59 * @param a_axes [in] The axes to copy for *this*.
60 * @param a_interpolation [in] The interpolation along the outer most independent axis and the dependent axis.
61 * @param a_values [in] The data values as ( x_1, y_1, x_2, y_2, ..., x_n, y_n ). Must be an even number since they are n-pairs of xy values.
62 * @param a_index [in] Currently not used.
63 * @param a_outerDomainValue [in] If embedded in a higher dimensional function, the value of the domain of the next higher dimension.
64 * @return
65 ***********************************************************************************************************/
66
67XYs1d::XYs1d( Axes const &a_axes, ptwXY_interpolation a_interpolation, std::vector<double> const &a_values, int a_index, double a_outerDomainValue ) :
68 Function1dForm( GIDI_XYs1dChars, FormType::XYs1d, a_axes, a_interpolation, a_index, a_outerDomainValue ) {
69
70 int64_t length = static_cast<int64_t>( a_values.size( ) ) / 2;
71
72 m_ptwXY = ptwXY_create2( nullptr, a_interpolation, length, 0, length, a_values.data( ), 0 );
73}
74
75/* *********************************************************************************************************//**
76 * Constructor that creates an instance from a list of x values and a list of y values. The size of **a_xs**
77 * and **a_ys** must be the same.
78 *
79 * @param a_axes [in] The axes to copy for *this*.
80 * @param a_interpolation [in] The interpolation along the outer most independent axis and the dependent axis.
81 * @param a_xs [in] The data values as ( x_1, x_2, ..., x_n ).
82 * @param a_ys [in] The data values as ( y_1, y_2, ..., y_n ).
83 * @param a_index [in] Currently not used.
84 * @param a_outerDomainValue [in] If embedded in a higher dimensional function, the value of the domain of the next higher dimension.
85 * @return
86 ***********************************************************************************************************/
87
88XYs1d::XYs1d( Axes const &a_axes, ptwXY_interpolation a_interpolation, std::vector<double> const &a_xs, std::vector<double> const &a_ys,
89 int a_index, double a_outerDomainValue ) :
90 Function1dForm( GIDI_XYs1dChars, FormType::XYs1d, a_axes, a_interpolation, a_index, a_outerDomainValue ) {
91
92 if( a_xs.size( ) != a_ys.size( ) ) throw Exception( "XYs1d::XYs1d: xs and ys not the same size" );
93 int64_t length = static_cast<int64_t>( a_xs.size( ) );
94
95 m_ptwXY = ptwXY_createFrom_Xs_Ys2( nullptr, a_interpolation, length, 0, length, a_xs.data( ), a_ys.data( ), 0 );
96}
97
98/* *********************************************************************************************************//**
99 * Constructor that uses an existing **ptwXYPoints** instance. The **m_ptwXY** member is set to **ptwXYPoints** (i.e., this
100 * XYs1d instance now owns the inputted **ptwXYPoints** instance).
101 *
102 * @param a_axes [in] The axes to copy for *this*.
103 * @param a_ptwXY [in] The **ptwXYPoints** instance that *this* takes ownership of.*
104 * @param a_index [in] Currently not used.
105 * @param a_outerDomainValue [in] If embedded in a higher dimensional function, the value of the domain of the next higher dimension.
106 * @return
107 ***********************************************************************************************************/
108
109XYs1d::XYs1d( Axes const &a_axes, ptwXYPoints *a_ptwXY, int a_index, double a_outerDomainValue ) :
110 Function1dForm( GIDI_XYs1dChars, FormType::XYs1d, a_axes, ptwXY_getInterpolation( a_ptwXY ), a_index, a_outerDomainValue ),
111 m_ptwXY( a_ptwXY ) {
112
113}
114
115/* *********************************************************************************************************//**
116 * Constructs the instance from a HAPI::Node instance.
117 *
118 * @param a_construction [in] Used to pass user options for parsing.
119 * @param a_node [in] The XYs1d HAPI::Node to be parsed and to construct the instance.
120 * @param a_setupInfo [in] Information create my the Protare constructor to help in parsing.
121 * @param a_parent [in] If imbedded in a two dimensional function, its pointers.
122 ***********************************************************************************************************/
123
124XYs1d::XYs1d( Construction::Settings const &a_construction, HAPI::Node const &a_node, SetupInfo &a_setupInfo, Suite *a_parent ) :
125 Function1dForm( a_construction, a_node, a_setupInfo, FormType::XYs1d, a_parent ) {
126
127 HAPI::Node values = a_node.child( GIDI_valuesChars );
128 nf_Buffer<double> vals;
129 parseValuesOfDoubles( a_construction, values, a_setupInfo, vals );
130
131 int primarySize = static_cast<int>( vals.size() / 2 ), secondarySize = 0;
132 double *dvals = new double[vals.size()]; // Not sure we really need a copy here.
133 for( size_t idx = 0; idx < vals.size(); idx++ ) dvals[idx] = vals[idx];
134 m_ptwXY = ptwXY_create( NULL, interpolation( ), interpolationString( ).c_str( ), 12, 1e-3, primarySize, secondarySize, primarySize, dvals, 0 );
135 delete[] dvals;
136 if( m_ptwXY == nullptr ) throw Exception( "XYs1d::XYs1d: ptwXY_fromString failed" );
137}
138
139/* *********************************************************************************************************//**
140 * The XYs1d copy constructor.
141 *
142 * @param a_XYs1d [in] The XYs1d instance to copy.
143 ***********************************************************************************************************/
144
145XYs1d::XYs1d( XYs1d const &a_XYs1d ) :
146 Function1dForm( a_XYs1d ),
147 m_ptwXY( nullptr ) {
148
149 m_ptwXY = ptwXY_clone2( nullptr, a_XYs1d.ptwXY( ) );
150 if( m_ptwXY == nullptr ) throw Exception( "XYs1d::XYs1d:2: ptwXY_clone2 failed" );
151}
152
153/* *********************************************************************************************************//**
154 ***********************************************************************************************************/
155
157
158 ptwXY_free( m_ptwXY );
159}
160
161/* *********************************************************************************************************//**
162 * The assignment operator. This method sets the members of *this* to those of *a_rhs* except for those
163 * not set by base classes.
164 *
165 * @param a_rhs [in] Instance whose member are used to set the members of *this*.
166 ***********************************************************************************************************/
167
168XYs1d &XYs1d::operator=( XYs1d const &a_rhs ) {
169
170 if( this != &a_rhs ) {
172
174 m_ptwXY = ptwXY_clone2( smr.smr( ), a_rhs.ptwXY( ) );
175 if( m_ptwXY == nullptr ) throw Exception( smr.constructMessage( "XYs1d::operator=", -1, true ) );
176 }
177
178 return( *this );
179}
180
181/* *********************************************************************************************************//**
182 * The element access methods that returns a point (i.e., an x1, y pair).
183 *
184 * @param a_index [in] The index of the element to access.
185 * @return The x1, y values at **a_index**.
186 ***********************************************************************************************************/
187
188std::pair<double, double> XYs1d::operator[]( std::size_t a_index ) const {
189
190 if( (int64_t) a_index >= ptwXY_length( nullptr, m_ptwXY ) ) throw Exception( "XYs1d::operator[]: index out of bounds." );
191
192 ptwXYPoint *point = ptwXY_getPointAtIndex_Unsafely( m_ptwXY, (int64_t) a_index );
193 std::pair<double, double> CPPPoint( point->x, point->y );
194
195 return( CPPPoint );
196}
197
198/* *********************************************************************************************************//**
199 * Adds two **XYs1d** instances and returns the result.
200 *
201 * @param a_rhs [in] The **XYs1d** instance to add to this instance.
202 * @return An **XYs1d** instance that is the sum of this and *a_rhs*.
203 ***********************************************************************************************************/
204
205XYs1d XYs1d::operator+( XYs1d const &a_rhs ) const {
206
207 XYs1d xys1d( *this );
208
209 xys1d += a_rhs;
210 return( xys1d );
211}
212
213/* *********************************************************************************************************//**
214 * Adds an **XYs1d** instance to this.
215 *
216 * @param a_rhs [in] The **XYs1d** instance to add to this instance.
217 * @return This instance.
218 ***********************************************************************************************************/
219
220XYs1d &XYs1d::operator+=( XYs1d const &a_rhs ) {
221
222 ptwXYPoints *sum, *ptwXY1, *ptwXY2;
224
225 mutualifyDomains( m_ptwXY, a_rhs.ptwXY( ), &ptwXY1, &ptwXY2 );
226 sum = ptwXY_add_ptwXY( smr.smr( ), ptwXY1, ptwXY2 );
227 ptwXY_free( ptwXY1 );
228 ptwXY_free( ptwXY2 );
229 if( sum == nullptr )
230 throw Exception( smr.constructMessage( "XYs1d::operator+=: ptwXY_add_ptwXY failed. ", -1, true ) );
231
232 ptwXY_free( m_ptwXY );
233 m_ptwXY = sum;
234
235 return( *this );
236}
237
238/* *********************************************************************************************************//**
239 * Subtracts two **XYs1d** instances and returns the result.
240 *
241 * @param a_rhs [in] The **XYs1d** instance to substract from this instance.
242 * @return An **XYs1d** instance that is the difference of this and *a_rhs*.
243 ***********************************************************************************************************/
244
245XYs1d XYs1d::operator-( XYs1d const &a_rhs ) const {
246
247 XYs1d xys1d( *this );
248
249 xys1d -= a_rhs;
250 return( xys1d );
251}
252
253/* *********************************************************************************************************//**
254 * Subtracts an **XYs1d** instance from this.
255 *
256 * @param a_rhs [in] The **XYs1d** instance to subtract from this instance.
257 * @return This instance.
258 ***********************************************************************************************************/
259
260XYs1d &XYs1d::operator-=( XYs1d const &a_rhs ) {
261
262 ptwXYPoints *sum, *ptwXY1, *ptwXY2;
264
265 mutualifyDomains( m_ptwXY, a_rhs.ptwXY( ), &ptwXY1, &ptwXY2 );
266 sum = ptwXY_sub_ptwXY( smr.smr( ), ptwXY1, ptwXY2 );
267 ptwXY_free( ptwXY1 );
268 ptwXY_free( ptwXY2 );
269 if( sum == nullptr )
270 throw Exception( smr.constructMessage( "XYs1d::operator-=: ptwXY_sub_ptwXY failed. ", -1, true ) );
271
272 ptwXY_free( m_ptwXY );
273 m_ptwXY = sum;
274
275 return( *this );
276}
277
278/* *********************************************************************************************************//**
279 * Multiplies *this* by a double and returns the result.
280 *
281 * @param a_value [in] Number with this instance.
282 *
283 * @return An **XYs1d** instance that is the product of this and *a_rhs*.
284 ***********************************************************************************************************/
285
286XYs1d XYs1d::operator*( double a_value ) const {
287
288 XYs1d xys1d( *this );
289
290 xys1d *= a_value;
291 return( xys1d );
292}
293
294/* *********************************************************************************************************//**
295 * Multiplies *this* with another **XYs1d** instances and returns the result.
296 *
297 * @param a_rhs [in] The **XYs1d** instance to multiply with this instance.
298 *
299 * @return An **XYs1d** instance that is the product of this and *a_rhs*.
300 ***********************************************************************************************************/
301
302XYs1d XYs1d::operator*( XYs1d const &a_rhs ) const {
303
304 XYs1d xys1d( *this );
305
306 xys1d *= a_rhs;
307 return( xys1d );
308}
309
310/* *********************************************************************************************************//**
311 * Multiplies a double with **this**.
312 *
313 * @param a_rhs [in] The **XYs1d** instance to subtract from this instance.
314 *
315 * @return This instance.
316 ***********************************************************************************************************/
317
318XYs1d &XYs1d::operator*=( double a_value ) {
319
321
322 nfu_status status = ptwXY_mul_double( smr.smr( ), m_ptwXY, a_value );
323 if( status != nfu_Okay )
324 throw Exception( smr.constructMessage( "XYs1d::operator*=: ptwXY_mul_double failed. ", -1, true ) );
325
326 return( *this );
327}
328
329/* *********************************************************************************************************//**
330 * Multiplies **this** with an **XYs1d** instance.
331 *
332 * @param a_rhs [in] The **XYs1d** instance to subtract from this instance.
333 *
334 * @return This instance.
335 ***********************************************************************************************************/
336
337XYs1d &XYs1d::operator*=( XYs1d const &a_rhs ) {
338
339 ptwXYPoints *mul, *ptwXY1, *ptwXY2;
341
342 mutualifyDomains( m_ptwXY, a_rhs.ptwXY( ), &ptwXY1, &ptwXY2 );
343 mul = ptwXY_mul2_ptwXY( smr.smr( ), ptwXY1, ptwXY2 );
344 ptwXY_free( ptwXY1 );
345 ptwXY_free( ptwXY2 );
346 if( mul == nullptr )
347 throw Exception( smr.constructMessage( "XYs1d::operator*=: ptwXY_mul2_ptwXY failed. ", -1, true ) );
348
349 ptwXY_free( m_ptwXY );
350 m_ptwXY = mul;
351
352 return( *this );
353}
354
355/* *********************************************************************************************************//**
356 * Returns the list of **x1** values of this.
357 *
358 * @return The **x1** values of this.
359 ***********************************************************************************************************/
360
361std::vector<double> XYs1d::xs( ) const {
362
363 auto n1 = size( );
364 std::vector<double> _xs( n1, 0. );
365
366 for( std::size_t i1 = 0; i1 < n1; ++i1 ) {
367 ptwXYPoint const *point = ptwXY_getPointAtIndex_Unsafely( m_ptwXY, static_cast<int64_t>( i1 ) );
368
369 _xs[i1] = point->x;
370 }
371 return( _xs );
372}
373
374/* *********************************************************************************************************//**
375 * Returns the list of **y** values of this.
376 *
377 * @return The **y** values of this.
378 ***********************************************************************************************************/
379
380std::vector<double> XYs1d::ys( ) const {
381
382 auto n1 = size( );
383 std::vector<double> _ys( n1, 0. );
384
385 for( std::size_t i1 = 0; i1 < n1; ++i1 ) {
386 ptwXYPoint const *point = ptwXY_getPointAtIndex_Unsafely( m_ptwXY, static_cast<int64_t>( i1 ) );
387
388 _ys[i1] = point->y;
389 }
390 return( _ys );
391}
392
393/* *********************************************************************************************************//**
394 * Returns a list of values that are this **y** mapped to the **x1** values in **a_xs**.
395 *
396 * @param a_xs [in] The list of **x1** values to map this' **y** values to.
397 * @param a_offset [out] The index of the first value in **a_xs** where this starts.
398 * @return The liist of **y** values.
399 ***********************************************************************************************************/
400
401std::vector<double> XYs1d::ysMappedToXs( std::vector<double> const &a_xs, std::size_t *a_offset ) const {
402
403 std::size_t n1 = size( ), i2, n2 = a_xs.size( );
404 std::vector<double> _ys;
405
406 *a_offset = 0;
407 if( n1 == 0 ) return( _ys );
408
409 ptwXYPoint const *point1 = ptwXY_getPointAtIndex_Unsafely( m_ptwXY, 0 );
410 for( i2 = 0; i2 < n2; ++i2 ) if( point1->x <= a_xs[i2] ) break;
411 *a_offset = i2;
412 if( i2 == n2 ) return( _ys );
413
414 for( std::size_t i1 = 1; i1 < n1; ++i1 ) {
415 ptwXYPoint const *point2 = ptwXY_getPointAtIndex_Unsafely( m_ptwXY, static_cast<int64_t>( i1 ) );
416
417 while( i2 < n2 ) {
418 double x = a_xs[i2], y;
419 if( x > point2->x ) break; // Happens because of round off errors. Need to fix.
420
421 ptwXY_interpolatePoint( nullptr, ptwXY_interpolationLinLin, x, &y, point1->x, point1->y, point2->x, point2->y );
422 _ys.push_back( y );
423 ++i2;
424 if( x >= point2->x ) break; // This check can fail hence check above.
425 }
426 point1 = point2;
427 }
428
429 return( _ys );
430}
431
432/* *********************************************************************************************************//**
433 * Returns an **XYs1d** instance that is a domain slice of *this* from **domainMin** to **domainMax**.
434 * If the minimum (maximum) of *this* is greater (less) than **domainMin** (**domainMax**) that domain is unchanged.
435 * If *this*'s minimum is less than **domainMin**, **a_fill** is true and there is no point at **domainMin**
436 * then an interpolated point is added at **domainMin**. Similarly for **domainMax**.
437 *
438 * @param a_domainMin [in] The minimum domain for the returned instance if *this*' minimum is less than **domainMin*.
439 * @param a_domainMax [in] The maximum domain for the returned instance if *this*' maximum is less than **domainMax*.
440 * @param a_fill [in] If true, values at **domainMin** and **domainMax** are added if needed.
441 *
442 * @return An **XYs1d** instance.
443 ***********************************************************************************************************/
444
445XYs1d XYs1d::domainSlice( double a_domainMin, double a_domainMax, bool a_fill ) const {
446
448 ptwXYPoints *ptwXY1 = ptwXY_clone2( smr.smr( ), m_ptwXY );
449 if( ptwXY1 == nullptr ) throw Exception( smr.constructMessage( "XYs1d::domainSlice", -1, true ) );
450
451 ptwXYPoints *ptwXYSliced = ptwXY_domainSlice( nullptr, ptwXY1, a_domainMin, a_domainMax, 10, a_fill ? 1 : 0 );
452 ptwXY_free( ptwXY1 );
453 if( ptwXYSliced == nullptr ) throw Exception( smr.constructMessage( "XYs1d::domainSlice", -1, true ) );
454
455 return( XYs1d( axes( ), ptwXYSliced, index( ), outerDomainValue( ) ) );
456}
457
458/* *********************************************************************************************************//**
459 * Returns an **XYs1d** instance that is this from its domain minimum to **domainMax**.
460 *
461 * @param a_domainMax [in] The maximum domain
462 * @return An **XYs1d** instance.
463 ***********************************************************************************************************/
464
465XYs1d XYs1d::domainSliceMax( double a_domainMax ) const {
466
467 ptwXYPoints *_ptwXY = ptwXY_clone2( nullptr, m_ptwXY );
468 if( _ptwXY == nullptr ) throw Exception( "domainSliceMax: ptwXY_clone2 failed" );
469
470 ptwXYPoints *ptwXYSliced = ptwXY_domainMaxSlice( nullptr, _ptwXY, a_domainMax, 10, 1 );
471 ptwXY_free( _ptwXY );
472 if( ptwXYSliced == nullptr ) throw Exception( "domainSliceMax: ptwXY_domainMaxSlice failed" );
473
474 return( XYs1d( axes( ), ptwXYSliced ) );
475}
476
477/* *********************************************************************************************************//**
478 * The **y** value of this at the domain value **a_x1**.
479 *
480 * @param a_x1 [in] Domain value to evaluate this at.
481 * @return The value of this at the domain value **a_x1**.
482 ***********************************************************************************************************/
483
484double XYs1d::evaluate( double a_x1 ) const {
485
486 std::size_t length = static_cast<std::size_t>( ptwXY_length( nullptr, m_ptwXY ) );
487 if( length == 0 ) throw Exception( "XYs1d::evaluate: XYs1d has no datum." );
488
489 ptwXYPoint *point = ptwXY_getPointAtIndex_Unsafely( m_ptwXY, 0 );
490 if( point->x >= a_x1 ) return( point->y );
491
492 point = ptwXY_getPointAtIndex_Unsafely( m_ptwXY, static_cast<int64_t>( length - 1 ) );
493 if( point->x <= a_x1 ) return( point->y );
494
495 double y;
496 nfu_status status = ptwXY_getValueAtX( nullptr, m_ptwXY, a_x1, &y );
497 if( status != nfu_Okay ) throw Exception( "XYs1d::evaluate: status != nfu_Okay" );
498 return( y );
499}
500
501/* *********************************************************************************************************//**
502 * Evaluates *this* at the X-values in *a_Xs*[*a_offset*:] and adds the results to *a_results*[*a_offset*:].
503 * *a_Xs* and *a_results* must be the same size otherwise a throw is executed.
504 *
505 * @param a_offset [in] The offset in *a_Xs* to start.
506 * @param a_Xs [in] The list of domain values to evaluate *this* at.
507 * @param a_results [in] The list whose values are added to by the Y-values of *this*.
508 * @param a_scaleFactor [in] A factor applied to each evaluation before it is added to *a_results*.
509 ***********************************************************************************************************/
510
511void XYs1d::mapToXsAndAdd( std::size_t a_offset, std::vector<double> const &a_Xs, std::vector<double> &a_results, double a_scaleFactor ) const {
512
513 if( a_Xs.size( ) != a_results.size( ) ) throw Exception( "XYs1d::mapToXsAndAdd: a_Xs.size( ) != a_results.size( )" );
514
516 int64_t length = static_cast<int64_t>( a_Xs.size( ) );
517
518 nfu_status status = ptwXY_mapToXsAndAdd( smr.smr( ), m_ptwXY, static_cast<int64_t>( a_offset ), length,
519 a_Xs.data( ), a_results.data( ), a_scaleFactor );
520 if( ( status != nfu_Okay ) && ( status != nfu_tooFewPoints ) )
521 throw Exception( smr.constructMessage( "XYs1d::mapToXsAndAdd", -1, true ) );
522}
523
524/* *********************************************************************************************************//**
525 * This methods returns an XYs1d representation of *this*. The calling function owns the created instance and is responible
526 * for freeing it.
527 *
528 * @param a_asLinlin [in] If **true**, the inpolatation of the returned XYs1d instance will always be lin-lin. Otherwise,
529 * the interpolation depends on the child 1d functions. This argument is not needed or used for this class.
530 * @param a_accuracy [in] The accuracy use to convert the data to lin=lin interpolation if needed. This argument is not needed or used for this cl
531 * @param a_lowerEps [in] The dulling of the point at the domain minimum.
532 * @param a_upperEps [in] The dulling of the point at the domain maximum.
533 *
534 * @return A pointer to an XYs1d instance that must be freed by the calling function.
535 ***********************************************************************************************************/
536
537XYs1d *XYs1d::asXYs1d( LUPI_maybeUnused bool a_asLinlin, double a_accuracy, double a_lowerEps, double a_upperEps ) const {
538
539 ptwXYPoints *ptwXY2 = nullptr;
540
541 if( m_ptwXY->interpolation == ptwXY_interpolationFlat ) {
542 ptwXY2 = ptwXY_flatInterpolationToLinear( nullptr, m_ptwXY, a_lowerEps, a_upperEps ); }
543 else {
544 ptwXY2 = ptwXY_toOtherInterpolation( nullptr, const_cast<ptwXYPoints *>( m_ptwXY ), ptwXY_interpolationLinLin, a_accuracy );
545 }
546
547
548 if( ptwXY2 == nullptr ) return( nullptr );
549
550 return( new XYs1d( axes( ), ptwXY2 ) );
551}
552
553/* *********************************************************************************************************//**
554 * This method returns **this** that is norimalized (i.e., its integral if 1.). The returned value is the integral
555 * of **this** before being normalized.
556 *
557 * @return A double.
558 ***********************************************************************************************************/
559
560double XYs1d::integrate( double a_dommainMin, double a_dommainMax ) {
561
562 double value = 0.0;
564
565 nfu_status status = ptwXY_integrate( smr.smr( ), m_ptwXY, a_dommainMin, a_dommainMax, &value );
566 if( status != nfu_Okay ) throw Exception( smr.constructMessage( "XYs1d::normalize", -1, true ) );
567
568 return( value );
569}
570
571/* *********************************************************************************************************//**
572 * This method returns **this** that is norimalized (i.e., its integral if 1.). The returned value is the integral
573 * of **this** before being normalized.
574 *
575 * @return A double.
576 ***********************************************************************************************************/
577
579
580 double value = 0.0;
582
583 nfu_status status = ptwXY_integrateDomain( smr.smr( ), m_ptwXY, &value );
584 if( status != nfu_Okay ) throw Exception( smr.constructMessage( "XYs1d::normalize", -1, true ) );
585
586 status = ptwXY_normalize( smr.smr( ), m_ptwXY );
587 if( status != nfu_Okay ) throw Exception( smr.constructMessage( "XYs1d::normalize", -1, true ) );
588
589 return( value );
590}
591
592/* *********************************************************************************************************//**
593 * This method returns a *Xs_pdf_cdf1d* representation of *this*.
594 *
595 * @return An instance of *Xs_pdf_cdf1d*.
596 ***********************************************************************************************************/
597
599// FIXME, need to check that two consecutive cdf values are not the same.
600
601 std::vector<double> xs1 = xs( );
602 std::vector<double> pdf1 = ys( );
603
605 ptwXPoints *ptwX_cdf = ptwXY_runningIntegral( smr.smr( ), m_ptwXY );
606 if( ptwX_cdf == nullptr ) throw Exception( smr.constructMessage( "XYs1d::toXs_pdf_cdf1d", -1, true ) );
607
608 std::size_t length = static_cast<std::size_t>( ptwX_cdf->length );
609 std::vector<double> cdf1( length );
610 for( std::size_t index = 0; index < length; ++index ) cdf1[index] = ptwX_cdf->points[index];
611 ptwX_free( ptwX_cdf );
612
613 return( Xs_pdf_cdf1d( GIDI::Axes( ), ptwXY_interpolationLinLin, xs1, pdf1, cdf1 ) );
614}
615
616/* *********************************************************************************************************//**
617 * Fills the argument *a_writeInfo* with the XML lines that represent *this*. Recursively enters each sub-node.
618 *
619 * @param a_writeInfo [in/out] Instance containing incremental indentation and other information and stores the appended lines.
620 * @param a_indent [in] The amount to indent *this* node.
621 * @param a_embedded [in] If *true*, *this* function is embedded in a higher dimensional function.
622 * @param a_inRegions [in] If *true*, *this* is in a Regions1d container.
623 ***********************************************************************************************************/
624
625void XYs1d::toXMLList_func( GUPI::WriteInfo &a_writeInfo, std::string const &a_indent, bool a_embedded, bool a_inRegions ) const {
626
627 std::string indent2 = a_writeInfo.incrementalIndent( a_indent );
628 std::string attributes;
629
630 if( a_embedded ) {
632 else {
633 if( a_inRegions ) {
634 attributes = a_writeInfo.addAttribute( GIDI_indexChars, intToString( index( ) ) ); }
635 else {
636 if( label( ) != "" ) attributes = a_writeInfo.addAttribute( GIDI_labelChars, label( ) );
637 }
638 }
639
641
642 a_writeInfo.addNodeStarter( a_indent, moniker( ), attributes );
643 axes( ).toXMLList( a_writeInfo, indent2 );
644
645 std::vector<double> doubles( 2 * size( ) );
646 for( std::size_t i1 = 0; i1 < size( ); ++i1 ) {
647 std::pair<double, double> point = (*this)[i1];
648 doubles[2*i1] = point.first;
649 doubles[2*i1+1] = point.second;
650 }
651
652 doublesToXMLList( a_writeInfo, indent2, doubles );
653 a_writeInfo.addNodeEnder( moniker( ) );
654}
655
656/* *********************************************************************************************************//**
657 * Writes the (x,y) values to *a_file*. The format string must have two double conversion specifiers (e.g., " %12.3e %.6f").
658 *
659 * @param a_file [in] The C FILE instance to write the data to.
660 * @param a_format [in] The format string passed to the C printf function.
661 ***********************************************************************************************************/
662
663void XYs1d::write( FILE *a_file, std::string const &a_format ) const {
664
665 ptwXY_simpleWrite( m_ptwXY, a_file, a_format.c_str( ) );
666}
667
668/* *********************************************************************************************************//**
669 * This is a factory function for the XYs1d class that creates a XYs1d instance with the constant value
670 * of *a_value* for the domain from *a_domainMin* to *a_domainMax*.
671 *
672 * @param a_axes [in] The axes for the function.
673 * @param a_domainMin [in] The minimum of the domain for which the function is defined.
674 * @param a_domainMax [in] The maximum of the domain for which the function is defined.
675 * @param a_value [in] The y-value of the function over its domain.
676 ***********************************************************************************************************/
677
678XYs1d *XYs1d::makeConstantXYs1d( Axes const &a_axes, double a_domainMin, double a_domainMax, double a_value ) {
679
680 std::vector<double> points( 4 );
681
682 points[0] = a_domainMin;
683 points[1] = a_value;
684 points[2] = a_domainMax;
685 points[3] = a_value;
686
687 return( new XYs1d( a_axes, ptwXY_interpolationLinLin, points ) );
688}
689
690} // End namespace Functions.
691
692} // End namespace GIDI.
693
694/* *********************************************************************************************************//**
695 * Returns to instances of **ptwXYPoints** that are the mutualified domains of **a_lhs** and **a_rhs**.
696 *
697 * @param a_lhs [in] One of the instances used to mutualify domains.
698 * @param a_rhs [in] One of the instances used to mutualify domains.
699 * @param a_ptwXY1 [out] The mutualified domain for **a_lhs**.
700 * @param a_ptwXY2 [out] The mutualified domain for **a_rhs**.
701 ***********************************************************************************************************/
702
703static void mutualifyDomains( ptwXYPoints const *a_lhs, ptwXYPoints const *a_rhs, ptwXYPoints **a_ptwXY1, ptwXYPoints **a_ptwXY2 ) {
704
705 double lowerEps = 1e-12, upperEps = 1e-12;
706
707 *a_ptwXY1 = ptwXY_clone2( nullptr, a_lhs );
708 if( *a_ptwXY1 == nullptr ) throw GIDI::Exception( "mutualifyDomains: ptwXY_clone2 failed for a_ptwXY1" );
709
710 *a_ptwXY2 = ptwXY_clone2( nullptr, a_rhs );
711 if( *a_ptwXY2 == nullptr ) {
712 ptwXY_free( *a_ptwXY1 );
713 throw GIDI::Exception( "mutualifyDomains: ptwXY_clone2 failed form a_ptwXY2" );
714 }
715
716 nfu_status status = ptwXY_mutualifyDomains( nullptr, *a_ptwXY1, lowerEps, upperEps, 1, *a_ptwXY2, lowerEps, upperEps, 1 );
717 if( status != nfu_Okay ) {
718 ptwXY_free( *a_ptwXY1 );
719 ptwXY_free( *a_ptwXY2 );
720 throw GIDI::Exception( "XYs1d::operator(+|-)=: mutualifyDomains in ptwXY_mutualifyDomains" );
721 }
722}
#define GIDI_XYs1dChars
Definition GIDI.hpp:288
#define GIDI_valuesChars
Definition GIDI.hpp:260
#define GIDI_outerDomainValueChars
Definition GIDI.hpp:436
#define GIDI_interpolationChars
Definition GIDI.hpp:434
#define GIDI_labelChars
Definition GIDI.hpp:438
#define GIDI_indexChars
Definition GIDI.hpp:437
#define LUPI_maybeUnused
void toXMLList(GUPI::WriteInfo &a_writeInfo, std::string const &a_indent="") const
Definition GIDI_axes.cc:113
std::string const & label() const
Definition GIDI.hpp:658
Function1dForm(std::string const &a_moniker, FormType a_type, ptwXY_interpolation a_interpolation, int a_index, double a_outerDomainValue)
Definition GIDI_form.cc:348
Function1dForm & operator=(Function1dForm const &a_rhs)
Definition GIDI_form.cc:405
std::string interpolationString() const
Definition GIDI.hpp:1017
Axes const & axes() const
Definition GIDI.hpp:1012
double outerDomainValue() const
Definition GIDI.hpp:1010
ptwXY_interpolation interpolation() const
Definition GIDI.hpp:1015
std::vector< double > ysMappedToXs(std::vector< double > const &a_xs, std::size_t *a_offset) const
double integrate(double a_dommainMin, double a_dommainMax)
XYs1d & operator+=(XYs1d const &a_XYs1d)
XYs1d operator*(double a_value) const
std::size_t size() const
Definition GIDI.hpp:1100
XYs1d & operator-=(XYs1d const &a_XYs1d)
Xs_pdf_cdf1d toXs_pdf_cdf1d()
void write(FILE *a_file, std::string const &a_format) const
XYs1d operator-(XYs1d const &a_XYs1d) const
void mapToXsAndAdd(std::size_t a_offset, std::vector< double > const &a_Xs, std::vector< double > &a_results, double a_scaleFactor) const
std::pair< double, double > operator[](std::size_t a_index) const
double evaluate(double a_x1) const
ptwXYPoints const * ptwXY() const
Definition GIDI.hpp:1101
void toXMLList_func(GUPI::WriteInfo &a_writeInfo, std::string const &a_indent, bool a_embedded, bool a_inRegions) const
XYs1d & operator=(XYs1d const &a_rhs)
XYs1d domainSliceMax(double a_domainMax) const
XYs1d & operator*=(double a_value)
XYs1d domainSlice(double a_domainMin, double a_domainMax, bool a_fill) const
XYs1d * asXYs1d(bool a_asLinlin, double a_accuray, double a_lowerEps, double a_upperEps) const
XYs1d operator+(XYs1d const &a_XYs1d) const
static XYs1d * makeConstantXYs1d(Axes const &a_axes, double a_domainMin, double a_domainMax, double a_value)
std::vector< double > xs() const
std::vector< double > ys() const
std::string const & moniker() const
Definition GUPI.hpp:102
void addNodeEnder(std::string const &a_moniker)
Definition GUPI.hpp:59
std::string incrementalIndent(std::string const &indent)
Definition GUPI.hpp:52
void addNodeStarter(std::string const &indent, std::string const &a_moniker, std::string const &a_attributes="")
Definition GUPI.hpp:55
std::string addAttribute(std::string const &a_name, std::string const &a_value) const
Definition GUPI.hpp:60
Node child(const char *name) const
Definition HAPI_Node.cc:72
statusMessageReporting * smr()
Definition LUPI.hpp:112
std::string constructMessage(std::string a_prefix, int a_reports=1, bool a_clear=false)
Definition GIDI.hpp:32
void parseValuesOfDoubles(Construction::Settings const &a_construction, HAPI::Node const &a_node, SetupInfo &a_setupInfo, nf_Buffer< double > &a_vector)
Definition GIDI_misc.cc:88
FormType
Definition GIDI.hpp:118
void doublesToXMLList(GUPI::WriteInfo &a_writeInfo, std::string const &a_indent, std::vector< double > const &a_values, std::size_t a_start=0, bool a_newLine=true, std::string const &a_valueType="")
Definition GIDI_misc.cc:180
std::string intToString(int a_value)
Definition GIDI_misc.cc:415
std::string doubleToShortestString(double a_value, int a_significantDigits=15, int a_favorEFormBy=0)
Definition LUPI_misc.cc:349
@ nfu_Okay
@ nfu_tooFewPoints
enum nfu_status_e nfu_status
ptwXYPoints * ptwXY_domainSlice(statusMessageReporting *smr, ptwXYPoints *ptwXY, double domainMin, double domainMax, int64_t secondarySize, int fill)
Definition ptwXY_core.c:422
ptwXY_interpolation ptwXY_getInterpolation(ptwXYPoints *ptwXY)
Definition ptwXY_core.c:518
ptwXYPoints * ptwXY_clone2(statusMessageReporting *smr, ptwXYPoints const *ptwXY)
Definition ptwXY_core.c:312
ptwXPoints * ptwXY_runningIntegral(statusMessageReporting *smr, ptwXYPoints *ptwXY)
nfu_status ptwXY_normalize(statusMessageReporting *smr, ptwXYPoints *ptwXY1)
ptwXYPoints * ptwXY_add_ptwXY(statusMessageReporting *smr, ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2)
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_integrate(statusMessageReporting *smr, ptwXYPoints *ptwXY, double domainMin, double domainMax, double *value)
nfu_status ptwXY_mul_double(statusMessageReporting *smr, ptwXYPoints *ptwXY, double value)
enum ptwXY_interpolation_e ptwXY_interpolation
ptwXYPoints * ptwXY_sub_ptwXY(statusMessageReporting *smr, ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2)
@ ptwXY_interpolationFlat
Definition ptwXY.h:38
@ ptwXY_interpolationLinLin
Definition ptwXY.h:37
ptwXYPoints * ptwXY_mul2_ptwXY(statusMessageReporting *smr, ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2)
struct ptwXYPoints_s ptwXYPoints
nfu_status ptwXY_mutualifyDomains(statusMessageReporting *smr, ptwXYPoints *ptwXY1, double lowerEps1, double upperEps1, int positiveXOnly1, ptwXYPoints *ptwXY2, double lowerEps2, double upperEps2, int positiveXOnly2)
ptwXYPoints * ptwXY_domainMaxSlice(statusMessageReporting *smr, ptwXYPoints *ptwXY, double domainMax, int64_t secondarySize, int fill)
Definition ptwXY_core.c:499
nfu_status ptwXY_mapToXsAndAdd(statusMessageReporting *a_smr, ptwXYPoints *a_ptwXY, int64_t a_offset, int64_t a_length, double const *a_Xs, double *a_results, double a_scaleFractor)
nfu_status ptwXY_interpolatePoint(statusMessageReporting *smr, ptwXY_interpolation interpolation, double x, double *y, double x1, double y1, double x2, double y2)
void ptwXY_simpleWrite(ptwXYPoints *ptwXY, FILE *f, char const *format)
Definition ptwXY_misc.c:329
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
struct ptwXYPoint_s ptwXYPoint
ptwXYPoints * ptwXY_free(ptwXYPoints *ptwXY)
Definition ptwXY_core.c:782
ptwXYPoint * ptwXY_getPointAtIndex_Unsafely(ptwXYPoints const *ptwXY, int64_t index)
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
ptwXYPoints * ptwXY_toOtherInterpolation(statusMessageReporting *smr, ptwXYPoints *ptwXY, ptwXY_interpolation interpolation, double accuracy)
nfu_status ptwXY_getValueAtX(statusMessageReporting *smr, ptwXYPoints *ptwXY, double x, double *y)
nfu_status ptwXY_integrateDomain(statusMessageReporting *smr, ptwXYPoints *ptwXY, double *value)
ptwXYPoints * ptwXY_flatInterpolationToLinear(statusMessageReporting *smr, ptwXYPoints *ptwXY, double lowerEps, double upperEps)
struct ptwXPoints_s ptwXPoints
ptwXPoints * ptwX_free(ptwXPoints *ptwX)
Definition ptwX_core.c:213
int64_t length
Definition ptwX.h:29
double * points
Definition ptwX.h:32
double y
Definition ptwXY.h:64
double x
Definition ptwXY.h:64