Return eigen complex matrix to matlab in mex function without extra copy

Viewed 190

This question shows how to return a double matrix to matlab using a map object. Pass C++ Eigen matrix to Matlab mex output The following works for non-complex data.

double *outputPtr;
plhs[0] = mxCreateDoubleMatrix((mwSize)n, (mwSize)m, mxREAL);
outputPtr = mxGetPr(plhs[0]);
Map<MatrixXd> output(outputPtr, n, m);

Since matlab stores real and complex elements of a matrix separately rather than interleaved I don't think you can directly map to MatrixXcd. This is what I'm trying but it doesn't write to the data at plhs[0].

double *outputReal, *outputImag;
plhs[0] = mxCreateDoubleMatrix((mwSize)n, (mwSize)m, mxCOMPLEX);
outputReal = mxGetPr(plhs[0]);
outputImag = mxGetPi(plhs[0]);
MatrixXcd outputMat(n,m);
outputMat.real() = Map<MatrixXd>(outputReal,n,m);
outputMat.imag() = Map<MatrixXd>(outputImag,n,m);

I think The problem with that is that it's copying the data in those maps to the real and imaginary parts of outputMat. So not only does this do an unnecessary copy on initializing but changes to a matrix assigned this way won't touch the data at the output pointer.

Is there a way to initialize the output matrix in such a way that it's real and imaginary data will be stored at mxGetPr(plhs[0]) and mxGetPi(plhs[0])?

1 Answers

Thanks to Cris Luengo for pointing me in the right direction. Here's what I got to work.

plhs[0] = mxCreateDoubleMatrix((mwSize)n, (mwSize)m, mxCOMPLEX);
auto* Poutput = reinterpret_cast<complex<double>*>(mxGetComplexDoubles(plhs[0]));
Map<MatrixXcd> output(Poutput, n, m);

Then when compiling make sure to give mex the -R2018a flag which will build for interleaved complex data.

Related