Notebooks · posts/make-gram-schmidt-orthogonal-to-rounding
Make Gram-Schmidt orthogonal to rounding
Ten nearly parallel vectors, each plus a tiny in its own direction. Classical Gram-Schmidt turns them into ten "orthonormal" vectors of which two are at 60 degrees: their dot product is 0.5. Rewrite orthonormalize so the vectors it returns are orthogonal to and equal the exact ones to .
Gram-Schmidt builds an orthonormal set one vector at a time: take the next vector, subtract its components along the vectors already made, normalize. It is how Krylov methods (Arnoldi, Lanczos) and deflation build their bases, and it fails when the input is close to dependent. These inputs, the Läuchli vectors, have condition number : after the subtraction what is left of each vector is of size , and the rounding in the subtracted parts, half a unit in the last place of numbers near 1, is then a relative error of or more.
The classical version computes every dot product with the original vector, so the errors of the early projections are never corrected. The modified version recomputes each dot product with the vector as updated so far; on these inputs it reaches , much better but still eight orders of magnitude from rounding, and the tests ask for . Running the orthogonalization a second time on the result (the rule known as "twice is enough") gets there, and so does a QR factorization by Householder reflections.
The expected vectors come from posts/refs/make-gram-schmidt-orthogonal-to-rounding.py,
which runs Gram-Schmidt at 60 digits in mpmath, where rounding does not
matter; it also measures the three double-precision versions.
Look inside this program
- Atlas
The program’s map: every function and which calls which.
There’s no recorded run of this program yet.
This is a problem: its tests fail until the functions in it are written. Edit a cell and run it to try; the cells below it show whether the tests pass.
Shift+Enter in a cell runs it and moves to the next. Running a cell runs every cell above it too, as one program.