3x3 Householder QR Demo¶
This demo constructs a $3\times 3$ QR factorization using Householder reflectors.
In [10]:
import numpy as np
import numpy.linalg as la
In [11]:
n = 3
e1 = np.array([1,0,0])
e2 = np.array([0,1,0])
e3 = np.array([0,0,1])
A = np.random.randn(n, n)
A
Out[11]:
array([[ 1.06427586, 1.03785412, 1.19643376], [-1.06405176, 0.48693156, -0.83335032], [-0.20227028, -1.10857722, 0.27986689]])
Householder reflector: $$I-2\frac{vv^T}{v^Tv}$$
Choose $v=a-\|a\|e_1$.
In [12]:
a = A[:, 0]
v = a-la.norm(a)*e1
H1 = np.eye(3) - 2*np.outer(v, v)/(v@v)
In [13]:
A1 = H1 @ A
A1
Out[13]:
array([[ 1.51848691e+00, 5.33870203e-01, 1.38523070e+00], [ 3.40401588e-16, -6.93719959e-01, -3.91067578e-01], [ 9.99443798e-17, -1.33301245e+00, 3.63942360e-01]])
NB: Never build full Householder matrices in actual code! (Why? How?)
In [14]:
a = A1[:, 1].copy()
a[0] = 0
v = a-la.norm(a)*e2
H2 = np.eye(3) - 2*np.outer(v, v)/(v@v)
In [15]:
R = H2 @ A1
R
Out[15]:
array([[ 1.51848691e+00, 5.33870203e-01, 1.38523070e+00], [ -2.45801147e-16, 1.50272073e+00, -1.42307423e-01], [ -2.55820086e-16, 1.61523465e-16, 5.14914060e-01]])
In [16]:
Q = np.dot(H2, H1).T
la.norm(np.dot(Q, R) - A)
Out[16]:
8.5458331069102901e-16
In [ ]: