17#ifdef NUMERICS_HAS_OMP
18 #pragma omp parallel for reduction(+ : sum) \
19 schedule(static) if (backend == Backend::omp)
21 for (
idx i = 1; i < n; ++i)
23 return h * (0.5 * (f(a) + f(b)) + sum);
28 throw std::invalid_argument(
"simpson: n must be even");
30 real sum = f(a) + f(b);
31#ifdef NUMERICS_HAS_OMP
32 #pragma omp parallel for reduction(+ : sum) \
33 schedule(static) if (backend == Backend::omp)
35 for (
idx i = 1; i < n; ++i)
36 sum += f(a + i * h) * (i % 2 == 0 ? 2.0 : 4.0);
42static constexpr real GL_NODES[5][5] = {
44 {-0.5773502691896257, 0.5773502691896257, 0, 0, 0},
45 {-0.7745966692414834, 0.0, 0.7745966692414834, 0, 0},
56static constexpr real GL_WEIGHTS[5][5] = {
59 {0.5555555555555556, 0.8888888888888889, 0.5555555555555556, 0, 0},
73 throw std::invalid_argument(
"gauss_legendre: p must be 1..5");
74 real mid = 0.5 * (a + b);
75 real half = 0.5 * (b - a);
77 for (
idx i = 0; i < p; ++i)
78 sum += GL_WEIGHTS[p - 1][i] * f(mid + half * GL_NODES[p - 1][i]);
92 real mid_l = 0.5 * (a + b * 0.5 + a * 0.5);
93 real mid_r = 0.5 * (0.5 * (a + b) + b);
94 real mid = 0.5 * (a + b);
95 real fl = f(0.5 * (a + mid));
96 real fr = f(0.5 * (mid + b));
100 real left = (b - a) / 12.0 * (fa + 4.0 * fl + fm);
101 real right = (b - a) / 12.0 * (fm + 4.0 * fr + fb);
102 real delta = left + right - whole;
104 if (depth == 0 || std::abs(delta) <= 15.0 * tol)
105 return left + right + delta / 15.0;
107 return adaptive_helper(f, a, mid, fa, fl, fm, left, tol * 0.5, depth - 1)
120 real fa = f(a), fb = f(b), fm = f(0.5 * (a + b));
121 real est = (b - a) / 6.0 * (fa + 4.0 * fm + fb);
122 return adaptive_helper(f, a, b, fa, fm, fb, est, tol, max_depth);
126 std::vector<std::vector<real>> R(max_levels,
127 std::vector<real>(max_levels, 0.0));
128 R[0][0] = 0.5 * (b - a) * (f(a) + f(b));
130 for (
idx i = 1; i < max_levels; ++i) {
132 real h = (b - a) / n;
134 for (
idx k = 1; k < n; k += 2)
136 R[i][0] = 0.5 * R[i - 1][0] + h * sum;
140 for (
idx j = 1; j <= i; ++j) {
142 R[i][j] = R[i][j - 1]
143 + (R[i][j - 1] - R[i - 1][j - 1]) / (factor - 1.0);
146 if (i > 0 && std::abs(R[i][i] - R[i - 1][i - 1]) < tol)
149 return R[max_levels - 1][max_levels - 1];
Common function type aliases for the analysis module.
real trapz(ScalarFn f, real a, real b, idx n=100, Backend backend=Backend::seq)
Trapezoidal rule with n panels.
Backend
Selects which backend handles a linalg operation.
real gauss_legendre(ScalarFn f, real a, real b, idx p=5)
Gauss-Legendre quadrature (exact for polynomials up to degree 2p-1)
real adaptive_simpson(ScalarFn f, real a, real b, real tol=1e-8, idx max_depth=50)
Adaptive Simpson quadrature.
real simpson(ScalarFn f, real a, real b, idx n=100, Backend backend=Backend::seq)
Simpson's 1/3 rule with n panels (n must be even)
std::function< real(real)> ScalarFn
Real-valued scalar function f(x)
real romberg(ScalarFn f, real a, real b, real tol=1e-10, idx max_levels=12)
Romberg integration (Richardson extrapolation on trapezoidal rule)
Numerical integration (quadrature) on [a, b].