13 template<
class function_2d_t>
16 const size_t nIntervals =
static_cast<size_t>(std::ceil((x1 - x0) *
static_cast<double>(nIntervalsPer1)));
18 const double dx = (x1 - x0) /
static_cast<double>(nIntervals);
19 double fTotalArea = 0.0;
22 for (
size_t i = 0; i < nIntervals; ++i)
24 fTotalArea += dx * func(x);
31 template<
class function_2d_t>
34 const size_t nIntervals =
static_cast<size_t>(std::ceil(
static_cast<double>(nIntervalsPer1) * (x1 - x0)));
36 const double dx = (x1 - x0) /
static_cast<double>(nIntervals);
37 double fTotalArea = 0.0;
40 for (
size_t i = 0; i < nIntervals; ++i)
42 fTotalArea += dx * (func(x) + func(x + dx)) / 2;
49 template<
class function_2d_t>
51 const function_2d_t& func,
54 double fMaxSliceError,
55 size_t nIntervalsPer1,
58 const size_t nIntervals =
static_cast<size_t>(std::ceil(
static_cast<double>(nIntervalsPer1) * (x1 - x0)));
60 const double dx = (x1 - x0) /
static_cast<double>(nIntervals);
61 double fTotalArea = 0.0;
66 const auto& slice_area,
67 const function_2d_t& func,
70 double max_slice_error,
71 size_t recursionLevel)
73 const double y0 = func(x0);
74 const double y1 = func(x1);
75 const double xm = (x0 + x1) / 2;
76 const double ym = func(xm);
78 const double fArea12 = (x1 - x0) * (y0 + y1) / 2.0;
79 const double fArea1m = (xm - x0) * (y0 + ym) / 2.0;
80 const double fAream2 = (x1 - xm) * (ym + y1) / 2.0;
81 const double fArea1m2 = fArea1m + fAream2;
83 const double fError = (fArea1m2 - fArea12) / fArea12;
86 if (recursionLevel > nMaxRecursion || std::abs(fError) < max_slice_error)
92 return slice_area(func, x0, xm, max_slice_error, recursionLevel)
93 + slice_area(func, xm, x1, max_slice_error, recursionLevel);
97 for (
size_t i = 0; i < nIntervals; ++i)
99 fTotalArea += slice_area(func, x, x + dx, fMaxSliceError, 0);
106 template<
class function_2d_t>
108 const function_2d_t& funcIsInside,
111 size_t nPointsPerOneSquare)
113 const double fArea = std::abs(pos1.x - pos0.x) * std::abs(pos1.y - pos0.y);
114 const int nTotalPoints =
static_cast<int>(std::ceil(fArea *
static_cast<double>(nPointsPerOneSquare)));
116 int points_inside = 0;
118 std::default_random_engine generator(
static_cast<unsigned>(std::time(
nullptr)));
120 std::uniform_real_distribution<double> x_dist(pos0.x, pos1.x);
121 std::uniform_real_distribution<double> y_dist(pos0.y, pos1.y);
123 for (
int i = 0; i < nTotalPoints; ++i)
125 int f = funcIsInside(x_dist(generator), y_dist(generator));
132 return (
static_cast<double>(points_inside) / nTotalPoints) * fArea;
double integrate_trapezoid_rule(const function_2d_t &func, double x0, double x1, size_t nIntervalsPer1=10)
Integrate using trapezoid rule.
double integrate_rectangle_rule(const function_2d_t &func, double x0, double x1, size_t nIntervalsPer1=10)
Integrate using rectangle rule.
double integrate_adaptive_midpoint(const function_2d_t &func, double x0, double x1, double fMaxSliceError, size_t nIntervalsPer1=10, size_t nMaxRecursion=300)
Integrate using adaptive midpoint.
double integrate_monte_carlo(const function_2d_t &funcIsInside, glm::dvec2 pos0, glm::dvec2 pos1, size_t nPointsPerOneSquare=1000)
Integrate using probabilistic algorithm Monte Carlo.
recursive_lambda< std::decay_t< lambda_t > > make_recursive_lambda(lambda_t &&lambda)
Create lambda that can be called recursively.