Re: Suppressing of numpy __mul__, __div__ etc
Dag Sverre Seljebotn <dagss <at> student.matnat.uio.no>
2009-12-13 22:05:21 GMT
Robert Kern wrote:
> On Sat, Dec 12, 2009 at 14:56, Charles R Harris
> <charlesr.harris <at> gmail.com> wrote:
>> 2009/12/12 Dmitrey <tmp50 <at> ukr.net>
>>> hello all,
>>> I have class oofun (in a package FuncDesigner, that is already used by
>>> lots of people) where some operations on numpy arrays (along with
>>> lists and numbers) are overloaded, such as __mul__, __add__, __pow__,
>>> __div__ etc.
>>> There is a problem with numpy arrays: if I use a*f where a is array and
>>> is oofun, it returns array with elements a[i]*f. Would it omit calling
>>> array.__mul__ and call only oofun.__rmul__, like it is done in
>>> and Python lists/numbers, all would work ok as expected; but now it
>>> FuncDesigner code to work much slower or unexpectedly or doesn't work
>>> at all
>>> So, does anyone mind if I'll commit some changes to numpy __mul__,
>>> I intend to implement the following walkaround:
>>> Now the code looks like this for array:
>>> def __mul__(self, i):
>>> return asarray(multiply(self, i))
>>> and like this for numpy/matrixlib/defmatrix.py:
>>> def __mul__(self, other):
>>> if isinstance(other,(N.ndarray, list, tuple)) :
>>> return N.dot(self, asmatrix(other))
>>> if isscalar(other) or not hasattr(other, '__rmul__') :
>>> return N.dot(self, other)
>>> return NotImplemented
>>> and I want to add an empty class named "CNumpyLeftOperatorOverloaded"
>>> numpy, and if someone defines his class as a child of the one, __mul__
>>> others will not invoke __div__ etc, calling otherClass.__rdiv__ etc:
>>> def __mul__(self, i):
>>> return asarray(multiply(self, i)) if not
>>> isinstance(i,CNumpyLeftOperatorOverloaded) else i.__rmul__(self)
>>> and declare my class as a child of the one.
>>> As far as I understood, the changes should be added to
>>> So, does anyone mind me to implement it?
>> Sounds like you are exporting an array interface or subclassing ndarray.
>> the latter, you might be able to manipulate the value of
>> I haven't experimented with these things myself.
> I don't think he's subclassing ndarray, but does have a class that
> shouldn't be interpreted by ndarray as a scalar. In any case,
> __array_priority__ doesn't matter; it just controls which type the
> output of a multi-input ufunc.
>> As to the proposed solutions, they are the start of a slippery slope of
>> trying to identify all objects to which they should apply. I don't think
>> want to go there.
> I think what he is asking for is an empty mixin class which other
> folks could subclass to mark their classes. It would say "Hey,
> ndarray! Let my __mul__, __rmul__, etc., take priority over yours,
> regardless of which of us comes first in the expression." Otherwise,
> ndarray will gladly consume pretty much any object on the other side
> of the operator because it will treat it as an object scalar.
> We could also define a standard attribute that could mark such classes
> instead of requiring a mixin subclass.
FWIW, I'd like to submit a patch to Sage for making NumPy arrays and Sage
matrices work better together which would require this functionality. +1
for an attribute and not a mixin, as that would allow Cython classes as
Something like "__do_not_treat_as_scalar__ = True". The idea is simply to
stop ndarray from handling the operation, and let other classes implement
specific support for arithmetic with NumPy arrays. Which is not a slippery
slope at all.