为什么用Eigen和OpenCV计算的SVD左奇异向量具有不同的符号

Why SVD left singular vectors computed with Eigen and OpenCV have different signs

本文关键字:向量 符号 Eigen OpenCV SVD 计算 为什么      更新时间:2023-10-16

我使用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类型,但计算的左奇异向量具有不同的符号。所以我的问题是:

  1. 这种符号差异真的重要吗
  2. 如何使它们相同
  1. 不,这没关系,因为相应的符号差也会出现在右边的奇异向量上,所以基本上

    U * S * V^adjoint
    

    会给你正确的结果。

    更确切地说,来自维基百科:

    非退化奇异值总是具有唯一的左和右奇异向量,直到与单位相位因子相乘exp(iφ)(对于实际情况,向上签名)。因此,如果M的所有奇异>值都是非退化且非零的,则其奇异值分解是唯一的,直到U的一列乘以单位相位因子和相应的V列的相同单位相位因子。

  2. 你为什么要它们一模一样?如果你真的想要,你可以通过除以第一个分量来获得相位,然后通过乘以该相位来使它们相等。

  3. 由于奇异值的排序,也可能出现额外的差异,afaik特征值按降序排序,不确定opencv。

奇异值分解不是唯一的,有多种可能的分解。奇异值的实际集合是唯一的,但向量的左矩阵和右矩阵可以有不同的符号,这无关紧要,因为多个组合符号可以抵消。

一个明显的例子是,对于M = UΣV*,像M=(-U)Σ(-V*) = UΣV*一样分解,但通常情况下,左右奇异向量可以有不同的符号组合。

这种差异其实并不重要,所以我认为你不应该试图让它们相同。

不仅如此,奇异向量的阶数也可以变化。通常,它是按照奇异值的降序排列的。