37#define G_ROMBERG "GIntegral::romberg(double&, double&, int&)"
38#define G_TRAPZD "GIntegral::trapzd(double&, double&, int&, double)"
39#define G_POLINT "GIntegral::polint(double*, double*, int, double, double*)"
52 0.973906528517171720077964012084452,
53 0.865063366688984510732096688423493,
54 0.679409568299024406234327365114874,
55 0.433395394129247190799265943165784,
56 0.148874338981631210884826001129720
61 0.066671344308688137593568809893332,
62 0.149451349150580593145776339657697,
63 0.219086362515982043995534934228163,
64 0.269266719309996355091226921569469,
65 0.295524224714752870173892994651338
70 0.995657163025808080735527280689003,
71 0.930157491355708226001207180059508,
72 0.780817726586416897063717578345042,
73 0.562757134668604683339000099272694,
74 0.294392862701460198131126603103866
79 0.032558162307964727478818972459390,
80 0.075039674810919952767043140916190,
81 0.109387158802297641899210590325805,
82 0.134709217311473325928054001771707,
83 0.147739104901338491374841515972068
88 0.011694638867371874278064396062192,
89 0.054755896574351996031381300244580,
90 0.093125454583697605535065465083366,
91 0.123491976262065851077958109831074,
92 0.142775938577060080797094273138717,
93 0.149445554002916905664936468389821
98 0.999333360901932081394099323919911,
99 0.987433402908088869795961478381209,
100 0.954807934814266299257919200290473,
101 0.900148695748328293625099494069092,
102 0.825198314983114150847066732588520,
103 0.732148388989304982612354848755461,
104 0.622847970537725238641159120344323,
105 0.499479574071056499952214885499755,
106 0.364901661346580768043989548502644,
107 0.222254919776601296498260928066212,
108 0.074650617461383322043914435796506
113 0.016296734289666564924281974617663,
114 0.037522876120869501461613795898115,
115 0.054694902058255442147212685465005,
116 0.067355414609478086075553166302174,
117 0.073870199632393953432140695251367,
118 0.005768556059769796184184327908655,
119 0.027371890593248842081276069289151,
120 0.046560826910428830743339154433824,
121 0.061744995201442564496240336030883,
122 0.071387267268693397768559114425516
127 0.001844477640212414100389106552965,
128 0.010798689585891651740465406741293,
129 0.021895363867795428102523123075149,
130 0.032597463975345689443882222526137,
131 0.042163137935191811847627924327955,
132 0.050741939600184577780189020092084,
133 0.058379395542619248375475369330206,
134 0.064746404951445885544689259517511,
135 0.069566197912356484528633315038405,
136 0.072824441471833208150939535192842,
137 0.074507751014175118273571813842889,
138 0.074722147517403005594425168280423
143 0.999902977262729234490529830591582,
144 0.997989895986678745427496322365960,
145 0.992175497860687222808523352251425,
146 0.981358163572712773571916941623894,
147 0.965057623858384619128284110607926,
148 0.943167613133670596816416634507426,
149 0.915806414685507209591826430720050,
150 0.883221657771316501372117548744163,
151 0.845710748462415666605902011504855,
152 0.803557658035230982788739474980964,
153 0.757005730685495558328942793432020,
154 0.706273209787321819824094274740840,
155 0.651589466501177922534422205016736,
156 0.593223374057961088875273770349144,
157 0.531493605970831932285268948562671,
158 0.466763623042022844871966781659270,
159 0.399424847859218804732101665817923,
160 0.329874877106188288265053371824597,
161 0.258503559202161551802280975429025,
162 0.185695396568346652015917141167606,
163 0.111842213179907468172398359241362,
164 0.037352123394619870814998165437704
169 0.008148377384149172900002878448190,
170 0.018761438201562822243935059003794,
171 0.027347451050052286161582829741283,
172 0.033677707311637930046581056957588,
173 0.036935099820427907614589586742499,
174 0.002884872430211530501334156248695,
175 0.013685946022712701888950035273128,
176 0.023280413502888311123409291030404,
177 0.030872497611713358675466394126442,
178 0.035693633639418770719351355457044,
179 0.000915283345202241360843392549948,
180 0.005399280219300471367738743391053,
181 0.010947679601118931134327826856808,
182 0.016298731696787335262665703223280,
183 0.021081568889203835112433060188190,
184 0.025370969769253827243467999831710,
185 0.029189697756475752501446154084920,
186 0.032373202467202789685788194889595,
187 0.034783098950365142750781997949596,
188 0.036412220731351787562801163687577,
189 0.037253875503047708539592001191226
194 0.000274145563762072350016527092881,
195 0.001807124155057942948341311753254,
196 0.004096869282759164864458070683480,
197 0.006758290051847378699816577897424,
198 0.009549957672201646536053581325377,
199 0.012329447652244853694626639963780,
200 0.015010447346388952376697286041943,
201 0.017548967986243191099665352925900,
202 0.019938037786440888202278192730714,
203 0.022194935961012286796332102959499,
204 0.024339147126000805470360647041454,
205 0.026374505414839207241503786552615,
206 0.028286910788771200659968002987960,
207 0.030052581128092695322521110347341,
208 0.031646751371439929404586051078883,
209 0.033050413419978503290785944862689,
210 0.034255099704226061787082821046821,
211 0.035262412660156681033782717998428,
212 0.036076989622888701185500318003895,
213 0.036698604498456094498018047441094,
214 0.037120549269832576114119958413599,
215 0.037334228751935040321235449094698,
216 0.037361073762679023410321241766599
308 if (
this != &integral) {
384 std::sort(bounds.begin(), bounds.end());
393 for (
int i = 0; i < bounds.size()-1; ++i) {
394 value +=
romberg(bounds[i], bounds[i+1], order);
441 bool converged =
false;
450 std::string msg =
"Requested integration order "+
452 "maximum number of iterations "+
454 "integration order or increase the (maximum) "
455 "number of iterations.";
474 #if defined(G_NAN_CHECK)
475 if (is_notanumber(s[
m_iter]) || is_infinite(s[
m_iter])) {
476 m_message =
"*** ERROR: GIntegral::romberg"
501 else if (std::abs(dss) <=
m_eps * std::abs(result)) {
507 if (std::abs(result) > 0) {
530 " exceeds absolute tolerance of "+
533 " iterations. Result "+
537 std::string origin =
"GIntegral::romberg("+
590 std::string msg =
"Function kernel not set. Please set a function "
591 "kernel before calling the method.";
612 result = 0.5*(b-a)*(y_a + y_b);
621 for (
int j = 1; j < n-1; ++j) {
634 ". Looks like n is too large.";
641 double tnm = double(it);
642 double del = (b-a)/tnm;
653 ". Step is too small to make sense.";
660 double x = a + 0.5*del;
662 for (
int j = 0; j < it; ++j, x+=del) {
674 result = 0.5*(result + (b-a)*
sum/tnm);
718 double c = 0.5*(a + b);
728 double S = (h/6.0) * (fa + 4.0*fc + fb);
731 double epsilon = (std::abs(S) > 0) ?
m_eps * S :
m_eps;
741 m_message =
"Integration uncertainty exceeds relative tolerance "
747 std::string origin =
"GIntegral::adaptive_simpson("+
789 if (
m_eps < 1.12e-14) {
792 " cannot be acheived. Please relax the integration "
795 std::string origin =
"GIntegral::gauss_kronrod("+
803 double h = 0.5 * (b - a);
804 double abs_h = std::abs(h);
805 double c = 0.5 * (b + a);
814 for (
int k = 0; k < 5; ++k) {
818 double fval = fval1 + fval2;
827 for (
int k = 0; k < 5; ++k) {
831 double fval = fval1 + fval2;
840 double mean = 0.5 * res21;
842 for (
int k = 0; k < 5; ++k) {
844 (std::abs(fv1[k] - mean) + std::abs(fv2[k] - mean)) +
846 (std::abs(fv3[k] - mean) + std::abs(fv4[k] - mean)));
850 double error =
rescale_error((res21 - res10) * h, resabs, resasc);
853 if (error <
m_eps * std::abs(result)) {
856 if (std::abs(result) > 0) {
858 m_relerr = error / std::abs(result);
866 for (
int k = 0; k < 10; ++k) {
869 for (
int k = 0; k < 11; ++k) {
881 if (error <
m_eps * std::abs(result)) {
884 if (std::abs(result) > 0) {
886 m_relerr = error / std::abs(result);
894 for (
int k = 0; k < 21; ++k) {
897 for (
int k = 0; k < 22; ++k) {
908 if (error <
m_eps * std::abs(result)) {
911 if (std::abs(result) > 0) {
913 m_relerr = error / std::abs(result);
921 "absolute tolerance of "+
927 std::string origin =
"GIntegral::gauss_kronrod("+
955 result.append(
"=== GIntegral ===");
973 result.append(
" (fixed: ");
978 result.append(
" (maximum: ");
986 result.append(
"Result accurate.");
996 result.append(
"in standard output");
1100 std::vector<double> c(n, 0.0);
1101 std::vector<double> d(n, 0.0);
1104 double dif = std::abs(x-xa[1]);
1108 for (
int i = 0; i < n; ++i) {
1109 double dift = std::abs(x-xa[i+1]);
1123 for (
int m = 1; m < n; ++m) {
1126 for (
int i = 0; i < n-m; ++i) {
1127 double ho = xa[i+1] - x;
1128 double hp = xa[i+m+1] - x;
1129 double w = c[i+1] - d[i];
1130 double den = ho - hp;
1134 " encountered. Two values in xa array are"
1146 *dy = (2*(ns+1) < (n-m)) ? c[ns+1] : d[ns--];
1174 const double& eps,
const double& S,
1175 const double& fa,
const double& fb,
1177 const int& bottom)
const
1185 double c = 0.5*(a + b);
1187 double d = 0.5*(a + c);
1188 double e = 0.5*(c + b);
1196 double h12 = h / 12.0;
1197 double Sleft = h12 * (fa + 4.0*fd + fc);
1198 double Sright = h12 * (fc + 4.0*fe + fb);
1199 double S2 = Sleft + Sright;
1205 if (std::abs(S2 - S) <= 15.0 *
eps) {
1207 value = S2 + (S2 - S)/15.0;
1212 else if (bottom <= 0) {
1213 value = S2 + (S2 - S)/15.0;
1237 const double& result_abs,
1238 const double& result_asc)
const
1241 err = std::abs(err);
1244 if (result_asc != 0.0 && err != 0.0) {
1245 double scale = std::pow((200.0 * err / result_asc), 1.5);
1247 err = result_asc * scale ;
1253 if (result_abs > 2.2250738585072014e-308 / (50.0 * 2.2204460492503131e-16)) {
1254 double min_err = 50.0 * 2.2204460492503131e-16 * result_abs;
1255 if (min_err > err) {
Exception handler interface definition.
Single parameter function abstract base class definition.
Integration class interface definition.
double sum(const GVector &vector)
Computes vector sum.
Single parameter function abstract base class.
virtual double eval(const double &x)=0
GIntegral class interface definition.
const bool & silent(void) const
Get silence flag.
const std::string & message(void) const
Return integration status message.
std::string m_message
Status message (if result is invalid)
int m_calls
Number of function calls used.
const double & eps(void) const
Get relative precision.
double adaptive_simpson_aux(const double &a, const double &b, const double &eps, const double &S, const double &fa, const double &fb, const double &fc, const int &bottom) const
Auxiliary function for adaptive Simpson's method.
const int & iter(void) const
Return number of iterations.
double romberg(std::vector< double > bounds, const int &order=5)
Perform Romberg integration.
double m_relerr
Absolute integration error.
void copy_members(const GIntegral &integral)
Copy class members.
double m_eps
Requested relative integration precision.
const int & fixed_iter(void) const
Return fixed number of iterations.
const int & calls(void) const
Get number of function calls.
bool m_has_abserr
Has absolute integration error.
bool m_has_relerr
Has relative integration error.
GIntegral * clone(void) const
Clone integral.
double trapzd(const double &a, const double &b, const int &n=1, double result=0.0)
Perform Trapezoidal integration.
void clear(void)
Clear integral.
bool m_silent
Suppress integration warnings in console.
const GFunction * kernel(void) const
Get function kernel.
int m_iter
Number of iterations used.
double gauss_kronrod(const double &a, const double &b) const
Gauss-Kronrod integration.
virtual ~GIntegral(void)
Destructor.
int m_max_iter
Maximum number of iterations.
void init_members(void)
Initialise class members.
double adaptive_simpson(const double &a, const double &b) const
Adaptive Simpson's integration.
GFunction * m_kernel
Pointer to function kernel.
std::string print(const GChatter &chatter=NORMAL) const
Print integral information.
GIntegral(void)
Void constructor.
void free_members(void)
Delete class members.
GIntegral & operator=(const GIntegral &integral)
Assignment operator.
const int & max_iter(void) const
Return maximum number of iterations.
double rescale_error(double err, const double &result_abs, const double &result_asc) const
Rescale errors for Gauss-Kronrod integration.
const bool & is_valid(void) const
Signal if integration result is valid.
double m_abserr
Absolute integration error.
bool m_isvalid
Integration result valid (true=yes)
double polint(double *xa, double *ya, int n, double x, double *dy)
Perform Polynomial interpolation.
int m_fix_iter
Fixed number of iterations.
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
void warning(const std::string &origin, const std::string &message)
Emits warning.