Problems with complex output in mex funtion

3 vues (au cours des 30 derniers jours)
Anabel almodovar
Anabel almodovar le 25 Juil 2018
Commenté : Anabel almodovar le 29 Août 2018
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

Réponses (1)

James Tursa
James Tursa le 26 Juil 2018
Modifié(e) : James Tursa le 26 Juil 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 commentaire
Anabel almodovar
Anabel almodovar le 29 Août 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&&’

Connectez-vous pour commenter.

Catégories

En savoir plus sur Write C Functions Callable from MATLAB (MEX Files) dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by