gpt4 book ai didi

c++ - 为什么 Armadillo 的 SVD 结果与 NumPy 不同?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:36:57 56 4
gpt4 key购买 nike

在我的 Python 代码中,我使用 numpy.linalg.svd 计算一些数据的 SVD :

from numpy import linalg
(_, _, v) = linalg.svd(m)

由此返回的 V 矩阵是:

[[ 0.4512937  -0.81992002 -0.35222884]
[-0.22254721 0.27882908 -0.93419863]
[ 0.86417981 0.4999855 -0.05663711]]

在将我的代码移植到 C++ 时,我切换到使用 Armadillo用于计算 SVD:

#include <armadillo>

arma::fmat M; // Input data
arma::fmat U;
arma::fvec S;
arma::fmat V;
arma::svd(U, S, V, M);

相同数据的结果 V 是:

  0.4513  -0.2225  -0.8642
-0.8199 0.2788 -0.5000
-0.3522 -0.9342 0.0566

我们可以看到 Armadillo 中 V 的转置与 NumPy 中的 V 匹配。除此之外,对于 Armadillo 的 V 的最后一列。这些值与 NumPy 结果最后一行中的值的符号相反。

这里发生了什么?为什么两个流行库的 SVD 结果会有这样的不同?两者中哪一个是正确的结果?

最佳答案

两者都是正确的......你从 numpy 得到的 v 的行是 M.dot(M.T) 的特征向量(转置将是共轭转置在复杂的情况下)。在一般情况下,特征向量仅定义为乘法常数,因此您可以将 v 的任意行乘以不同的数字,它仍然是一个特征向量矩阵。

v 有额外的限制,它是一个 unitary matrix ,这松散地转化为它的行是正交的。这会将每个特征向量的可用选择减少到只有 2 个:指向任一方向的归一化特征向量。但是您仍然可以将任何行乘以 -1,并且仍然有一个有效的 v

如果你想为你的矩阵测试它,我已经加载为a:

>>> u, d, v = np.linalg.svd(a)
>>> D = np.zeros_like(a)
>>> idx = np.arange(a.shape[1])
>>> D[idx, idx] = d
>>> np.allclose(a, u.dot(D).dot(v))
True
>>> v[2] *= -1
>>> np.allclose(a, u.dot(D).dot(v))
True

实际上,在实域中,您只能将v的行乘以-1,但在复数情况下,您可以将它们乘以任何绝对值为1的复数:

>>> vv = v.astype(np.complex)
>>> vv[0] *= (1+1.j)/np.sqrt(2)
>>> np.allclose(a, u.dot(D).dot(v))
True

关于c++ - 为什么 Armadillo 的 SVD 结果与 NumPy 不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20112490/

56 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com