|
|
Gram--Schmidt process
The Gram-Schmidt process is an algorithm to transform an ordered set of vectors into an orthogonal or orthonormal set spanning the same subspace, that is generating the same collection of linear combinations.For n ∈ ℤ, let ℘≤n⟦x⟧ be a vector space of real-valued polynomials of degree at most n. This space is equipped with the inner product \[ \langle f \mid g \rangle = \int_0^1 f(x)\,g(x)\,{\text d}x , \] making it an inner product space. Let us consider the list 𝓜 = (1, x, x², … , xm) for some m ∈ [0..n] = { 0, 1, … , n }. The Gram-Schmidt Orthogonalization Algorithm produces an orthonormal list of vectors 𝓞 = { ω₀, ω₁, … ,⃗ωm } such that span(𝓞) = span(𝓜). We show that \[ \omega_n (x) = \sqrt{2n+1}\,\sum_{k=0}^n (-1)^{k+n} \binom{n}{k} \binom{n+k}{k} x^k . \]
■
Recurrence relation
However, when the initial list is arbitrary and no structural assumptions (such as polynomial degree) are imposed, the Gram–Schmidt process still yields a recurrence, but of a simpler form: a two‑term recurrence expressing each new orthogonal vector as a linear combination of the previous orthogonal vector and the next raw input vector. This recurrence is the algebraic heart of the Gram–Schmidt algorithm and is independent of any special structure of the underlying space.
Let V be an inner‑product space over ℝ or ℂ. Let { vₙ }n≥0 be a linearly independent sequence in V.
Applying Gram–Schmidt produces an orthogonal sequence { ψₙ }n≥0 defined recursively by
We make the Key Observation: Triangularity of the Gram--Schmidt process. The Gram–Schmidt formula shows that ψₙ lies in the span of { v₀, v₁, … ,vₙ }. More importantly, the transformation from the basis { vₙ }n≥0 to the orthogonal basis { ψₙ }n≥0 is upper triangular with nonzero diagonal entries.
This triangularity implies that the inverse transformation is also triangular:
For derivation of the two‑term recurrence, we start from the Gram–Schmidt definition by writing the Gram–Schmidt step as
Now orthogonality forces all coefficients to vanish because { ψₖ } is an orthogonal basis, the only way the above linear combination can vanish is if each coefficient is zero:
- the new input vector vₙ, and
- the immediately preceding orthogonal vector ψn-1.
This recurrence is universal: it holds for any linearly independent sequence { v₀, v₁, … ,vₙ, … } in any inner‑product space. It is the minimal recurrence compatible with orthogonality and triangularity.
The two‑term recurrence \eqref{EqRecurrence} expresses a simple geometric fact: to make vₙ orthogonal to all previous ψₖ, it suffices to remove only its component along ψn-1.
Why? Because the triangular structure ensures that vₙ is already orthogonal to ψ₀, ψ₁, … , ψn-2 after subtracting the ψn-1-component. The Gram–Schmidt projections onto earlier vectors are implicitly encoded in the triangular change‑of‑basis coefficients. Thus, the recurrence is not merely an algebraic convenience; it reflects the geometry of nested subspaces:
The Gram–Schmidt process, when viewed through the lens of triangularity and orthogonality, naturally yields a two‑term recurrence for the orthogonal sequence \{ \psi _n\} . This recurrence is the minimal algebraic structure required to enforce orthogonality at each step and is independent of any special properties of the initial list. In contexts where the initial list has additional structure—such as monomials ordered by degree—the two‑term recurrence expands into the familiar three‑term recurrence of orthogonal polynomials. But at its core, Gram–Schmidt always operates through the same geometric mechanism: subtracting the projection onto the most recently constructed orthogonal direction.
Below is a compact, reusable Mathematica snippet that:
- takes a list of linearly independent vectors vList = { v₀, v₁, … },
- an inner product function ip[.,.],
-
and returns the orthogonal sequence { ψ₀, ψ₁, … } using only the two‑term recurrence.
(* ip[f, g] should implement the inner product ⟨f, g⟩ *) Clear[GramSchmidtTwoTerm]; GramSchmidtTwoTerm[v_List, ip_] := Module[{psi}, psi[0] = v[[1]]; Do[ psi[n] = v[[n + 1]] - (ip[v[[n + 1]], psi[n - 1]]/ip[psi[n - 1], psi[n - 1]]) psi[n - 1] , {n, 1, Length[v] - 1} ]; Table[psi[n], {n, 0, Length[v] - 1}] ]; (* ip[f, g] should implement the inner product ⟨f, g⟩ *) Clear[GramSchmidtTwoTerm]; GramSchmidtTwoTerm[v_List, ip_] := Module[{psi}, psi[0] = v[[1]]; Do[ psi[n] = v[[n + 1]] - (ip[v[[n + 1]], psi[n - 1]]/ip[psi[n - 1], psi[n - 1]]) psi[n - 1] , {n, 1, Length[v] - 1} ]; Table[psi[n], {n, 0, Length[v] - 1}] ];For polynomials with weight w(x) on [𝑎,b], you might defineip[f_, g_] := Integrate[f[x] g[x] w[x], {x, a, b}]; vList = Table[x^n, {n, 0, N}]; psiList = GramSchmidtTwoTerm[vList, ip];This directly realizes the two‑term recurrence in a form you can adapt, extend, or wrap into a package.Example 1: ■End of Example 1
