1

How do I copy an Eigen vector mesh to a C array r?

double *r;
typedef Eigen::VectorXd RealVector;
Eigen::Map<RealVector>(r, 1, mesh.cols()) = mesh;

gives an assert from Eigen

DenseBase::resize() does not actually allow to resize.

The same message comes from either

Eigen::Map<RealVector>(r, mesh.cols()) = mesh;

or

Eigen::Map<RealVector>(r, mesh.cols(), 1) = mesh;

I need the values to be copied, not just mapped.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
Woody20
  • 791
  • 11
  • 30
  • According to [this answer](http://stackoverflow.com/a/29865019/4342498) you need to allocate the space for `r` yourself. – NathanOliver May 18 '17 at 18:58
  • I did allocate space for `r`; just didn't show that part in the code. But if I hadn't, I'd be getting a different error, such as an access violation. – Woody20 May 18 '17 at 19:02
  • What is the size of `mesh`? I.e. does it have exactly 1 row? – chtz May 18 '17 at 19:31

2 Answers2

3

Since you did not clarify, I'm speculating three possible errors you could have made:

  • Either your mesh is actually a VectorXd, but then it will always have exactly one column, but potentially multiple rows, i.e., you need to write:

    Eigen::VectorXd::Map(r, mesh.rows()) = mesh;
    
  • Or your mesh is a RowVectorXd (i.e., having one row and multiple columns). Then you need to write:

    Eigen::RowVectorXd::Map(r, mesh.cols()) = mesh;
    
  • If mesh actually is a matrix, you need to decide how to map it to linear memory (i.e. row-major or column-major). This is also possible with Map:

    Eigen::MatrixXd::Map(r, mesh.rows(), mesh.cols()) = mesh;
    
chtz
  • 17,329
  • 4
  • 26
  • 56
  • Tnx for your detailed analysis. Here is what the debugger is showing for `mesh`: Eigen::Matrix - Eigen::PlainObjectBase > {m_storage m_rows=500 } } . It is indeed a VectorXd, but I had rows and cols switched. `Eigen::Map(r, mesh.rows()) = mesh` works. – Woody20 May 19 '17 at 19:03
2

You don't have to copy anything actually. You can access the raw data using the .data() member function.

#include <Eigen/Core>

int main()
{
  Eigen::VectorXd mesh = Eigen::VectorXd::Random(10);
  double * r = mesh.data();

  r[5] = 0; // writes to mesh directly
  assert(mesh(5) == 0);
}

If you want to copy the data to the pointer, you have to allocate memory, perform the copy and deallocate after use.

#include <algorithm>
#include <Eigen/Core>

int main()
{
  Eigen::VectorXd mesh = Eigen::VectorXd::Random(10);
  double * r = new double[mesh.size()];

  std::copy(mesh.data(), mesh.data() + mesh.size(), r);
  assert(r[5] == mesh(5));

  delete[] r;
}
Henri Menke
  • 10,705
  • 1
  • 24
  • 42
  • Tnx for the info. As I said in the original post, I needed a copy of the data in separate memory (which I had allocated, but not shown in my code). And, as chtz suggested, `Eigen::Map(r, mesh.rows()) = mesh` worked as I wanted. – Woody20 Jun 02 '17 at 05:23