Reputation: 97
i defined a custom iterator, how can i do multiplication with numpy array and it?
from collections.abc import Iterable
class Vector3d(object):
def __init__(self, *args):
if len(args)==3:
self.x = args[0]
self.y = args[1]
self.z = args[2]
else:
self.x, self.y, self.z = args[0]
def _apply(self, func, o):
if isinstance(o, Iterable):
xyz = [self.x, self.y, self.z]
for i,j in enumerate(o):
xyz[i] = func(xyz[i], j)
return Vector3d(xyz)
else:
return Vector3d(func(self.x, o), func(self.y, o), func(self.z, o))
def __getitem__(self, i):
if i=='x' or i==0: return self.x
if i=='y' or i==1: return self.y
if i=='z' or i==2: return self.z
def __repr__(self): return "Vector3d({}, {}, {})".format(self.x, self.y, self.z)
def __iter__(self): return iter([self.x,self.y,self.z])
def __neg__(self): return Vector3d(-self.x, -self.y, -self.z)
def __add__(self, o): return self._apply(lambda x,y: x+y, o)
def __sub__(self, o): return self._apply(lambda x,y: x-y, o)
def __mul__(self, o): return self._apply(lambda x,y: x*y, o)
def __truediv__(self, o): return self._apply(lambda x,y: x/y, o)
def __eq__(self, o): return all(self._apply(lambda x,y: x==y, o))
def __ne__(self, o): return any(self._apply(lambda x,y: x!=y, o))
here is what happend when i do multiplication with numpy array and it
>>> a = np.array([[1,2,3],[4,5,6],[5,6,7]])
>>> a*Vector3d(1,2,3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for *: 'int' and 'Vector3d'
it seem numpy think it is not a vector, what should i do? thx
Upvotes: 1
Views: 82
Reputation: 36550
Use __rmul__
to implement custom behavior when object of your class is right (hence r
before mul
) to *
operator, consider following simple example
import numpy as np
class MyNumber:
def __init__(self, value):
self.value = value
def __rmul__(self, other):
print("MyNumber.__rmul__ triggered")
return other * self.value
arr = np.array([1,2,3])
dos = MyNumber(2)
arr2 = arr * dos
print(arr2)
gives output
MyNumber.__rmul__ triggered
MyNumber.__rmul__ triggered
MyNumber.__rmul__ triggered
[2 4 6]
Upvotes: 3