[Numpy-discussion] __iadd__(ndarray<int>, ndarray<float>)

Nadav Horesh nadavh at visionsense.com
Tue Mar 25 02:08:49 EDT 2008




-----הודעה מקורית-----
מאת: numpy-discussion-bounces at scipy.org בשם Andreas Kl?ckner
נשלח: ג 25-מרץ-08 06:42
אל: Discussion of Numerical Python
נושא: Re: [Numpy-discussion] __iadd__(ndarray<int>, ndarray<float>)
 
On Montag 24 M?rz 2008, St?fan van der Walt wrote:
> >  I think this is highly undesirable and should be fixed, or at least
> > warned about. Opinions?
>
> I know the result is surprising, but it follows logically.  You have
> created two integers in memory, and now you add 0.2 and 0.1 to both --
> not enough to flip them over to the next value.  The equivalent in C
> is roughly:

<snip>

Thanks for the explanation. By now I've even found the fat WARNING in the 
Numpy book. 

I understand *why* this happens, but I still don't think it's a particular 
sensible thing to do.

I found past discussion on this on the list:
http://article.gmane.org/gmane.comp.python.numeric.general/2924/match=inplace+int+float
but the issue didn't seem finally settled then. If I missed later discussions, 
please let me know.

Question: If it's a known trap, why not change it?

To me, it's the same idea as 3/4==0 in Python--if you know C, it makes sense. 
OTOH, Python itself will silently upcast on int+=float, and they underwent 
massive breakage to make 3/4==0.75.

****************************************************
****************************************************
scalars are immutable objects in python. Thus the += (and alike) are "fake":

>>> a = 23
>>> id(a)
10835088
>>> a += 3
>>> id(a)
10835052      << 'a' is a different object
>>> l = ['a',3]
>>> id(l)
13523744
>>> l += [34]
>>> id(l)
13523744    << lists are mutable, thus 'l' stays the same

a += 3 is really equivalent to a = a+3. Python does not allow in place type change, it just creates a different object. numpy convention is consistent with the python's spirit. I really use that fact to write arr1 += something, in order to be sure that the type of arr1 is conserved, and write arr1 = arr1+something, to allow upward type casting.


  Nadav.
****************************************************
****************************************************

I see 2.5 acceptable resolutions of ndarray<int> += ndarray<float>, in order 
of preference:

- Raise an error, but add a lightweight wrapper, such as 
int_array += downcast_ok(float_array)
to allow the operation anyway.

- Raise an error unconditionally, forcing the user to make a typecast copy.

- Silently upcast the target. This is no good because it breaks existing code 
non-obviously.

I'd provide a patch if there's any interest.

Andreas

-------------- next part --------------
A non-text attachment was scrubbed...
Name: winmail.dat
Type: application/ms-tnef
Size: 4462 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20080325/5d9577c7/attachment.bin>


More information about the NumPy-Discussion mailing list