Notebook for 2023-03-08
Basic QR iteration
The basic QR iteration is
$$\begin{align*} A^{(k)} &= Q^{(k)} R^{(k)} \\ A^{(k+1)} &= R^{(k)} Q^{(k)} \end{align*}$$
sympart (generic function with 1 method)
10×10 Matrix{Float64}:
0.349856 0.52095 0.421871 0.460524 … 0.350273 0.401769 0.337866 0.224796
0.52095 0.652474 0.377681 0.651064 0.678696 0.678326 0.695169 0.371226
0.421871 0.377681 0.973693 0.479816 0.545122 0.691404 0.280855 0.245604
0.460524 0.651064 0.479816 0.177518 0.766478 0.355246 0.0976494 0.591847
0.526778 0.738552 0.268403 0.392175 0.549213 0.36241 0.238191 0.712749
0.879979 0.273363 0.897537 0.549474 … 0.934543 0.151518 0.627998 0.512173
0.350273 0.678696 0.545122 0.766478 0.230484 0.369452 0.471768 0.526793
0.401769 0.678326 0.691404 0.355246 0.369452 0.700768 0.478094 0.646642
0.337866 0.695169 0.280855 0.0976494 0.471768 0.478094 0.815433 0.254728
0.224796 0.371226 0.245604 0.591847 0.526793 0.646642 0.254728 0.615335
naive_qr_iteration (generic function with 1 method)
Remarkably enough, the basic iteration does converge! But it takes some time.
test_naive_qr (generic function with 1 method)
Hessenberg reduction
The first step for fast QR iteration is reduction to upper Hessenberg form, i.e.
$$H = Q^T A Q$$
where $Q$ is an orthogonal matrix. As described in the notes, we can do this via Householder transformations. It is possible (as with ordinary QR) to save the vectors defining the Householder transformation where we have zeros, but we are not going to bother. Instead, we'll form $Q$ explicitly by accumulating the Householder transformations.
householder (generic function with 1 method)
my_hessenberg (generic function with 1 method)
6.15438e-16
0.0
2.08533e-15
Bidiagonalization
The bidiagonal reduction involves computing
$$U^T A V = B$$
where $B$ is an upper bidiagonal matrix. We compute it via a sequence of interleaved Householder transformations on the left and right.
my_bidiagonalization (generic function with 1 method)
5.95399e-16
0.0
0.0
2.84586e-15
1.84655e-15