This forum has been archived. All content is frozen. Please use KDE Discuss instead.

matrix to const vector conversion without copy ?

Tags: None
(comma "," separated)
martin_IM
Registered Member
Posts
9
Karma
0
OS
I have a eigen matrix of type "MatrixXd" that contains a single columns (this is known only at run time )and i want to convert it to a "const eigen::Vector<double>" without copying the data (In case that matrix happen to have more than one colums at run time i could either raise an error or use only the first row).
I tried the following code :

Eigen::MatrixXd m = Eigen::MatrixXd::Random(10000,1);
const Eigen::VectorXd m_vec(m.col(0));

it compile and runs, but the second line produces a copy of the data. In theory that seems possible avoid a copy of the data : the data is continuous and well aligned and because i use the "const" there will not be any resize or modification of elements of the resulting vector . However i'm not able to do that and i had to resort
to use a map (of type "const Map<VectorXr,true>") instead. This is not very convenient for me because it implies changing all my function interfaces to use a map instead of a vector. Is there anyway i could obtain an object of type "const Eigen::VectorXd" from my single column matrix ? if not, what makes it impossible?
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
MatrixXd::ColXpr m_vec(m.col(0));

or:

MatrixXd::ConstColXpr m_vec(m.col(0));


should do the job.
martin_IM
Registered Member
Posts
9
Karma
0
OS
ggael wrote:MatrixXd::ColXpr m_vec(m.col(0));

or:

MatrixXd::ConstColXpr m_vec(m.col(0));


should do the job.


I tried it but it still does copies before or within the function call. here is my code that i used to test it. In order to make my intial question more explicit : i do not want to change the interface of my_function, because the function that i actually want to use is from a library of which i can't change the interface.
Code: Select all
#include <Eigen/Core>
#include <iostream>

const double* my_function(const Eigen::VectorXd &m)
{return m.data();}

void main(void){

  Eigen::MatrixXd m = Eigen::MatrixXd::Random(10000,1);

  // const Eigen::VectorXd m_vec(m.col(0));        // causes a copy
  const Eigen::MatrixXd::ColXpr m_vec(m.col(0));   // will copy at the function call
  // Eigen::MatrixXd::ConstColXpr m_vec(m.col(0)); // does not compile

  const double *ptr=my_function( m_vec);
  if (m.data()==ptr)
  {std::cout<<"great, no copy occurred";}
  else
  {std::cout<<"too bad, a copy occurred";}

}
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
well, then you're screwed. you should check if there is really no way for you to get an overload for this function. A very ugly and unsafe solution:

struct UglyWrapper {
double* ptr;
DenseIndex size;
};

UglyWrapper vec;
vec.ptr = m.col(j).data();
vec.size = m.rows();

my_function(reinterpret_cast<VectorXd&>(vec));


Bookmarks



Who is online

Registered users: Bing [Bot], Google [Bot], Yahoo [Bot]