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;
449 if (order > max_iter) {
450 std::string msg =
"Requested integration order "+
452 "maximum number of iterations "+
454 "integration order or increase the (maximum) "
455 "number of iterations.";
460 double* s =
new double[max_iter+2];
461 double* h =
new double[max_iter+2];
474 #if defined(G_NAN_CHECK)
476 m_message =
"*** ERROR: GIntegral::romberg"
487 if (m_iter >= order) {
490 result =
polint(&h[m_iter-order], &s[m_iter-order],
497 if (m_iter == max_iter) {
517 h[m_iter+1]= 0.25 * h[
m_iter];
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);
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);
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) {
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) {
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) {
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) {
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);
1108 for (
int i = 0; i < n; ++i) {
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;
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
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) {
const double & eps(void) const
Get relative precision.
const int & fixed_iter(void) const
Return fixed number of iterations.
double romberg(std::vector< double > bounds, const int &order=5)
Perform Romberg integration.
int m_iter
Number of iterations used.
void warning(const std::string &origin, const std::string &message)
Emits warning.
GVector abs(const GVector &vector)
Computes absolute of vector elements.
const bool & silent(void) const
Get silence flag.
void init_members(void)
Initialise class members.
double polint(double *xa, double *ya, int n, double x, double *dy)
Perform Polynomial interpolation.
double sum(const GVector &vector)
Computes vector sum.
double rescale_error(double err, const double &result_abs, const double &result_asc) const
Rescale errors for Gauss-Kronrod integration.
int m_max_iter
Maximum number of iterations.
const std::string & message(void) const
Return integration status message.
GIntegral class interface definition.
double gauss_kronrod(const double &a, const double &b) const
Gauss-Kronrod integration.
int m_fix_iter
Fixed number of iterations.
GIntegral & operator=(const GIntegral &integral)
Assignment operator.
void clear(void)
Clear integral.
bool is_notanumber(const double &x)
Signal if argument is not a number.
bool is_infinite(const double &x)
Signal if argument is infinite.
const int & iter(void) const
Return number of iterations.
bool m_isvalid
Integration result valid (true=yes)
GIntegral(void)
Void constructor.
Single parameter function abstract base class definition.
double trapzd(const double &a, const double &b, const int &n=1, double result=0.0)
Perform Trapezoidal integration.
bool m_has_abserr
Has absolute integration error.
std::string m_message
Status message (if result is invalid)
bool m_has_relerr
Has relative integration error.
const int & calls(void) const
Get number of function calls.
virtual double eval(const double &x)=0
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 GFunction * kernel(void) const
Get function kernel.
double m_relerr
Absolute integration error.
void copy_members(const GIntegral &integral)
Copy class members.
double m_eps
Requested relative integration precision.
bool m_silent
Suppress integration warnings in console.
std::string print(const GChatter &chatter=NORMAL) const
Print integral information.
virtual ~GIntegral(void)
Destructor.
Single parameter function abstract base class.
const int & max_iter(void) const
Return maximum number of iterations.
GVector pow(const GVector &vector, const double &power)
Computes tanh of vector elements.
Exception handler interface definition.
GFunction * m_kernel
Pointer to function kernel.
int m_calls
Number of function calls used.
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Integration class interface definition.
const bool & is_valid(void) const
Signal if integration result is valid.
double m_abserr
Absolute integration error.
void free_members(void)
Delete class members.
GIntegral * clone(void) const
Clone integral.
double adaptive_simpson(const double &a, const double &b) const
Adaptive Simpson's integration.
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.