(ns emmy.numerical.quadrature.simpson
(:require [emmy.numerical.quadrature.common :as qc]
[emmy.numerical.quadrature.trapezoid :as qt]
[emmy.polynomial.richardson :as pr]))

Simpson's Rule

This numerical integration method is a closed Newton-Cotes formula; for each integral slice, Simpson's rule samples each endpoint and the midpoint and combines them into an area estimate for this slice using the following formula:

Loading...

Given a window of Loading... and a "step size" of Loading.... The point Loading... is the point Loading... steps into the window.

There are a few simpler ways to understand this:

  • Simpson's rule is simply the trapezoid method (see trapezoid.cljc), subject to a single refinement of "Richardson extrapolation".

  • The trapezoid method fits a line to each integration slice. Simpson's rule fits a quadratic to each slice.

  • Simpson's rule Loading... is the weighted average of the Midpoint rule Loading... and the trapezoid rule Loading...:

Loading...

The test namespace contains a symbolic proof that the Richardson-extrapolated Trapezoid method is equivalent to using the formula above to calculate Simpson's rule directly.

(defn simpson-sequence
"Returns a (lazy) sequence of successively refined estimates of the integral of
`f` over the closed interval $[a, b]$ using Simpson's rule.
Simpson's rule is equivalent to the trapezoid method subject to one refinement
of Richardson extrapolation. The trapezoid method fits a line to each
integration slice. Simpson's rule fits a quadratic to each slice.
Returns estimates with $n, 2n, 4n, ...$ slices, geometrically increasing by a
factor of 2 with each estimate.
### Optional arguments:
If supplied, `:n` (default 1) specifies the initial number of slices to use."
([f a b] (simpson-sequence f a b {:n 1}))
([f a b {:keys [n] :or {n 1}}]
{:pre [(number? n)]}
(-> (qt/trapezoid-sequence f a b n)
(pr/richardson-column 1 2 2 2))))
#object[emmy.numerical.quadrature.simpson$simpson_sequence 0x5c9061a8 "
emmy.numerical.quadrature.simpson$simpson_sequence@5c9061a8"
]
(qc/defintegrator integral
"Returns an estimate of the integral of `f` over the closed interval $[a, b]$
using Simpson's rule with $1, 2, 4 ... 2^n$ windows for each estimate.
Optionally accepts `opts`, a dict of optional arguments. All of these get
passed on to `us/seq-limit` to configure convergence checking.
See [[simpson-sequence]] for more information about Simpson's rule, caveats that
might apply when using this integration method and information on the optional
args in `opts` that customize this function's behavior."
:area-fn (comp first simpson-sequence)
:seq-fn simpson-sequence)
#object[emmy.numerical.quadrature.common$make_integrator_fn$call__53914 0xedefa67 "
emmy.numerical.quadrature.common$make_integrator_fn$call__53914@edefa67"
]