Asked by Argon
on 24 Oct 2012

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

Answer by James Tursa
on 24 Oct 2012

Accepted Answer

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).

James Tursa
on 25 Oct 2012

CORRECTION to my earlier post: The A(1,:,:) and A(2,:,:) slices are not in fact contiguous in memory, they are interleaved (as you stated). So there is no way to do this in a mex function either. The real and imag parts would have to be in the A(:,:,1) and A(:,:,2) slices for this to be possible even with a mex function. But that is assuming that the data is already in memory.

If you are reading the data from a file, then you are in luck if we are talking about a regular binary file and not a .mat file. It would not be hard at all to do the reading in a mex routine and de-interleave the data one element at a time as you are reading it and stuff the real and imaginary elements separately into the appropriate spots in a MATLAB variable as you go. Do you know (or can you easily find out) the size of the variable prior to reading the file?

Argon
on 26 Oct 2012

James Tursa
on 26 Oct 2012

Sign in to comment.

Answer by Wayne King
on 24 Oct 2012

Edited by Wayne King
on 24 Oct 2012

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?

Opportunities for recent engineering grads.

Apply Today
## 0 Comments

Sign in to comment.