Duplicate Python int * numpy.array behavior

I am trying to build a matrix class view complete with most normal math operations. I fell into a trap with the scalar multiplication operation.

The relevant part of the code looks like this:

import numpy

class Matrix(object):

    def __init__(self, array):
        self.array = numpy.array(array, dtype=int)

    def __mul__(self, other):
        if type(other) == int:
            return Matrix(other*self.array)
        else:
            raise ValueError("Can not multiply a matrix with {0}".format(type(other)))

      

The standard way to express scalar multiplication is cA, where c is a scalar and A is a matrix, hence c*A

in Python. However, this does not work with TypeError: unsupported operand type(s) for *: 'int' and 'Matrix'

, but A*c

works as expected (note on other*self.array

). So I conclude that the * operand is defined for int

and numpy.array

.

What is this magic and how can I reproduce the behavior?

+3


source to share


1 answer


You need __rmul__

in your calss. For example, if you added

def __rmul__(self, other):
    return self.__mul__(other)

      

then



>>> A = Matrix(np.arange(12).reshape(3, 4))
>>> (2 * A).array
array([[ 0,  2,  4,  6],
       [ 8, 10, 12, 14],
       [16, 18, 20, 22]])

      

As in the docs ,__r***__

are called to implement binary arithmetic operations with mirrored (replaced) operands. These functions are called only if the left operand does not support the corresponding operation and the operands are of different types.

+5


source







All Articles