[Numpy-discussion] Unpleasant behavior with poly1d and numpy scalar multiplication

josef.pktd@gmai... josef.pktd@gmai...
Sat Feb 13 02:41:09 CST 2010


On Sat, Feb 13, 2010 at 3:11 AM, Fernando Perez <fperez.net@gmail.com> wrote:
> Mmh, today I got bitten by this again.  It took me a while to figure
> out what was going on while trying to construct a pedagogical example
> manipulating numpy poly1d objects, and after searching for 'poly1d
> multiplication float' in my gmail inbox, the *only* post I found was
> this old one of mine, so I guess I'll just resuscitate it:
>
> On Tue, Jul 31, 2007 at 2:54 PM, Fernando Perez <fperez.net@gmail.com> wrote:
>> Hi all,
>>
>> consider this little script:
>>
>> from numpy import poly1d, float, float32
>> p=poly1d([1.,2.])
>> three=float(3)
>> three32=float32(3)
>>
>> print 'three*p:',three*p
>> print 'three32*p:',three32*p
>> print 'p*three32:',p*three32
>>
>>
>> which produces when run:
>>
>> In [3]: run pol1d.py
>> three*p:
>> 3 x + 6
>> three32*p: [ 3.  6.]
>> p*three32:
>> 3 x + 6
>>
>>
>> The fact that multiplication between poly1d objects and numbers is:
>>
>> - non-commutative when the numbers are numpy scalars
>> - different for the same number if it is a python float vs a numpy scalar
>>
>> is rather unpleasant, and I can see this causing hard to find bugs,
>> depending on whether your code gets a parameter that came as a python
>> float or a numpy one.
>>
>> This was found today by a colleague on numpy 1.0.4.dev3937.   It feels
>> like a bug to me, do others agree? Or is it consistent with a part of
>> the zen of numpy I've missed thus far?
>
> Tim H. mentioned how it might be tricky to fix. I'm wondering if there
> are any new ideas since on this front, because it's really awkward to
> explain to new students that poly1d objects have this kind of odd
> behavior regarding operations with scalars.
>
> The same underlying problem happens for addition, but in this case the
> answer (depending on the order of operations) changes even more:
>
> In [560]: p
> Out[560]: poly1d([ 1.,  2.])
>
> In [561]: print(p)
>
> 1 x + 2
>
> In [562]: p+3
> Out[562]: poly1d([ 1.,  5.])
>
> In [563]: p+three32
> Out[563]: poly1d([ 1.,  5.])
>
> In [564]: three32+p
> Out[564]: array([ 4.,  5.])  # !!!
>
> I'm ok with teaching students that in floating point, basic algebraic
> operations may not be exactly associative and that ignoring this fact
> can lead to nasty surprises.  But explaining that a+b and b+a give
> completely different *types* of answer is kind of defeating my 'python
> is the simple language you want to learn' :)
>
> Is this really unfixable, or does one of our resident gurus have some
> ideas on how to approach the problem?

>From several recent discussion about selecting which method is called,
it looks like multiplication and addition could easily be fixed by
adding a higher  __array_priority__  to poly1d.  I didn't see any
__array_priority__ specified in class poly1d(object)


For the discussion about fixing equal, notequal or whichever other
methods cannot be changed by __array_priority__ , I haven't seen  any
solution.

(but maybe I'm wrong)

Josef



> Thanks!
>
> f
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion@scipy.org
> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>


More information about the NumPy-Discussion mailing list