Problems with complex output in mex funtion

3 views (last 30 days)
I'm trying to get an array of complex numbers at the output of my mex function. I am using the function mxGetComplexInt16s that returns as a result a pointer to the first mxComplexInt16 element of the data, which according to Matlab support (https://es.mathworks.com/help/matlab/matlab_external/matlab-support-for-interleaved-complex.html?searchHighlight=interleaved%20complex%20mex&s_tid=doc_srchtitle) is compatible with R2018a. However this gives me the following error:
Building with 'g++'.
Error using mex
/home/rs3lab/Escritorio/codigos_idepar_C_funcionando/IdeparMexV5.cpp: In function void mexFunction(int, mxArray**, int, const mxArray**):
/home/rs3lab/Escritorio/codigos_idepar_C_funcionando/IdeparMexV5.cpp:419:19: error: cannot convert ‘mxComplexInt16*’ to
‘__gnu_cxx::__alloc_traits<std::allocator<std::complex<short int>*> >::value_type {aka std::complex<short int>*}in assignment
buf_prueba[0] = mxGetComplexInt16s(plhs[2]);
My mxFuntion.cpp contain this:
...
std::vector<std::vector<std::vector<std::vector<std::complex<short> > > > > buffs(cicles,
std::vector<std::vector<std::vector<std::complex<short> > > > ( control_frag_total,
std::vector<std::vector<std::complex<short> > >(num_rx_channels,
std::vector<std::complex<short> >(samps_per_buff))));
std::vector<std::vector<std::vector<std::complex<short> *> > > buff_ptrs (cicles,
std::vector<std::vector<std::complex<short> *> > (control_frag_total));
for (int t=0; t < cicles; t++) // for each cicle
{
for (size_t j=0; j < control_frag_total; j++) // for each buffer set
{
for (size_t i = 0; i < buffs[t][j].size(); i++) // for each channel
buff_ptrs[t][j].push_back(&buffs[t][j][i].front()); // point each set to the pointer
}
}
...
// mxComplexInt16 *buf_prueba;
std::vector<std::complex<short int>*> buf_prueba(total_num_samps);
plhs[2] = mxCreateNumericMatrix(total_num_samps, 1, mxINT16_CLASS, mxCOMPLEX);
buf_prueba[0] = mxGetComplexInt16s(plhs[2]);
//buf_prueba[0]=buff_ptrs[0];
size_t i=0;
for (size_t j = sample_offset; j < control_frag_total ; j++)
{
buf_prueba[0+i]=buff_ptrs[0][j][0];
i+=samps_per_buff;
}
After this I made some changes and compiled correctly, but the result was a matrix of zeros.
// mxComplexInt16 *buf_prueba;
std::vector<std::complex<short int> *> buf_prueba(acq_num_samps);
plhs[2] = mxCreateNumericMatrix(total_num_samps, 1, mxINT16_CLASS, mxCOMPLEX);
buf_prueba[0]= reinterpret_cast<std::complex<short>*>(mxGetComplexInt16s(prhs[2]));
//buf_prueba = mxGetComplexInt16s(plhs[2]);
//buf_prueba[0]=buff_ptrs[0];
size_t i=0;
for (size_t j = sample_offset; j < control_frag_total ; j++)
{
buf_prueba[0+i]=buff_ptrs[0][j][0];
i+=samps_per_buff;
}
>> [f,g,ch]=IdeparMexV5
f
100000000
g
70
ch
0 + 0i
0 + 0i
0 + 0i
0 + 0i
0 + 0i
0 + 0i
0 + 0i
0 + 0i
...
I'm confused with the classes, for what I understand complexInt16 should be compatible with std :: complex short. Why am I getting bad results? Does the way I indicate that buff_ptrs is the output variable is the correct one?
Regards, -Anabel

Answers (1)

James Tursa
James Tursa on 26 Jul 2018
Edited: James Tursa on 26 Jul 2018
E.g., just using the definitions in the MATLAB doc:
mxComplexInt16 *buf_prueba;
:
plhs[2] = mxCreateNumericMatrix(total_num_samps, 1, mxINT16_CLASS, mxCOMPLEX);
buf_prueba = mxGetComplexInt16s(plhs[2]);
Then use buf_prueba[i] downstream in your code to access the complex elements.
  1 Comment
Anabel almodovar
Anabel almodovar on 29 Aug 2018
Dear James,
I have also tried with this syntax but it gives me the following error.
Error using mex
/home/rs3lab/Escritorio/codigos_idepar_C_funcionando/IdeparMexV5.cpp: In function void mexFunction(int, mxArray**, int, const mxArray**):
/home/rs3lab/Escritorio/codigos_idepar_C_funcionando/IdeparMexV5.cpp:439:23: error: no match for ‘operator=’ (operand types are ‘mxComplexInt16’ and
‘__gnu_cxx::__alloc_traits<std::allocator<std::complex<short int> > >::value_type {aka std::complex<short int>})
buf_prueba[i]=buffs[0][m][1][n];
^
In file included from /home/rs3lab/Escritorio/codigos_idepar_C_funcionando/IdeparMexV5.cpp:7:0:
/usr/local/MATLAB/R2018a/extern/include/matrix.h:776:40: note: candidate: mxComplexInt16& mxComplexInt16::operator=(const mxComplexInt16&)
typedef struct { mxInt16 real, imag; } mxComplexInt16;
^
/usr/local/MATLAB/R2018a/extern/include/matrix.h:776:40: note: no known conversion for argument 1 from
‘__gnu_cxx::__alloc_traits<std::allocator<std::complex<short int> > >::value_type {aka std::complex<short int>}to ‘const mxComplexInt16&’
/usr/local/MATLAB/R2018a/extern/include/matrix.h:776:40: note: candidate: mxComplexInt16& mxComplexInt16::operator=(mxComplexInt16&&)
/usr/local/MATLAB/R2018a/extern/include/matrix.h:776:40: note: no known conversion for argument 1 from
‘__gnu_cxx::__alloc_traits<std::allocator<std::complex<short int> > >::value_type {aka std::complex<short int>}to ‘mxComplexInt16&&’

Sign in to comment.

Categories

Find more on Write C Functions Callable from MATLAB (MEX Files) in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!