【发布时间】:2013-11-21 04:28:27
【问题描述】:
在我的 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 相匹配。除此之外,对于犰狳的 V 的最后一列。这些值与 NumPy 结果最后一行中的值符号相反。
这里发生了什么?为什么两个流行库的 SVD 结果如此不同?两者中哪一个是正确的结果?
【问题讨论】:
-
您应用 SVD 的原始矩阵是什么?你能保证它在两个系统之间是相同的吗?通常唯一的区别可能是特征向量的比例......
-
@AlexanderL.Belikoff:是的,输入数据是相同的。在 C++ 中,类型是浮点数,而在 Python 中,我猜是双精度数。但是,这种精度差异应该无关紧要吗?
-
从技术上讲,SVD 分解不是唯一的(不确定符号的变化)。除此之外,可能两者之一是返回 V* 而不是 V,因此是转置。此外,在实数方阵的 SVD 中,会产生一个 U 和一个 V,它们都是旋转矩阵,
armadillo是正确的。你能发布你的原始矩阵吗? -
@sbabbi:输入矩阵不是正方形的。在此分享:pastebin.com/bPgKER7E
-
犰狳返回
V,而numpy返回V*。至于符号的变化,我不知道,但可能两个结果都是正确的,V中的符号变化被U中的另一个平衡。您可以计算 USV 并检查它是否等于原始矩阵。
标签: c++ python numpy linear-algebra armadillo