GammaLib  2.1.0.dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GIntegrals.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * GIntegrals.cpp - Integration class for set of functions *
3  * ----------------------------------------------------------------------- *
4  * copyright (C) 2020 by Juergen Knoedlseder *
5  * ----------------------------------------------------------------------- *
6  * *
7  * This program is free software: you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation, either version 3 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License *
18  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19  * *
20  ***************************************************************************/
21 /**
22  * @file GIntegrals.cpp
23  * @brief Integration class for set of functions implementation
24  * @author Juergen Knoedlseder
25  */
26 
27 /* __ Includes ___________________________________________________________ */
28 #include <cmath> // std::abs()
29 #include <vector>
30 #include <algorithm> // std::sort
31 #include "GIntegrals.hpp"
32 #include "GException.hpp"
33 #include "GTools.hpp"
34 #include "GFunctions.hpp"
35 
36 /* __ Method name definitions ____________________________________________ */
37 #define G_ROMBERG1 "GIntegrals::romberg(std::vector<double>, int&)"
38 #define G_ROMBERG2 "GIntegrals::romberg(double&, double&, int&)"
39 #define G_GAUSS_KRONROD "GIntegrals::gauss_kronrod(double&, double&)"
40 #define G_TRAPZD "GIntegrals::trapzd(double&, double&, int&, GVector)"
41 #define G_POLINT "GIntegrals::polint(double*, GVector*, int, int, double, "\
42  "GVector*)"
43 
44 /* __ Macros _____________________________________________________________ */
45 
46 /* __ Coding definitions _________________________________________________ */
47 
48 /* __ Debug definitions __________________________________________________ */
49 
50 /* __ Constants __________________________________________________________ */
51 
52 
53 /*==========================================================================
54  = =
55  = Constructors/destructors =
56  = =
57  ==========================================================================*/
58 
59 /***********************************************************************//**
60  * @brief Void constructor
61  ***************************************************************************/
63 {
64  // Initialise members
65  init_members();
66 
67  // Return
68  return;
69 }
70 
71 
72 /***********************************************************************//**
73  * @brief Vector function kernels constructor
74  *
75  * @param[in] kernels Pointer to function kernels.
76  *
77  * The vector function kernels constructor assigns the vector function
78  * kernels pointer in constructing the object.
79  ***************************************************************************/
81 {
82  // Initialise members
83  init_members();
84 
85  // Set function kernel
87 
88  // Return
89  return;
90 }
91 
92 
93 /***********************************************************************//**
94  * @brief Copy constructor
95  *
96  * @param[in] integrals Integrals.
97  ***************************************************************************/
99 {
100  // Initialise members
101  init_members();
102 
103  // Copy members
104  copy_members(integrals);
105 
106  // Return
107  return;
108 }
109 
110 
111 /***********************************************************************//**
112  * @brief Destructor
113  ***************************************************************************/
115 {
116  // Free members
117  free_members();
118 
119  // Return
120  return;
121 }
122 
123 
124 /*==========================================================================
125  = =
126  = Operators =
127  = =
128  ==========================================================================*/
129 
130 /***********************************************************************//**
131  * @brief Assignment operator
132  *
133  * @param[in] integrals Integrals.
134  * @return Integrals.
135  ***************************************************************************/
137 {
138  // Execute only if object is not identical
139  if (this != &integrals) {
140 
141  // Free members
142  free_members();
143 
144  // Initialise integral
145  init_members();
146 
147  // Copy members
148  copy_members(integrals);
149 
150  } // endif: object was not identical
151 
152  // Return
153  return *this;
154 }
155 
156 
157 /*==========================================================================
158  = =
159  = Public methods =
160  = =
161  ==========================================================================*/
162 
163 /***********************************************************************//**
164  * @brief Clear integral
165  ***************************************************************************/
167 {
168  // Free members
169  free_members();
170 
171  // Initialise private members
172  init_members();
173 
174  // Return
175  return;
176 }
177 
178 
179 /***********************************************************************//**
180  * @brief Clone integral
181  *
182  * @return Pointer to deep copy of integrals.
183  ***************************************************************************/
185 {
186  return new GIntegrals(*this);
187 }
188 
189 
190 /***********************************************************************//**
191  * @brief Perform Romberg integration
192  *
193  * @param[in] bounds Integration boundaries.
194  * @param[in] order Integration order (default: 5)
195  * @return Vector of integration results.
196  *
197  * Returns the integral of the integrand, computed over a number of
198  * intervals [a0,a1], [a1,a2], ... that are given as an unordered vector
199  * by the @p bounds argument.
200  *
201  * Integration is performed by Romberg's method of order 2*order, where
202  *
203  * order=1 is equivalent to the trapezoidal rule,
204  * order=2 is equivalent to Simpson's rule, and
205  * order=3 is equivalent to Boole's rule.
206  *
207  * The number of iterations is limited by m_max_iter. m_eps specifies the
208  * requested fractional accuracy. By default it is set to 1e-6.
209  ***************************************************************************/
210 GVector GIntegrals::romberg(std::vector<double> bounds, const int& order)
211 {
212  // Throw an exception if the instance has no kernels
213  if (m_kernels == NULL) {
214  std::string msg = "Function kernels not set. Please set function "
215  "kernels before calling the method.";
217  }
218 
219  // Sort integration boundaries in ascending order
220  std::sort(bounds.begin(), bounds.end());
221 
222  // Initialise result
223  GVector result(m_kernels->size());
224 
225  // Initialise integration status information
226  int calls = 0;
227 
228  // Add integral of all intervals
229  for (int i = 0; i < bounds.size()-1; ++i) {
230  result += romberg(bounds[i], bounds[i+1], order);
231  calls += m_calls;
232  }
233 
234  // Set integration status information
235  m_calls = calls;
236 
237  // Return result
238  return result;
239 }
240 
241 
242 /***********************************************************************//**
243  * @brief Perform Romberg integration
244  *
245  * @param[in] a Left integration boundary.
246  * @param[in] b Right integration boundary.
247  * @param[in] order Integration order (default: 5)
248  * @return Vector of integration results.
249  *
250  * @exception GException::invalid_value
251  * Function kernels not set.
252  * @exception GException::invalid_argument
253  * Integration order incompatible with number of iterations.
254  *
255  * Returns the integral of the integrand from a to b. Integration is
256  * performed by Romberg's method of order 2*order, where
257  *
258  * order=1 is equivalent to the trapezoidal rule,
259  * order=2 is equivalent to Simpson's rule, and
260  * order=3 is equivalent to Boole's rule.
261  *
262  * The number of iterations is limited by m_max_iter. m_eps specifies the
263  * requested fractional accuracy. By default it is set to 1e-6.
264  ***************************************************************************/
265 GVector GIntegrals::romberg(const double& a, const double& b, const int& order)
266 {
267  // Throw an exception if the instance has no kernels
268  if (m_kernels == NULL) {
269  std::string msg = "Function kernels not set. Please set function "
270  "kernels before calling the method.";
272  }
273 
274  // Initialise result
275  GVector result(m_kernels->size());
276 
277  // Initialise integration status information
278  m_isvalid = true;
279  m_calls = 0;
280  m_has_abserr = false;
281  m_has_relerr = false;
282 
283  // Continue only if integration range is valid
284  if (b > a) {
285 
286  // Initialise variables
287  bool converged = false;
288  GVector dss(m_kernels->size());
289 
290  // Determine (maximum) number of iterations
291  int max_iter = (m_fix_iter > 0) ? m_fix_iter : m_max_iter;
292 
293  // Check whether maximum number of iterations is compliant with
294  // order
295  if (order > max_iter) {
296  std::string msg = "Requested integration order "+
297  gammalib::str(order)+" is larger than the "
298  "maximum number of iterations "+
299  gammalib::str(max_iter)+". Either reduce the "
300  "integration order or increase the (maximum) "
301  "number of iterations.";
303  }
304 
305  // Allocate temporal storage
306  double* h = new double[max_iter+2];
307  GVector* s = new GVector[max_iter+2];
308 
309  // Initialise step size and initial result
310  h[1] = 1.0;
311  s[0] = GVector(m_kernels->size());
312 
313  // Iterative loop
314  for (m_iter = 1; m_iter <= max_iter; ++m_iter) {
315 
316  // Integration using Trapezoid rule
317  s[m_iter] = trapzd(a, b, m_iter, s[m_iter-1]);
318 
319  // Compile option: Check for NaN/Inf
320  #if defined(G_NAN_CHECK)
321  if (is_notanumber(s[m_iter]) || is_infinite(s[m_iter])) {
322  m_message = "*** ERROR: GIntegrals::romberg"
323  "(a="+gammalib::str(a)+", b="+gammalib::str(b)+""
324  ", k="+gammalib::str(k)+"): NaN/Inf encountered"
325  " (s["+gammalib::str(m_iter)+"]="
326  ""+s[m_iter]->print()+")";
327  std::cout << m_message << std::endl;
328  m_isvalid = false;
329  }
330  #endif
331 
332  // Starting from iteration order on, use polynomial interpolation
333  if (m_iter >= order) {
334 
335  // Compute result using polynom interpolation
336  result = polint(&h[m_iter-order], &s[m_iter-order], order, 0.0, &dss);
337 
338  // If a fixed number of iterations has been requested and if
339  // the final iteration was reached then set the converged
340  // flag
341  if (m_fix_iter > 0) {
342  if (m_iter == max_iter) {
343  converged = true;
344  }
345  }
346 
347  // ... otherwise if the requested precision was reached for
348  // all functions then set the converged flag
349  else {
350  converged = true;
351  for (int i = 0; i < result.size(); ++i) {
352  if (std::abs(dss[i]) > m_eps * std::abs(result[i])) {
353  converged = false;
354  break;
355  }
356  }
357  }
358 
359  // If the integration has converged then compute the absolute
360  // and the relative integration errors. If an intergation result
361  // is zero, the relative error is set to zero. The relative
362  // error flag is set to true if at least one of the relative
363  // integration errors is valid.
364  if (converged) {
365  m_has_abserr = true;
366  m_abserr = abs(dss);
367  m_relerr = m_abserr;
368  for (int i = 0; i < result.size(); ++i) {
369  double abs_result = std::abs(result[i]);
370  if (abs_result > 0.0) {
371  m_relerr[i] /= abs_result;
372  m_has_relerr = true;
373  }
374  else {
375  m_relerr[i] = 0.0;
376  }
377  }
378  break;
379  }
380 
381  } // endif: polynomial interpolation performed
382 
383  // Reduce step size
384  h[m_iter+1] = 0.25 * h[m_iter];
385 
386  } // endfor: iterative loop
387 
388  // Delete temporal storage
389  delete [] s;
390  delete [] h;
391 
392  // Set status and optionally dump warning
393  if (!converged) {
394  m_isvalid = false;
395  m_message = "Integration uncertainty "+(abs(dss)).print()+
396  " exceeds absolute tolerance of "+
397  (m_eps * abs(result)).print()+
398  " after "+gammalib::str(m_iter)+" iterations. Result "+
399  result.print()+" is inaccurate.";
400  if (!m_silent) {
401  std::string origin = "GIntegrals::romberg("+
402  gammalib::str(a)+", "+
403  gammalib::str(b)+", "+
404  gammalib::str(order)+")";
405  gammalib::warning(origin, m_message);
406  }
407  }
408 
409  } // endif: integration range was valid
410 
411  // Return result
412  return result;
413 }
414 
415 
416 /***********************************************************************//**
417  * @brief Perform Trapezoidal integration for a set of functions
418  *
419  * @param[in] a Left integration boundary.
420  * @param[in] b Right integration boundary.
421  * @param[in] n Number of steps.
422  * @param[in] previous_result Result vector from a previous trapezoidal
423  * integration step.
424  * @return Vector of integration results.
425  *
426  * @exception GException::invalid_value
427  * Function kernels not set.
428  *
429  * The method performs a trapezoidal integration of a set of functions for
430  * the integration interval [a,b].
431  *
432  * If @p n = 1 the integral for each function \f$j\f$ is computed using
433  *
434  * \f[
435  * \int_a^b f_j(x) \, dx = \frac{1}{2} (b-a) (f_j(a) + f_j(b))
436  * \f]
437  *
438  * For @p n > 1 the integral is computed using
439  *
440  * \f[
441  * \int_a^b f_j(x) \, dx = \frac{1}{2} \left[{\tt previous\_result}_j +
442  * \frac{b-a}{2^{n-1}}
443  * \sum_{i=0}^{2^{n-1}-1} f_j \left( a + (0.5+i) \frac{b-a}{2^{n-1}}
444  * \right) \right]
445  * \f]
446  *
447  * where \f${\tt previous\_result}_j\f$ is the integration result for
448  * function \f$j\f$ from a previous call to the method with @p n = @p n - 1.
449  ***************************************************************************/
450 GVector GIntegrals::trapzd(const double& a,
451  const double& b,
452  const int& n,
453  const GVector& previous_result)
454 {
455  // Throw an exception if the instance has no kernel
456  if (m_kernels == NULL) {
457  std::string msg = "Function kernels not set. Please set function "
458  "kernels before calling the method.";
460  }
461 
462  // If lower boundary is smaller than upper boundary than use trapezoidal
463  // rule
464  if (a < b) {
465 
466  // Case A: Only a single step is requested
467  if (n == 1) {
468 
469  // Evaluate integrand at boundaries
470  GVector result = 0.5 * (b-a) * (m_kernels->eval(a) +
471  m_kernels->eval(b));
472 
473  // Bookkeeping of function calls
474  m_calls += 2;
475 
476  // Return result here to avoid an extra vector copy
477  return result;
478 
479  } // endif: only a single step was requested
480 
481  // Case B: More than a single step is requested
482  else {
483 
484  // Compute step level 2^(n-1)
485  int it = 1;
486  for (int j = 1; j < n-1; ++j) {
487  it <<= 1;
488  }
489 
490  // Verify that step level is valid
491  if (it == 0) {
492  m_isvalid = false;
493  m_message = "Invalid step level "+gammalib::str(it)+
494  " encountered for"
495  " a="+gammalib::str(a)+
496  ", b="+gammalib::str(b)+
497  ", n="+gammalib::str(n)+
498  ", result="+previous_result.print()+
499  ". Looks like n is too large.";
500  if (!m_silent) {
502  }
503  }
504 
505  // Set step size
506  double tnm = double(it);
507  double del = (b-a)/tnm;
508 
509  // Verify that step is >0
510  if (del == 0) {
511  m_isvalid = false;
512  m_message = "Invalid step size "+gammalib::str(del)+
513  " encountered for"
514  " a="+gammalib::str(a)+
515  ", b="+gammalib::str(b)+
516  ", n="+gammalib::str(n)+
517  ", result="+previous_result.print()+
518  ". Step is too small to make sense.";
519  if (!m_silent) {
521  }
522  }
523 
524  // Initialise result
525  GVector result(previous_result.size());
526 
527  // Initialise argument
528  double x = a + 0.5 * del;
529 
530  // Sum up values
531  for (int j = 0; j < it; ++j, x += del) {
532 
533  // Evaluate and add integrand
534  result += m_kernels->eval(x);
535 
536  // Bookkeeping of function calls
537  m_calls++;
538 
539  } // endfor: looped over steps
540 
541  // Compute result benefiting from previous result
542  result *= del;
543  result += previous_result;
544  result *= 0.5;
545 
546  // Return result here to avoid an extra vector copy
547  return result;
548 
549  } // endelse: Case B
550 
551  } // endif: trapezoidal rule was applied
552 
553  // ... otherwise handle case a >= b
554  else {
555 
556  // Set empty vector
557  GVector result(previous_result.size());
558 
559  // Return result here to avoid an extra vector copy
560  return result;
561  }
562 
563 }
564 
565 
566 /***********************************************************************//**
567  * @brief Print integral information
568  *
569  * @param[in] chatter Chattiness.
570  * @return String containing integral information.
571  ***************************************************************************/
572 std::string GIntegrals::print(const GChatter& chatter) const
573 {
574  // Initialise result string
575  std::string result;
576 
577  // Continue only if chatter is not silent
578  if (chatter != SILENT) {
579 
580  // Append header
581  result.append("=== GIntegrals ===");
582 
583  // Append information
584  result.append("\n"+gammalib::parformat("Relative precision"));
585  result.append(gammalib::str(eps()));
586  if (m_has_abserr) {
587  result.append("\n"+gammalib::parformat("Absolute errors"));
588  result.append(m_abserr.print());
589  }
590  if (m_has_relerr) {
591  result.append("\n"+gammalib::parformat("Relative errors"));
592  result.append(m_relerr.print());
593  }
594  result.append("\n"+gammalib::parformat("Function calls"));
595  result.append(gammalib::str(calls()));
596  result.append("\n"+gammalib::parformat("Iterations"));
597  result.append(gammalib::str(iter()));
598  if (m_fix_iter > 0) {
599  result.append(" (fixed: ");
600  result.append(gammalib::str(fixed_iter()));
601  result.append(")");
602  }
603  else {
604  result.append(" (maximum: ");
605  result.append(gammalib::str(max_iter()));
606  result.append(")");
607  }
608 
609  // Append status information
610  result.append("\n"+gammalib::parformat("Status"));
611  if (is_valid()) {
612  result.append("Result accurate.");
613  }
614  else {
615  result.append(message());
616  }
617  if (silent()) {
618  result.append("\n"+gammalib::parformat("Warnings")+"suppressed");
619  }
620  else {
621  result.append("\n"+gammalib::parformat("Warnings"));
622  result.append("in standard output");
623  }
624 
625  } // endif: chatter was not silent
626 
627  // Return result
628  return result;
629 }
630 
631 
632 /*==========================================================================
633  = =
634  = Protected methods =
635  = =
636  ==========================================================================*/
637 
638 /***********************************************************************//**
639  * @brief Initialise class members
640  ***************************************************************************/
642 {
643  // Initialise members
644  m_kernels = NULL;
645  m_eps = 1.0e-6;
646  m_max_iter = 20;
647  m_fix_iter = 0;
648  m_message.clear();
649  m_silent = false;
650 
651  // Initialise results
652  m_iter = 0;
653  m_calls = 0;
654  m_isvalid = true;
655  m_has_abserr = false;
656  m_has_relerr = false;
657  m_abserr.clear();
658  m_relerr.clear();
659 
660  // Return
661  return;
662 }
663 
664 
665 /***********************************************************************//**
666  * @brief Copy class members
667  *
668  * @param[in] integral Integral.
669  ***************************************************************************/
671 {
672  // Copy attributes
673  m_kernels = integral.m_kernels;
674  m_eps = integral.m_eps;
675  m_max_iter = integral.m_max_iter;
676  m_fix_iter = integral.m_fix_iter;
677  m_message = integral.m_message;
678  m_silent = integral.m_silent;
679 
680  // Copy results
681  m_iter = integral.m_iter;
682  m_calls = integral.m_calls;
683  m_isvalid = integral.m_isvalid;
684  m_has_abserr = integral.m_has_abserr;
685  m_has_relerr = integral.m_has_relerr;
686  m_abserr = integral.m_abserr;
687  m_relerr = integral.m_relerr;
688 
689  // Return
690  return;
691 }
692 
693 
694 /***********************************************************************//**
695  * @brief Delete class members
696  ***************************************************************************/
698 {
699  // Return
700  return;
701 }
702 
703 
704 /***********************************************************************//**
705  * @brief Perform Polynomial interpolation
706  *
707  * @param[in] xa Pointer to array of X values.
708  * @param[in] ya Pointer to GVector of Y values.
709  * @param[in] order Number of elements in arrays.
710  * @param[in] x X value for which interpolations should be performed.
711  * @param[out] dy Pointer to vector of error estimates for interpolated values.
712  * @return Vector of interpolated values.
713  *
714  * Given arrays @p xa[1,..,n] and @p ya[1,..,n], and given a value @p x, this
715  * method returns a value y, and an error estimate @p dy. If P(x) is the
716  * polynomial of degree n-1, then the returned value y=P(x).
717  ***************************************************************************/
718 GVector GIntegrals::polint(const double* xa,
719  const GVector* ya,
720  const int& order,
721  const double& x,
722  GVector* dy)
723 {
724  // Get vector dimension
725  int nsize = ya->size();
726 
727  // Initialise result
728  GVector y(nsize);
729 
730  // Allocate temporary memory
731  double* c = new double[order];
732  double* d = new double[order];
733 
734  // Find index nclosest of the closest table entry
735  int nclosest = 0;
736  double dif = std::abs(x-xa[1]);
737  for (int i = 1; i < order; ++i) {
738  double dift = std::abs(x-xa[i+1]);
739  if (dift < dif) {
740  nclosest = i;
741  dif = dift;
742  }
743  }
744 
745  // Loop over vector dimension
746  for (int index = 0; index < nsize; ++index) {
747 
748  // Set closest table entry
749  int ns = nclosest;
750 
751  // Initialise table values
752  for (int i = 0; i < order; ++i) {
753  double value = ya[i+1][index];
754  c[i] = value;
755  d[i] = value;
756  }
757 
758  // Get initial approximation to y
759  y[index] = ya[ns+1][index];
760  ns--;
761 
762  // Loop over each column of the tableau
763  for (int m = 1; m < order; ++m) {
764 
765  // Update current c's and d's
766  for (int i = 0; i < order-m; ++i) {
767  double ho = xa[i+1] - x;
768  double hp = xa[i+m+1] - x;
769  double w = c[i+1] - d[i];
770  double den = ho - hp;
771  if (den == 0.0) {
772  m_isvalid = false;
773  m_message = "Invalid step size "+gammalib::str(den)+
774  " encountered. Two values in xa array are"
775  " identical.";
776  if (!m_silent) {
778  }
779  }
780  den = w/den;
781  d[i] = hp*den;
782  c[i] = ho*den;
783  }
784 
785  // Compute y correction
786  double delta_y = (2*(ns+1) < (order-m)) ? c[ns+1] : d[ns--];
787 
788  // Update y
789  y[index] += delta_y;
790 
791  // Store result
792  (*dy)[index] = delta_y;
793 
794  } // endfor: looped over columns of tableau
795 
796  } // endfor: looped over vector dimension
797 
798  // Free temporary memory
799  delete [] c;
800  delete [] d;
801 
802  // Return
803  return y;
804 }
const bool & silent(void) const
Get silence flag.
Definition: GIntegrals.hpp:254
GIntegrals(void)
Void constructor.
Definition: GIntegrals.cpp:62
void warning(const std::string &origin, const std::string &message)
Emits warning.
Definition: GTools.cpp:1386
virtual ~GIntegrals(void)
Destructor.
Definition: GIntegrals.cpp:114
GVector abs(const GVector &vector)
Computes absolute of vector elements.
Definition: GVector.cpp:1253
void init_members(void)
Initialise class members.
Definition: GIntegrals.cpp:641
int m_iter
Number of iterations used.
Definition: GIntegrals.hpp:108
int m_fix_iter
Fixed number of iterations.
Definition: GIntegrals.hpp:104
void copy_members(const GIntegrals &integral)
Copy class members.
Definition: GIntegrals.cpp:670
GIntegrals & operator=(const GIntegrals &integral)
Assignment operator.
Definition: GIntegrals.cpp:136
const GFunctions * kernels(void) const
Get function kernels.
Definition: GIntegrals.hpp:281
Gammalib tools definition.
bool m_isvalid
Integration result valid (true=yes)
Definition: GIntegrals.hpp:110
void clear(void)
Clear integral.
Definition: GIntegrals.cpp:166
virtual GVector eval(const double &x)=0
int m_max_iter
Maximum number of iterations.
Definition: GIntegrals.hpp:103
double m_eps
Requested relative integration precision.
Definition: GIntegrals.hpp:102
bool m_silent
Suppress integration warnings in console.
Definition: GIntegrals.hpp:105
bool m_has_relerr
Has relative integration errors.
Definition: GIntegrals.hpp:112
void clear(void)
Clear vector.
Definition: GVector.cpp:489
bool is_notanumber(const double &x)
Signal if argument is not a number.
Definition: GTools.hpp:201
bool is_infinite(const double &x)
Signal if argument is infinite.
Definition: GTools.hpp:184
Single parameter functions abstract base class definition.
std::string print(const GChatter &chatter=NORMAL) const
Print integral information.
Definition: GIntegrals.cpp:572
const int & calls(void) const
Get number of function calls.
Definition: GIntegrals.hpp:229
Integration class for set of functions interface definition.
GFunctions * m_kernels
Pointer to function kernels.
Definition: GIntegrals.hpp:101
const bool & is_valid(void) const
Signal if integration result is valid.
Definition: GIntegrals.hpp:293
virtual int size(void) const =0
GIntegrals * clone(void) const
Clone integral.
Definition: GIntegrals.cpp:184
int m_calls
Number of function calls used.
Definition: GIntegrals.hpp:109
void free_members(void)
Delete class members.
Definition: GIntegrals.cpp:697
#define G_POLINT
Definition: GIntegrals.cpp:41
GChatter
Definition: GTypemaps.hpp:33
GVector m_relerr
Absolute integration errors.
Definition: GIntegrals.hpp:114
std::string m_message
Status message (if result is invalid)
Definition: GIntegrals.hpp:115
const int & fixed_iter(void) const
Return fixed number of iterations.
Definition: GIntegrals.hpp:192
#define G_ROMBERG1
Definition: GIntegrals.cpp:37
const int & iter(void) const
Return number of iterations.
Definition: GIntegrals.hpp:137
bool m_has_abserr
Has absolute integration errors.
Definition: GIntegrals.hpp:111
#define G_ROMBERG2
Definition: GIntegrals.cpp:38
#define G_TRAPZD
Definition: GIntegrals.cpp:40
const int & max_iter(void) const
Return maximum number of iterations.
Definition: GIntegrals.hpp:162
GVector romberg(std::vector< double > bounds, const int &order=5)
Perform Romberg integration.
Definition: GIntegrals.cpp:210
Exception handler interface definition.
GVector trapzd(const double &a, const double &b, const int &n, const GVector &previous_result)
Perform Trapezoidal integration for a set of functions.
Definition: GIntegrals.cpp:450
const int & size(void) const
Return size of vector.
Definition: GVector.hpp:178
Vector class.
Definition: GVector.hpp:46
std::string print(const GChatter &chatter=NORMAL) const
Print vector information.
Definition: GVector.cpp:661
GVector polint(const double *xa, const GVector *ya, const int &order, const double &x, GVector *dy)
Perform Polynomial interpolation.
Definition: GIntegrals.cpp:718
Integration class for set of functions.
Definition: GIntegrals.hpp:47
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition: GTools.cpp:1143
GVector m_abserr
Absolute integration errors.
Definition: GIntegrals.hpp:113
const double & eps(void) const
Get relative precision.
Definition: GIntegrals.hpp:217
const std::string & message(void) const
Return integration status message.
Definition: GIntegrals.hpp:305
Single parameter functions abstract base class.
Definition: GFunctions.hpp:50
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition: GTools.cpp:489