Eigen3:定义可变大小矩阵
Eigen3: defining a variable size matrix
我想编写一个例程,使用 Eigen3(在 RcppEigen 内)将矩阵的转置创建为行主双矩阵.我主要将它用于不同大小的矩阵。
在 Eigen3 中,模板 Matrix
有 6 个参数:
三项必修:
(标量、RowsAtCompileTime 和 ColsAtCompileTime)
三个可选:
(选项、MaxRowsAtCompileTime 和 MaxColsAtCompileTime)
Options 可以是 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;
}
但是我遇到了编译器错误
error: 'p' cannot appear in a constant-expression
error: 'n' cannot appear in a constant-expression
我想这是因为 n
和 p
在编译时未知。
所以我尝试了这个解决方案
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++ 中传递数组大小。它使您的代码更具可读性、更易于维护且不易出错。
我想编写一个例程,使用 Eigen3(在 RcppEigen 内)将矩阵的转置创建为行主双矩阵.我主要将它用于不同大小的矩阵。
在 Eigen3 中,模板 Matrix
有 6 个参数:
三项必修:
(标量、RowsAtCompileTime 和 ColsAtCompileTime)三个可选:
(选项、MaxRowsAtCompileTime 和 MaxColsAtCompileTime)
Options 可以是 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;
}
但是我遇到了编译器错误
error: 'p' cannot appear in a constant-expression
error: 'n' cannot appear in a constant-expression
我想这是因为 n
和 p
在编译时未知。
所以我尝试了这个解决方案
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++ 中传递数组大小。它使您的代码更具可读性、更易于维护且不易出错。