Eigen3:定义可变大小矩阵

时间:2018-05-20 02:02:34

标签: c++ dynamic eigen3

我想编写一个例程,使用 Eigen3 (在 RcppEigen 内)创建矩阵转置为行主要双矩阵。在主要内容中,我将它用于不同大小的矩阵。

在Eigen3中,模板Matrix有6个参数:

  • 三个是强制性的:
    (Scalar,RowsAtCompileTime和ColsAtCompileTime)

  • 三个是可选的:
     (Options,MaxRowsAtCompileTime和MaxColsAtCompileTime)
     选项可以是 RowMajor ColMajor

我更喜欢动态地将维度分配给矩阵,因为我使用大型数据集而且我想避免浪费RAM。

所以,我写了以下内容

Eigen::MatrixXd mktrasp(Eigen::MatrixXd X const int n, const int p){
  Eigen::Matrix<double, p, n, RowMajor> T;
  T = X.transpose();
  return T;
}

但我得到了编译器错误

  

错误:'p'不能出现在常量表达式中   错误:'n'不能出现在常量表达式

我想这是因为np在编译时是未知的。

所以我尝试了这个解决方案

Eigen::MatrixXd mktrasp(Eigen::MatrixXd X, const int n, const int p){
  Eigen::Matrix<double, Dynamic, Dynamic, RowMajor> T(p, n);
  T = X.transpose();
  return T;
}

这有效,但我完全失去了情节。 T现在是动态矩阵还是固定大小?这样做安全吗?有人可以提出更好的方法吗?

1 个答案:

答案 0 :(得分:4)

在许多情况下,动态分配数组/矩阵很有意义。除了不过度声称内存的优点之外,我会说最大的优点是矩阵的维度通过代码传播,因为它是矩阵的属性。对于您的示例,您可以随时通过

获取尺寸
A.rows(); // number of rows    (at runtime)
A.cols(); // number of columns (at runtime)
A.size(); // total size of the 'plain storage' (at runtime)

您的示例现在变得像

一样简单
#include <iostream>
#include <Eigen/Eigen>

typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> MatD;

MatD mktrasp(const MatD &X)
{
  return X.transpose();
}

int main()
{
  MatD A = MatD::Random(5,5);

  MatD B = mktrasp(A);

  std::cout << "A = " << std::endl << A << std::endl;
  std::cout << "B = " << std::endl << B << std::endl;
}

如果您想使用某个临时变量(如示例中所示),您还可以使用:

MatD mktrasp(const MatD &X)
{
  // copies the transpose of "X" -> T
  // N.B. the dimensions (and possible other attributes) are also copied
  // you would thus find that "T.rows() == X.cols()"
  // (or if you would do "MatD A = X": "T.rows() == X.rows()")
  MatD T = X.transpose(); 

  return T;
}

BTW你非常接近,但你过度复杂/过度思考。在许多(几乎所有)情况下,您可以而且应该真正避免在C ++中传递数组大小。它使您的代码更易读,更易于维护,并且更不容易出错。