This question is close to what is asked in Overriding other __rmul__ with your class's __mul__ but I am under the impression that this is a more general problem then only numerical data. Also that is not answered and I really don't want to use the matrix multiplication @
for this operation. Hence, the question.
I do have an object which accepts multiplication with scalars and numerical arrays. As usual, the left multiplication works fine since it is the myobj()
methods are used but in the right multiplication, NumPy uses broadcasting rules and gives elementwise results with dtype=object
.
This has also the side-effect of not being able to check the size of the array whether the size is compatible or not.
Therefore, the question is
Is there a way to force numpy array to look for the
__rmul__()
of the other object instead of broadcasting and performing elementwise__mul__()
?
In my particular case, the object is a MIMO (multiple-input, multiple-output) transfer function matrix (or filter coefficients matrix if you will) so matrix multiplication has a special meaning in terms of adding and multiplying linear systems. Hence in each entry there is SISO system.
import numpy as np
class myobj():
def __init__(self):
pass
def __mul__(self, other):
if isinstance(other, type(np.array([0.]))):
if other.size == 1:
print('Scalar multiplication')
else:
print('Multiplication of arrays')
def __rmul__(self, other):
if isinstance(other, type(np.array([0.]))):
if other.size == 1:
print('Scalar multiplication')
else:
print('Multiplication of arrays')
A = myobj()
a = np.array([[[1+1j]]]) # some generic scalar
B = np.random.rand(3, 3)
With these definitions, the following commands show the undesired behavior.
In [123]: A*a
Scalar multiplication
In [124]: a*A
Out[124]: array([[[None]]], dtype=object)
In [125]: B*A
Out[125]:
array([[None, None, None],
[None, None, None],
[None, None, None]], dtype=object)
In [126]: A*B
Multiplication of arrays
In [127]: 5 * A
In [128]: A.__rmul__(B) # This is the desired behavior for B*A
Multiplication of arrays
@
was mentioned because it is anp.dot
like operator, not because it addresses thermul
issue. – Pickwickianmul
vrmul
is a basis python syntax issue. – Pickwickiandot()
like operation but I would like to take care of the row vector multiplications in a specialized way. The key point here is the broadcasting. I'm perfectly OK with mul vs rmul since numpy will not be able to see how it can multiply if it doesn't do the broadcasting. See the last example it works with no problem. – Lamblike