Projection¶
This notebook accompanies Chapter 2, section on the inner product and projection.
A uniform load $f = 2$ deflects the string into the parabola $u(x) = x(1-x)$, and one blend of the three modes is closest to it in the $L^2$ distance. Closeness by perpendicularity needs angles, and the inner product $\langle f, g \rangle = \int_0^1 f g \, dx$ supplies them. The first lab rotates one unit function against another and shows the inner product as net signed overlap. Green bars mark where the two functions agree in sign, red where they oppose, and at $90$ degrees the two areas cancel exactly.
The best coefficient is a perpendicular drop¶
The second lab projects the parabola onto the three-mode family with $c_2 = 0$ and $c_3 = 8/(27\pi^3)$ held at their best values. Slide $c_1$ and watch the squared error trace a parabola whose minimum sits at $c_1 = 8/\pi^3 = 0.258$, the value the projection formula computes with one division.
The book's numbers¶
The cell below reproduces the section's measured values, the projected coefficients, the orthogonality of the error, the Pythagorean split, and the cost of a mistuned coefficient.
import numpy as np
x = np.linspace(0.0, 1.0, 8001)
parab = x * (1 - x)
modes = [np.sin(k * np.pi * x) for k in (1, 2, 3)]
def inner(f, g):
return np.trapezoid(f * g, x)
c = [2 * inner(parab, m) for m in modes]
best = sum(ck * m for ck, m in zip(c, modes))
e = parab - best
print(f"c1 = {c[0]:.4f} (8/pi^3 = {8/np.pi**3:.4f})")
print(f"c2 = {c[1]:.1e}")
print(f"c3 = {c[2]:.5f} (8/27pi^3 = {8/(27*np.pi**3):.5f})")
print("error orthogonal to each mode:", ", ".join(f"{abs(inner(e, m)):.1e}" for m in modes))
print(f"Pythagoras: ||u||^2 = {inner(parab, parab):.6f} = "
f"{inner(best, best):.6f} + {inner(e, e):.2e}")
print(f"relative L2 error of the best blend: {np.sqrt(inner(e, e)/inner(parab, parab)):.2%}")
mist = 1.2 * c[0] * modes[0] + c[2] * modes[2]
em = parab - mist
print(f"c1 mistuned +20%: error norm ratio = "
f"{np.sqrt(inner(em, em)/inner(e, e)):.1f}x")
c1 = 0.2580 (8/pi^3 = 0.2580) c2 = 0.0e+00 c3 = 0.00956 (8/27pi^3 = 0.00956) error orthogonal to each mode: 1.3e-17, 6.2e-18, 8.5e-18 Pythagoras: ||u||^2 = 0.033333 = 0.033331 + 2.51e-06 relative L2 error of the best blend: 0.87% c1 mistuned +20%: error norm ratio = 23.1x
A Cauchy sequence leaving the continuous functions¶
A finite-dimensional family contains its own closest point. For families with infinitely many shapes, a sequence can improve forever, and the lab below runs one to the edge of a space. Each stage halves the width of a continuous ramp; the members approach one another and the $L^2$ limit is the step, which is not continuous. A space in which every such sequence keeps its limit inside is complete, and a complete inner-product space is a Hilbert space.
A difference at one point weighs nothing¶
The second lab squeezes a spike of fixed height toward a single point. The $L^2$ norm falls toward zero while the peak stays at one, so the limit is the zero function in $L^2$, and a difference at exactly one point has distance zero. An element of $L^2$ has no value at a point, which is why sensor readings need the finite-energy space $H^1$.
# the book's numbers for the Hilbert-spaces section
x = np.linspace(0, 1, 16001)
step = np.where(x < 0.5, 0.0, 1.0)
def ramp(n):
h = 1 / (2 * n)
return np.clip((x - (0.5 - h)) / (2 * h), 0.0, 1.0)
def l2(f):
return np.sqrt(np.trapezoid(f**2, x))
for n in (2, 8, 32):
print(f"ramp n = {n:3d}: distance to step = {l2(ramp(n) - step):.4f} "
f"(exact 1/sqrt(12n) = {1/np.sqrt(12*n):.4f})")
print(f"Cauchy gap ||f_8 - f_32|| = {l2(ramp(8) - ramp(32)):.4f}")
xa = np.linspace(1e-8, 1, 200001)
f_in = xa**(-0.25)
print(f"||x^(-1/4)||_L2 = {np.sqrt(np.trapezoid(f_in**2, xa)):.4f} (exact sqrt(2) = {np.sqrt(2):.4f})")
for eps in (1e-2, 1e-4, 1e-6):
print(f"x^(-1/2): squared norm truncated at eps = {eps:g}: ln(1/eps) = {np.log(1/eps):.1f}")
ramp n = 2: distance to step = 0.2041 (exact 1/sqrt(12n) = 0.2041) ramp n = 8: distance to step = 0.1021 (exact 1/sqrt(12n) = 0.1021) ramp n = 32: distance to step = 0.0510 (exact 1/sqrt(12n) = 0.0510) Cauchy gap ||f_8 - f_32|| = 0.0765 ||x^(-1/4)||_L2 = 1.4219 (exact sqrt(2) = 1.4142) x^(-1/2): squared norm truncated at eps = 0.01: ln(1/eps) = 4.6 x^(-1/2): squared norm truncated at eps = 0.0001: ln(1/eps) = 9.2 x^(-1/2): squared norm truncated at eps = 1e-06: ln(1/eps) = 13.8
What comes next¶
$L^2$ and $H^1$ are complete inner-product spaces, Hilbert spaces, and the projection theorem's closest point exists in them. The chapter turns next to the families themselves, which shapes a description should use and what each choice buys.