Code Monkey home page Code Monkey logo

Comments (10)

patrikhuber avatar patrikhuber commented on May 29, 2024 1

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!

from mexplus.

kyamagu avatar kyamagu commented on May 29, 2024 1

@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.

from mexplus.

kyamagu avatar kyamagu commented on May 29, 2024

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

from mexplus.

bonanza123 avatar bonanza123 commented on May 29, 2024

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>*).

from mexplus.

kyamagu avatar kyamagu commented on May 29, 2024

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

from mexplus.

bonanza123 avatar bonanza123 commented on May 29, 2024

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

from mexplus.

kyamagu avatar kyamagu commented on May 29, 2024

@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.

from mexplus.

kyamagu avatar kyamagu commented on May 29, 2024

@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.

from mexplus.

patrikhuber avatar patrikhuber commented on May 29, 2024

@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.

from mexplus.

patrikhuber avatar patrikhuber commented on May 29, 2024

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

Cheers,
Patrik

from mexplus.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.