Note: scipy.linalg
, not numpy.linalg
!
import numpy as np
import scipy.linalg as la
import matplotlib.pyplot as pt
n = 100
A0 = np.random.randn(n, n)
U0, sigma0, VT0 = la.svd(A0)
print(la.norm((U0*sigma0)@VT0 - A0))
sigma = np.exp(-np.arange(n))
A = (U0 * sigma).dot(VT0)
2.654266110213982e-13
Compute the QR factorization with pivoting=True
.
Q, R, perm = la.qr(A, pivoting=True)
First of all, check that we've obtained a valid factorization
la.norm(A[:, perm] - Q@R, 2)
6.317156500391685e-16
la.norm(Q@Q.T - np.eye(n))
7.773451587511033e-15
Next, examine $R$:
pt.imshow(np.log10(1e-15+np.abs(R)))
pt.colorbar()
<matplotlib.colorbar.Colorbar at 0x7f33a92b6fd0>
Specifically, recall that the diagonal of $R$ in QR contains column norms:
pt.semilogy(np.abs(np.diag(R)))
[<matplotlib.lines.Line2D at 0x7f33ad9f27d0>]
scipy
's transform, diagonal entries of $R$ are guaranteed non-increasing.