【问题标题】:Does Eigen::map really have "view" semanticEigen::map 真的有“视图”语义吗
【发布时间】:2016-12-06 18:34:55
【问题描述】:

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

#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

【问题讨论】:

    标签: c++ smart-pointers eigen eigen3


    【解决方案1】:

    广告第一季度:

    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())就会计算一个逆矩阵。

    【讨论】:

    • 谢谢!但是,如果 Mc 是地图/视图,那么在实际计算中它是行优先还是列优先“矩阵”?在我的代码中,我可以指定映射本身是行优先的,而矩阵 Mc 是列优先的,这对我来说很清楚。
    • 如果你声明Eigen::Map&lt;Mrow&gt; Mc(...)Mrow 如上所述,那么Mc 是row-major。并且只要您不在表达式中混合行优先矩阵和列优先矩阵,所有计算都将执行行优先(某些分解可能存在例外)。
    • 你应该避免将auto与Eigen一起使用:eigen.tuxfamily.org/dox/TopicPitfalls.html 我的代码编译了,但是返回了错误的结果,而auto是当时的罪魁祸首。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多