为什么用Eigen和OpenCV计算的SVD左奇异向量具有不同的符号
Why SVD left singular vectors computed with Eigen and OpenCV have different signs
我使用OpenCV和Eigen来计算SVD:
Eigen:
JacobiSVD<Matrix3f> svd(myM, ComputeFullU);
OpenCV:
cvSVD(&myM, &w, &u, 0, CV_SVD_MODIFY_A | CV_SVD_U_T);
我专注于左奇异向量:
Eigen result:
0.0341698 -0.064916 0.997306
0.950241 -0.307051 -0.0525437
0.309635 0.949476 0.051194
OpenCV result:
[0.03417001163639093, -0.06491612525262211, 0.9973055233913801;
-0.9502414121501213, 0.3070511298822651, 0.05254390804810754;
-0.3096347347112595, -0.9494764348419663, -0.05119404985032185]
尽管一个是float类型,另一个是double类型,但计算的左奇异向量具有不同的符号。所以我的问题是:
- 这种符号差异真的重要吗
- 如何使它们相同
-
不,这没关系,因为相应的符号差也会出现在右边的奇异向量上,所以基本上
U * S * V^adjoint
会给你正确的结果。
更确切地说,来自维基百科:
非退化奇异值总是具有唯一的左和右奇异向量,直到与单位相位因子相乘
exp(iφ)
(对于实际情况,向上签名)。因此,如果M的所有奇异>值都是非退化且非零的,则其奇异值分解是唯一的,直到U的一列乘以单位相位因子和相应的V列的相同单位相位因子。 -
你为什么要它们一模一样?如果你真的想要,你可以通过除以第一个分量来获得相位,然后通过乘以该相位来使它们相等。
-
由于奇异值的排序,也可能出现额外的差异,afaik特征值按降序排序,不确定opencv。
一个明显的例子是,对于M = UΣV*
,像M=(-U)Σ(-V*) = UΣV*
一样分解,但通常情况下,左右奇异向量可以有不同的符号组合。
这种差异其实并不重要,所以我认为你不应该试图让它们相同。
不仅如此,奇异向量的阶数也可以变化。通常,它是按照奇异值的降序排列的。
相关文章:
- 在 std::无符号字符的向量处存储 int 的十六进制表示形式
- 将无符号字符的向量存储在数组中会给我 std::bad_alloc
- 尝试将字符串从文件读取到无符号字符向量中
- 使用192/256位整数求和无符号64位整数向量的点积的最快方法
- 如何使用istream_iterator将无符号字符向量转换为字符串?
- 快速将无符号字符的向量强制转换为POD结构的向量,反之亦然
- C++向量中找到重复的符号
- 将无符号字符的向量写入二进制文件 c++
- 如何确定向量的元素是否交替为符号?
- 自动符号转换,用于对类等数学向量进行操作
- 如何以精度换取速度来评估C++中两个向量的点积符号?(不特定于硬件)
- C++将向量转换为<string>无符号字符数组
- SSE2 内部函数 - 找到两个无符号短向量的最大值
- 您可以将向量<无符号字符>转换为字节[]吗?
- C++ 强制转换向量<无符号字符>到无符号字符 *
- 无符号字符迭代器的向量不起作用
- 将字符串存储在无符号长整型的向量中
- 从int c++的向量返回一个无符号长
- 为什么用Eigen和OpenCV计算的SVD左奇异向量具有不同的符号
- 将 int 数组值传输到无符号向量