IsaacMak
IsaacMak

Reputation: 97

How can i do multiplication with numpy array and custom iterator

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

Answers (1)

Daweo
Daweo

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

Related Questions