import numpy as np
import numpy.linalg as la
np.set_printoptions(precision=4, linewidth=100)
A = np.random.randn(5, 3)
Now compute the SVD of $A$. Note that numpy.linalg.svd
returns $V^T$:
U, singval, VT = la.svd(A)
V = VT.T
Let's first understand the shapes of these arrays:
print(U.shape)
print(singval.shape)
print(V.shape)
Check the orthogonality of $U$ and $V$:
U.T.dot(U)
V.T.dot(V)
Now build the matrix $\Sigma$:
Sigma = np.zeros(A.shape)
Sigma[:3, :3] = np.diag(singval)
Sigma
Now piece $A$ back together from the factorization:
U.dot(Sigma).dot(V.T) - A
Next, compute the pseudoinverse:
SigmaInv = np.zeros((3,5))
SigmaInv[:3, :3] = np.diag(1/singval)
SigmaInv
A_pinv = V.dot(SigmaInv).dot(U.T)
Now use the pseudoinverse to "solve" $Ax=b$ for our tall-and-skinny $A$:
b = np.random.randn(5)
A_pinv.dot(b)
Compare with the solution from QR-based Least Squares:
Q, R = la.qr(A, "complete")
la.solve(R[:3], Q.T.dot(b)[:3])