Reputation: 2243
I'm attempting to build a class representation of a matrix complete with most of the normal mathematical operations. I've hit a snag with the scalar multiplication operation.
The relevant part of the code is as follows:
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 the scalar multiplication is expressed is cA where c is a scalar and A is a matrix, so c*A
in Python. However, this fails with a TypeError: unsupported operand type(s) for *: 'int' and 'Matrix'
while A*c
runs as expected (note the other*self.array
). Thus I conclude that the * operand is defined for int
and numpy.array
.
What is this magic and how can I replicate the behavior?
Upvotes: 3
Views: 39
Reputation: 77961
You need a __rmul__
in your calss. For example if you add
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, the __r***__
are called to implement the binary arithmetic operations with reflected (swapped) operands. These functions are only called if the left operand does not support the corresponding operation and the operands are of different types.
Upvotes: 5