Skip to content

Commit

Permalink
Update AdaptiveSimpson.cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
i1011 authored Oct 15, 2023
1 parent 7a48d9e commit 00245b1
Showing 1 changed file with 30 additions and 28 deletions.
58 changes: 30 additions & 28 deletions codebook/9_Else/AdaptiveSimpson.cpp
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
using F_t = function<double(double)>;
pdd simpson(const F_t &f, double l, double r,
double fl, double fr, double fm = nan("")) {
if (isnan(fm)) fm = f((l + r) / 2);
return {fm, (r - l) / 6 * (fl + 4 * fm + fr)};
}
double simpson_ada(const F_t &f, double l, double r,
double fl, double fm, double fr, double eps) {
double m = (l + r) / 2,
s = simpson(f, l, r, fl, fr, fm).second;
auto [flm, sl] = simpson(f, l, m, fl, fm);
auto [fmr, sr] = simpson(f, m, r, fm, fr);
double delta = sl + sr - s;
if (abs(delta) <= 15 * eps)
return sl + sr + delta / 15;
return simpson_ada(f, l, m, fl, flm, fm, eps / 2) +
simpson_ada(f, m, r, fm, fmr, fr, eps / 2);
}
double simpson_ada(const F_t &f, double l, double r) {
return simpson_ada(
f, l, r, f(l), f((l + r) / 2), f(r), 1e-9 / 7122);
}
double simpson_ada2(const F_t &f, double l, double r) {
double h = (r - l) / 7122, s = 0;
for (int i = 0; i < 7122; ++i, l += h)
s += simpson_ada(f, l, l + h);
return s;
}
template<typename Func, typename d = double>
struct Simpson {
using pdd = pair<d, d>;
Func f;
pdd mix(pdd l, pdd r, optional<d> fm = {}) {
d h = (r.X - l.X) / 2, v = fm.value_or(f(l.X + h));
return {v, h / 3 * (l.Y + 4 * v + r.Y)};
}
d eval(pdd l, pdd r, d fm, d eps) {
pdd m((l.X + r.X) / 2, fm);
d s = mix(l, r, fm).second;
auto [flm, sl] = mix(l, m);
auto [fmr, sr] = mix(m, r);
d delta = sl + sr - s;
if (abs(delta) <= 15 * eps) return sl + sr + delta / 15;
return eval(l, m, flm, eps / 2) +
eval(m, r, fmr, eps / 2);
}
d eval(d l, d r, d eps) {
return eval({l, f(l)}, {r, f(r)}, f((l + r) / 2), eps);
}
d eval2(d l, d r, d eps, int k = 997) {
d h = (r - l) / k, s = 0;
for (int i = 0; i < k; ++i, l += h)
s += eval(l, l + h, eps / k);
return s;
}
};
template<typename Func>
Simpson<Func> make_simpson(Func f) { return {f}; }

0 comments on commit 00245b1

Please sign in to comment.