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

C++ 为什么用Eigen和OpenCV计算的SVD左奇异向量有不同的符号,c++,algorithm,opencv,math,eigen,C++,Algorithm,Opencv,Math,Eigen,我使用OpenCV和Eigen计算SVD: Eigen: JacobiSVD<Matrix3f> svd(myM, ComputeFullU); OpenCV: cvSVD(&myM, &w, &u, 0, CV_SVD_MODIFY_A | CV_SVD_U_T); 尽管一个是浮点型,另一个是双类型,但计算出的左奇异向量具有不同的符号。因此,我的问题是: 这种符号的差异真的重要吗 如何使它们相同 不,没关系,因为相应的符号差也会出现在右边的奇异向量上,所

我使用OpenCV和Eigen计算SVD:

Eigen:
JacobiSVD<Matrix3f> svd(myM, ComputeFullU);

OpenCV:
cvSVD(&myM, &w, &u, 0, CV_SVD_MODIFY_A | CV_SVD_U_T);
尽管一个是浮点型,另一个是双类型,但计算出的左奇异向量具有不同的符号。因此,我的问题是:

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

    U * S * V^adjoint
    
    会给你正确的结果

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

    非退化奇异值总是具有唯一的左和右奇异值 右奇异向量,最多乘以单位相位因子
    exp(iφ)
    (适用于实际情况,直至签字)。因此,如果M的所有奇异值都是非退化且非零的,则其奇异值 分解是唯一的,直到U列乘以a 单位相位因子和相应相位的同时相乘 V列采用相同的单位相位系数

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

  • 由于奇异值的顺序,可能还会出现额外的差异,afaik特征值按降序排列,但不确定opencv


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

    一个明显的例子是,对于
    M=U∑V*
    ,分解方式类似于
    M=(-U)∑(-V*)=U∑V*
    ,但一般来说,左右奇异向量可以有不同的符号组合

    这种差异其实并不重要,所以我认为你不应该费心去尝试使它们相同

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

    U * S * V^adjoint