svd函数编写

作者:Anges
链接:https://www.zhihu.com/question/277311874/answer/1838981558
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

import numpy as np # 本着做一遍才算理解的学习思路,用原生的np.linalg.eig实现了一个简单的svd函数 # 做的过程中也碰到了一些问题,如下做法是错的: # sigma, V = np.linalg.eig(A.T @ A) # sigma, U = np.linalg.eig(A @ A.T) // 错误 # 因为特征值正负号是随机的,所以U和V的特征向量正负号是有某种关联的, # 所以正确的做法是通过U推导VT或者通过VT推导U: A = U @ sigma @ VT def svd(A): m, n = A.shape if m > n: sigma, V = np.linalg.eig(A.T @ A) # 将sigma 和V 按照特征值从大到小排列 arg_sort = np.argsort(sigma)[::-1] sigma = np.sort(sigma)[::-1] V = V[:, arg_sort] # 对sigma进行平方根处理 sigma_matrix = np.diag(np.sqrt(sigma)) sigma_inv = np.linalg.inv(sigma_matrix) U = A @ V.T @ sigma_inv U = np.pad(U, pad_width=((0, 0), (0, m - n))) sigma_matrix = np.pad(sigma_matrix, pad_width=((0, m - n), (0, 0))) return (U, sigma_matrix, V) else: # 同m>n 只不过换成从U开始计算 sigma, U = np.linalg.eig(A @ A.T) arg_sort = np.argsort(sigma)[::-1] sigma = np.sort(sigma)[::-1] U = U[:, arg_sort] sigma_matrix = np.diag(np.sqrt(sigma)) sigma_inv = np.linalg.inv(sigma_matrix) V = sigma_inv @ U.T @ A V = np.pad(V, pad_width=((0, n - m), (0, 0))) sigma_matrix = np.pad(sigma_matrix, pad_width=((0, 0), (0, n - m))) return (U, sigma_matrix, V) if __name__ == "__main__": a = np.array([[12, -5, 7, 62333, 255], [-2, 1, -10, 4, 4], [3, 6, 7, 5, -2]]) U, sigma, V = svd(a) print(U @ sigma @ V)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值