问题
The following MATLAB code snippet, which creates two arrays of complex numbers,
x = complex(1:2,0:1);
y = complex(zeros(1,2),0);
whos x y
prints
Name Size Bytes Class Attributes
x 1x2 32 double complex
y 1x2 32 double complex
as expected. However, after these two additional statements,
y(1) = x(1);
whos x y
the following gets printed:
Name Size Bytes Class Attributes
x 1x2 32 double complex
y 1x2 16 double
How can one prevent the complex attribute from being dropped?
For the record, Octave does the same.
In practice, x
is a function argument whose first entry happens to have a zero imaginary part, and y
is the return value that is being preallocated.
回答1:
If you want to make sure that the complex
data type is maintained, explicitly cast the number to complex
. Therefore:
y(1) = complex(x(1));
Because x(1)
only has a real component, MATLAB automatically converts this to real
in order to save space. As you can see, it would be more efficient to simply store the real component if the complex number is purely real as it's 8 bytes a number in comparison to complex
where it's 16 bytes a number - 8 for the real component and 8 for the imaginary component.
Also in your code,y
would technically be all real
as there are no imaginary components. If y
had at least one value that was complex valued, y
would still be maintained as complex
. Take a look at this code:
x = complex(1:2,0:1);
y = complex(zeros(1,2), [3 5]);
whos x y
Name Size Bytes Class Attributes
x 1x2 32 double complex
y 1x2 32 double complex
Now, let's try that assignment and examining the classes of x
and y
:
y(1) = x(1);
whos x y
Name Size Bytes Class Attributes
x 1x2 32 double complex
y 1x2 32 double complex
Also, as a sidenote, you shouldn't be concerned with x
being converted to purely real. As soon as you place at least one complex valued number into this array, x
automatically gets promoted to complex
. Try, for example:
x = 1:5;
whos x
Name Size Bytes Class Attributes
x 1x5 40 double
Now using the same x
array, try:
x(3) = 1 + 4i;
whos x
Name Size Bytes Class Attributes
x 1x5 80 double complex
Edit
Going with your comments, what you can do to make sure that the array will stay complex would be to add an infinitesimal number to the imaginary part of x(1)
. A number small enough so that numerical differences are virtually zero, but enough to respect that y
is still a complex valued array. As such:
x = complex(1:2,0:1);
y = complex(zeros(1,2),0);
y(1) = x(1) + i*eps;
who x y
Name Size Bytes Class Attributes
x 1x2 32 double complex
y 1x2 32 double complex
eps stands for machine epsilon. If you display y
and show more significant digits, this is what we see:
format long
y
y =
1.000000000000000 + 0.000000000000000i 0.000000000000000 + 0.000000000000000i
Try that and see if that works for you.
回答2:
I think I found what I was looking for in this answer. In sum, an array of complex numbers has two memory blocks for the data: one to store the real parts and one to store the imaginary parts. The best course of action should be to initialize y
to an array of doubles of the right size and let MATLAB add the second memory block on demand. The number of memory allocations is at most two, and there seems to be no way to reduce it.
来源:https://stackoverflow.com/questions/27327951/how-do-i-prevent-matlab-from-dropping-the-complex-attribute-of-an-array