Eigen中无需临时矩阵实现子矩阵重塑与linSpaced向量直接赋值
针对Eigen无临时变量操作的解决方案
嘿,刚上手Eigen的话,想绕开临时变量优化代码是很合理的需求,我来给你拆解这两个问题的具体实现:
主问题:子矩阵复制时直接重塑,无需临时矩阵
Eigen从3.4版本开始提供了reshaped()方法,它返回的是一个表达式模板(不是实际的矩阵对象),可以直接用来赋值给目标矩阵,完全不需要临时变量。举个实际的例子:
假设我们有一个6行2列的源矩阵src,想要把它的前4行子矩阵重塑成3行4列,直接赋值给目标矩阵dest:
#include <Eigen/Dense> int main() { Eigen::MatrixXd src(6, 2); src.setRandom(); // 填充随机值 Eigen::MatrixXd dest(3, 4); // 直接将子矩阵重塑后赋值,无临时矩阵 dest = src.topRows(4).reshaped<Eigen::RowMajor>(3, 4); // 注:RowMajor指定重塑时的内存顺序,如果和目标矩阵布局一致可以省略 return 0; }
如果你用的是Eigen 3.4之前的旧版本,可以用Map来实现类似效果,直接映射子矩阵的内存到目标形状:
// 旧版本替代方案,注意内存布局要匹配,否则会有未定义行为 dest = Eigen::Map<Eigen::MatrixXd>(src.topRows(4).data(), 3, 4);
副问题:生成linSpaced后直接复制到现有矩阵,无需临时向量
Eigen的LinSpaced本身返回的就是一个表达式对象,不是实际的向量,所以我们可以直接把它重塑成目标矩阵的形状后赋值,全程不会产生临时向量。比如要给一个2行3列的矩阵填充0到5的线性间隔值:
#include <Eigen/Dense> int main() { Eigen::MatrixXd dest(2, 3); // 直接生成线性间隔表达式并重塑赋值,无临时向量 dest = Eigen::VectorXd::LinSpaced(dest.size(), 0, 5).reshaped(dest.rows(), dest.cols()); // 这里LinSpaced的第一个参数是总元素数,刚好等于dest的size() return 0; }
本质上,Eigen的表达式模板机制就是为了避免不必要的临时变量,只要你链式调用这些返回表达式的方法(比如reshaped()、LinSpaced、block()等),编译器会自动优化成直接操作内存的代码,完全不需要手动创建临时对象。
内容的提问来源于stack exchange,提问作者Southern.Cross
相关产品推荐
相关产品推荐

