大矩阵,编译时已知大小,以Eigen.MatrixXd或Matrix<double,n,m&gt? MatrixXd还是Matrix<double, n, m>?

问题描述 投票:0回答:1

我正在使用Eigen编写一些C++线性代数代码。我需要处理一些不太小的矩阵(大于4x4,但小于50x50,如果这很重要的话),它们的大小在编译时是完全已知的。

我很想受益于Eigen库在编译时对矩阵操作进行的大小检查,只要在代码中发生不同大小的矩阵之间的和,就会触发一个错误,然而我也害怕如果我不对那些相对较大的对象进行dinamically分配,可能会对堆栈造成滥用。性能问题并不影响我。

在这里,我想说的是,如果我不对那些比较大的对象进行分配,我可能会滥用堆栈。本征文件 有一个关于固定和动态大小矩阵的简短段落,其中讨论了我之前关注的问题,但不幸的是,没有强调编译时的检查,而我很想维护这些检查。文档中建议。

在可以的情况下,对很小的尺寸使用固定尺寸,而对较大的尺寸或必须使用动态尺寸。

最后,我的问题是:在Eigen中是否有一种方法可以让编译时已知大小的动态分配矩阵,同时保留标准固定大小矩阵的通常编译时检查?

就像这样。

using MyMatrix = MatrixXd<12, 15>; // Currently I can only do Matrix<double, 12, 15>
using MyVector = MatrixXd<14, 1>;
MyMatrix M;
MyVector v;
auto w = M * v; // This should trigger an INVALID_MATRIX_PRODUCT error

其中 MatrixXd<n, m> 是我想使用的假设的动态分配的、编译时已知大小的矩阵!我使用Eigen来编写一些C++线性代数代码。

c++ eigen
1个回答
3
投票

你可以从Eigen类中滥用继承,提供类似矩阵的包装器。

  1. Eigen::Block

    struct MatrixHelper { Eigen::MatrixXd mat; };
    
    template <int Rows, int Cols>
    struct CheckedDynamicMatrix
      : MatrixHelper, Eigen::Block<Eigen::MatrixXd, Rows, Cols>
    {
      using Block = Eigen::Block<Eigen::MatrixXd, Rows, Cols>;
      CheckedDynamicMatrix() :
        MatrixHelper { Eigen::MatrixXd(Rows, Cols) },
        Block { mat.topLeftCorner<Rows, Cols>() }
      {}
    };
    
  2. Eigen::Map

    template <int Rows, int Cols>
    struct CheckedDynamicMatrix
      : Eigen::Map<Eigen::Matrix<double, Rows, Cols>>
    {
      using Map = Eigen::Map<Eigen::Matrix<double, Rows, Cols>>;
      std::unique_ptr<double[]> data;
      CheckedDynamicMatrix() :
        Map { nullptr },
        data { new double[Rows * Cols] }
      {
        new (static_cast<Map*>(this)) Map(data.get(), Rows, Cols);
      }
    };
    

为了实现完整的功能,你还应该添加必要的构造函数和赋值操作符,就像下面描述的那样 Eigen: 继承自矩阵


1
投票

劝也劝不住1 Eigen来实现这两个功能,但你可以动态地分配一个固定大小的矩阵。

using MyMatrix = Matrix<double, 12, 15>;
using MyVector = Matrix<double, 14, 1>;
auto M = std::make_unique<MyMatrix>();
auto v = std::make_unique<MyVector>();
auto w = *M * *v; // compile time error, as desired

脚注1: 没有文档说明如果你设置了 MaxRowsMaxCols 定尺 Matrix所以你可以试试 Matrix<double, 12, 15, 0, Dynamic, Dynamic> 并看看会发生什么,但要注意的行为,可能会改变没有警告,或可能导致未定义的行为。

© www.soinside.com 2019 - 2024. All rights reserved.