$\begin{matrix} \text{The matrix} \\ \text{A} \end{matrix}$ $\begin{matrix} \text{Orthogonal basis for} \\ \text{column space of A} \end{matrix}$ $\begin{matrix} \text{Singular} \\ \text{values of A} \end{matrix}$ $\begin{matrix} \text{Orthogonal basis for} \\ \text{row space of A} \end{matrix}$
$\: \: \: \left[ \begin{matrix} \\ \\ A \\ m\times n \\ \\ \end{matrix} \right] \: \: = \: \:$ $\left[ \begin{matrix} \\ \\ \quad \quad U \quad \quad \\ m\times m \\ \\ \end{matrix} \right] \quad$ $\left[ \begin{matrix} \\ \\ \sum \\ m\times n \\ \\ \end{matrix} \right] \quad \quad$ $\left[ \begin{matrix} \\ \quad V^T \quad \\ n\times n \\\end{matrix} \right] $
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
ein = Image.open('einstein.jpg')
print(np.shape(ein))
ein = np.mean(ein,2) # 2: 3rd dimention: 3 colors (rgb)
print(np.shape(ein))
plt.imshow(ein)
plt.show()
U,s,V = np.linalg.svd(ein) # U: matrix, s: singular value, V: matrix
print(np.shape(U)) # square matrix
print(np.shape(s)) # vector
print(np.shape(V)) # square matrix
fig,ax = plt.subplots(1,3)
ax[0].imshow(U)
ax[0].set_title('U')
ax[1].imshow(np.diag(np.log(s)))
ax[1].set_title('$\\Sigma$')
print(s)
print(np.log(s))
ax[2].imshow(V)
ax[2].set_title('V')
plt.show()
plt.plot(s,'ks-',markerfacecolor='w')
plt.xlim([-1,50])
plt.title('Eigenspectrum of Einstein')
plt.show()
Reconstruct the image from the SVD.
S = np.zeros(np.shape(ein))
for i in range(0,len(s)):
S[i,i] = s[i] # diagonalize
rein = U@S@V
plt.subplot(1,2,1)
plt.imshow(ein)
plt.axis('off')
plt.title('original')
plt.subplot(1,2,2)
plt.imshow(rein)
plt.axis('off')
plt.title('SVD version')
plt.show()
Reconstruct the image but shuffle the singular values.
# shuffle the order of the singular values
randorder = np.random.permutation(len(s))
print(np.random.permutation(5))
print(randorder)
S = np.zeros(np.shape(ein))
for i in range(0,len(s)):
S[i,i] = s[randorder[i]] # diagonalize
rein = U@S@V
plt.subplot(1,2,1)
plt.imshow(ein)
plt.axis('off')
plt.title('original')
plt.subplot(1,2,2)
plt.imshow(rein)
plt.axis('off')
plt.title('SVD version')
plt.show()
Partially reconstruct the image using the first N components.
S = np.zeros(np.shape(ein))
for i in range(10,len(s)):
S[i,i] = s[i]
rein = U@S@V
plt.subplot(1,2,1)
plt.imshow(ein)
plt.axis('off')
plt.title('original')
plt.subplot(1,2,2)
plt.imshow(rein)
plt.axis('off')
plt.title('SVD version')
plt.show()