[Numpy-discussion] unexpected behavior of __array_wrap__ in matrix subclass

Aronne Merrelli aronne.merrelli at gmail.com
Thu Dec 22 13:44:43 EST 2011


Hello NumPy list,

While experimenting with a subclass of numpy.matrix, I discovered cases
where __array_wrap__ is not called during multiplication. I'm not sure
whether this is a bug or my own misunderstanding of np.matrix &
__array_wrap__; if nothing else I thought it would be helpful to describe
this in case other people run into the same problem.

If the matrix is created from an array of integers, then __array_wrap__ is
called if the matrix is multiplied by an integer. It appears that in all
other cases, __array_wrap__ is not called for multiplication (int times
float scalar, float times float scalar, float matrix times float matrix,
etc). For addition, __array_wrap__ is called for all cases that I checked.

I did find a possible workaround. If you define a __mul__ method in the
matrix subclass, and then just call np.multiply, then __array_wrap__ is
called in all cases I expect it to be called.

I uploaded a example script here: https://gist.github.com/1511354

Hopefully it is not too confusing. I'm basically abusing the python
exception handler to tell whether or not __array_wrap__ is called for any
particular case. The MatSubClass shows the problem, and the
MatSubClassFixed as the __mul__ method defined. Here are the results I see
in my working environment (ipython in EPD 7.1):

In [1]: np.__version__
Out[1]: '1.6.0'
In [2]: execfile('matrix_array_wrap_test.py')
In [3]: run_test()
array_wrap called for o2 = o * 2 after o=MatSubClass([1,1])
array_wrap NOT called for o2 = o * 2.0 after o=MatSubClass([1,1])
array_wrap NOT called for o2 = o * 2 after o=MatSubClass([1.0, 1.0])
array_wrap NOT called for o2 = o * 2.0 after o=MatSubClass([1.0, 1.0])
array_wrap called for o2 = o * 2 after o=MatSubClassFixed([1,1])
array_wrap called for o2 = o * 2.0 after o=MatSubClassFixed([1,1])
array_wrap called for o2 = o * 2 after o=MatSubClassFixed([1.0, 1.0])
array_wrap called for o2 = o * 2.0 after o=MatSubClassFixed([1.0, 1.0])



Thanks,
Aronne
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20111222/4cb0135f/attachment.html>


More information about the NumPy-Discussion mailing list