Fast conversion of 2 matrices to 1 complex matrix

조회 수: 5 (최근 30일)
Argon
Argon 2012년 10월 24일
편집: James Tursa 2024년 7월 11일
Hi,
After reading my data from an external binary file, I have a 3 dimensional array representing one complex matrix, like this:
A(1,:,:) = rand(10); % real part
A(2,:,:) = rand(10); % imaginary part
I need to convert that into a complex matrix, e.g.
A = complex(A(1,:,:), A(2,:,:));
But this is rather slow. As far as I have been able to find out, Matlab stores complex matrices internally as two matrices, one for the real and one for the imaginary part. This is about the same as my original 3-dimensional matrix -- and should be quite fast! My assumption therefore is that Matlab uses a temporary variable which of course needs to be allocated, resulting in slow code.
Is it possible to make Matlab do this conversion without allocating more memory? Maybe just setting the 'complex' attribute to A... It might be possible using mex files, but I never used them before, and I would prefer a 'pure' Matlab solution.
Any comments, hints or keywords I can google for are welcome!
Regards Argon

채택된 답변

James Tursa
James Tursa 2012년 10월 24일
For your specific example, the A(1,:,:) and A(2,:,:) data blocks are contiguous memory and, more importantly, were both allocated with a single malloc (or similar) call in the background. They cannot be legally separated into separate real and imaginary parts of another variable. You will be required to copy the data as you (and Wayne King) are doing.
Regarding mex routines, there are ways to do stuff like this. I have code (as yet unpublished to the FEX) that can pretty much do what you are asking, but it involves manipulating the mxArray structure behind the scenes (i.e., not using the official API functions). Also, for your particular case, one would have to keep a shared data copy of the new complex variable locked up in the mex routine to prevent MATLAB from trying to free the imaginary part (if that ever happened MATLAB would crash). To clear it you would have to manually reverse the process that you did to create it. So it gets to be very tricky to manage, but technically it can be done. Can you redo the part of your code that creates A and instead put the A(1,:,:) and A(2,:,:) parts into separate variables from the outset? If so, then what you are asking becomes much easier to do in a mex routine (but still requires unofficial behind the scenes techniques).
  댓글 수: 4
Argon
Argon 2012년 10월 26일
I do -- and it is a regular binary file. I've thought of doing just that out of a Matlab function, but I assumed that calling fread for every value separately would be slower than calling it once just because of the function overhead. Maybe I should do some tests here...
James Tursa
James Tursa 2012년 10월 26일
편집: James Tursa 2012년 10월 26일
Haven't done the comparison myself yet, but my guess is that doing this at the Matlab level would in fact be quite a bit slower than doing it in a mex routine because of all the extra overhead involved in creating/copying/deleting the individual Matlab variables involved. I.e., when you fread at the mex level you essentially get just the data. But when you fread at the Matlab level you have to create these 100+ byte Matlab variable structures to hold each individual value. All that overhead will be quite a drag on performance. If you need help setting up the C-code for this let me know.

댓글을 달려면 로그인하십시오.

추가 답변 (2개)

Wayne King
Wayne King 2012년 10월 24일
편집: Wayne King 2012년 10월 24일
A(1,:,:) = randn(100);
A(2,:,:) = randn(100);
B = squeeze(A(1,:,:)+1i*A(2,:,:));
Seems pretty fast to me, is your matrix really big?
  댓글 수: 1
Argon
Argon 2012년 10월 24일
It is essentially a (complex) image, so it can be quite large, from 10'000 x 10'000 up to 10'000 x 100'000 (complex) pixels, so I really don't want it to be in memory twice at any point.

댓글을 달려면 로그인하십시오.


James Tursa
James Tursa 2020년 7월 8일
See this FEX submission for reading and writing interleaved complex data in R2018a or later without extra data copies:
See this FEX submission for reinterpreting an existing real variable as interleaved complex or vice-versa in R2018a or later:
  댓글 수: 2
Muhammad
Muhammad 2024년 7월 11일
Hi James,
I have the signal in complex format, I want to convert it to .dat form but not interleaved. I tried the fwritecomplex but it didn't help as it interleaved the data. I want to save each complex value as single value not interleaved. Is it possible?
Thanks in advance.
James Tursa
James Tursa 2024년 7월 11일
편집: James Tursa 2024년 7월 11일
Can you clarify what you want to do? Preferably with a very small example? Show exactly what you are starting with and exactly what you want as an end result. E.g., if you want data written to a file show excatly how you want it written to the file with the example data. Also what MATLAB version are you running with? The approach is very different depending on whether you are using R2018a & later vs R2017b & earlier. Thanks.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Performance and Memory에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by