Eigen::map 真的有 "view" 语义吗
Does Eigen::map really have "view" semantic
我想用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 中接受的答案表明有一些副本,但是,原则上 "view" 不应复制任何内容。
我有问题 2,因为否则结果不是预期的,但是这不像 "view"(另见 answer)如果我真的必须分配回来
简而言之,构造地图对象通常不会复制。但是,随后的计算可能会创建副本或临时文件或两者。
广告 Q1:
Eigen::MatrixXd Mc = Eigen::Map<Mrow>(p_data, row, col);
这会将临时 Map
复制到动态矩阵 Mc
中。如果你想避免那个副本,你可以写:
Eigen::Map<Mrow> Mc(p_data, row, col);
广告问题 2:如果您将 Mc
声明为地图(如上),则可以避免该副本。在您编写它时,您正在将 MatrixXd Mc
中的值复制回临时 Map
.
顺便说一句,写作
auto M_temp = Mc.inverse();
Mc = M_temp;
几乎相当于直接写
Mc = Mc.inverse();
因为 auto M_temp
实际上不是矩阵,而是一个表达式模板,一旦将其分配给实际矩阵(或调用 M_temp.eval()
就会计算逆矩阵。
我想用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 中接受的答案表明有一些副本,但是,原则上 "view" 不应复制任何内容。
我有问题 2,因为否则结果不是预期的,但是这不像 "view"(另见 answer)如果我真的必须分配回来
简而言之,构造地图对象通常不会复制。但是,随后的计算可能会创建副本或临时文件或两者。
广告 Q1:
Eigen::MatrixXd Mc = Eigen::Map<Mrow>(p_data, row, col);
这会将临时 Map
复制到动态矩阵 Mc
中。如果你想避免那个副本,你可以写:
Eigen::Map<Mrow> Mc(p_data, row, col);
广告问题 2:如果您将 Mc
声明为地图(如上),则可以避免该副本。在您编写它时,您正在将 MatrixXd Mc
中的值复制回临时 Map
.
顺便说一句,写作
auto M_temp = Mc.inverse();
Mc = M_temp;
几乎相当于直接写
Mc = Mc.inverse();
因为 auto M_temp
实际上不是矩阵,而是一个表达式模板,一旦将其分配给实际矩阵(或调用 M_temp.eval()
就会计算逆矩阵。