Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么犰狳的SVD结果与NumPy不同?_C++_Python_Numpy_Linear Algebra_Armadillo - Fatal编程技术网

C++ 为什么犰狳的SVD结果与NumPy不同?

C++ 为什么犰狳的SVD结果与NumPy不同?,c++,python,numpy,linear-algebra,armadillo,C++,Python,Numpy,Linear Algebra,Armadillo,在我的Python代码中,我使用以下方法计算一些数据的SVD: 由此返回的V矩阵为: [[ 0.4512937 -0.81992002 -0.35222884] [-0.22254721 0.27882908 -0.93419863] [ 0.86417981 0.4999855 -0.05663711]] 将代码移植到C++中,转换为SVD: #include <armadillo> arma::fmat M; // Input data arma::fmat U;

在我的Python代码中,我使用以下方法计算一些数据的SVD:

由此返回的V矩阵为:

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

将代码移植到C++中,转换为SVD:

#include <armadillo>

arma::fmat M; // Input data
arma::fmat U;
arma::fvec S;
arma::fmat V;
arma::svd(U, S, V, M);
我们可以看到,犰狳的V的转置与NumPy的V相匹配。除了犰狳的最后一列V。这些值与NumPy结果最后一行中的值具有相反的符号


这里发生了什么?为什么来自两个流行库的SVD结果会如此不同?这两个结果中哪一个是正确的。。。从numpy获得的
v
行是
M.dot(M.T)
的特征向量(在复杂情况下,转置将是共轭转置)。在一般情况下,特征向量最多只能定义一个乘法常数,因此您可以将
v
的任何一行乘以不同的数字,它仍然是一个特征向量矩阵

v
上还有一个额外的约束,即它是a,它松散地转换为它的行是正交的。这将每个特征向量的可用选项减少到只有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

您应用SVD的原始矩阵是什么?你能保证这两个系统是相同的吗?通常,唯一的区别可能是特征向量的比例。…。@alexander.Belikoff:是的,输入数据是相同的。在C++中,类型是浮点,在Python中,它是双的。但是,精度差异的大小应该无关紧要?从技术上讲,SVD分解不是唯一的(不确定符号tho的变化)。除此之外,两个函数中可能有一个返回V*而不是V,因此是转置。此外,在实方阵的奇异值分解中,产生的U和V都是旋转矩阵,
armadillo
在这方面是正确的。你能发布你的原始矩阵吗?@sbabbi:输入矩阵不是正方形的。它在这里共享:犰狳返回
V
,而numpy返回
V*
。至于符号的变化,我不知道,但可能两个结果都是正确的,而且
V
中的符号变化与
U
中的另一个符号变化是平衡的。您可以计算USV并检查它是否等于原始矩阵。谢谢Jaime!我用v来旋转点,就像在PCA中一样。所以,我想用犰狳的V来做这个没有什么害处?是的,你的轴的对齐方式不会改变,唯一的区别是,在大多数情况下,这不应该是一个相关的问题。请注意,至少在这种情况下,是numpy给出了基础的惯常右手方向。同样,我认为这种差异不应该与调整数据相关。
>>> 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
>>> vv = v.astype(np.complex)
>>> vv[0] *= (1+1.j)/np.sqrt(2)
>>> np.allclose(a, u.dot(D).dot(v))
True