Symbolic vs Numeric Integration¶
This notebook demonstrates Maxima's symbolic-numeric bridge by comparing
exact symbolic integration (integrate()) with numeric trapezoidal
approximation (np_trapz()). We explore convergence, special functions,
oscillatory integrands, and the Fundamental Theorem of Calculus.
load("numerics")$
load("ax-plots")$
Exact Symbolic Integration¶
Maxima computes closed-form antiderivatives using its powerful symbolic engine. No discretisation, no approximation -- just exact algebra.
/* Polynomial: integral of x^2 from 0 to 1 */
exact1 : integrate(x^2, x, 0, 1);
/* Trigonometric: integral of sin(x) from 0 to pi */
exact2 : integrate(sin(x), x, 0, %pi);
1/3
Numeric Approximation with np_trapz¶
The trapezoidal rule approximates the integral by summing trapezoids
under a sampled curve. With np_linspace we create a grid, evaluate
the function, and feed both arrays to np_trapz.
/* Approximate integral of x^2 on [0,1] with 10 points */
xs : np_linspace(0, 1, 10)$
ys : np_pow(xs, 2)$
numeric1 : np_trapz(ys, xs);
print("Exact:", 1/3, " Numeric:", numeric1)$
0.3353909465020576 Exact: 1/3 Numeric: 0.3353909465020576
/* Approximate integral of sin(x) on [0, pi] with 50 points */
xs2 : np_linspace(0, float(%pi), 50)$
ys2 : np_map(sin, xs2)$
numeric2 : np_trapz(ys2, xs2);
print("Exact: 2", " Numeric:", numeric2)$
1.9993148493240624 Exact: 2 Numeric: 1.9993148493240624
Convergence Study¶
How does the trapezoidal error decrease as we add more sample points? For $f(x) = e^{-x^2}$ on $[0, 3]$, the trapezoidal rule has error $O(h^2) = O(1/n^2)$. We verify this by computing the error at several resolutions and plotting on a log-log scale.
/* Exact value via symbolic integration + float conversion */
exact_gauss : float(integrate(exp(-t^2), t, 0, 3))$
print("Exact integral of exp(-x^2) on [0,3]:", exact_gauss)$
/* Sweep over increasing number of points */
ns : [10, 20, 50, 100, 200, 500, 1000]$
errors : makelist(
block([xg, yg, approx],
xg : np_linspace(0, 3, ns[i]),
yg : np_map(lambda([z], exp(-z^2)), xg),
approx : np_trapz(yg, xg),
abs(approx - exact_gauss)),
i, 1, length(ns))$
print("Errors:", errors)$
Exact integral of exp(-x^2) on [0,3]: 0.8862073482595211
Errors:
[6.495944890105854e-6,1.5194130239537529e-6,2.308643267667776e-7,
5.663598212635179e-8,1.402189420129929e-8,2.2302486524239384e-9,
5.564541050162575e-10]
/* Log-log convergence plot */
log_ns : map(lambda([n], float(log(n))), ns)$
log_errs : map(lambda([e], float(log(e))), errors)$
ax_draw2d(
color=blue, name="measured error",
points(log_ns, log_errs),
color=red, dash="dash", name="O(1/n^2) reference",
lines([float(log(10)), float(log(1000))],
[log_errs[1], log_errs[1] - 2*(float(log(1000))-float(log(10)))]),
title="Trapezoidal Rule Convergence",
xlabel="log(n)", ylabel="log(error)", grid=true
)$
Integrating Special Functions¶
Maxima can evaluate improper integrals that would be difficult or impossible to compute numerically. For example, $\int_0^\infty \frac{1}{1+x^4}\,dx$ has an exact closed form involving radicals.
/* Exact symbolic result for an improper integral */
exact_special : integrate(1/(1+x^4), x, 0, inf);
print("Exact:", float(exact_special))$
/* Numeric approximation on [0, 100] (truncated tail) */
xs3 : np_linspace(0, 100, 5000)$
ys3 : np_map(lambda([z], 1/(1+z^4)), xs3)$
print("np_trapz on [0,100]:", np_trapz(ys3, xs3))$
%pi/2^(3/2) Exact: 1.1107207345395913 np_trapz on [0,100]: 1.110720401206242
Oscillatory Integrals¶
When the integrand oscillates rapidly, numeric methods need many sample
points to avoid aliasing. Symbolic integration handles this effortlessly.
We compare np_trapz at two resolutions for $g(x) = \sin(10x)\,e^{-x}$.
/* Exact symbolic integral of sin(10*x)*exp(-x) on [0, 2*pi] */
exact_osc : float(integrate(sin(10*t)*exp(-t), t, 0, 2*%pi));
/* Numeric with n=100 (under-resolved) vs n=1000 */
xo1 : np_linspace(0, float(2*%pi), 100)$
yo1 : np_map(lambda([z], sin(10*z)*exp(-z)), xo1)$
xo2 : np_linspace(0, float(2*%pi), 1000)$
yo2 : np_map(lambda([z], sin(10*z)*exp(-z)), xo2)$
print("n=100:", np_trapz(yo1, xo1),
" n=1000:", np_trapz(yo2, xo2))$
0.09882500567012793 n=100: 0.09545259472279734 n=1000: 0.09879210054768726
/* Plot the oscillatory integrand with shaded area */
xp : np_linspace(0, float(2*%pi), 500)$
yp : np_map(lambda([z], sin(10*z)*exp(-z)), xp)$
ax_draw2d(
color=blue, fill="tozeroy", opacity=0.3,
name="sin(10x) exp(-x)",
lines(xp, yp),
title="Oscillatory Integrand",
xlabel="x", ylabel="g(x)", grid=true
)$
The Fundamental Theorem of Calculus¶
The FTC says $\frac{d}{dx}\int_0^x f(t)\,dt = f(x)$.
We verify this two ways: first symbolically — Maxima integrates
$1/(1+t^2)$ to get $\arctan(x)$, then differentiates to recover the
integrand — and then numerically — we accumulate np_trapz values
at many points, take finite differences, and compare against $f(x)$.
/* Symbolic FTC: integrate then differentiate */
assume(x > 0)$
F_sym : integrate(1/(1+t^2), t, 0, x);
result : diff(F_sym, x);
is(ratsimp(result - 1/(1+x^2)) = 0);
atan(x) 1/(x^2+1)
/* Numeric FTC: accumulate trapezoid sums F(x_k), then
approximate F'(x_k) with finite differences */
npts : 500$
xf : np_linspace(0, 5, npts)$
yf : np_map(lambda([z], 1/(1+z^2)), xf)$
y_list : np_to_list(yf)$
/* F(x_k) = cumulative trapezoid sum from 0 to x_k */
dx : 5.0 / (npts - 1)$
F_vals : [0.0]$
for k : 2 thru npts do
F_vals : endcons(last(F_vals) + dx * (y_list[k-1] + y_list[k]) / 2, F_vals)$
/* Numeric derivative: dF/dx via central differences */
dFdx : makelist(
if i = 1 then (F_vals[2] - F_vals[1]) / dx
elseif i = npts then (F_vals[i] - F_vals[i-1]) / dx
else (F_vals[i+1] - F_vals[i-1]) / (2*dx),
i, 1, npts)$
/* Compare against exact f(x) = 1/(1+x^2) */
x_list : np_to_list(xf)$
ax_draw2d(
color="steelblue", line_width=2, name="f(x) = 1/(1+x^2)",
lines(x_list, y_list),
color="red", dash="dash", line_width=2, name="d/dx [trapz sum]",
lines(x_list, dFdx),
title="FTC Verification: Numeric Derivative of Numeric Integral",
xlabel="x", ylabel="f(x)", grid=true
)$
Summary¶
- Symbolic integration (
integrate) gives exact, closed-form answers for a wide class of integrands, including improper integrals and special functions. - Numeric integration (
np_trapz) is useful when symbolic methods fail, when data is empirical or tabulated, or when a quick numerical check is needed. Its accuracy improves as $O(1/n^2)$. - Maxima's symbolic-numeric bridge lets you derive formulas symbolically, then validate or visualise them numerically -- the best of both worlds.