请用Python写一个svd算法,不用numpy库
时间: 2024-03-28 09:11:25 浏览: 81
著名 SVD算法的python快速实现_推荐算法_python_代码_下载
很高兴为您解答问题。以下是使用Python编写SVD算法的代码,不使用numpy库。
```python
def svd(A):
# 首先计算A的转置矩阵
ATA = [[0]*len(A) for i in range(len(A))]
for i in range(len(A)):
for j in range(len(A)):
for k in range(len(A[0])):
ATA[i][j] += A[k][i]*A[k][j]
# 利用Jacobi方法求ATA的奇异值与奇异向量
def jacobi(A):
EPSILON = 1e-10
n = len(A)
S = [[0]*n for i in range(n)]
for i in range(n):
S[i][i] = 1
changed = True
while changed:
changed = False
for i in range(n):
for j in range(i+1, n):
if abs(A[i][j]) > EPSILON:
changed = True
tau = (A[j][j] - A[i][i]) / (2*A[i][j])
t = 1 / (abs(tau) + math.sqrt(1 + tau*tau))
if tau < 0:
t = -t
c = 1 / math.sqrt(1 + t*t)
s = c*t
for k in range(n):
A_ik = A[i][k]
A_jk = A[j][k]
A[i][k] = c*A_ik - s*A_jk
A[j][k] = s*A_ik + c*A_jk
S_ik = S[i][k]
S_jk = S[j][k]
S[i][k] = c*S_ik - s*S_jk
S[j][k] = s*S_ik + c*S_jk
return A, S
ATA, V = jacobi(ATA)
# 根据V求解A的奇异向量
U = [[0]*len(A) for i in range(len(A[0]))]
for i in range(len(A[0])):
for j in range(len(A)):
U[i][j] = V[j][i]
# 计算S
S = []
for i in range(len(A[0])):
s = math.sqrt(sum([U[i][k]**2 for k in range(len(A))]))
S.append(s)
for k in range(len(A)):
U[i][k] /= s
return U, S, V
```
希望对您有所帮助!
阅读全文