[Numpy-discussion] bug in oldnumeric.ma

Eric Firing efiring@hawaii....
Fri May 9 11:55:39 CDT 2008


Stefan, (and Jarrod and Pierre)

(Context for anyone new to the thread: the subject is slightly 
misleading, because the bug is/was present in both oldnumeric.ma and 
numpy.ma; the discussion of fix pertains to the latter only.)

Regarding your objections to r5137: good point.  I wondered about that. 
  I think the function should look like this (although it might be 
possible to speed up the implementation for the most common case):

def power(a, b, third=None):
     """Computes a**b elementwise.

     Where a is negative and b has a non-integer value,
     the result is masked.

     """
     if third is not None:
         raise MAError, "3-argument power not supported."
     ma = getmask(a)
     mb = getmask(b)
     m = mask_or(ma, mb)
     fa = getdata(a)
     fb = getdata(b)
     if fb.dtype.char in typecodes["Integer"]:
         return masked_array(umath.power(fa, fb), m)
     md = make_mask((fb != fb.astype(int)) & (fa < 0), shrink=True)
     m = mask_or(m, md)
     if m is nomask:
         return masked_array(umath.power(fa, fb))
     else:
         fa = fa.copy()
         fa[m] = 1
         return masked_array(umath.power(fa, fb), m)


I don't have time right now to turn this into a proper patch, complete 
with test case, but if no one else can do it sooner then I can probably 
do it in the next day or two.  Here is a quick partial example of the 
behavior of the version above:

In [1]:import numpy as np

In [2]:xx = np.ma.array([-2.2, -2.2, 2.2, 2.2], mask = [True, False, 
False, True])

In [3]:xx
Out[3]:
masked_array(data = [-- -2.2 2.2 --],
       mask = [ True False False  True],
       fill_value=1e+20)


In [4]:np.ma.power(xx, 2.0)
Out[4]:
masked_array(data = [-- 4.84 4.84 --],
       mask = [ True False False  True],
       fill_value=1e+20)


In [5]:np.ma.power(xx, -2.0)
Out[5]:
masked_array(data = [-- 0.206611570248 0.206611570248 --],
       mask = [ True False False  True],
       fill_value=1e+20)


In [6]:np.ma.power(xx, -2.1)
Out[6]:
masked_array(data = [-- -- 0.190946793699 --],
       mask = [ True  True False  True],
       fill_value=1e+20)


Eric



Stéfan van der Walt wrote:
> 2008/5/9 Eric Firing <efiring@hawaii.edu>:
>> Pierre GM fixed this in r5137, so that the result is masked only if the
>> first argument is negative and the power is between -1 and 1.
> 
> Why should the output be masked only when the power is between -1 and
> 1?  Other powers also produce nan's.  Either way, the docstring should
> be updated:
> 
>     Computes a**b elementwise.
> 
>     Masked values are set to 1.
> 
> Regards
> Stéfan
> _______________________________________________
> Numpy-discussion mailing list
> Numpy-discussion@scipy.org
> http://projects.scipy.org/mailman/listinfo/numpy-discussion



More information about the Numpy-discussion mailing list