Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create an Eigen Matrix from a C array

Tags:

c++

arrays

eigen

What I would like to do essentially is implement this function:

template<typename T>
Matrix<T, Dynamic, Dynamic, ColMajor>* dataToEigen(T* const data, const int rows, const int cols);

without copying any data. I know the standard way to accomplish something like this is with a Map, but I have several issues with this approach.

  1. I don't want to rewrite the rest of my code to accept Maps as inputs (without copying the Map into a temporary matrix, that is). I know I could do this by generalizing my functions to take MatrixBase objects as inputs, but I've defined specific Matrix templates in my inputs for a reason - if my function takes a Matrix<T, Dynamic, Dynamic, ColMajor>, then it's because only matrices of that type should be used as inputs.

  2. Ideally, I'd like the created Matrix to take ownership of the data pointer, so I can just manage the Matrix via shared_ptr and not have to touch the original data pointer again.

My initial thought was that I could do something like create an uninitialized dynamically sized Matrix object, and then just set the object's dimensions and data pointer, but this doesn't seem to be possible in the Eigen API. Does anyone know of any workarounds?

like image 362
user2452966 Avatar asked Jun 04 '13 18:06

user2452966


1 Answers

There is little chance that Eigen::Matrix will ever be allowed to directly wrap external buffers, and there are many good reasons for that including ABI compatibility, API consistency across dynamically and statically allocated matrices.

An ugly workaround would be to define a struct with the same layout as MatrixX_:

template<typename T> struct Foo {
  T* data;
  DenseIndex rows, cols;
  Matrix<T, Dynamic, Dynamic, ColMajor>& asMatrix() {
    return reinterpret_cast<Matrix<T, Dynamic, Dynamic, ColMajor>&>(*this);
  }
};

Another solution would be to move to the devel branch (pretty stable), and use the new Ref<> class that was designed to solve your exact problem, and more. Its documentation should be enough to use it properly. The only difficulty is that you be able to easily templatize the scalar type because Ref<> is not a base class of Matrix or Map, and so you will have to either call your fonction by specifying the scalar type explicitly, or create the Ref<> copy yourself:

foo<T>(M);
foo(Ref<MatrixXd>(M));
like image 164
ggael Avatar answered Oct 19 '22 01:10

ggael