<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Apr 17, 2015 at 12:09 PM,  <span dir="ltr"><<a href="mailto:josef.pktd@gmail.com" target="_blank">josef.pktd@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 class="HOEnZb"><div class="h5">On Fri, Apr 17, 2015 at 11:22 AM, Neil Girdhar <<a href="mailto:mistersheik@gmail.com">mistersheik@gmail.com</a>> wrote:<br>
><br>
><br>
> On Fri, Apr 17, 2015 at 10:47 AM, <<a href="mailto:josef.pktd@gmail.com">josef.pktd@gmail.com</a>> wrote:<br>
>><br>
>> On Fri, Apr 17, 2015 at 10:07 AM, Sebastian Berg<br>
>> <<a href="mailto:sebastian@sipsolutions.net">sebastian@sipsolutions.net</a>> wrote:<br>
>> > On Do, 2015-04-16 at 15:28 -0700, Matthew Brett wrote:<br>
>> >> Hi,<br>
>> >><br>
>> > <snip><br>
>> >><br>
>> >> So, how about a slight modification of your proposal?<br>
>> >><br>
>> >> 1) Raise deprecation warning for np.outer for non 1D arrays for a few<br>
>> >> versions, with depraction in favor of np.multiply.outer, then<br>
>> >> 2) Raise error for np.outer on non 1D arrays<br>
>> >><br>
>> ><br>
>> > I think that was Neil's proposal a bit earlier, too. +1 for it in any<br>
>> > case, since at least for the moment I doubt outer is used a lot for non<br>
>> > 1-d arrays. Possible step 3) make it work on higher dims after a long<br>
>> > period.<br>
>><br>
>> sounds ok to me<br>
>><br>
>> Some random comments of what I remember or guess in terms of usage<br>
>><br>
>> I think there are at most very few np.outer usages with 2d or higher<br>
>> dimension.<br>
>> (statsmodels has two models that switch between 2d and 1d<br>
>> parameterization where we don't use outer but it has similar<br>
>> characteristics. However, we need to control the ravel order, which<br>
>> IIRC is Fortran)<br>
>><br>
>> The current behavior of 0-D scalars in the initial post might be<br>
>> useful if a numpy function returns a scalar instead of a 1-D array in<br>
>> size=1. np.diag which is a common case, doesn't return a scalar (in my<br>
>> version of numpy).<br>
>><br>
>> I don't know any use case where I would ever want to have the 2d<br>
>> behavior of np.multiply.outer.<br>
><br>
<br>
</div></div>I only understand part of your example, but it looks similar to what<br>
we are doing in statsmodels.<br>
<span class=""><br>
><br>
> My use case is pretty simple.  Given an input vector x, and a weight matrix<br>
> W, and a model y=Wx, I calculate the gradient of the loss L with respect W.<br>
> It is the outer product of x with the vector of gradients dL/dy.  So the<br>
> code is simply:<br>
><br>
> W -= outer(x, dL_by_dy)<br>
<br>
</span>if you sum/subtract over all the values, isn't this the same as<br>
np.dot(x, dL_by_dy)<br>
<span class=""><br>
<br>
><br>
> Sometimes, I have some x_indices and y_indices.  Now I want to do:<br>
><br>
> W[x_indices, y_indices] -= outer(x[x_indices], dL_by_dy[y_indices])<br>
><br>
> Unfortunately, if x_indices or y_indices are "int" or slice in some way that<br>
> removes a dimension, the left side will have fewer dimensions than the<br>
> right.  np.multipy.outer does the right thing without the ugly cases:<br>
><br>
> if isinstance(x_indices, int): … # ugly hacks follow.<br>
<br>
</span>My usual hacks are either to use np.atleast_1d or np.atleast_1d or<br>
np.squeeze if there is shape mismatch in some cases.<br>
<span class=""><br>
><br>
>> I guess we will or would have applications for outer along an axis,<br>
>> for example if x.shape = (100, 10), then we have<br>
>> x[:,None, :] * x[:, :, None]     (I guess)<br>
>> Something like this shows up reasonably often in econometrics as<br>
>> "Outer Product". However in most cases we can avoid constructing this<br>
>> matrix and get the final results in a more memory efficient or faster<br>
>> way.<br>
>> (example an array of covariance matrices)<br>
><br>
><br>
> Not sure I see this.  outer(a, b) should return something that has shape:<br>
> (a.shape + b.shape).  If you're doing it "along an axis", you mean you're<br>
> reshuffling the resulting shape vector?<br>
<br>
</span>No I'm not reshaping the full tensor product.<br>
<br>
It's a vectorized version of looping over independent outer products<br>
<br>
np.array([outer(xi, yi) for xi,yi in zip(x, y)])<br>
(which I would never use with outer)<br>
<br>
but I have code that works similar for a reduce (or reduce_at) loop over this.<br></blockquote><div><br></div><div>Hmmm… I see what your'e writing.   This doesn't really have a geometrical meaning as far as I can tell.  You're interpreting the first index of x, y, and your result, as if it were a list — as if x and y are lists of vectors, and you want a list of matrices.   That really should be written as a loop in my opinion. </div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Josef<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
>><br>
>><br>
>> Josef<br>
>><br>
>><br>
>><br>
>><br>
>> ><br>
>> > - Sebastian<br>
>> ><br>
>> ><br>
>> >> Best,<br>
>> >><br>
>> >> Matthew<br>
>> >> _______________________________________________<br>
>> >> NumPy-Discussion mailing list<br>
>> >> <a href="mailto:NumPy-Discussion@scipy.org">NumPy-Discussion@scipy.org</a><br>
>> >> <a href="http://mail.scipy.org/mailman/listinfo/numpy-discussion" target="_blank">http://mail.scipy.org/mailman/listinfo/numpy-discussion</a><br>
>> >><br>
>> ><br>
>> ><br>
>> > _______________________________________________<br>
>> > NumPy-Discussion mailing list<br>
>> > <a href="mailto:NumPy-Discussion@scipy.org">NumPy-Discussion@scipy.org</a><br>
>> > <a href="http://mail.scipy.org/mailman/listinfo/numpy-discussion" target="_blank">http://mail.scipy.org/mailman/listinfo/numpy-discussion</a><br>
>> ><br>
>> _______________________________________________<br>
>> NumPy-Discussion mailing list<br>
>> <a href="mailto:NumPy-Discussion@scipy.org">NumPy-Discussion@scipy.org</a><br>
>> <a href="http://mail.scipy.org/mailman/listinfo/numpy-discussion" target="_blank">http://mail.scipy.org/mailman/listinfo/numpy-discussion</a><br>
><br>
><br>
><br>
> _______________________________________________<br>
> NumPy-Discussion mailing list<br>
> <a href="mailto:NumPy-Discussion@scipy.org">NumPy-Discussion@scipy.org</a><br>
> <a href="http://mail.scipy.org/mailman/listinfo/numpy-discussion" target="_blank">http://mail.scipy.org/mailman/listinfo/numpy-discussion</a><br>
><br>
_______________________________________________<br>
NumPy-Discussion mailing list<br>
<a href="mailto:NumPy-Discussion@scipy.org">NumPy-Discussion@scipy.org</a><br>
<a href="http://mail.scipy.org/mailman/listinfo/numpy-discussion" target="_blank">http://mail.scipy.org/mailman/listinfo/numpy-discussion</a><br>
</div></div></blockquote></div><br></div></div>