Eigen3:定义可变大小矩阵

Eigen3: defining a variable size matrix

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

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

我更喜欢将维度动态分配给矩阵,因为我处理大型数据集并且我想避免浪费 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;
}

但是我遇到了编译器错误

error: 'p' cannot appear in a constant-expression
error: 'n' cannot appear in a constant-expression

我想这是因为 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 现在是动态矩阵还是固定大小?这样做安全吗?有人可以建议更好的方法吗?

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

获取尺寸
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;
}

顺便说一句,你非常接近,但你过于复杂/想得太多了。在许多(几乎所有)情况下,您可以而且应该真正避免在 C++ 中传递数组大小。它使您的代码更具可读性、更易于维护且不易出错。