Eigen::map 真的有"view"语义吗



我想用 Eigen 在一些 C 风格的代码中做一些计算,函数接口有一个原始指针如下,

#include <iostream>
#include <memory>
#include <Eigen/Dense>
using namespace Eigen;  
typedef Eigen::Matrix<double, -1, -1, Eigen::RowMajor> Mrow;
void compute_with_Eigen(double * p_data, int row, int col)
{       
// Q1: is there any data copy here?
Eigen::MatrixXd Mc = Eigen::Map<Mrow>(p_data, row, col);
// do computations with Mc, for example
auto M_temp = Mc.inverse();
Mc = M_temp;
// Q2: why is this assign-back necessary?
Eigen::Map<Mrow>( p_data, row, col ) =   Mc;   
}
int main()
{
std::unique_ptr<double[]> p(new double[10]);
for (int i = 0; i < 9; ++i)
{
p[i]=i+1.0;
std::cout<<p[i]<<std::endl;
}
compute_with_Eigen(p.get(),3,3);
std::cout<<"after inversen";
for (int i = 0; i < 10; ++i)
std::cout<<p[i]<<std::endl;
}

我有问题 1,因为此线程中接受的答案表明有一些副本,但是,原则上"视图"不应该复制任何内容。

我有 Question2,因为否则结果与预期不符,但是如果我真的必须重新分配,这不像"视图"(另请参阅此答案)

Ad Q1:

Eigen::MatrixXd Mc = Eigen::Map<Mrow>(p_data, row, col);

这会将临时Map复制到动态矩阵Mc中。如果你想避免该副本,你可以写:

Eigen::Map<Mrow> Mc(p_data, row, col);

广告 Q2:如果您将Mc声明为地图(如上所述),则可以避免该副本。编写时,您正在将值从MatrixXd Mc复制回临时Map

顺便说一句,写作

auto M_temp = Mc.inverse();
Mc = M_temp;

几乎等同于直接写作

Mc = Mc.inverse();

因为auto M_temp实际上不是一个矩阵,而是一个表达式模板,一旦它被分配给实际的矩阵(或调用M_temp.eval(),它就会计算一个逆矩阵。

简短的回答是构造映射对象通常不会复制。但是,下面的计算可能会创建副本或临时副本或两者。

相关内容

  • 没有找到相关文章

最新更新