Skip to content
This repository has been archived by the owner on Mar 22, 2021. It is now read-only.

Eigen support #14

Closed
bonanza123 opened this issue Sep 2, 2016 · 10 comments
Closed

Eigen support #14

bonanza123 opened this issue Sep 2, 2016 · 10 comments
Labels

Comments

@bonanza123
Copy link

If I'm not wrong, your awesome library doesn't support Eigen. Is there any change that this will be added?

@kyamagu
Copy link
Owner

kyamagu commented Sep 2, 2016

@bonanza123 Can you describe what exactly is the coding issue?

@bonanza123
Copy link
Author

bonanza123 commented Sep 4, 2016

I used the following example and noted that the line with STL vector compiles fine while the line with the Eigen vector gives me errors

#include "mex.h"
#include "Eigen/Dense"
#include "mexplus.h"
#include <vector>

using namespace mexplus;
using namespace std;

void mexFunction(int nlhs, mxArray *plhs[ ], int nrhs, const mxArray *prhs[ ]) {

    vector<double> value = MxArray::to<vector<double> >(prhs[0]);
    Eigen::VectorXd value2 = MxArray::to<Eigen::VectorXd>(prhs[0]);

} 

Here are the errors from this MATLAB command: mex '-I/usr/include/eigen3' '-I/usr/include/mexplus/include' test.cpp:

In file included from /usr/include/mexplus/include/mexplus/arguments.h:38:0,
                 from /usr/include/mexplus/include/mexplus.h:9,
                 from /home/xxx/test.cpp:3:
/usr/include/mexplus/include/mexplus/mxarray.h: In instantiation of ‘static T mexplus::MxArray::to(const mxArray*) [with T
= Eigen::Matrix<double, -1, 1>; mxArray = mxArray_tag]’:
/home/xxx/test.cpp:12:66:   required from here
/usr/include/mexplus/include/mexplus/mxarray.h:296:18: error: no matching function for call to
‘mexplus::MxArray::toInternal(const mxArray*&, Eigen::Matrix<double, -1, 1>*)’
     toInternal<T>(array, &value);
     ~~~~~~~~~~~~~^~~~~~~~~~~~~~~
