29#include "../algorithms/integrators/integrators.hpp"
30#include "../algorithms/quadrature/quadrature.hpp"
39template<std::
size_t N,
typename T =
double>
41 static constexpr std::size_t
order = N;
46 [[nodiscard]] algorithms::integration_result<T>
47 operator()(std::function<T(T)> const& f, T a, T b)
const {
49 return integrator(f, a, b);
53template<std::
size_t N,
typename T>
57template<std::
size_t N,
typename T =
double>
58[[nodiscard]]
constexpr auto gauss() {
67template<
typename T =
double>
74 constexpr adaptive(T tol = T(1e-10), std::size_t max_sub = 1000) noexcept
77 [[nodiscard]] algorithms::integration_result<T>
78 operator()(std::function<T(T)>
const& f, T a, T b)
const {
96template<
typename T =
double>
106template<
typename T =
double>
111 std::optional<std::size_t>
seed;
113 constexpr monte_carlo(std::size_t n, std::optional<std::size_t> s = std::nullopt) noexcept
116 [[nodiscard]] algorithms::integration_result<T>
122 std::random_device rd;
126 std::uniform_real_distribution<T> dist(a, b);
131 for (std::size_t i = 0; i <
samples; ++i) {
137 T interval_length = b - a;
140 T value = mean * interval_length;
141 T error = std::sqrt(variance) * interval_length;
161template<
typename T =
double>
171template<std::
size_t N,
typename T =
double>
173 static_assert(N % 2 == 0,
"Simpson's rule requires even number of subdivisions");
180 [[nodiscard]] algorithms::integration_result<T>
181 operator()(std::function<T(T)> const& f, T a, T b)
const {
182 T h = (b - a) / T(N);
185 for (std::size_t i = 1; i < N; i += 2) {
186 sum += T(4) * f(a + T(i) * h);
188 for (std::size_t i = 2; i < N; i += 2) {
189 sum += T(2) * f(a + T(i) * h);
192 T value = sum * h / T(3);
193 T error = std::abs(value) * std::pow(h, 4);
199template<std::
size_t N,
typename T>
203template<std::
size_t N,
typename T =
double>
213template<std::
size_t N,
typename T =
double>
220 [[nodiscard]] algorithms::integration_result<T>
221 operator()(std::function<T(T)> const& f, T a, T b)
const {
222 T h = (b - a) / T(N);
223 T sum = (f(a) + f(b)) / T(2);
225 for (std::size_t i = 1; i < N; ++i) {
226 sum += f(a + T(i) * h);
230 T error = std::abs(value) * h * h;
236template<std::
size_t N,
typename T>
240template<std::
size_t N,
typename T =
double>
250template<
typename BaseMethod,
typename T =
double>
261 [[nodiscard]] algorithms::integration_result<T>
263 return integrate_adaptive(f, a, b, 0);
272 integrate_adaptive(std::function<T(T)>
const& f, T a, T b, std::size_t depth)
const {
273 auto full =
base(f, a, b);
276 full.converged_ =
false;
280 T mid = (a + b) / T(2);
281 auto left =
base(f, a, mid);
282 auto right =
base(f, mid, b);
283 auto refined = left + right;
285 T error = std::abs(full.value() - refined.value());
288 refined.error_ = error;
292 auto left_refined = integrate_adaptive(f, a, mid, depth + 1);
293 auto right_refined = integrate_adaptive(f, mid, b, depth + 1);
295 return left_refined + right_refined;
299template<
typename M,
typename T>
303template<
typename M,
typename T =
double>
304[[nodiscard]]
constexpr auto make_adaptive(M base_method, T tol = T(1e-10)) {
313template<
typename T =
double>
constexpr auto monte_carlo_method(std::size_t n)
Factory for Monte Carlo integration.
constexpr auto adaptive_method(T tol=T(1e-10))
Factory for adaptive integration.
constexpr auto make_adaptive(M base_method, T tol=T(1e-10))
Factory for adaptive composition of any base method.
constexpr auto trapezoidal_method()
Factory for trapezoidal rule.
constexpr auto gauss()
Factory for Gauss-Legendre quadrature.
constexpr auto simpson_method()
Factory for Simpson's rule.
std::optional< T > variance_
Wraps any base method with adaptive interval subdivision until convergence.
constexpr adaptive_composed(BaseMethod m, T tol=T(1e-10), std::size_t depth=20) noexcept
algorithms::integration_result< T > operator()(std::function< T(T)> const &f, T a, T b) const
constexpr adaptive_composed with_tolerance(T tol) const noexcept
Adaptive integration with recursive interval subdivision until convergence.
algorithms::integration_result< T > operator()(std::function< T(T)> const &f, T a, T b) const
constexpr adaptive with_max_subdivisions(std::size_t max_sub) const noexcept
constexpr adaptive with_tolerance(T tol) const noexcept
constexpr adaptive(T tol=T(1e-10), std::size_t max_sub=1000) noexcept
std::size_t max_subdivisions
N-point Gauss-Legendre quadrature, achieving degree 2N-1 polynomial exactness.
static constexpr std::size_t order
constexpr gauss_legendre() noexcept=default
Type trait to tag types as integration methods (specialized per method struct)
Monte Carlo integration using random sampling. Error decreases as O(1/sqrt(n)).
std::optional< std::size_t > seed
constexpr monte_carlo with_seed(std::size_t s) const noexcept
constexpr monte_carlo(std::size_t n, std::optional< std::size_t > s=std::nullopt) noexcept
algorithms::integration_result< T > operator()(std::function< T(T)> const &f, T a, T b) const
constexpr monte_carlo with_samples(std::size_t n) const noexcept
Simpson's 1/3 rule with N subdivisions (N must be even). Achieves O(h^4) convergence.
static constexpr std::size_t subdivisions
constexpr simpson() noexcept=default
Trapezoidal rule with N subdivisions. Achieves O(h^2) convergence.
constexpr trapezoidal() noexcept=default
static constexpr std::size_t subdivisions