【问题标题】:Eigen Library : Different behaviors between static and dynamic size matrices when computing inverse特征库:计算逆时静态和动态大小矩阵之间的不同行为
【发布时间】:2017-03-12 20:04:27
【问题描述】:

在计算小 float 矩阵的逆时,我从 Eigen 库中遇到了一些奇怪的行为。我发现对静态和动态矩阵大小使用相同数据之间存在意想不到的差异。

更令人惊讶的是,与我使用double 矩阵得到的结果相比,似乎只有动态版本才能提供令人满意的结果。

那么我在这里错过了什么?这是否意味着我应该在所有情况下都使用动态版本?这不可能是对的。

这是一个代码示例,使用 Visual Studio 2012,Release,x64 编译。

#include <iostream>
#include <Eigen/Dense>

int main()
{
    //some static size 4x3 matrix
    Eigen::Matrix<float,4,3> m;
    m <<
        -166.863f,  -172.49f,   -172.49f,
        107.422f,   101.71f,    107.422f,
        708.306f,   706.599f,   708.029f,
        1.0f,       1.0f,       1.0f ;

    //same but dynamic size
    Eigen::MatrixXf mx = m;

    //first result
    std::cout << (m.transpose()*m).inverse()  << std::endl << std::endl ;
    /*
        0.00490293 0.000445721 -0.00533875
        0.000445721  0.00502179  -0.0054378
        -0.00533875  -0.0054378   0.0107567
    */

    //second result, completely different from the first one
    std::cout << (mx.transpose()*mx).inverse() << std::endl << std::endl ;
    /*
        0.0328157 0.00291519 -0.0356753
        0.00287851  0.0337197  -0.036493
        -0.0356387 -0.0365297  0.0720099
    */

    //third result, same as the second one, only small differences due to better accuracy
    std::cout << (m.transpose()*m).cast<double>().inverse() << std::endl << std::endl ;
    /*
        0.032961 0.00297425 -0.0358793
        0.00297425  0.0337394 -0.0366082
        -0.0358793 -0.0366082  0.0723284
    */

    //the condition number of the inversed matrix is quite huge if that matters : 175918
    Eigen::JacobiSVD<Eigen::MatrixXf> svdF(m.transpose()*m);
    std::cout << svdF.singularValues()(0) / svdF.singularValues()(svdF.singularValues().size()-1) << std::endl;
}

【问题讨论】:

    标签: c++ matrix eigen eigen3 matrix-inverse


    【解决方案1】:

    如 Eigen 所述,inverse 对小型固定矩阵(最大 4x4)使用不同的算法。

    对于小的固定矩阵,Eigen 使用cofactors 方法(Cramers 规则)。这种方法是基于行列式的计算,它是通过减去乘积来计算的。对于高条件数和/或低浮点精度,您会获得高相对误差。

    对于其他矩阵,Eigen 使用 Partial Pivoting LU 分解,比 cofactors 方法更稳定。

    【讨论】:

    • 我期待这样的事情,但我不明白为什么 Eigen 在已知矩阵大小时使用不稳定算法。拥有有关矩阵的更多信息只会改善事情。或者这只是速度/质量的权衡?
    • 这确实是速度和质量之间的权衡。本征有much more methods计算逆,各有优缺点。
    • 我明白了。我想这就是为什么关注速度的openGL matrix inverse 对于不可逆矩阵和条件差矩阵都没有定义的原因。
    猜你喜欢
    • 1970-01-01
    • 2019-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多