[eigen] Passing Eigen::Map types to functions that take Eigen types

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]


Hi,

in my rigid body dynamics library RBDL [1] I use Eigen3 as the linear
algebra package and most functions use MatrixXd& as parameters, e.g.

void do_work (Eigen::MatrixXd &mat) {
  // just for illustration, actual code is far more complex!
  Eigen::Matrix2d mask;
  mask << 10., -15., -20., 30.;
  mat.block<2,2>(0,0) = mask;
}

Now I would like to make my library to work with raw double* pointers to
avoid copying of the data into temporary MatrixXds. Eigen::Map sounded
like an ideal choice, however when using it as

void do_work_ptr (double* ptr) {
  Eigen::MatrixXd mat_data (Map<Eigen::MatrixXd> (ptr, rows, cols));
  do_work (mat_data);
}

the data in ptr does not get modified, and instead it gets copied into a
new MatrixXd and leaves the data in ptr unchanged when returning from
do_work_ptr().

Another approach I tried was to rewrite the do_work function to use
Eigen::Map types:

void do_work_map (Eigen::Map<Eigen::MatrixXd> &mat) {
  Eigen::Matrix2d mask;
  mask << 10., -15., -20., 30.;
  mat.block<2,2>(0,0) = mask;and
}

and use it with

  Eigen::Map<Eigen::MatrixXd> data_map (matrix.data(), 2, 3);
  do_work_map (data_map);

That does work, however I would have to create "fat wrappers" which are
essentially copies of the functions that only use a different data type.

Is there any way to avoid this to allow for thin wrappers à la do_work_ptr?

Attached is a complete program which contains my attempts.

Regards,
Martin

[1] http://rbdl.bitbucket.org
-- 
mail  : martin.felis@xxxxxxxxxxxxxxxxxxxxx
phone : +49 6221 544983
office: IWR | Speyerer Str 6 | Room 319 | 69115 Heidelberg | Germany
#include <Eigen/Dense>
#include <iostream>

using namespace std;

void do_work (Eigen::MatrixXd &mat) {
  Eigen::Matrix2d mask;
  mask << 10., -15., -20., 30.;
  mat.block<2,2>(0,0) = mask;
}

void do_work_map (Eigen::Map<Eigen::MatrixXd> &mat) {
  Eigen::Matrix2d mask;
  mask << 10., -15., -20., 30.;
  mat.block<2,2>(0,0) = mask;
}

void do_work_ptr (double* ptr) {
  Eigen::MatrixXd mat_data (Eigen::Map<Eigen::MatrixXd> (ptr, 2, 3));
  do_work (mat_data);
  cout << "mat_data in do_work_ptr" << endl << mat_data << endl;
}

int main (void) {
  Eigen::MatrixXd matrix(2,3);
  matrix << 1., 2., 3., 4., 5., 6.;
  cout << "matrix:" << endl << matrix<< endl;
  do_work (matrix);
  cout << "matrix after do_work:" << endl << matrix << endl;

  matrix << 1., 2., 3., 4., 5., 6.;
  do_work_ptr (matrix.data());
  cout << "matrix after do_work_ptr:" << endl << matrix << endl;

  matrix << 1., 2., 3., 4., 5., 6.;
  Eigen::Map<Eigen::MatrixXd> data_map (matrix.data(), 2, 3);
  do_work_map (data_map);

  cout << "matrix after do_work_map:" << endl << matrix << endl;
}


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/