[Numpy-discussion] ndarray.__mul__ is too gready?

Pearu Peterson pearu@cens.ioc...
Wed Jan 23 05:11:28 CST 2008


Say, one defines a class A that does not like to have numpy
arrays in the left-hand-side of an operation, say *,
but in the rhs it is expected.

For an example, consider A as a huge customized matrix that defines
only matrix * vector where vector can be numpy array
and scalar * matrix where scalar is python float or int.

Users may accidentally hit vector * matrix and this should raise
an exception. But when vector is numpy array, then ndarray.__mul__
calls element * A for each array element and here A.__rmul__
gets only the types of array elements (that are floats, for instance)
as rhs and hence is not able to decide that it should return
NotImplemented. Instead, it computes scalar * matrix and
the final result will be
  array([element1*matrix, element2*matrix, ..])
which is not desired already because of the memory usage and
should have raised an exception instead.

Here is a small example illustrating the problem:

class A:
    def __rmul__(self, other):
        if isinstance(other, ndarray):
            return NotImplemented
        if isinstance(other, (int, float)):
            return self # pretend other==1 for an example
        return NotImplemented

    def __repr__(self): return 'A()'

>>> array([1,2,3]) * A()
array([A(), A(), A()], dtype=object)
# expected TypeError

Is there any workaround to this problem?
In other situations/applications the above behavior of
ndarray.__mul__ is a feature but is there any way to
avoid this feature?


More information about the Numpy-discussion mailing list