Search code examples
c++matlabmatlab-coder

Convert vector<> to emxArray_real_T in C++ after code-generation from MATLAB


I have converted some matlab code to C++ using the MATLAB coder.

I am aware that there are some questions similar to this one, but none of the explanations I found did help with my problem, which is somewhat different.

The generated code for C++ gives me the following function:

void getTargetPoint(const emxArray_real_T *eyeMatrix, const emxArray_real_T
                *HypAlpha, const emxArray_real_T *HypCov, const
                emxArray_real_T *HypMean, const double xs[4], double Ymu[3])

Where Ymu is the output I am looking for. However, even if I defined my inputs as arrays of undetermined size in the converter, they are vectors of vectors in my code:

eyeMatrix = vector<vector <double>>  

They all have different dimensions, for instance, eyeMatrix = [968x4], but in any other case it could be [anything x 4]

I have tried many things, but I cannot manage to convert my input data (vector of vectors) into type: emxArray_real_T

Is there anyway to do this? Or should I convert my input data into something else and then into emxArray_real_T?

Any help or idea is greatly appreciated!


Solution

  • This answer assumes that eyeMatrix is a rectangular matrix (i.e. each inner vector has the same length) since the generated code likely is meant to work with non-ragged arrays.

    You can check out:

    https://stackoverflow.com/a/24271438/3297440

    and the documentation for an overview of working with emxArray* data types.

    To summarize the answer, you'll have functions declared in the file <name>_emxAPI.h that look like:

    extern emxArray_real_T *emxCreateWrapper_real_T(double *data, int rows,
                                                    int cols);
    extern emxArray_real_T *emxCreate_real_T(int rows, int cols);
    

    You'll notice that the first takes a double *. This should be a pointer to your data stored in column-major order.

    Since eyeMatrix is likely in row-major order and may not actually be contiguous (I'm not aware of a guarantee that nested std::vectors result in contiguous data) a first step can be to call emxCreate_real_T with the proper dimensions.

    This allocates and returns an emxArray_real_T which we can call emx. emx->size will have 2 elements which are the dimensions you set. The field emx->data will be a pointer to rows*cols values (double values in your case). Then you can just copy the data from eyeMatrix to emx->data in a column-major fashion. So if your matrix is:

    1, 2
    3, 4
    

    The data in emx->data should be:

    1, 3, 2, 4
    

    From there, just pass emx as the input.

    Lastly, don't forget to call the proper emxDestroyArray* functions to clean up any allocated memory when you are done with the emxArray_real_T values.