【问题标题】:How to compute basis of nullspace with Eigen library?如何用 Eigen 库计算零空间的基础?
【发布时间】:2016-01-07 18:51:52
【问题描述】:

如何利用特征库计算矩阵的零空间基数

我试图找到 explicit function name 来计算 null 基础,并作为一种解决方法,找到 计算矩阵的 rref 的方法(因为我们能够从 rref 获取空基)。

但我找不到任何相关的函数名称。

我认为必须有解决方案,但我对 Eigen 库了解不多,而且 Eigen 的代码也很难理解。

请给我建议这个问题的解决方案。

【问题讨论】:

  • @OldProgrammer 您是否指出这不是编码问题?抱歉,我不明白你想指出什么。
  • 您确定需要 rref 吗?你的实际问题是什么?线性最小二乘法?
  • @kchoose2 我想计算空空间的基础。不只是投射到零空间。

标签: c++ linear-algebra eigen


【解决方案1】:

您可以使用Eigen::FullPivLU::kernel() 方法获得空空间的基础:

FullPivLU<MatrixXd> lu(A);
MatrixXd A_null_space = lu.kernel();

【讨论】:

    【解决方案2】:

    FullPivLU 在 Eigen 中的计算成本最高,http://eigen.tuxfamily.org/dox/group__DenseDecompositionBenchmark.html

    更快的替代方法是使用 CompleteOrthogonalDecomposition。此代码使用矩阵的四个基本子空间(google 四个基本子空间和 URV 分解):

    Matrix<double, Dynamic, Dynamic> mat37(3,7);
    mat37 = MatrixXd::Random(3, 7);
    
    CompleteOrthogonalDecomposition<Matrix<double, Dynamic, Dynamic> > cod;
    cod.compute(mat37);
    cout << "rank : " << cod.rank() << "\n";
    // Find URV^T
    MatrixXd V = cod.matrixZ().transpose();
    MatrixXd Null_space = V.block(0, cod.rank(),V.rows(), V.cols() - cod.rank());
    MatrixXd P = cod.colsPermutation();
    Null_space = P * Null_space; // Unpermute the columns
    // The Null space:
    std::cout << "The null space: \n" << Null_space << "\n" ;
    // Check that it is the null-space:
    std::cout << "mat37 * Null_space = \n" << mat37 * Null_space  << '\n';
    

    【讨论】:

    • 感谢您的回答 (+1)。你知道我们是否可以通过这种分解得到矩阵的图像(列空间)?
    • 使用 MatrixXd = cod.matrixQ() 提取 Q 矩阵;并且前 r 列,其中 r 是秩(您可以使用 cod.rank() 提取它)是矩阵的列空间。
    • 是的,我同时找到了方法:scicomp.stackexchange.com/q/36308/14840>。抱歉,我应该通知你的。
    • 这不适用于复数(例如 std::complex),而接受的答案可以。任何人都可以提议对复杂矩阵进行编辑吗?
    • 如果我们在MatrixXd V = cod.matrixZ().transpose(); -> MatrixXd V = cod.matrixZ().transpose().conjugate(); 行使用共轭,它似乎适用于复数。不确定,我们能否对此进行确认?
    【解决方案3】:

    替代方案:使用OpenCV计算零空间:

    `
    cv::Mat EpipolarConstraint::getNullSpace(cv::Mat p)
    {
        cv::SVD svd = cv::SVD(p, cv::SVD::FULL_UV);
        cv::Mat vt_ = svd.vt;
        int i;
        for (i = 1; i <= 3; i++)
        {
            if (p.at<double>(i - 1, i - 1) == 0)
            {
                break;
            }
        }
        cv::Mat result = vt_(cv::Rect(0, i-1, p.cols, vt_.rows-i+1));
        cv::Mat result_t;
        cv::transpose(result, result_t);
        return result_t;
    }`
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-09
      • 1970-01-01
      • 2011-02-28
      • 1970-01-01
      • 2014-04-18
      • 2018-04-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多