when 'myArray * 'myObject' is not equal to 'myObject' * 'myArray'

D

Duim

Although I'm sure somewhere this issue is discussed in this (great)
group, I didn't know the proper search words for it (although I
tried).

I'm using python (2.6) scientifically mostly, and created a simple
class to store time series (my 'Signal' class).
I need this class to have a possibility to get multiplied by an array,
but pre and post multiplication have different mathematical outcomes
( basically A* B != B*A ) .

Post multiplication by an array works fine defining __mul__ in the
Signal class, but pre multiplication does not. It keeps trying to
multiply all elements separately instead to send this array to my
__rmul__ function.

How can I fix this without the need for a separate
'multiplysignal(A,B)' function?
To make things easy I've made a small example:

Code:
import numpy as np

class Signal(object):
    def __init__(self,data,dt):
        self.data=data
        self.dt=dt

    def Nch(self):
        return self.data.shape[0]

    def __mul__(self,other):
        print 'mul called! ',other

        if isinstance(other,type(np.array([1,2]))):
            #it's an array: use dot product:
            return Signal(np.dot(self.data,other),self.dt)


        if other.__class__.__name__=='Signal':
            # do something
            pass


    def __rmul__(self,other):
        print 'rmul called! ',other

        if isinstance(other,type(np.array([1,2]))):
            #it's an array: use dot product:
            return Signal(np.dot(other,self.data),self.dt)


        if other.__class__.__name__=='Signal':
            # do something
            pass

mySignal=Signal(np.array([[1.,2],[4,5]]),1.)
myArray=np.array([[1.,2.],[4.,3.]])

result_mul = mySignal*myArray
result_rmul = myArray*mySignal #called 4 times for all members once!

#result:
#mul called!  [[ 1.  2.]
# [ 4.  3.]]
#rmul called!  1.0
#rmul called!  2.0
#rmul called!  4.0
#rmul called!  3.0
 
N

Nobody

Although I'm sure somewhere this issue is discussed in this (great)
group, I didn't know the proper search words for it (although I
tried).

I'm using python (2.6) scientifically mostly, and created a simple
class to store time series (my 'Signal' class).
I need this class to have a possibility to get multiplied by an array,
but pre and post multiplication have different mathematical outcomes
( basically A* B != B*A ) .

Post multiplication by an array works fine defining __mul__ in the
Signal class, but pre multiplication does not. It keeps trying to
multiply all elements separately instead to send this array to my
__rmul__ function.

How can I fix this without the need for a separate
'multiplysignal(A,B)' function?

Make Signal a subclass of numpy.ndarray. If one operand is a subclass of
the other, its __rmul__ will be preferred to the parent's __mul__.

In the absence of a subclass-superclass relationship, the LHS's __mul__ is
preferred to the RHS's __rmul__, so the RHS's __rmul__ is only called if
the LHS lacks a __mul__ method or if the method refuses its argument
(returns NotImplemented).

Likewise for other "reflected" methods.
 
D

Duim

Make Signal a subclass of numpy.ndarray. If one operand is a subclass of
the other, its __rmul__ will be preferred to the parent's __mul__.

In the absence of a subclass-superclass relationship, the LHS's __mul__ is
preferred to the RHS's __rmul__, so the RHS's __rmul__ is only called if
the LHS lacks a __mul__ method or if the method refuses its argument
(returns NotImplemented).

Likewise for other "reflected" methods.

Great, many thanks. It seems to work well.
For others looking into the same issue: http://www.scipy.org/Subclasses
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top