
Hello list, I posted an issue many months ago [1] about confusing __array_wrap__ behavior in a subclass of np.matrix. Since that time I wasn't really using the code that used the matrix subclass, but lately I have starting using the code so I've run into the issue again. Looking into a little more detail, I think the root of the problem is how __array_wrap__ interacts with the dot functions. Operations like M*2 will be processed differently depending on whether M is a ndarray or matrix subclass; it appears that a matrix will always call np.dot for that operation, while an ndarray will go through np.multiply. Since dot acts differently than multiply here, you get different results between the two subclasses. I updated the gist to show the problem [2]. The output I get on my system is pasted at the bottom. It looks like __array_wrap__ gets called sometimes, depending on the type of one of the arguments. I'm not seeing any logical pattern to it, which makes it confusing. My expectation (perhaps incorrect) is that __array_wrap__ should be invoked any time dot is called. I guess that depends on whether dot should be considered a ufunc - I don't know the answer to that question. If someone with more knowledge of the internals could take a look at this, that would be great - I think this is a bug, but I'm not really sure what is the expected behavior here. Thanks, Aronne [1] http://mail.scipy.org/pipermail/numpy-discussion/2011-December/059665.html [2] https://gist.github.com/1511354 Output from run_test (see the gist code) using ipython: In [1]: import matrix_array_wrap_test as mtest; import numpy as np In [2]: np.__version__ Out[2]: '1.6.1' In [3]: np.dot Out[3]: <function numpy.core._dotblas.dot> In [4]: mtest.run_test() aw called? | creation | use Yes | o=ArrSubClass(2) | o2 = o + 2 Yes | o=ArrSubClass(2) | o2 = o + 2.0 Yes | o=ArrSubClass(2) | o2 = o * 2 Yes | o=ArrSubClass(2) | o2 = o * 2.0 Yes | o=ArrSubClass(2) | o2 = o * o.T No | o=ArrSubClass(2) | o2 = np.dot(o,2) No | o=ArrSubClass(2) | o2 = np.dot(o,2.0) No | o=ArrSubClass(2) | o2 = np.dot(o,o.T) Yes | o=ArrSubClass(2) | o2 = np.core.multiarray.dot(o,2) Yes | o=ArrSubClass(2) | o2 = np.core.multiarray.dot(o,2.0) No | o=ArrSubClass(2) | o2 = np.core.multiarray.dot(o,o.T) Yes | o=MatSubClass([1, 1]) | o2 = o + 2 Yes | o=MatSubClass([1, 1]) | o2 = o + 2.0 Yes | o=MatSubClass([1, 1]) | o2 = o * 2 No | o=MatSubClass([1, 1]) | o2 = o * 2.0 No | o=MatSubClass([1, 1]) | o2 = o * o.T Yes | o=MatSubClass([1, 1]) | o2 = np.dot(o,2) No | o=MatSubClass([1, 1]) | o2 = np.dot(o,2.0) No | o=MatSubClass([1, 1]) | o2 = np.dot(o,o.T) Yes | o=MatSubClass([1, 1]) | o2 = np.core.multiarray.dot(o,2) Yes | o=MatSubClass([1, 1]) | o2 = np.core.multiarray.dot(o,2.0) No | o=MatSubClass([1, 1]) | o2 = np.core.multiarray.dot(o,o.T) Yes | o=MatSubClass([1.0, 1.0]) | o2 = o + 2 Yes | o=MatSubClass([1.0, 1.0]) | o2 = o + 2.0 No | o=MatSubClass([1.0, 1.0]) | o2 = o * 2 No | o=MatSubClass([1.0, 1.0]) | o2 = o * 2.0 No | o=MatSubClass([1.0, 1.0]) | o2 = o * o.T No | o=MatSubClass([1.0, 1.0]) | o2 = np.dot(o,2) No | o=MatSubClass([1.0, 1.0]) | o2 = np.dot(o,2.0) No | o=MatSubClass([1.0, 1.0]) | o2 = np.dot(o,o.T) Yes | o=MatSubClass([1.0, 1.0]) | o2 = np.core.multiarray.dot(o,2) Yes | o=MatSubClass([1.0, 1.0]) | o2 = np.core.multiarray.dot(o,2.0) No | o=MatSubClass([1.0, 1.0]) | o2 = np.core.multiarray.dot(o,o.T)
participants (1)
-
Aronne Merrelli