<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Sep 16, 2014 at 12:27 PM, Charles R Harris <span dir="ltr"><<a href="mailto:charlesr.harris@gmail.com" target="_blank">charlesr.harris@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><div><div><div>Hi All,<br><br></div>It turns out that gufuncs will broadcast the last dimension if it is one. For instance, inner1d has signature `(n), (n) -> ()`, yet<br><br><span style="font-family:'courier new',monospace">In [27]: inner1d([1,1,1], [1])<br>Out[27]: 3<br><br>In [28]: inner1d([1,1,1], [1,1])<br>---------------------------------------------------------------------------<br>ValueError                                Traceback (most recent call last)<br><ipython-input-28-e53e62e35349> in <module>()<br>----> 1 inner1d([1,1,1], [1,1])<br><br>ValueError: inner1d: Operand 1 has a mismatch in its core dimension 0, with gufunc signature (i),(i)->() (size 2 is different from 3)<br></span><br><br></div>I'd think this is a bug, as the dimensions should match. Note that scalar 1 will be promoted to [1] in this case.<br><br></div>Thoughts?<br></div></div></blockquote><div><br></div><div>If it is a bug, it is an extended one, because it is the same behavior of einsum:</div><div><br></div><div><div><font face="courier new, monospace">>>> np.einsum('i,i', [1,1,1], [1])</font></div><div><font face="courier new, monospace">3</font></div><div><font face="courier new, monospace">>>> np.einsum('i,i', [1,1,1], [1,1])</font></div><div><font face="courier new, monospace">Traceback (most recent call last):</font></div><div><font face="courier new, monospace">  File "<stdin>", line 1, in <module></font></div><div><font face="courier new, monospace">ValueError: operands could not be broadcast together with remapped shapes [origi</font></div><div><font face="courier new, monospace">nal->remapped]: (3,)->(3,) (2,)->(2,)</font></div></div><div><br></div><div>And I think it is a conscious design decision, there is a comment about broadcasting missing core dimensions here:<br></div><div><br></div><div>    <a href="https://github.com/numpy/numpy/blob/master/numpy/core/src/umath/ufunc_object.c#L1940">https://github.com/numpy/numpy/blob/master/numpy/core/src/umath/ufunc_object.c#L1940</a><br></div><div><br></div><div>and the code makes it very explicit that input argument dimensions with the same label are broadcast to a common shape, see here:</div><div><br></div><div>    <a href="https://github.com/numpy/numpy/blob/master/numpy/core/src/umath/ufunc_object.c#L1956">https://github.com/numpy/numpy/blob/master/numpy/core/src/umath/ufunc_object.c#L1956</a><br></div><div><br></div><div>I kind of expect numpy to broadcast whenever possible, so this doesn't feel wrong to me.</div><div><br></div><div>That said, it is hard to come up with convincing examples of how this behavior would be useful in any practical context. But changing something that has been working like that for so long seems like a risky thing. And I cannot come with a convincing example of why it would be harmful either.</div><div><br></div><div>Jaime</div><div><br></div></div>-- <br>(\__/)<br>( O.o)<br>( > <) Este es Conejo. Copia a Conejo en tu firma y ayúdale en sus planes de dominación mundial.
</div></div>