C++ 特征:如何编写一个既可以接受常规(密集)矩阵,又可以接受对角矩阵的函数

C++ Eigen: How to write a function that can both take a regular (dense) Matrix, but also a DiagonalMatrix?

本文关键字:函数 矩阵 密集 一个 既可以 常规 C++ 特征 何编写      更新时间:2023-10-16

我有一个函数可以在内部执行一些线性代数,但我希望能够将常规密集矩阵以及对角矩阵(后者出于效率目的(传递到其中。我尝试了以下语法:

void bla( const Vector* v, const Eigen::MatrixBase<float>* A, Vector* out )
{
  int colunms = A->cols();
  ....
}

但这不会编译,因为 MatrixBase 没有 cols(( 函数!

我知道DiagonalMatrix类有一个toDenseMatrix((函数,但我担心的是这涉及值的内部复制,因此会使我希望从DiagonalMatrix获得的所有优化无效。

我该怎么做?

在任何矩阵上工作的通用特征例程都应该将类模板template<typename Derived> MatrixBase作为参数,它本身将派生自它的矩阵类作为模板参数(即,它使用 CRTP 模式(。所以基本上,你的函数应该以这样的方式设置。

  template<typename Derived>
  void foo(const Eigen::MatrixBase<Derived>& x)
  {
      //do something
  }
在这个函数中,

正如你所注意到的,你只能调用那些在MatrixBase中实际可用的成员函数,而cols()确实不可用。但是,您可以使用成员函数 innerSizeouterSize ,它们根据存储方案分别表现为 ''rows(( and cols(('。在此处阅读详细信息。

但是,如果这些函数不可用,您也可以通过重载函数来获得所需的行为。例如,您可以编写一个采用矩阵并使用上述cols()的一般例程,以及一个对角矩阵的重载,

  template<typename T>
  void foo(const Eigen::DiagonalMatrix<T>& x)
  {
      //do something for diagonal matrices
  }