1#ifndef VIENNASHE_MATH_INTEGRATOR_HPP
2#define VIENNASHE_MATH_INTEGRATOR_HPP
57 template <
typename IntRule>
66 template <
int int_po
ints>
78 BindFirst(T
const & func,
double value) : func_(func), value_(value) {}
80 double operator()(
double x)
const {
return func_(value_, x); }
81 double operator()(
double x1,
double x2)
const {
return func_(value_, x1, x2); }
82 double operator()(
double x1,
double x2,
double x3)
const {
return func_(value_, x1, x2, x3); }
83 double operator()(
double x1,
double x2,
double x3,
double x4)
const {
return func_(value_, x1, x2, x3, x4); }
85 operator double()
const {
return func_(value_); }
100 BindSecond(T
const & func,
double value) : func_(func), value_(value) {}
102 double operator()(
double x)
const {
return func_(x, value_); }
103 double operator()(
double x1,
double x2)
const {
return func_(x1, value_, x2); }
104 double operator()(
double x1,
double x2,
double x3)
const {
return func_(x1, value_, x2, x3); }
105 double operator()(
double x1,
double x2,
double x3,
double x4)
const {
return func_(x1, value_, x2, x3, x4); }
117 template <
typename T>
121 return ( f( (a+b)/2.0 ) ) * fabs(b-a);
125 template <
typename T>
128 return ( f(a) + f(b) ) * fabs(b-a) / 2.0;
132 template <
typename T>
135 return (f( a ) + 4.0 * f( (a+b)/2.0 ) + f(b)) * fabs(b-a) / 6.0;
139 template <
typename T>
142 return f( (a + b) / 2.0 ) * fabs(b-a);
146 template <
typename T>
149 double xmid = (a + b) / 2.0;
150 double xdiff = (b - a) * 0.288675135;
152 return (f( xmid - xdiff ) + f( xmid + xdiff )) * fabs(b-a) / 2.0;
156 template <
typename T>
159 double xmid = (a + b) / 2.0;
160 double xdiff = (b - a) * 0.387298335;
161 return ( f(xmid - xdiff ) * 5.0/9.0
163 + f(xmid + xdiff ) * 5.0/9.0) * fabs(b-a) / 2.0;
167 template <
typename T>
170 double xmid = (a + b) / 2.0;
171 double xdiff = (b - a) / 2.0;
173 return ( f(xmid - xdiff * 0.8611363115940525752239465 ) * 0.3478548451374538573730639
174 + f(xmid - xdiff * 0.3399810435848562648026658 ) * 0.6521451548625461426269361
175 + f(xmid + xdiff * 0.3399810435848562648026658 ) * 0.6521451548625461426269361
176 + f(xmid + xdiff * 0.8611363115940525752239465 ) * 0.3478548451374538573730639) * xdiff;
180 template <
typename T>
183 double xmid = (a + b) / 2.0;
184 double xdiff = (b - a) / 2.0;
186 return ( f(xmid - xdiff * 0.90617985 ) * 0.23692689
187 + f(xmid - xdiff * 0.53846931 ) * 0.47862867
188 + f(xmid ) * 0.56888888888889
189 + f(xmid + xdiff * 0.53846931 ) * 0.47862867
190 + f(xmid + xdiff * 0.90617985 ) * 0.23692689) * xdiff;
195 template <
typename T>
198 double xmid = (a + b) / 2.0;
199 double xdiff = (b - a) / 2.0;
201 return ( f(xmid - xdiff * 0.9324695142031520278123016 ) * 0.1713244923791703450402961
202 + f(xmid - xdiff * 0.6612093864662645136613996 ) * 0.3607615730481386075698335
203 + f(xmid - xdiff * 0.2386191860831969086305017 ) * 0.4679139345726910473898703
204 + f(xmid + xdiff * 0.2386191860831969086305017 ) * 0.4679139345726910473898703
205 + f(xmid + xdiff * 0.6612093864662645136613996 ) * 0.3607615730481386075698335
206 + f(xmid + xdiff * 0.9324695142031520278123016 ) * 0.1713244923791703450402961) * xdiff;
210 template <
typename T>
213 double xmid = (a + b) / 2.0;
214 double xdiff = (b - a) / 2.0;
216 return ( f(xmid - xdiff * 0.9491079123427585245261897 ) * 0.1294849661688696932706114
217 + f(xmid - xdiff * 0.7415311855993944398638648 ) * 0.2797053914892766679014678
218 + f(xmid - xdiff * 0.4058451513773971669066064 ) * 0.3818300505051189449503698
219 + f(xmid ) * 0.4179591836734693877551020
220 + f(xmid + xdiff * 0.4058451513773971669066064 ) * 0.3818300505051189449503698
221 + f(xmid + xdiff * 0.7415311855993944398638648 ) * 0.2797053914892766679014678
222 + f(xmid + xdiff * 0.9491079123427585245261897 ) * 0.1294849661688696932706114) * xdiff;
227 template <
typename T>
230 double xmid = (a + b) / 2.0;
231 double xdiff = (b - a) / 2.0;
233 return ( f(xmid - xdiff * 0.96028986 ) * 0.10122854
234 + f(xmid - xdiff * 0.79666648 ) * 0.22238103
235 + f(xmid - xdiff * 0.52553241 ) * 0.31370665
236 + f(xmid - xdiff * 0.18343464 ) * 0.36268378
237 + f(xmid + xdiff * 0.18343464 ) * 0.36268378
238 + f(xmid + xdiff * 0.52553241 ) * 0.31370665
239 + f(xmid + xdiff * 0.79666648 ) * 0.22238103
240 + f(xmid + xdiff * 0.96028986 ) * 0.10122854) * xdiff;
244 template <
typename T>
247 double xmid = (a + b) / 2.0;
248 double xdiff = (b - a) / 2.0;
250 return ( f(xmid - xdiff * 0.9681602395076260898355762 ) * 0.0812743883615744119718922
251 + f(xmid - xdiff * 0.8360311073266357942994298 ) * 0.1806481606948574040584720
252 + f(xmid - xdiff * 0.6133714327005903973087020 ) * 0.2606106964029354623187429
253 + f(xmid - xdiff * 0.3242534234038089290385380 ) * 0.3123470770400028400686304
254 + f(xmid ) * 0.3302393550012597631645251
255 + f(xmid + xdiff * 0.3242534234038089290385380 ) * 0.3123470770400028400686304
256 + f(xmid + xdiff * 0.6133714327005903973087020 ) * 0.2606106964029354623187429
257 + f(xmid + xdiff * 0.8360311073266357942994298 ) * 0.1806481606948574040584720
258 + f(xmid + xdiff * 0.9681602395076260898355762 ) * 0.0812743883615744119718922) * xdiff;
262 template <
typename T>
265 double xmid = (a + b) / 2.0;
266 double xdiff = (b - a) / 2.0;
268 return ( f(xmid - xdiff * 0.9739065285171717200779640 ) * 0.0666713443086881375935688
269 + f(xmid - xdiff * 0.8650633666889845107320967 ) * 0.1494513491505805931457763
270 + f(xmid - xdiff * 0.6794095682990244062343274 ) * 0.2190863625159820439955349
271 + f(xmid - xdiff * 0.4333953941292471907992659 ) * 0.2692667193099963550912269
272 + f(xmid - xdiff * 0.1488743389816312108848260 ) * 0.2955242247147528701738930
273 + f(xmid + xdiff * 0.1488743389816312108848260 ) * 0.2955242247147528701738930
274 + f(xmid + xdiff * 0.4333953941292471907992659 ) * 0.2692667193099963550912269
275 + f(xmid + xdiff * 0.6794095682990244062343274 ) * 0.2190863625159820439955349
276 + f(xmid + xdiff * 0.8650633666889845107320967 ) * 0.1494513491505805931457763
277 + f(xmid + xdiff * 0.9739065285171717200779640 ) * 0.0666713443086881375935688) * xdiff;
282 template <
typename T,
typename U>
289 if (recursion_depth == 10)
298 double half_left =
integrate(f, a, (a+b)/2.0, U());
299 double half_right =
integrate(f, (a+b)/2.0, b, U());
301 if ( fabs(direct) > 1e-8 )
304 if ( fabs( (direct - half_left - half_right) / direct) > 1e-8 )
307 return integrate(f, a, (a+b)/2.0, adaptiverule, recursion_depth + 1) +
integrate(f, (a+b)/2.0, b, adaptiverule, recursion_depth + 1);
310 log::warn<log_integrate>() <<
"Precision reached: a: " << a <<
", b: " << b << std::endl;
311 return half_left + half_right;
314 if ( fabs(direct - (half_left + half_right)) > 1e-8 )
317 return integrate(f, a, (a+b)/2.0, adaptiverule, recursion_depth + 1) +
integrate(f, (a+b)/2.0, b, adaptiverule, recursion_depth + 1);
320 return half_left + half_right;
324 template <
typename T,
typename IntRule>
333 return integrate(integrand, a_, b_, IntRule());
356 template <
typename T,
typename IntRuleTag>
358 double a2,
double b2, T
const & func2integrate, IntRuleTag)
362 double result =
integrate(innerIntegral, a1, b1, IntRuleTag());
363 log::debug<log_integrate>() <<
"check 0.25: " << innerIntegral(0.25) << std::endl;
364 log::debug<log_integrate>() <<
"check 0.5: " << innerIntegral(0.5) << std::endl;
365 log::debug<log_integrate>() <<
"check 0.75: " << innerIntegral(0.75) << std::endl;
Binds the first argument of a function of functor to a certain value.
double operator()(double x1, double x2, double x3, double x4) const
BindFirst(T const &func, double value)
double operator()(double x1, double x2, double x3) const
double operator()(double x) const
double operator()(double x1, double x2) const
Binds the second argument of a function or functor to a certain value.
double operator()(double x1, double x2) const
BindSecond(T const &func, double value)
double operator()(double x1, double x2, double x3) const
double operator()(double x1, double x2, double x3, double x4) const
double operator()(double x) const
Tag for an adaptive integration rule.
Gaussian integration rule.
Tag for the midpoint rule.
Tag for the simpson rule.
Tag for the trapezoidal rule.
A binder for reducing an n-ary function to an n-1-ary function by integration over one variable.
double operator()(double x) const
IntegrationBinder(T const &func, double a, double b)
Contains forward declarations and definition of small classes that must be defined at an early stage.
A logging facility providing fine-grained control over logging in ViennaSHE.
double integrate2D(double a1, double b1, double a2, double b2, T const &func2integrate, IntRuleTag)
Convenience overload for two-dimensional integration.
double integrate(T const &f, double a, double b, IntMidPointRule)
Integration of a function using the mid point rule.
The main ViennaSHE namespace. All functionality resides inside this namespace.
Defines the log keys used within the viennashe::math namespace.