/usr/include/mexplus/include/mexplus/mxarray.h:770:15: note: candidate: template<class T> static void
mexplus::MxArray::toInternal(const mxArray*, typename std::enable_if<(((mexplus::MxArithmeticType<T>::value ||
mexplus::MxComplexType<T>::value) || mexplus::MxLogicalType<T>::value) || mexplus::MxCharType<T>::value), T>::type*)
   static void toInternal(const mxArray* array,
               ^~~~~~~~~~
/usr/include/mexplus/include/mexplus/mxarray.h:770:15: note:   template argument deduction/substitution failed:
/usr/include/mexplus/include/mexplus/mxarray.h: In substitution of ‘template<class T> static void
mexplus::MxArray::toInternal(const mxArray*, typename std::enable_if<(((mexplus::MxArithmeticType<T>::value ||
mexplus::MxComplexType<T>::value) || mexplus::MxLogicalType<T>::value) || mexplus::MxCharType<T>::value), T>::type*) [with
T = Eigen::Matrix<double, -1, 1>]’:
/usr/include/mexplus/include/mexplus/mxarray.h:296:18:   required from ‘static T mexplus::MxArray::to(const mxArray*)
[with T = Eigen::Matrix<double, -1, 1>; mxArray = mxArray_tag]’
/home/xxx/test.cpp:12:66:   required from here
/usr/include/mexplus/include/mexplus/mxarray.h:770:15: error: no type named ‘type’ in ‘struct std::enable_if<false,
Eigen::Matrix<double, -1, 1> >’
/usr/include/mexplus/include/mexplus/mxarray.h: In instantiation of ‘static T mexplus::MxArray::to(const mxArray*) [with T
= Eigen::Matrix<double, -1, 1>; mxArray = mxArray_tag]’:
/home/xxx/test.cpp:12:66:   required from here
/usr/include/mexplus/include/mexplus/mxarray.h:1258:6: note: candidate: template<class T> static void
mexplus::MxArray::toInternal(const mxArray*, typename std::enable_if<((mexplus::MxComplexOrArithmeticCompound<T>::value ||
mexplus::MxLogicalCompound<Container>::value) || mexplus::MxCharCompound<Container>::value), T>::type*)
 void MxArray::toInternal(const mxArray* array, typename std::enable_if<
      ^~~~~~~
/usr/include/mexplus/include/mexplus/mxarray.h:1258:6: note:   template argument deduction/substitution failed:
/usr/include/mexplus/include/mexplus/mxarray.h: In substitution of ‘template<class T> static void
mexplus::MxArray::toInternal(const mxArray*, typename std::enable_if<((mexplus::MxComplexOrArithmeticCompound<T>::value ||
mexplus::MxLogicalCompound<Container>::value) || mexplus::MxCharCompound<Container>::value), T>::type*) [with T =
Eigen::Matrix<double, -1, 1>]’:
/usr/include/mexplus/include/mexplus/mxarray.h:296:18:   required from ‘static T mexplus::MxArray::to(const mxArray*)
[with T = Eigen::Matrix<double, -1, 1>; mxArray = mxArray_tag]’
/home/xxx/test.cpp:12:66:   required from here
/usr/include/mexplus/include/mexplus/mxarray.h:1258:6: error: no type named ‘type’ in ‘struct std::enable_if<false,
Eigen::Matrix<double, -1, 1> >’
/usr/include/mexplus/include/mexplus/mxarray.h: In instantiation of ‘static T mexplus::MxArray::to(const mxArray*) [with T
= Eigen::Matrix<double, -1, 1>; mxArray = mxArray_tag]’:
/home/xxx/test.cpp:12:66:   required from here
/usr/include/mexplus/include/mexplus/mxarray.h:793:15: note: candidate: template<class T> static void
mexplus::MxArray::toInternal(const mxArray*, typename std::enable_if<(mexplus::MxCellType<T>::value && ((!
std::is_compound<T>::value) || mexplus::MxCellType<typename T::value_type>::value)), T>::type*)
   static void toInternal(const mxArray* array,
               ^~~~~~~~~~
/usr/include/mexplus/include/mexplus/mxarray.h:793:15: note:   template argument deduction/substitution failed:
/usr/include/mexplus/include/mexplus/mxarray.h: In substitution of ‘template<class T> static void
mexplus::MxArray::toInternal(const mxArray*, typename std::enable_if<(mexplus::MxCellType<T>::value && ((!
std::is_compound<T>::value) || mexplus::MxCellType<typename T::value_type>::value)), T>::type*) [with T =
Eigen::Matrix<double, -1, 1>]’:
/usr/include/mexplus/include/mexplus/mxarray.h:296:18:   required from ‘static T mexplus::MxArray::to(const mxArray*)
[with T = Eigen::Matrix<double, -1, 1>; mxArray = mxArray_tag]’
/home/xxx/test.cpp:12:66:   required from here
/usr/include/mexplus/include/mexplus/mxarray.h:796:57: error: no type named ‘value_type’ in ‘class Eigen::Matrix<double,
-1, 1>’
                            (!std::is_compound<T>::value ||
                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
                             MxCellType<typename T::value_type>::value),
                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I assumed that particular Eigen support in mexplus is missing e.g. because of the line no matching function for call to ‘mexplus::MxArray::toInternal(const mxArray*&, Eigen::Matrix<double, -1, 1>*).

@kyamagu
Copy link
Owner

kyamagu commented Sep 4, 2016

@bonanza123 You have to define how to convert the data structure between Matlab and Eigen library. See class MyObject example in README.

@bonanza123
Copy link
Author

Sorry, but I don't understand. Isn't that exactly the missing (not implemented) Eigen support?

@kyamagu
Copy link
Owner

kyamagu commented Sep 30, 2016

@bonanza123 Mexplus only is a helper library. You have to develop by yourself the actual implementation of whatever the conversion logic, except for a few C++ standard containers such as std::vector.

@patrikhuber
Copy link
Contributor

Hi!

I've implemented MxArray::from and MxArray::to functions for Eigen::MatrixXd and it works well so far. See eos/matlab/include/mexplus_eigen.hpp.
@kyamagu, I wasn't sure in a few places whether to copy data or if we can just map it. Do you think you could have a quick look to see if what I did looks alright? It's only a few lines of code, and I've put comments in the respective places.

Thank you very much and thank you also for making mexplus available on GitHub, it's really awesome!

@kyamagu
Copy link
Owner

kyamagu commented Jan 29, 2017

@patrikhuber Yes, that implementation looks correct. Data should be always copied unless it's read-only in both C++/Matlab side. I'm not familiar with Eigen library, but the MxArray::from could be further optimized to use memcpy or std::copy for performance, because for-loop + index-addressing incurs some performance overhead.

@patrikhuber
Copy link
Contributor

patrikhuber commented Jan 30, 2017

@kyamagu Thank you very much for having a look! Thanks - I'll think about your proposed optimisation, I need to see whether/how that's possible with Eigen. But in any case I don't have a performance issue right now.

In MxArray::to the code actually doesn't copy data: The Eigen::Map is a mapper that points to existing memory, in this case it points to the mxArray's data, array.getData<double>(). Eigen::Map is a "mapper" that allows to point to data that it does not own.
I assume that it is ok for C++ code to point into data owned by Matlab (mxArray), since it will always exist, while the C++ code is running. Hence no copy is needed in ::to. Is that correct?
So in my ::to, the C++ code could actually even modify the data on the C++ side (which would modify the underlying data, the mxArray), so we would directly modify Matlab's data.

@kyamagu
Copy link
Owner

kyamagu commented Jan 30, 2017

@patrikhuber I remember Mathworks doesn't recommend in-place operation to mxArray, though it is doable as you did. Just be cautious on memory management whenever Matlab operates on the modified data.

My typical design pattern is either 1) completely converting the data with copy, or 2) create a wrapper class in Matlab so that memory always sits in C++ side.

@patrikhuber
Copy link
Contributor

@kyamagu Thank you very much! Your advice is very helpful and highly appreciated. Thank you for taking the time to reply.

Cheers,
Patrik

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants