<br><br><div class="gmail_quote">On Sun, Mar 8, 2009 at 3:27 PM, Darren Dale <span dir="ltr">&lt;<a href="mailto:dsdale24@gmail.com">dsdale24@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div class="gmail_quote"><div><div></div><div class="h5">On Sun, Mar 8, 2009 at 5:02 PM, Darren Dale <span dir="ltr">&lt;<a href="mailto:dsdale24@gmail.com" target="_blank">dsdale24@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">

<div><div></div><div><div class="gmail_quote">On Sun, Mar 8, 2009 at 4:54 PM, Charles R Harris <span dir="ltr">&lt;<a href="mailto:charlesr.harris@gmail.com" target="_blank">charlesr.harris@gmail.com</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br><br><div class="gmail_quote"><div><div></div><div>On Sun, Mar 8, 2009 at 2:48 PM, Charles R Harris <span dir="ltr">&lt;<a href="mailto:charlesr.harris@gmail.com" target="_blank">charlesr.harris@gmail.com</a>&gt;</span> wrote:<br>


<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br><br><div class="gmail_quote"><div><div></div><div>On Sun, Mar 8, 2009 at 1:04 PM, Darren Dale <span dir="ltr">&lt;<a href="mailto:dsdale24@gmail.com" target="_blank">dsdale24@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div class="gmail_quote"><div><div></div><div>On Sat, Mar 7, 2009 at 1:23 PM, Darren Dale <span dir="ltr">&lt;<a href="mailto:dsdale24@gmail.com" target="_blank">dsdale24@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">





<div><div></div><div><div class="gmail_quote">On Sun, Feb 22, 2009 at 7:01 PM, Darren Dale <span dir="ltr">&lt;<a href="mailto:dsdale24@gmail.com" target="_blank">dsdale24@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">






<div class="gmail_quote"><div><div></div><div>On Sun, Feb 22, 2009 at 6:35 PM, Darren Dale <span dir="ltr">&lt;<a href="mailto:dsdale24@gmail.com" target="_blank">dsdale24@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">







<div class="gmail_quote"><div>On Sun, Feb 22, 2009 at 6:28 PM, Pierre GM <span dir="ltr">&lt;<a href="mailto:pgmdevlist@gmail.com" target="_blank">pgmdevlist@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">








<div><br>
On Feb 22, 2009, at 6:21 PM, Eric Firing wrote:<br>
<br>
&gt; Darren Dale wrote:<br>
&gt;&gt; Does anyone know why __array_wrap__ is not called for subclasses<br>
&gt;&gt; during<br>
&gt;&gt; arithmetic operations where an iterable like a list or tuple<br>
&gt;&gt; appears to<br>
&gt;&gt; the right of the subclass? When I do &quot;mine*[1,2,3]&quot;, array_wrap is<br>
&gt;&gt; not<br>
&gt;&gt; called and I get an ndarray instead of a MyArray. &quot;[1,2,3]*mine&quot; is<br>
&gt;&gt; fine, as is &quot;mine*array([1,2,3])&quot;. I see the same issue with<br>
&gt;&gt; division,<br>
&gt;<br>
&gt; The masked array subclass does not show this behavior:<br>
<br>
</div>Because MaskedArray.__mul__ and others are redefined.<br>
<br>
Darren, you can fix your problem by redefining MyArray.__mul__ as:<br>
<br>
     def __mul__(self, other):<br>
         return np.ndarray.__mul__(self, np.asanyarray(other))<br>
<br>
forcing the second term to be a ndarray (or a subclass of). You can do<br>
the same thing for the other functions (__add__, __radd__, ...)</blockquote></div><div><br>Thanks for the suggestion. I know this can be done, but ufuncs like np.multiply(mine,[1,2,3]) will still not work. Plus, if I reimplement these methods, I take some small performance hit. I&#39;ve been putting a lot of work in lately to get quantities to work with numpy&#39;s stock ufuncs.</div>







</div></blockquote></div></div><div><br>I should point out:<br><br>import numpy as np<br><br>a=np.array([1,2,3,4])<br>b=np.ma.masked_where(a&gt;2,a)<br>np.multiply([1,2,3,4],b) # yields a masked array<br>np.multiply(b,[1,2,3,4]) # yields an ndarray <br>







</div></div><br>
</blockquote></div><br></div></div>I&#39;m not familiar with the numpy codebase, could anyone help me figure out where I should look to try to fix this bug? I&#39;ve got a nice set of generators that work with nosetools to test all combinations of numerical dtypes, including combinations of scalars, arrays, and iterables of each type. In my quantities package, just testing multiplication yields 1031 failures, all of which appear to be caused by this bug (#1026 on trak) or bug #826.<font color="#888888"></font></blockquote>





</div></div><div><br><br>I finally managed to track done the source of this problem. _find_array_wrap steps through the inputs, asking each of them for their __array_wrap__ and binding it to wrap. If more than one input defines __array_wrap__, you enter a block that selects one based on array priority, and binds it back to wrap. The problem was when the first input defines array_wrap but the second one does not. In that case, _find_array_wrap never bothered to rebind the desired wraps[0] to wrap, so wrap remains Null or None, and wrap is what is returned to the calling function. <br>





<br>I&#39;ve tested numpy with this patch applied, and didn&#39;t see any regressions. Would someone please consider committing it?<br><br>Thanks,<br>Darren<br><br>$ svn diff numpy/core/src/umath_ufunc_object.inc <br>Index: numpy/core/src/umath_ufunc_object.inc                       <br>





===================================================================<br>--- numpy/core/src/umath_ufunc_object.inc       (revision 6569)<br>+++ numpy/core/src/umath_ufunc_object.inc       (working copy)<br>@@ -3173,8 +3173,10 @@<br>





             PyErr_Clear();<br>         }<br>     }<br>+    if (np &gt;= 1) {<br>+        wrap = wraps[0];<br>+    }<br>     if (np &gt;= 2) {<br>-        wrap = wraps[0];<br>         maxpriority = PyArray_GetPriority(with_wrap[0],<br>





                                         PyArray_SUBTYPE_PRIORITY);<br>         for (i = 1; i &lt; np; ++i) {<br></div></div></blockquote></div></div><div><br>Applied in r6573. Thanks.<br></div></div></blockquote></div></div>


<div><br>
Oh, and can you provide a test for this fix? <br></div></div></blockquote><div> </div></div></div></div>Yes, I&#39;ll send a patch for a test as soon as its ready. 6573 closes two tickets, 1026 and 1022. Did you see the patch I sent for issue #826? It is also posted at the bug report.<font color="#888888"></font></blockquote>

</div></div><div><br><br>Index: numpy/core/tests/test_umath.py<br>===================================================================<br>--- numpy/core/tests/test_umath.py      (revision 6573)<br>+++ numpy/core/tests/test_umath.py      (working copy)<br>

@@ -240,6 +240,19 @@<br>         assert_equal(args[1], a)<br>         self.failUnlessEqual(i, 0)<br><br>+    def test_wrap_with_iterable(self):<br>+        # test fix for bug #1026:<br>+        class with_wrap(np.ndarray):<br>

+            __array_priority = 10<br>+            def __new__(cls):<br>+                return np.asarray(1).view(cls).copy()<br>+            def __array_wrap__(self, arr, context):<br>+                return arr.view(type(self))<br>

+        a = with_wrap()<br>+        x = ncu.multiply(a, (1, 2, 3))<br>+        self.failUnless(isinstance(x, with_wrap))<br>+        assert_array_equal(x, np.array((1, 2, 3)))<br>+<br>     def test_old_wrap(self):<br>         class with_wrap(object):<br>

             def __array__(self): <br></div></div></blockquote><div><br>Thanks. This was applied in r6575.<br><br>Chuck <br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br></blockquote></div><br>