matrices and __radd__

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

matrices and __radd__

Keith Goodman
I have a class that stores some of its data in a matrix. I can't
figure out how to do right adds with a matrix. Here's a toy example:

class Myclass(object):

    def __init__(self, x, a):
        self.x = x  # numpy matrix
        self.a = a  # some attribute, say, an integer

    def __add__(self, other):
        # Assume other is a numpy matrix
        return Myclass(self.x + other, self.a += 1)

    def __radd__(self, other):
        print other

>> from myclass import Myclass
>> import numpy.matlib as mp
>> m = Myclass(mp.zeros((2,2)), 1)
>> x = mp.asmatrix(range(4)).reshape(2,2)
>> radd = x + m
0
1
2
3

The matrix.__add__ sends one element at a time. That sounds slow. Do I
have to grab the corresponding element of self.x and add it to the
element passed in by matrix.__add__? Or is there a better way?
_______________________________________________
Numpy-discussion mailing list
[hidden email]
http://projects.scipy.org/mailman/listinfo/numpy-discussion
Reply | Threaded
Open this post in threaded view
|

Re: matrices and __radd__

Robert Kern-2
On Wed, May 21, 2008 at 5:28 PM, Keith Goodman <[hidden email]> wrote:

> I have a class that stores some of its data in a matrix. I can't
> figure out how to do right adds with a matrix. Here's a toy example:
>
> class Myclass(object):
>
>    def __init__(self, x, a):
>        self.x = x  # numpy matrix
>        self.a = a  # some attribute, say, an integer
>
>    def __add__(self, other):
>        # Assume other is a numpy matrix
>        return Myclass(self.x + other, self.a += 1)
>
>    def __radd__(self, other):
>        print other
>
>>> from myclass import Myclass
>>> import numpy.matlib as mp
>>> m = Myclass(mp.zeros((2,2)), 1)
>>> x = mp.asmatrix(range(4)).reshape(2,2)
>>> radd = x + m
> 0
> 1
> 2
> 3
>
> The matrix.__add__ sends one element at a time. That sounds slow.

Well, what's actually going on here is this: ndarray.__add__() looks
at m and decides that it doesn't look like anything it can make an
array from. However, it does have an __add__() method, so it assumes
that it is intended to be a scalar. It uses broadcasting to treat it
as if it were an object array of the shape of x with each element
identical. Then it adds together the two arrays element-wise. Each
element-wise addition triggers the MyClass.__radd__() call.

> Do I
> have to grab the corresponding element of self.x and add it to the
> element passed in by matrix.__add__? Or is there a better way?

There probably is, but not being familiar with your actual use case,
I'm not sure what it would be.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
 -- Umberto Eco
_______________________________________________
Numpy-discussion mailing list
[hidden email]
http://projects.scipy.org/mailman/listinfo/numpy-discussion
Reply | Threaded
Open this post in threaded view
|

Re: matrices and __radd__

Keith Goodman
On Wed, May 21, 2008 at 4:07 PM, Robert Kern <[hidden email]> wrote:

> On Wed, May 21, 2008 at 5:28 PM, Keith Goodman <[hidden email]> wrote:
>> I have a class that stores some of its data in a matrix. I can't
>> figure out how to do right adds with a matrix. Here's a toy example:
>>
>> class Myclass(object):
>>
>>    def __init__(self, x, a):
>>        self.x = x  # numpy matrix
>>        self.a = a  # some attribute, say, an integer
>>
>>    def __add__(self, other):
>>        # Assume other is a numpy matrix
>>        return Myclass(self.x + other, self.a += 1)
>>
>>    def __radd__(self, other):
>>        print other
>>
>>>> from myclass import Myclass
>>>> import numpy.matlib as mp
>>>> m = Myclass(mp.zeros((2,2)), 1)
>>>> x = mp.asmatrix(range(4)).reshape(2,2)
>>>> radd = x + m
>> 0
>> 1
>> 2
>> 3
>>
>> The matrix.__add__ sends one element at a time. That sounds slow.
>
> Well, what's actually going on here is this: ndarray.__add__() looks
> at m and decides that it doesn't look like anything it can make an
> array from. However, it does have an __add__() method, so it assumes
> that it is intended to be a scalar. It uses broadcasting to treat it
> as if it were an object array of the shape of x with each element
> identical. Then it adds together the two arrays element-wise. Each
> element-wise addition triggers the MyClass.__radd__() call.

Oh, broadcasting. OK that makes sense.

>> Do I
>> have to grab the corresponding element of self.x and add it to the
>> element passed in by matrix.__add__? Or is there a better way?
>
> There probably is, but not being familiar with your actual use case,
> I'm not sure what it would be.

From

http://projects.scipy.org/pipermail/numpy-discussion/2006-December/025075.html

I see that the trick is to add

__array_priority__ = 10

to my class.

class Myclass(object):

    __array_priority__ = 10

    def __init__(self, x, a):
        self.x = x  # numpy matrix
        self.a = a  # some attribute, say, an integer

    def __add__(self, other):
        # Assume other is a numpy matrix
        return Myclass(self.x + other, 2*self.a)

    __radd__ = __add__

>> from myclass import Myclass
>> import numpy.matlib as mp
>> m = Myclass(mp.zeros((2,2)), 1)
>> x = mp.asmatrix(range(4)).reshape(2,2)
>> radd = x + m
>> radd.a
   2
>> radd.x

matrix([[ 0.,  1.],
        [ 2.,  3.]])
_______________________________________________
Numpy-discussion mailing list
[hidden email]
http://projects.scipy.org/mailman/listinfo/numpy-discussion