Eigen :: map是否真的具有“视图”语义

时间:2016-12-06 18:34:55

标签: c++ smart-pointers eigen eigen3

我想用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 inverse\n";
for (int i = 0; i < 10; ++i)
    std::cout<<p[i]<<std::endl;
}

我有问题1,因为此thread中接受的答案表明存在一些副本,但原则上“视图”不应复制任何内容。

我有问题2,因为否则结果不符合预期,但是这不像“视图”(也见answer),如果我真的需要分配回来

2 个答案:

答案 0 :(得分:3)

广告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(),它就会计算一个反转。

答案 1 :(得分:0)

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