[Numpy-discussion] Scalar-ndarray arguments passed to not_equal

Keith Goodman kwgoodman at gmail.com
Wed Feb 10 14:04:32 EST 2010


On Wed, Feb 10, 2010 at 10:57 AM, Friedrich Romstedt
<friedrichromstedt at gmail.com> wrote:
> I wonder why there is no response on my e-mail dating back to Feb 4.
> Is there nobody interested in it, is somebody working on it, or did it
> simply did not come through?  I changed the recipient now to
> "Discussion of Numerical Python", hth ...
>
> Sorry when there is double posting now, it's not intended if so.
>
> 2010/2/4 Friedrich Romstedt <friedrichromstedt at gmail.com>:
>> Hi,
>>
>> I'm just coding a package for uncertain arrays using the accelerated
>> numpy functionality intensively.  I'm sorry, but I have to give some
>> background information first.  The package provides a class
>> upy.undarray, which holds the nominal value and the uncertainty
>> information.  It has methods __add__(other), __radd__(other), ...,
>> __eq__(other), __ne__(other), which accept both upy.undarrays and all
>> other values suitable for coercion, thus also native numpy.ndarrays.
>> But because numpy treats in the statement:
>>
>> result = numpyarray * upyarray
>>
>> upyarray as a scalar, because it's not an numpy.ndarray, I have to
>> overload the numpy arithmetics by own objects by using
>> numpy.set_numeric_ops(add = ..., ..., equal = equal, not_equal =
>> not_equal).  The arguments are defined by the module (it will be
>> clearifiied below).
>>
>> Because numpy.add etc. are ufuncs exhibiting attributes, I wrote a
>> class to wrap them:
>>
>> class ufuncWrap:
>>        """Wraps numpy ufuncs.  Behaves like the original, with the exception
>>        that __call__() will be overloaded."""
>>
>>        def __init__(self, ufunc, overload):
>>                """UFUNC is the ufunc to be wrapped.  OVERLOAD is the name (string)
>>                of the undarray method to be used in overloading __call__()."""
>>
>>                self.ufunc = ufunc
>>                self.overload = overload
>>
>>        def __call__(self, a, b, *args, **kwargs):
>>                """When B is an undarray, call B.overload(a), else .ufunc(a, b)."""
>>
>>                if isinstance(b, undarray):
>>                        return getattr(b, self.overload)(a)
>>                else:
>>                        return self.ufunc(a, b, *args, **kwargs)
>>
>>        def __getattr__(self, attr):
>>                """Return getattr(.ufunc, ATTR)."""
>>
>>                return getattr(self.ufunc, attr)
>>
>> I only have to wrap binary operators.
>>
>> Then, e.g.:
>>
>> class Equal(ufuncWrap):
>>        def __init__(self):
>>                ufuncWrap.__init__(self, numpy.equal, '__eq__')
>>
>> equal = Equal()
>>
>> This works as expected.
>>
>> But this approach fails (in first iteration) for a similar class
>> NotEqual. I have let the module output the arguments passed to
>> ufuncWrap.__call__(), and I found that the statement:
>>
>> result = (numpyarray != upyarray)
>>
>> with:
>>
>> numpyarray = numpy.asarray([1.0])
>> upyarray = upy.ndarray([2.0], error = [0.1])
>>
>> is passed on to NotEqual.__call__() as the arguments:
>>
>> a = a numpy-array array([1.0])
>> b = a numpy-array array(shape = (), dtype = numpy.object), which is a
>> scalar array holding the upy.ndarray instance passed to !=.
>>
>> I can work around the exhbited behaviour by:
>>
>> class NotEqual(ufuncWrap):
>>        def __init__(self):
>>                ufuncWrap.__init__(self, numpy.not_equal, '__ne__')
>>
>>        def __call__(self, a, b, *args, **kwargs):
>>                # numpy's calling mechanism of not_equal() seems to have a bug,
>>                # such that b is always a numpy.ndarray.  When b should be an undarray,
>>                # it is a numpy.ndarray(dtype = numpy.object, shape = ()) ...
>>
>>                # Make the call also compatible with future, bug-fixed versions.
>>                if isinstance(b, numpy.ndarray):
>>                        if b.ndim == 0:
>>                                # Implement some conversion from scalar array to stored object.
>>                                b = b.sum()
>>
>>                return ufuncWrap.__call__(self, a, b, *args, **kwargs)
>>
>> What is the reason for the behaviour observed?
>>
>> I'm using numpy 1.4.0 with Python 2.5.
>>
>> Friedrich

No one answered my post either  :(

http://old.nabble.com/arrays-and-__eq__-td26987903.html#a26987903

Is it the same issue?



More information about the NumPy-Discussion mailing list