How to define a pointer to an array of complex numbers ?

4 vues (au cours des 30 derniers jours)
Jerome Almon
Jerome Almon le 28 Nov 2023
Modifié(e) : Sameer le 26 Mar 2024
I have created an array of 10 complex numbers and initialized all elements to (1.0 +1.0i). I would like to define a pointer to the array "complex_array" inorder to pass that as an input argument to a c function. The function in the shared library has "_Complex float * v" as the argument type, which has been converted to "s_C_float_complexPtr" by the matlab loadlibrary(). Can this be achieved using libpointer() ? If yes, what is the type of the pointer ? Or is there any other way ?
array = zeros(1, 10, 'single');
complex_array = complex(complex(array, single(1.0)) + single(1.0));
dataptr = libpointer('s_C_float_complexPtr', complex_array);
calllib('lib','cmplx_mean_removal', dataptr, 10);
The above code throws the following error,
A structure is required.
Error in libpointer (line 21)
ptr=lib.pointer(varargin{:});
Note:
  1. Here is the content of ‘complex_array’ when I print it,
complex_array =
1×10 single row vector
Columns 1 through 8
1.0000 + 1.0000i 1.0000 + 1.0000i 1.0000 + 1.0000i 1.0000 + 1.0000i 1.0000 + 1.0000i 1.0000 + 1.0000i 1.0000 + 1.0000i 1.0000 + 1.0000i
Columns 9 through 10
1.0000 + 1.0000i 1.0000 + 1.0000i
2. Here is the signature of the c function, (uses standard complex notation from “complex.h”)
void cmplx_mean_removal( _Complex float * v, uint32_t len);
Would appreciate any inputs. Thank you.
  1 commentaire
Jerome Almon
Jerome Almon le 4 Déc 2023
Modifié(e) : Jerome Almon le 4 Déc 2023
Based on the suggestion from this link, I tried to make the real and imaginary values interleaved.
https://uk.mathworks.com/matlabcentral/answers/349479-pass-complex-number-to-shared-library
array = zeros(1, 10, 'single');
complex_array = complex(complex(array, single(1.0)) + single(1.0));
complex_array = [real(complex_array(:))';imag(complex_array(:))'];
dataptr = libpointer('s_C_float_complexPtr', complex_array);
calllib('lib','cmplx_mean_removal', dataptr, 10);
but I get the same error.

Connectez-vous pour commenter.

Réponse acceptée

Sameer
Sameer le 26 Mar 2024
Modifié(e) : Sameer le 26 Mar 2024
Hi Jerome,
From my understanding, you are trying to interface MATLAB with a C library function that requires an input argument of type ‘ _Complex float * ‘. You have encountered an issue when attempting to pass a MATLAB array of complex numbers to this C function using ‘libpointer()’.
The error you're encountering suggests that MATLAB is having trouble interpreting the complex array in the format expected by the C function through the libpointer mechanism, especially since MATLAB's complex number representation doesn't directly map to C's ‘_Complex float’ type.
Given the constraints and the error message, it appears that there might be a misalignment in how MATLAB handles complex data when interacting with C libraries. MATLAB represents complex numbers in a format that is not directly compatible with C's ‘_Complex‘ type, which expects the real and imaginary parts interleaved in memory.
Your second approach, where you manually interleave the real and imaginary parts, is on the right track. However, the issue might be with how you're creating the libpointer. When you interleave the real and imaginary parts, the data is no longer recognized by MATLAB as complex. Instead, it's seen as a real array twice the length of the original complex array, with alternating real and imaginary parts.
Here's how you can adjust your approach:
  1. Ensure Correct Data Interleaving: You've already interleaved the data correctly, but ensure it's in a single contiguous array suitable for passing to the C function.
  2. Correctly Define the libpointer Type: Since you've now effectively got an array of float (or single in MATLAB terms) rather than a complex array, you should define your libpointer with a type that reflects this.
Here's a refined version of your code:
% Original complex array
array = zeros(1, 10, 'single');
complex_array = complex(array + single(1.0), array + single(1.0));
% Interleaving real and imaginary parts
interleavedArray = zeros(1, numel(complex_array)*2, 'single');
interleavedArray(1:2:end) = real(complex_array); % Real parts
interleavedArray(2:2:end) = imag(complex_array); % Imaginary parts
% Create libpointer with correct type
dataptr = libpointer('singlePtr', interleavedArray);
% Call the library function
calllib('lib','cmplx_mean_removal', dataptr, 10);
'singlePtr' is used as the type for ‘libpointer’ since you're passing a single-precision, floating-point array (interleaved real and imaginary parts) to the C function. This is assuming your C function is indeed expecting an array of float representing the complex numbers in interleaved format.
‘interleavedArray’ is prepared to exactly match the memory layout expected by the C function for ‘_Complex float * ‘.
For additional information, please refer to the link below:
I hope this helps!
Sameer

Plus de réponses (0)

Catégories

En savoir plus sur Call C from MATLAB dans Help Center et File Exchange

Produits


Version

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by