[Numpy-discussion] Assigning complex values to a real array

David Warde-Farley dwf at cs.toronto.edu
Tue Dec 8 02:32:20 EST 2009


On 7-Dec-09, at 11:13 PM, Dr. Phillip M. Feldman wrote:

> Example #1:
> IPython 0.10   [on Py 2.5.4]
> [~]|1> z= zeros(3)
> [~]|2> z[0]= 1+1J
>
> TypeError: can't convert complex to float; use abs(z)

The problem is that you're using Python's built-in complex type, and  
it responds to type coercion differently than NumPy types do. Calling  
float() on a Python complex will raise the exception. Calling float()  
on (for example) a numpy.complex64 will not. Notice what happens here:

In [14]: z = zeros(3)

In [15]: z[0] = complex64(1+1j)

In [16]: z[0]
Out[16]: 1.0

> Example #2:
>
> ### START OF CODE ###
> from numpy import *
> q = ones(2,dtype=complex)*(1 + 1J)
> r = zeros(2,dtype=float)
> r[:] = q
> print 'q = ',q
> print 'r = ',r
> ### END OF CODE ###

Here, both operands are NumPy arrays. NumPy is in complete control of  
the situation, and it's well documented what it will do.

I do agree that the behaviour in example #1 is mildly inconsistent,  
but such is the way with NumPy vs. Python scalars. They are mostly  
transparently intermingled, except when they're not.

> At a minimum, this inconsistency needs to be cleared up.  My  
> preference
> would be that the programmer should have to explicitly downcast from
> complex to float, and that if he/she fails to do this, that an  
> exception be
> triggered.

That would most likely break a *lot* of deployed code that depends on  
the implicit downcast behaviour. A less harmful solution (if a  
solution is warranted, which is for the Council of the Elders to  
decide) would be to treat the Python complex type as a special case,  
so that the .real attribute is accessed instead of trying to cast to  
float.

David



More information about the NumPy-Discussion mailing list