1

I have a data array (double *) in memory which looks like:

[x0,y0,z0,junk,x1,y1,z1,junk,...]

I would like to map it to an Eigen vector and virtually remove the junk values by doing something like:

Eigen::Map<
  Eigen::Matrix<double, Eigen::Dynamic, 1, Eigen::ColMajor>,
  Eigen::Unaligned,
  Eigen::OuterStride<4>
  >

But it does not work because the outerstride seems to be restricted to 2D matrices.

Is there a trick to do what I want?

Many thanks!

janou195
  • 1,175
  • 2
  • 10
  • 25

2 Answers2

1

With the head of Eigen, you can map it as a 2D matrix and then view it as a 1D vector:

auto m1 = Matrix<double,3,Dynamic>::Map(ptr, 3, n, OuterStride<4>());
auto v = m1.reshaped(); // new in future Eigen 3.4

But be aware accesses to such a v involve costly integer division/modulo.

ggael
  • 28,425
  • 2
  • 65
  • 71
  • Division/modulo with a number known at compile-time will usually get compiled to some shifting and multiplication with a magic number (something similar to `(n * ((2<<63)/3)) >> 63`, but compilers are pretty good at that). – chtz Apr 04 '19 at 09:22
0

If you want a solution compatible with Eigen 3.3, you can do something like this

VectorXd convert(double const* ptr, Index n)
{
    VectorXd res(n*3);
    Matrix3Xd::Map(res.data(), 3, n) = Matrix4Xd::Map(ptr, 4, n).topRows<3>();
    return res;
}

But this of course would copy the data, which you probably intended to avoid.

Alternatively, you should think about whether it is possible to access your data as a 3xN array/matrix instead of a flat vector (really depends on what you are actually doing).

chtz
  • 17,329
  • 4
  • 26
  • 56