SVD与matlab,numpy和pytorch

qzlgjiam  于 2023-04-30  发布在  Matlab
关注(0)|答案(2)|浏览(146)

Matlab

A=[-0.67645626,  0.63071378, -0.27856928;
       -0.02497551,  0.42396278,  2.22727768;
       -0.43153722,  1.20107944,  0.39737373;
       -0.878973  , -1.20829399,  0.40960471]
[x,y,v]=svds(A)

numpy

u_np, s_np, vh_np = np.linalg.svd(a, full_matrices=False, compute_uv=True)

右奇异向量(v)的matlab结果为

-0.0807 -0.1227 0.9892
0.3219  -0.9424 -0.0906
0.9433  0.3111  0.1155

右奇异向量(vh_np)T的numpy的结果为

array([[ 0.08067148, -0.12268262,  0.98916181],
       [-0.32185978, -0.94243885, -0.09063832],
       [-0.94334426,  0.31105947,  0.11551454]])

你能解释一下,符号上有什么不同吗?如果矩阵是方阵,则结果相同。
numpy(Pytorch优先)和matlab的一致结果。我不知道哪一个是正确的。

slwdgvem

slwdgvem1#

numpy.linalg.svd()documentation之后,vh_np的行(同样,vh_np.T的列)是右奇异向量,它们是A^H @ A的特征向量。
本征向量的符号是任意的(例如参见this discussion on Cross Validated),即。即,如果v是特征向量,则-v也是。注意,这不是SVD的性质,而是一般特征向量的性质。与此属性一致,Matlab和Numpy在您的示例中提供了相同的正确解决方案,因为它们仅在第一个向量的符号上有所不同(忽略数值不精确或舍入误差)。
如果你想解决模棱两可的标志,你需要自己去做;例如通过选择它使得最大矢量分量总是正的(这也可能是不明确的,e.例如,如果多个向量分量具有相同的绝对值)。

更新:由于您还要求提供PyTorch解决方案:使用torch.linalg.svd()可以获得相同的结果:

import torch

A = [[-0.67645626,  0.63071378, -0.27856928],
     [-0.02497551,  0.42396278,  2.22727768],
     [-0.43153722,  1.20107944,  0.39737373],
     [-0.878973  , -1.20829399,  0.40960471]]

u_torch, s_torch, vh_torch = torch.linalg.svd(torch.tensor(A))
print(vh_torch.T)
# >>> tensor([[-0.0807, -0.1227,  0.9892],
#             [ 0.3219, -0.9424, -0.0906],
#             [ 0.9433,  0.3111,  0.1155]])

同样,这个解决方案对向量的符号也有同样的模糊性,你需要自己解决。

rseugnpd

rseugnpd2#

Matlab svd返回右奇异向量作为矩阵v的列。
NumPy linalg.svd返回右奇异向量的转置,作为矩阵vh的行。
您可以转置NumPy返回的矩阵vh_np以获得相同的右奇异向量矩阵,并直接比较MATLAB和NumPy的结果:

v_np = vh_np.T

相关问题