forked from SleepyBag/Statistical-Learning-Methods
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SVD.py
66 lines (56 loc) · 1.77 KB
/
SVD.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import numpy as np
import sys
import os
from pathlib import Path
sys.path.append(str(Path(os.path.abspath(__file__)).parent.parent))
from utils import *
def svd(A):
"""
given an m x n matrix,
return the result of SVD,
as a tuple of (U, Sigma, V)
"""
m , n = A.shape
symmetry = A.T @ A
rank = np.linalg.matrix_rank(symmetry)
eigen_values, eigen_vectors = np.linalg.eig(symmetry)
eigen_order = eigen_values.argsort()[::-1]
eigen_values = eigen_values[eigen_order]
eigen_values = eigen_values[: rank]
eigen_vectors = eigen_vectors[:, eigen_order]
# V is of shape [n, n]
V = eigen_vectors
eigen_vectors = eigen_vectors[:, : rank]
singular_values = np.sqrt(eigen_values)
singular_matrix = np.zeros_like(A)
for i, v in enumerate(singular_values):
singular_matrix[i][i] = v
U1 = A @ eigen_vectors / singular_values
U2 = get_solution_domain(row_echelon(A.T))
U = np.concatenate([U1, U2], axis=-1)
return U, singular_matrix, V
if __name__ == '__main__':
def demonstrate(A, desc):
print(desc)
U, singular_matrix, V = svd(A)
print("U is:")
print(U)
print("Singular matrix is:")
print(singular_matrix)
print("V is:")
print(V)
print("The reconstructed matrix is:")
print(U @ singular_matrix @ V.T)
A = np.array([[1, 1],
[2, 2],
[0, 0]]).astype(float)
demonstrate(A, 'Example 1')
A = np.array([[1, 0, 0, 0],
[0, 0, 0, 4],
[0, 3, 0, 0],
[0, 0, 0, 0],
[2, 0, 0, 0]]).astype(float)
demonstrate(A, 'Example 2')
A = np.array([[3, 1],
[2, 1]]).astype(float)
demonstrate(A, 'Example 3')