<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Mar 17, 2016 at 10:41 PM, Stephan Hoyer <span dir="ltr"><<a href="mailto:shoyer@gmail.com" target="_blank">shoyer@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="">On Thu, Mar 17, 2016 at 1:04 AM, Travis Oliphant <span dir="ltr"><<a href="mailto:travis@continuum.io" target="_blank">travis@continuum.io</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span><div>I think that is a good idea.    Let the user decide if scalar broadcasting is acceptable for their function. <br></div></span><div><br></div><div>Here is a simple concrete example where scalar broadcasting makes sense:   </div><div><br></div><div>A 1-d dot product (the core of np.inner)   (k), (k) -> ()</div><div><br></div><div>A user would assume they could call this function with a scalar in either argument and have it broadcast to a 1-d array.    Of course, if both arguments are scalars, then it doesn't make sense.  </div><div><br></div><div>Having a way for the user to allow scalar broadcasting seems sensible and a nice compromise. </div><div><br></div><div>-Travis</div></div></div></div></blockquote><div><br></div></span><div>To generalize a little bit, consider the entire family of weighted statistical function (mean, std, median, etc.). For example, the gufunc version of np.average is basically equivalent to np.inner with a bit of preprocessing.</div><div><br></div><div>Arguably, it *could* make sense to broadcast weights when given a scalar: np.average(values, weights=1.0 / len(values)) is pretty unambiguous.</div><div><br></div><div>That said, adding an explicit "scalar broadcasting OK flag" seems like a hack that will need even more special logic (e.g., so we can error if both arguments to np.inner are scalars).</div><div><br></div><div>Multiple dispatch for gufunc core signatures seems like the cleaner solution. If you want np.inner to handle scalars, you need to supply core signatures (k),()->() and (),(k)->() along with (k),(k)->(). This is the similar to vision of three core signatures for np.matmul: (i),(i,j)->(j), (i,j),(j)->(i) and (i,j),(j,k)->(i,k).</div></div></div></div></blockquote><div><br></div><div>Would the logic for such a thing be consistent? E.g. how do you decide if the user is requesting (k),(k)->(), or (k),()->() with broadcasting over a non-core dimension of size k in the second argument? What if your signatures are (m, k),(k)->(m) and (k),(n,k)->(n) and your two inputs are (m,k) and (n,k), how do you decide which one to call? Or alternatively, how do you detect and forbid such ambiguous designs? Figuring out the dispatch rules for the general case seems like a non-trivial problem to me.</div><div><br></div><div>Jaime</div><div><br></div></div>-- <br><div class="gmail_signature">(\__/)<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></div>