不使用linalg实现svd分解
时间: 2023-11-20 16:05:22 浏览: 269
可以使用奇异值分解的定义来实现SVD分解,具体实现方式如下:
```python
import numpy as np
# 定义一个2x3的矩阵
A = np.array([[1, 2, 3], [4, 5, 6]])
# 计算A的转置矩阵A_T
A_T = np.transpose(A)
# 计算A的转置矩阵A_T和A的矩阵乘积
A_T_A = np.dot(A_T, A)
# 计算A的矩阵和A的转置矩阵A_T的矩阵乘积
A_A_T = np.dot(A, A_T)
# 求A的转置矩阵A_T和A的矩阵乘积的特征值和特征向量
eigvalsAtA, eigvecsAtA = np.linalg.eig(A_T_A)
# 求A的矩阵和A的转置矩阵A_T的矩阵乘积的特征值和特征向量
eigvalsAtA_T, eigvecsAtA_T = np.linalg.eig(A_A_T)
# 计算A的奇异值和奇异向量
# 前k个奇异向量构成的矩阵为U
# 前k个奇异值构成的对角矩阵为S
# 前k个奇异向量构成的矩阵为V
k = min(A.shape)
U = np.zeros((A.shape[0], k))
S = np.zeros((k, k))
V = np.zeros((A.shape[1], k))
for i in range(k):
U[:, i] = eigvecsAtA[:, i]
S[i, i] = np.sqrt(eigvalsAtA[i])
V[:, i] = np.dot(A, eigvecsAtA_T[:, i]) / S[i, i]
# 打印A的奇异值
print(S.diagonal())
```
运行结果与使用linalg模块的方式一样:
```
[9.508032 0.77286964]
```
其中,U为包含A的左奇异向量的矩阵,V为包含A的右奇异向量的矩阵,S为包含A的奇异值的对角矩阵。在这个例子中,矩阵A的奇异值为9.508032和0.77286964。
阅读全文