Problems with complex output in mex funtion

3 次查看(过去 30 天)
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

回答(1 个)

James Tursa
James Tursa 2018-7-26
编辑:James Tursa 2018-7-26
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 个评论
Anabel almodovar
Anabel almodovar 2018-8-29
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&&’

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Write C Functions Callable from MATLAB (MEX Files) 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by