Consider improving numpy.outer's behavior with zero-dimensional vectors

Numpy's outer product works fine with vectors. However, I seem to always want len(outer(a, b).shape) to be equal to len(a.shape) + len(b.shape). Wolfram-alpha seems to agree https://reference.wolfram.com/language/ref/Outer.html with respect to matrix outer products. My suggestion is to define outer as defined below. I've contrasted it with numpy's current outer product. In [36]: def a(n): return np.ones(n) In [37]: b = a(()) In [38]: c = a(4) In [39]: d = a(5) In [40]: np.outer(b, d).shape Out[40]: (1, 5) In [41]: np.outer(c, d).shape Out[41]: (4, 5) In [42]: np.outer(c, b).shape Out[42]: (4, 1) In [43]: def outer(a, b): return a[(...,) + len(b.shape) * (np.newaxis,)] * b ....: In [44]: outer(b, d).shape Out[44]: (5,) In [45]: outer(c, d).shape Out[45]: (4, 5) In [46]: outer(c, b).shape Out[46]: (4,) Best, Neil

On Mi, 2015-04-08 at 19:34 -0400, Neil Girdhar wrote:
Numpy's outer product works fine with vectors. However, I seem to always want len(outer(a, b).shape) to be equal to len(a.shape) + len(b.shape). Wolfram-alpha seems to agree https://reference.wolfram.com/language/ref/Outer.html with respect to matrix outer products. My suggestion is to define outer as defined below. I've contrasted it with numpy's current outer product.
Actually this behaviour already exists (I was not aware it was different) for all ufuncs, though it is not that well known, and I tend to broadcast manually which may be a pity ;): np.multiply.outer(a, b) does exactly what you want, though I am not sure if np.outer might leverage blas or not. - Sebastian
In [36]: def a(n): return np.ones(n)
In [37]: b = a(())
In [38]: c = a(4)
In [39]: d = a(5)
In [40]: np.outer(b, d).shape Out[40]: (1, 5)
In [41]: np.outer(c, d).shape Out[41]: (4, 5)
In [42]: np.outer(c, b).shape Out[42]: (4, 1)
In [43]: def outer(a, b): return a[(...,) + len(b.shape) * (np.newaxis,)] * b ....:
In [44]: outer(b, d).shape Out[44]: (5,)
In [45]: outer(c, d).shape Out[45]: (4, 5)
In [46]: outer(c, b).shape Out[46]: (4,)
Best,
Neil _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Wed, Apr 8, 2015 at 7:34 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
Numpy's outer product works fine with vectors. However, I seem to always want len(outer(a, b).shape) to be equal to len(a.shape) + len(b.shape). Wolfram-alpha seems to agree https://reference.wolfram.com/language/ref/Outer.html with respect to matrix outer products.
You're probably right that this is the correct definition of the outer product in an n-dimensional world. But this seems to go beyond being just a bug in handling 0-d arrays (which is the kind of corner case we've fixed in the past); np.outer is documented to always ravel its inputs to 1d. In fact the implementation is literally just: a = asarray(a) b = asarray(b) return multiply(a.ravel()[:, newaxis], b.ravel()[newaxis,:], out) Sebastian's np.multiply.outer is much more generic and effective. Maybe we should just deprecate np.outer? I don't see what use it serves. (When and whether it actually got removed after being deprecated would depend on how much use it actually gets in real code, which I certainly don't know while typing a quick email. But we could start telling people not to use it any time.) -n -- Nathaniel J. Smith -- http://vorpus.org

On Wed, Apr 8, 2015 at 7:34 PM, Neil Girdhar <mistersheik@gmail.com <http://mail.scipy.org/mailman/listinfo/numpy-discussion>> wrote:
* Numpy's outer product works fine with vectors. However, I seem to always *> * want len(outer(a, b).shape) to be equal to len(a.shape) + len(b.shape). *
* Wolfram-alpha seems to agree *> * https://reference.wolfram.com/language/ref/Outer.html <https://reference.wolfram.com/language/ref/Outer.html> with respect to matrix *> * outer products. * You're probably right that this is the correct definition of the outer product in an n-dimensional world. But this seems to go beyond being just a bug in handling 0-d arrays (which is the kind of corner case we've fixed in the past); np.outer is documented to always ravel its inputs to 1d. In fact the implementation is literally just: a = asarray(a) b = asarray(b) return multiply(a.ravel()[:, newaxis], b.ravel()[newaxis,:], out) Sebastian's np.multiply.outer is much more generic and effective. Maybe we should just deprecate np.outer? I don't see what use it serves. (When and whether it actually got removed after being deprecated would depend on how much use it actually gets in real code, which I certainly don't know while typing a quick email. But we could start telling people not to use it any time.)
+1 with everything you said. (And thanks Sebastian for the pointer to np.multiply.outer!)
-n
On Wed, Apr 8, 2015 at 7:34 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
Numpy's outer product works fine with vectors. However, I seem to always want len(outer(a, b).shape) to be equal to len(a.shape) + len(b.shape). Wolfram-alpha seems to agree https://reference.wolfram.com/language/ref/Outer.html with respect to matrix outer products. My suggestion is to define outer as defined below. I've contrasted it with numpy's current outer product.
In [36]: def a(n): return np.ones(n)
In [37]: b = a(())
In [38]: c = a(4)
In [39]: d = a(5)
In [40]: np.outer(b, d).shape Out[40]: (1, 5)
In [41]: np.outer(c, d).shape Out[41]: (4, 5)
In [42]: np.outer(c, b).shape Out[42]: (4, 1)
In [43]: def outer(a, b): return a[(...,) + len(b.shape) * (np.newaxis,)] * b ....:
In [44]: outer(b, d).shape Out[44]: (5,)
In [45]: outer(c, d).shape Out[45]: (4, 5)
In [46]: outer(c, b).shape Out[46]: (4,)
Best,
Neil

On Sat, Apr 11, 2015 at 12:06 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
Numpy's outer product works fine with vectors. However, I seem to always want len(outer(a, b).shape) to be equal to len(a.shape) + len(b.shape). Wolfram-alpha seems to agree https://reference.wolfram.com/language/ref/Outer.html with respect to matrix outer products. You're probably right that this is the correct definition of the outer
On Wed, Apr 8, 2015 at 7:34 PM, Neil Girdhar <mistersheik@gmail.com> wrote: product in an n-dimensional world. But this seems to go beyond being just a bug in handling 0-d arrays (which is the kind of corner case we've fixed in the past); np.outer is documented to always ravel its inputs to 1d. In fact the implementation is literally just: a = asarray(a) b = asarray(b) return multiply(a.ravel()[:, newaxis], b.ravel()[newaxis,:], out) Sebastian's np.multiply.outer is much more generic and effective. Maybe we should just deprecate np.outer? I don't see what use it serves. (When and whether it actually got removed after being deprecated would depend on how much use it actually gets in real code, which I certainly don't know while typing a quick email. But we could start telling people not to use it any time.)
+1 with everything you said.
Want to write a PR? :-) -- Nathaniel J. Smith -- http://vorpus.org

I would be happy to, but I'm not sure what that involves? It's just a documentation changelist? On Sat, Apr 11, 2015 at 12:29 PM, Nathaniel Smith <njs@pobox.com> wrote:
On Sat, Apr 11, 2015 at 12:06 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
Numpy's outer product works fine with vectors. However, I seem to always want len(outer(a, b).shape) to be equal to len(a.shape) + len(b.shape). Wolfram-alpha seems to agree https://reference.wolfram.com/language/ref/Outer.html with respect to matrix outer products. You're probably right that this is the correct definition of the outer
On Wed, Apr 8, 2015 at 7:34 PM, Neil Girdhar <mistersheik@gmail.com> wrote: product in an n-dimensional world. But this seems to go beyond being just a bug in handling 0-d arrays (which is the kind of corner case we've fixed in the past); np.outer is documented to always ravel its inputs to 1d. In fact the implementation is literally just: a = asarray(a) b = asarray(b) return multiply(a.ravel()[:, newaxis], b.ravel()[newaxis,:], out) Sebastian's np.multiply.outer is much more generic and effective. Maybe we should just deprecate np.outer? I don't see what use it serves. (When and whether it actually got removed after being deprecated would depend on how much use it actually gets in real code, which I certainly don't know while typing a quick email. But we could start telling people not to use it any time.)
+1 with everything you said.
Want to write a PR? :-)
-- Nathaniel J. Smith -- http://vorpus.org _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

Documentation and a call to warnings.warn(DeprecationWarning(...)), I guess. On Sat, Apr 11, 2015 at 12:39 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
I would be happy to, but I'm not sure what that involves? It's just a documentation changelist?
On Sat, Apr 11, 2015 at 12:29 PM, Nathaniel Smith <njs@pobox.com> wrote:
On Sat, Apr 11, 2015 at 12:06 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
Numpy's outer product works fine with vectors. However, I seem to always want len(outer(a, b).shape) to be equal to len(a.shape) + len(b.shape). Wolfram-alpha seems to agree https://reference.wolfram.com/language/ref/Outer.html with respect to matrix outer products. You're probably right that this is the correct definition of the outer
On Wed, Apr 8, 2015 at 7:34 PM, Neil Girdhar <mistersheik@gmail.com> wrote: product in an n-dimensional world. But this seems to go beyond being just a bug in handling 0-d arrays (which is the kind of corner case we've fixed in the past); np.outer is documented to always ravel its inputs to 1d. In fact the implementation is literally just: a = asarray(a) b = asarray(b) return multiply(a.ravel()[:, newaxis], b.ravel()[newaxis,:], out) Sebastian's np.multiply.outer is much more generic and effective. Maybe we should just deprecate np.outer? I don't see what use it serves. (When and whether it actually got removed after being deprecated would depend on how much use it actually gets in real code, which I certainly don't know while typing a quick email. But we could start telling people not to use it any time.)
+1 with everything you said.
Want to write a PR? :-)
-- Nathaniel J. Smith -- http://vorpus.org _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
-- Nathaniel J. Smith -- http://vorpus.org

Okay, but by the same token, why do we have cumsum? Isn't it identical to np.add.accumulate — or if you're passing in multidimensional data — np.add.accumulate(a.flatten()) ? add.accumulate feels more generic, would make the other ufunc things more discoverable, and is self-documenting. Similarly, cumprod is just np.multiply.accumulate. Best, Neil On Sat, Apr 11, 2015 at 12:49 PM, Nathaniel Smith <njs@pobox.com> wrote:
Documentation and a call to warnings.warn(DeprecationWarning(...)), I guess.
On Sat, Apr 11, 2015 at 12:39 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
I would be happy to, but I'm not sure what that involves? It's just a documentation changelist?
On Sat, Apr 11, 2015 at 12:29 PM, Nathaniel Smith <njs@pobox.com> wrote:
On Sat, Apr 11, 2015 at 12:06 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
On Wed, Apr 8, 2015 at 7:34 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
Numpy's outer product works fine with vectors. However, I seem to always want len(outer(a, b).shape) to be equal to len(a.shape) + len(b.shape). Wolfram-alpha seems to agree https://reference.wolfram.com/language/ref/Outer.html with
respect to
matrix outer products. You're probably right that this is the correct definition of the outer product in an n-dimensional world. But this seems to go beyond being just a bug in handling 0-d arrays (which is the kind of corner case we've fixed in the past); np.outer is documented to always ravel its inputs to 1d. In fact the implementation is literally just: a = asarray(a) b = asarray(b) return multiply(a.ravel()[:, newaxis], b.ravel()[newaxis,:], out) Sebastian's np.multiply.outer is much more generic and effective. Maybe we should just deprecate np.outer? I don't see what use it serves. (When and whether it actually got removed after being deprecated would depend on how much use it actually gets in real code, which I certainly don't know while typing a quick email. But we could start telling people not to use it any time.)
+1 with everything you said.
Want to write a PR? :-)
-- Nathaniel J. Smith -- http://vorpus.org _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
-- Nathaniel J. Smith -- http://vorpus.org _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

It also appears that cumsum has a lot of unnecessary overhead over add.accumulate: In [51]: %timeit np.add.accumulate(a) The slowest run took 46.31 times longer than the fastest. This could mean that an intermediate result is being cached 1000000 loops, best of 3: 372 ns per loop In [52]: %timeit np.cum np.cumprod np.cumproduct np.cumsum In [52]: %timeit np.cumsum(a) The slowest run took 18.44 times longer than the fastest. This could mean that an intermediate result is being cached 1000000 loops, best of 3: 912 ns per loop In [53]: %timeit np.add.accumulate(a.flatten()) The slowest run took 25.59 times longer than the fastest. This could mean that an intermediate result is being cached 1000000 loops, best of 3: 834 ns per loop On Tue, Apr 14, 2015 at 7:42 AM, Neil Girdhar <mistersheik@gmail.com> wrote:
Okay, but by the same token, why do we have cumsum? Isn't it identical to
np.add.accumulate
— or if you're passing in multidimensional data —
np.add.accumulate(a.flatten())
?
add.accumulate feels more generic, would make the other ufunc things more discoverable, and is self-documenting.
Similarly, cumprod is just np.multiply.accumulate.
Best,
Neil
On Sat, Apr 11, 2015 at 12:49 PM, Nathaniel Smith <njs@pobox.com> wrote:
Documentation and a call to warnings.warn(DeprecationWarning(...)), I guess.
On Sat, Apr 11, 2015 at 12:39 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
I would be happy to, but I'm not sure what that involves? It's just a documentation changelist?
On Sat, Apr 11, 2015 at 12:29 PM, Nathaniel Smith <njs@pobox.com> wrote:
On Sat, Apr 11, 2015 at 12:06 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
On Wed, Apr 8, 2015 at 7:34 PM, Neil Girdhar <mistersheik@gmail.com
wrote: > Numpy's outer product works fine with vectors. However, I seem to > always > want len(outer(a, b).shape) to be equal to len(a.shape) + > len(b.shape). > Wolfram-alpha seems to agree > https://reference.wolfram.com/language/ref/Outer.html with respect to > matrix > outer products. You're probably right that this is the correct definition of the outer product in an n-dimensional world. But this seems to go beyond being just a bug in handling 0-d arrays (which is the kind of corner case we've fixed in the past); np.outer is documented to always ravel its inputs to 1d. In fact the implementation is literally just: a = asarray(a) b = asarray(b) return multiply(a.ravel()[:, newaxis], b.ravel()[newaxis,:], out) Sebastian's np.multiply.outer is much more generic and effective. Maybe we should just deprecate np.outer? I don't see what use it serves. (When and whether it actually got removed after being deprecated would depend on how much use it actually gets in real code, which I certainly don't know while typing a quick email. But we could start telling people not to use it any time.)
+1 with everything you said.
Want to write a PR? :-)
-- Nathaniel J. Smith -- http://vorpus.org _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
-- Nathaniel J. Smith -- http://vorpus.org _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Apr 14, 2015 2:48 PM, "Neil Girdhar" <mistersheik@gmail.com> wrote:
Okay, but by the same token, why do we have cumsum? Isn't it identical to
np.add.accumulate
— or if you're passing in multidimensional data —
np.add.accumulate(a.flatten())
?
add.accumulate feels more generic, would make the other ufunc things more
discoverable, and is self-documenting.
Similarly, cumprod is just np.multiply.accumulate.
Yeah, but these do have several differences than np.outer: - they get used much more - their definitions are less obviously broken (cumsum has no obvious definition for an n-d array so you have to pick one; outer does have an obvious definition and np.outer got it wrong) - they're more familiar from other systems (R, MATLAB) - they allow for special dispatch rules (e.g. np.sum(a) will try calling a.sum() before it tries coercing a to an ndarray, so e.g. on np.ma objects np.sum works and np.add.accumulate doesn't. Eventually this will perhaps be obviated by __numpy_ufunc__, but that is still some ways off.) So the situation is much less clear cut. -n

Yes, I totally agree with you regarding np.sum and np.product, which is why I didn't suggest np.add.reduce, np.multiply.reduce. I wasn't sure whether cumsum and cumprod might be on the line in your judgment. Best, Neil On Tue, Apr 14, 2015 at 3:37 PM, Nathaniel Smith <njs@pobox.com> wrote:
On Apr 14, 2015 2:48 PM, "Neil Girdhar" <mistersheik@gmail.com> wrote:
Okay, but by the same token, why do we have cumsum? Isn't it identical
to
np.add.accumulate
— or if you're passing in multidimensional data —
np.add.accumulate(a.flatten())
?
add.accumulate feels more generic, would make the other ufunc things
more discoverable, and is self-documenting.
Similarly, cumprod is just np.multiply.accumulate.
Yeah, but these do have several differences than np.outer:
- they get used much more - their definitions are less obviously broken (cumsum has no obvious definition for an n-d array so you have to pick one; outer does have an obvious definition and np.outer got it wrong) - they're more familiar from other systems (R, MATLAB) - they allow for special dispatch rules (e.g. np.sum(a) will try calling a.sum() before it tries coercing a to an ndarray, so e.g. on np.ma objects np.sum works and np.add.accumulate doesn't. Eventually this will perhaps be obviated by __numpy_ufunc__, but that is still some ways off.)
So the situation is much less clear cut.
-n
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Tue, Apr 14, 2015 at 3:48 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
Yes, I totally agree with you regarding np.sum and np.product, which is why I didn't suggest np.add.reduce, np.multiply.reduce. I wasn't sure whether cumsum and cumprod might be on the line in your judgment.
Ah, I see. I think we should treat them the same for now -- all the comments I made apply to a lesser or greater extent (in particular, cumsum and cumprod both do the thing where they dispatch to .cumsum() .cumprod() method). -n -- Nathaniel J. Smith -- http://vorpus.org

Ok, I didn't know that. Are you at pycon by any chance? On Tue, Apr 14, 2015 at 7:16 PM, Nathaniel Smith <njs@pobox.com> wrote:
On Tue, Apr 14, 2015 at 3:48 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
Yes, I totally agree with you regarding np.sum and np.product, which is why I didn't suggest np.add.reduce, np.multiply.reduce. I wasn't sure whether cumsum and cumprod might be on the line in your judgment.
Ah, I see. I think we should treat them the same for now -- all the comments I made apply to a lesser or greater extent (in particular, cumsum and cumprod both do the thing where they dispatch to .cumsum() .cumprod() method).
-n
-- Nathaniel J. Smith -- http://vorpus.org _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

I am, yes. On Apr 14, 2015 9:17 PM, "Neil Girdhar" <mistersheik@gmail.com> wrote:
Ok, I didn't know that. Are you at pycon by any chance?
On Tue, Apr 14, 2015 at 7:16 PM, Nathaniel Smith <njs@pobox.com> wrote:
On Tue, Apr 14, 2015 at 3:48 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
Yes, I totally agree with you regarding np.sum and np.product, which is why I didn't suggest np.add.reduce, np.multiply.reduce. I wasn't sure whether cumsum and cumprod might be on the line in your judgment.
Ah, I see. I think we should treat them the same for now -- all the comments I made apply to a lesser or greater extent (in particular, cumsum and cumprod both do the thing where they dispatch to .cumsum() .cumprod() method).
-n
-- Nathaniel J. Smith -- http://vorpus.org _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

Just a general thing, if someone has a few minutes, I think it would make sense to add the ufunc.reduce thing to all of these functions at least in the "See Also" or "Notes" section in the documentation. These special attributes are not that well known, and I think that might be a nice way to make it easier to find. - Sebastian On Di, 2015-04-14 at 22:18 -0400, Nathaniel Smith wrote:
I am, yes.
On Apr 14, 2015 9:17 PM, "Neil Girdhar" <mistersheik@gmail.com> wrote: Ok, I didn't know that. Are you at pycon by any chance?
On Tue, Apr 14, 2015 at 7:16 PM, Nathaniel Smith <njs@pobox.com> wrote: On Tue, Apr 14, 2015 at 3:48 PM, Neil Girdhar <mistersheik@gmail.com> wrote: > Yes, I totally agree with you regarding np.sum and np.product, which is why > I didn't suggest np.add.reduce, np.multiply.reduce. I wasn't sure whether > cumsum and cumprod might be on the line in your judgment.
Ah, I see. I think we should treat them the same for now -- all the comments I made apply to a lesser or greater extent (in particular, cumsum and cumprod both do the thing where they dispatch to .cumsum() .cumprod() method).
-n
-- Nathaniel J. Smith -- http://vorpus.org _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

Yes, I totally agree. If I get started on the PR to deprecate np.outer, maybe I can do it as part of the same PR? On Wed, Apr 15, 2015 at 4:32 AM, Sebastian Berg <sebastian@sipsolutions.net> wrote:
Just a general thing, if someone has a few minutes, I think it would make sense to add the ufunc.reduce thing to all of these functions at least in the "See Also" or "Notes" section in the documentation.
These special attributes are not that well known, and I think that might be a nice way to make it easier to find.
- Sebastian
On Di, 2015-04-14 at 22:18 -0400, Nathaniel Smith wrote:
I am, yes.
On Apr 14, 2015 9:17 PM, "Neil Girdhar" <mistersheik@gmail.com> wrote: Ok, I didn't know that. Are you at pycon by any chance?
On Tue, Apr 14, 2015 at 7:16 PM, Nathaniel Smith <njs@pobox.com> wrote: On Tue, Apr 14, 2015 at 3:48 PM, Neil Girdhar <mistersheik@gmail.com> wrote: > Yes, I totally agree with you regarding np.sum and np.product, which is why > I didn't suggest np.add.reduce, np.multiply.reduce. I wasn't sure whether > cumsum and cumprod might be on the line in your judgment.
Ah, I see. I think we should treat them the same for now -- all the comments I made apply to a lesser or greater extent (in particular, cumsum and cumprod both do the thing where they dispatch to .cumsum() .cumprod() method).
-n
-- Nathaniel J. Smith -- http://vorpus.org _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Wed, Apr 15, 2015 at 7:35 AM, Neil Girdhar <mistersheik@gmail.com> wrote:
Yes, I totally agree. If I get started on the PR to deprecate np.outer, maybe I can do it as part of the same PR?
On Wed, Apr 15, 2015 at 4:32 AM, Sebastian Berg <sebastian@sipsolutions.net> wrote:
Just a general thing, if someone has a few minutes, I think it would make sense to add the ufunc.reduce thing to all of these functions at least in the "See Also" or "Notes" section in the documentation.
These special attributes are not that well known, and I think that might be a nice way to make it easier to find.
- Sebastian
On Di, 2015-04-14 at 22:18 -0400, Nathaniel Smith wrote:
I am, yes.
On Apr 14, 2015 9:17 PM, "Neil Girdhar" <mistersheik@gmail.com> wrote: Ok, I didn't know that. Are you at pycon by any chance?
On Tue, Apr 14, 2015 at 7:16 PM, Nathaniel Smith <njs@pobox.com> wrote: On Tue, Apr 14, 2015 at 3:48 PM, Neil Girdhar <mistersheik@gmail.com> wrote: > Yes, I totally agree with you regarding np.sum and np.product, which is why > I didn't suggest np.add.reduce, np.multiply.reduce. I wasn't sure whether > cumsum and cumprod might be on the line in your judgment.
Ah, I see. I think we should treat them the same for now -- all the comments I made apply to a lesser or greater extent (in particular, cumsum and cumprod both do the thing where they dispatch to .cumsum() .cumprod() method).
-n
-- Nathaniel J. Smith -- http://vorpus.org _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
I'm just looking at this thread. I see outer used quite often corrcoef = cov / np.outer(std, std) (even I use it sometimes instead of cov / std[:,None] / std Josef

Does it work for you to set outer = np.multiply.outer ? It's actually faster on my machine. On Wed, Apr 15, 2015 at 5:29 PM, <josef.pktd@gmail.com> wrote:
On Wed, Apr 15, 2015 at 7:35 AM, Neil Girdhar <mistersheik@gmail.com> wrote:
Yes, I totally agree. If I get started on the PR to deprecate np.outer, maybe I can do it as part of the same PR?
On Wed, Apr 15, 2015 at 4:32 AM, Sebastian Berg < sebastian@sipsolutions.net> wrote:
Just a general thing, if someone has a few minutes, I think it would make sense to add the ufunc.reduce thing to all of these functions at least in the "See Also" or "Notes" section in the documentation.
These special attributes are not that well known, and I think that might be a nice way to make it easier to find.
- Sebastian
On Di, 2015-04-14 at 22:18 -0400, Nathaniel Smith wrote:
I am, yes.
On Apr 14, 2015 9:17 PM, "Neil Girdhar" <mistersheik@gmail.com>
wrote:
Ok, I didn't know that. Are you at pycon by any chance?
On Tue, Apr 14, 2015 at 7:16 PM, Nathaniel Smith <njs@pobox.com> wrote: On Tue, Apr 14, 2015 at 3:48 PM, Neil Girdhar <mistersheik@gmail.com> wrote: > Yes, I totally agree with you regarding np.sum and np.product, which is why > I didn't suggest np.add.reduce, np.multiply.reduce. I wasn't sure whether > cumsum and cumprod might be on the line in your judgment.
Ah, I see. I think we should treat them the same for now -- all the comments I made apply to a lesser or greater extent (in particular, cumsum and cumprod both do the thing where they dispatch to .cumsum() .cumprod() method).
-n
-- Nathaniel J. Smith -- http://vorpus.org _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
I'm just looking at this thread.
I see outer used quite often
corrcoef = cov / np.outer(std, std)
(even I use it sometimes instead of cov / std[:,None] / std
Josef _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Wed, Apr 15, 2015 at 5:31 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
Does it work for you to set
outer = np.multiply.outer
?
It's actually faster on my machine.
I assume it does because np.corrcoeff uses it, and it's the same type of use cases. However, I'm not using it very often (I prefer broadcasting), but I've seen it often enough when reviewing code. This is mainly to point out that it could be a popular function (that maybe shouldn't be deprecated) https://github.com/search?utf8=%E2%9C%93&q=np.outer 416914 Josef
On Wed, Apr 15, 2015 at 5:29 PM, <josef.pktd@gmail.com> wrote:
On Wed, Apr 15, 2015 at 7:35 AM, Neil Girdhar <mistersheik@gmail.com> wrote:
Yes, I totally agree. If I get started on the PR to deprecate np.outer, maybe I can do it as part of the same PR?
On Wed, Apr 15, 2015 at 4:32 AM, Sebastian Berg <sebastian@sipsolutions.net> wrote:
Just a general thing, if someone has a few minutes, I think it would make sense to add the ufunc.reduce thing to all of these functions at least in the "See Also" or "Notes" section in the documentation.
These special attributes are not that well known, and I think that might be a nice way to make it easier to find.
- Sebastian
On Di, 2015-04-14 at 22:18 -0400, Nathaniel Smith wrote:
I am, yes.
On Apr 14, 2015 9:17 PM, "Neil Girdhar" <mistersheik@gmail.com> wrote: Ok, I didn't know that. Are you at pycon by any chance?
On Tue, Apr 14, 2015 at 7:16 PM, Nathaniel Smith <njs@pobox.com> wrote: On Tue, Apr 14, 2015 at 3:48 PM, Neil Girdhar <mistersheik@gmail.com> wrote: > Yes, I totally agree with you regarding np.sum and np.product, which is why > I didn't suggest np.add.reduce, np.multiply.reduce. I wasn't sure whether > cumsum and cumprod might be on the line in your judgment.
Ah, I see. I think we should treat them the same for now -- all the comments I made apply to a lesser or greater extent (in particular, cumsum and cumprod both do the thing where they dispatch to .cumsum() .cumprod() method).
-n
-- Nathaniel J. Smith -- http://vorpus.org _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
I'm just looking at this thread.
I see outer used quite often
corrcoef = cov / np.outer(std, std)
(even I use it sometimes instead of cov / std[:,None] / std
Josef _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Wed, Apr 15, 2015 at 6:08 PM, <josef.pktd@gmail.com> wrote:
On Wed, Apr 15, 2015 at 5:31 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
Does it work for you to set
outer = np.multiply.outer
?
It's actually faster on my machine.
I assume it does because np.corrcoeff uses it, and it's the same type of use cases. However, I'm not using it very often (I prefer broadcasting), but I've seen it often enough when reviewing code.
This is mainly to point out that it could be a popular function (that maybe shouldn't be deprecated)
After thinking another minute: I think it should not be deprecated, it's like toepliz. We can use it also to normalize 2d arrays where columns and rows are different not symmetric as in the corrcoef case. Josef
Josef
On Wed, Apr 15, 2015 at 5:29 PM, <josef.pktd@gmail.com> wrote:
On Wed, Apr 15, 2015 at 7:35 AM, Neil Girdhar <mistersheik@gmail.com> wrote:
Yes, I totally agree. If I get started on the PR to deprecate np.outer, maybe I can do it as part of the same PR?
On Wed, Apr 15, 2015 at 4:32 AM, Sebastian Berg <sebastian@sipsolutions.net> wrote:
Just a general thing, if someone has a few minutes, I think it would make sense to add the ufunc.reduce thing to all of these functions at least in the "See Also" or "Notes" section in the documentation.
These special attributes are not that well known, and I think that might be a nice way to make it easier to find.
- Sebastian
On Di, 2015-04-14 at 22:18 -0400, Nathaniel Smith wrote:
I am, yes.
On Apr 14, 2015 9:17 PM, "Neil Girdhar" <mistersheik@gmail.com> wrote: Ok, I didn't know that. Are you at pycon by any chance?
On Tue, Apr 14, 2015 at 7:16 PM, Nathaniel Smith <njs@pobox.com> wrote: On Tue, Apr 14, 2015 at 3:48 PM, Neil Girdhar <mistersheik@gmail.com> wrote: > Yes, I totally agree with you regarding np.sum and np.product, which is why > I didn't suggest np.add.reduce, np.multiply.reduce. I wasn't sure whether > cumsum and cumprod might be on the line in your judgment.
Ah, I see. I think we should treat them the same for now -- all the comments I made apply to a lesser or greater extent (in particular, cumsum and cumprod both do the thing where they dispatch to .cumsum() .cumprod() method).
-n
-- Nathaniel J. Smith -- http://vorpus.org _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
I'm just looking at this thread.
I see outer used quite often
corrcoef = cov / np.outer(std, std)
(even I use it sometimes instead of cov / std[:,None] / std
Josef _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

I don't understand. Are you at pycon by any chance? On Wed, Apr 15, 2015 at 6:12 PM, <josef.pktd@gmail.com> wrote:
On Wed, Apr 15, 2015 at 6:08 PM, <josef.pktd@gmail.com> wrote:
On Wed, Apr 15, 2015 at 5:31 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
Does it work for you to set
outer = np.multiply.outer
?
It's actually faster on my machine.
I assume it does because np.corrcoeff uses it, and it's the same type of use cases. However, I'm not using it very often (I prefer broadcasting), but I've seen it often enough when reviewing code.
This is mainly to point out that it could be a popular function (that maybe shouldn't be deprecated)
After thinking another minute:
I think it should not be deprecated, it's like toepliz. We can use it also to normalize 2d arrays where columns and rows are different not symmetric as in the corrcoef case.
Josef
Josef
On Wed, Apr 15, 2015 at 5:29 PM, <josef.pktd@gmail.com> wrote:
On Wed, Apr 15, 2015 at 7:35 AM, Neil Girdhar <mistersheik@gmail.com> wrote:
Yes, I totally agree. If I get started on the PR to deprecate
np.outer,
maybe I can do it as part of the same PR?
On Wed, Apr 15, 2015 at 4:32 AM, Sebastian Berg <sebastian@sipsolutions.net> wrote:
Just a general thing, if someone has a few minutes, I think it would make sense to add the ufunc.reduce thing to all of these functions
at
least in the "See Also" or "Notes" section in the documentation.
These special attributes are not that well known, and I think that might be a nice way to make it easier to find.
- Sebastian
On Di, 2015-04-14 at 22:18 -0400, Nathaniel Smith wrote: > I am, yes. > > On Apr 14, 2015 9:17 PM, "Neil Girdhar" <mistersheik@gmail.com> > wrote: > Ok, I didn't know that. Are you at pycon by any chance? > > On Tue, Apr 14, 2015 at 7:16 PM, Nathaniel Smith > <njs@pobox.com> wrote: > On Tue, Apr 14, 2015 at 3:48 PM, Neil Girdhar > <mistersheik@gmail.com> wrote: > > Yes, I totally agree with you regarding np.sum and > np.product, which is why > > I didn't suggest np.add.reduce, np.multiply.reduce. > I wasn't sure whether > > cumsum and cumprod might be on the line in your > judgment. > > Ah, I see. I think we should treat them the same for > now -- all the > comments I made apply to a lesser or greater extent > (in particular, > cumsum and cumprod both do the thing where they > dispatch to .cumsum() > .cumprod() method). > > -n > > -- > Nathaniel J. Smith -- http://vorpus.org > _______________________________________________ > NumPy-Discussion mailing list > NumPy-Discussion@scipy.org > > http://mail.scipy.org/mailman/listinfo/numpy-discussion > > > > > _______________________________________________ > NumPy-Discussion mailing list > NumPy-Discussion@scipy.org > http://mail.scipy.org/mailman/listinfo/numpy-discussion > > _______________________________________________ > NumPy-Discussion mailing list > NumPy-Discussion@scipy.org > http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
I'm just looking at this thread.
I see outer used quite often
corrcoef = cov / np.outer(std, std)
(even I use it sometimes instead of cov / std[:,None] / std
Josef _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Wed, Apr 15, 2015 at 6:08 PM, <josef.pktd@gmail.com> wrote:
On Wed, Apr 15, 2015 at 5:31 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
Does it work for you to set
outer = np.multiply.outer
?
It's actually faster on my machine.
I assume it does because np.corrcoeff uses it, and it's the same type of use cases. However, I'm not using it very often (I prefer broadcasting), but I've seen it often enough when reviewing code.
This is mainly to point out that it could be a popular function (that maybe shouldn't be deprecated)
For future reference, that's not the number -- you have to click through to "Code" and then look at a single-language result to get anything remotely meaningful. In this case b/c they're different by an order of magnitude, and in general because sometimes the "top line" number is completely made up (like it has no relation to the per-language numbers on the left and then changes around randomly if you simply reload the page). (So 29,397 is what you want in this case.) Also that count then tends to have tons of duplicates (e.g. b/c there are hundreds of copies of numpy itself on github), so you need a big grain of salt when looking at the absolute number, but it can be useful, esp. for relative comparisons. -n

On Wed, Apr 15, 2015 at 6:40 PM, Nathaniel Smith <njs@pobox.com> wrote:
On Wed, Apr 15, 2015 at 6:08 PM, <josef.pktd@gmail.com> wrote:
On Wed, Apr 15, 2015 at 5:31 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
Does it work for you to set
outer = np.multiply.outer
?
It's actually faster on my machine.
I assume it does because np.corrcoeff uses it, and it's the same type of use cases. However, I'm not using it very often (I prefer broadcasting), but I've seen it often enough when reviewing code.
This is mainly to point out that it could be a popular function (that maybe shouldn't be deprecated)
For future reference, that's not the number -- you have to click through to "Code" and then look at a single-language result to get anything remotely meaningful. In this case b/c they're different by an order of magnitude, and in general because sometimes the "top line" number is completely made up (like it has no relation to the per-language numbers on the left and then changes around randomly if you simply reload the page).
(So 29,397 is what you want in this case.)
Also that count then tends to have tons of duplicates (e.g. b/c there are hundreds of copies of numpy itself on github), so you need a big grain of salt when looking at the absolute number, but it can be useful, esp. for relative comparisons.
My mistake, rushing too much. github show only 25 code references in numpy itself. in quotes, python only (namespace conscious packages on github) (I think github counts modules not instances) "np.cumsum" 11,022 "np.cumprod" 1,290 "np.outer" 6,838 statsmodels "np.cumsum" 21 "np.cumprod" 2 "np.outer" 15 Josef
-n _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

Would it be possible to deprecate np.outer's usage on non one-dimensional vectors for a few versions, and then reintroduce it with definition np.outer == np.multiply.outer? On Wed, Apr 15, 2015 at 8:02 PM, <josef.pktd@gmail.com> wrote:
On Wed, Apr 15, 2015 at 6:40 PM, Nathaniel Smith <njs@pobox.com> wrote:
On Wed, Apr 15, 2015 at 6:08 PM, <josef.pktd@gmail.com> wrote:
On Wed, Apr 15, 2015 at 5:31 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
Does it work for you to set
outer = np.multiply.outer
?
It's actually faster on my machine.
I assume it does because np.corrcoeff uses it, and it's the same type of use cases. However, I'm not using it very often (I prefer broadcasting), but I've seen it often enough when reviewing code.
This is mainly to point out that it could be a popular function (that maybe shouldn't be deprecated)
For future reference, that's not the number -- you have to click through to "Code" and then look at a single-language result to get anything remotely meaningful. In this case b/c they're different by an order of magnitude, and in general because sometimes the "top line" number is completely made up (like it has no relation to the per-language numbers on the left and then changes around randomly if you simply reload the page).
(So 29,397 is what you want in this case.)
Also that count then tends to have tons of duplicates (e.g. b/c there are hundreds of copies of numpy itself on github), so you need a big grain of salt when looking at the absolute number, but it can be useful, esp. for relative comparisons.
My mistake, rushing too much. github show only 25 code references in numpy itself.
in quotes, python only (namespace conscious packages on github) (I think github counts modules not instances)
"np.cumsum" 11,022 "np.cumprod" 1,290 "np.outer" 6,838
statsmodels "np.cumsum" 21 "np.cumprod" 2 "np.outer" 15
Josef
-n _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

Actually, looking at the docs, numpy.outer is *only* defined for 1-d vectors. Should anyone who used it with multi-dimensional arrays have an expectation that it will keep working in the same way? On Thu, Apr 16, 2015 at 10:53 AM, Neil Girdhar <mistersheik@gmail.com> wrote:
Would it be possible to deprecate np.outer's usage on non one-dimensional vectors for a few versions, and then reintroduce it with definition np.outer == np.multiply.outer?
On Wed, Apr 15, 2015 at 8:02 PM, <josef.pktd@gmail.com> wrote:
On Wed, Apr 15, 2015 at 6:40 PM, Nathaniel Smith <njs@pobox.com> wrote:
On Wed, Apr 15, 2015 at 6:08 PM, <josef.pktd@gmail.com> wrote:
On Wed, Apr 15, 2015 at 5:31 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
Does it work for you to set
outer = np.multiply.outer
?
It's actually faster on my machine.
I assume it does because np.corrcoeff uses it, and it's the same type of use cases. However, I'm not using it very often (I prefer broadcasting), but I've seen it often enough when reviewing code.
This is mainly to point out that it could be a popular function (that maybe shouldn't be deprecated)
For future reference, that's not the number -- you have to click through to "Code" and then look at a single-language result to get anything remotely meaningful. In this case b/c they're different by an order of magnitude, and in general because sometimes the "top line" number is completely made up (like it has no relation to the per-language numbers on the left and then changes around randomly if you simply reload the page).
(So 29,397 is what you want in this case.)
Also that count then tends to have tons of duplicates (e.g. b/c there are hundreds of copies of numpy itself on github), so you need a big grain of salt when looking at the absolute number, but it can be useful, esp. for relative comparisons.
My mistake, rushing too much. github show only 25 code references in numpy itself.
in quotes, python only (namespace conscious packages on github) (I think github counts modules not instances)
"np.cumsum" 11,022 "np.cumprod" 1,290 "np.outer" 6,838
statsmodels "np.cumsum" 21 "np.cumprod" 2 "np.outer" 15
Josef
-n _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

Hi, On Thu, Apr 16, 2015 at 3:19 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
Actually, looking at the docs, numpy.outer is *only* defined for 1-d vectors. Should anyone who used it with multi-dimensional arrays have an expectation that it will keep working in the same way?
On Thu, Apr 16, 2015 at 10:53 AM, Neil Girdhar <mistersheik@gmail.com> wrote:
Would it be possible to deprecate np.outer's usage on non one-dimensional vectors for a few versions, and then reintroduce it with definition np.outer == np.multiply.outer?
I think the general idea is that a) people often miss deprecation warnings b) there is lots of legacy code out there, and c) it's very bad if legacy code silently gives different answers in newer numpy versions d) it's not so bad if newer numpy gives an intelligible error for code that used to work. So, how about a slight modification of your proposal? 1) Raise deprecation warning for np.outer for non 1D arrays for a few versions, with depraction in favor of np.multiply.outer, then 2) Raise error for np.outer on non 1D arrays Best, Matthew

That sounds good to me. I can always put np.outer = np.multiply.outer at the start of my code to get what I want. Or could that break things? On Thu, Apr 16, 2015 at 6:28 PM, Matthew Brett <matthew.brett@gmail.com> wrote:
Hi,
On Thu, Apr 16, 2015 at 3:19 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
Actually, looking at the docs, numpy.outer is *only* defined for 1-d vectors. Should anyone who used it with multi-dimensional arrays have an expectation that it will keep working in the same way?
On Thu, Apr 16, 2015 at 10:53 AM, Neil Girdhar <mistersheik@gmail.com> wrote:
Would it be possible to deprecate np.outer's usage on non
one-dimensional
vectors for a few versions, and then reintroduce it with definition np.outer == np.multiply.outer?
I think the general idea is that
a) people often miss deprecation warnings b) there is lots of legacy code out there, and c) it's very bad if legacy code silently gives different answers in newer numpy versions d) it's not so bad if newer numpy gives an intelligible error for code that used to work.
So, how about a slight modification of your proposal?
1) Raise deprecation warning for np.outer for non 1D arrays for a few versions, with depraction in favor of np.multiply.outer, then 2) Raise error for np.outer on non 1D arrays
Best,
Matthew _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Thu, Apr 16, 2015 at 6:37 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
I can always put np.outer = np.multiply.outer at the start of my code to get what I want. Or could that break things?
Please don't do this. It means that there are any calls to np.outer in libraries you are using (or other libraries that are also used by anyone who is using your code), they will silently get np.multiply.outer instead of np.outer. And then if this breaks things we end up getting extremely confusing bug reports from angry users who think we broke np.outer. Just do 'outer = np.multiply.outer' and leave the np namespace alone :-) -n -- Nathaniel J. Smith -- http://vorpus.org

Right. On Thu, Apr 16, 2015 at 6:44 PM, Nathaniel Smith <njs@pobox.com> wrote:
On Thu, Apr 16, 2015 at 6:37 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
I can always put np.outer = np.multiply.outer at the start of my code to get what I want. Or could that break things?
Please don't do this. It means that there are any calls to np.outer in libraries you are using (or other libraries that are also used by anyone who is using your code), they will silently get np.multiply.outer instead of np.outer. And then if this breaks things we end up getting extremely confusing bug reports from angry users who think we broke np.outer.
Just do 'outer = np.multiply.outer' and leave the np namespace alone :-)
-n
-- Nathaniel J. Smith -- http://vorpus.org _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Do, 2015-04-16 at 15:28 -0700, Matthew Brett wrote:
Hi,
<snip>
So, how about a slight modification of your proposal?
1) Raise deprecation warning for np.outer for non 1D arrays for a few versions, with depraction in favor of np.multiply.outer, then 2) Raise error for np.outer on non 1D arrays
I think that was Neil's proposal a bit earlier, too. +1 for it in any case, since at least for the moment I doubt outer is used a lot for non 1-d arrays. Possible step 3) make it work on higher dims after a long period. - Sebastian
Best,
Matthew _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Fri, Apr 17, 2015 at 10:07 AM, Sebastian Berg <sebastian@sipsolutions.net> wrote:
On Do, 2015-04-16 at 15:28 -0700, Matthew Brett wrote:
Hi,
<snip>
So, how about a slight modification of your proposal?
1) Raise deprecation warning for np.outer for non 1D arrays for a few versions, with depraction in favor of np.multiply.outer, then 2) Raise error for np.outer on non 1D arrays
I think that was Neil's proposal a bit earlier, too. +1 for it in any case, since at least for the moment I doubt outer is used a lot for non 1-d arrays. Possible step 3) make it work on higher dims after a long period.
sounds ok to me Some random comments of what I remember or guess in terms of usage I think there are at most very few np.outer usages with 2d or higher dimension. (statsmodels has two models that switch between 2d and 1d parameterization where we don't use outer but it has similar characteristics. However, we need to control the ravel order, which IIRC is Fortran) The current behavior of 0-D scalars in the initial post might be useful if a numpy function returns a scalar instead of a 1-D array in size=1. np.diag which is a common case, doesn't return a scalar (in my version of numpy). I don't know any use case where I would ever want to have the 2d behavior of np.multiply.outer. I guess we will or would have applications for outer along an axis, for example if x.shape = (100, 10), then we have x[:,None, :] * x[:, :, None] (I guess) Something like this shows up reasonably often in econometrics as "Outer Product". However in most cases we can avoid constructing this matrix and get the final results in a more memory efficient or faster way. (example an array of covariance matrices) Josef
- Sebastian
Best,
Matthew _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Fr, 2015-04-17 at 10:47 -0400, josef.pktd@gmail.com wrote:
On Fri, Apr 17, 2015 at 10:07 AM, Sebastian Berg <sebastian@sipsolutions.net> wrote:
On Do, 2015-04-16 at 15:28 -0700, Matthew Brett wrote:
Hi,
<snip>
So, how about a slight modification of your proposal?
1) Raise deprecation warning for np.outer for non 1D arrays for a few versions, with depraction in favor of np.multiply.outer, then 2) Raise error for np.outer on non 1D arrays
I think that was Neil's proposal a bit earlier, too. +1 for it in any case, since at least for the moment I doubt outer is used a lot for non 1-d arrays. Possible step 3) make it work on higher dims after a long period.
sounds ok to me
Some random comments of what I remember or guess in terms of usage
I think there are at most very few np.outer usages with 2d or higher dimension. (statsmodels has two models that switch between 2d and 1d parameterization where we don't use outer but it has similar characteristics. However, we need to control the ravel order, which IIRC is Fortran)
The current behavior of 0-D scalars in the initial post might be useful if a numpy function returns a scalar instead of a 1-D array in size=1. np.diag which is a common case, doesn't return a scalar (in my version of numpy).
I don't know any use case where I would ever want to have the 2d behavior of np.multiply.outer. I guess we will or would have applications for outer along an axis, for example if x.shape = (100, 10), then we have x[:,None, :] * x[:, :, None] (I guess) Something like this shows up reasonably often in econometrics as "Outer Product". However in most cases we can avoid constructing this matrix and get the final results in a more memory efficient or faster way. (example an array of covariance matrices)
So basically outer product of stacked vectors (fitting basically into how np.linalg functions now work). I think that might be a good idea, but even then we first need to do the deprecation and it would be a long term project. Or you add np.linalg.outer or such sooner and in the longer run it will be an alias to that instead of np.multiple.outer.
Josef
- Sebastian
Best,
Matthew _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Fri, Apr 17, 2015 at 10:59 AM, Sebastian Berg <sebastian@sipsolutions.net> wrote:
On Fr, 2015-04-17 at 10:47 -0400, josef.pktd@gmail.com wrote:
On Fri, Apr 17, 2015 at 10:07 AM, Sebastian Berg <sebastian@sipsolutions.net> wrote:
On Do, 2015-04-16 at 15:28 -0700, Matthew Brett wrote:
Hi,
<snip>
So, how about a slight modification of your proposal?
1) Raise deprecation warning for np.outer for non 1D arrays for a few versions, with depraction in favor of np.multiply.outer, then 2) Raise error for np.outer on non 1D arrays
I think that was Neil's proposal a bit earlier, too. +1 for it in any case, since at least for the moment I doubt outer is used a lot for non 1-d arrays. Possible step 3) make it work on higher dims after a long period.
sounds ok to me
Some random comments of what I remember or guess in terms of usage
I think there are at most very few np.outer usages with 2d or higher dimension. (statsmodels has two models that switch between 2d and 1d parameterization where we don't use outer but it has similar characteristics. However, we need to control the ravel order, which IIRC is Fortran)
The current behavior of 0-D scalars in the initial post might be useful if a numpy function returns a scalar instead of a 1-D array in size=1. np.diag which is a common case, doesn't return a scalar (in my version of numpy).
I don't know any use case where I would ever want to have the 2d behavior of np.multiply.outer. I guess we will or would have applications for outer along an axis, for example if x.shape = (100, 10), then we have x[:,None, :] * x[:, :, None] (I guess) Something like this shows up reasonably often in econometrics as "Outer Product". However in most cases we can avoid constructing this matrix and get the final results in a more memory efficient or faster way. (example an array of covariance matrices)
So basically outer product of stacked vectors (fitting basically into how np.linalg functions now work). I think that might be a good idea, but even then we first need to do the deprecation and it would be a long term project. Or you add np.linalg.outer or such sooner and in the longer run it will be an alias to that instead of np.multiple.outer.
Essentially yes, but I don't have an opinion about location or implementation in numpy, nor do I know enough. I always considered np.outer conceptually as belonging to linalg that provides a more convenient interface than np.dot if both arrays are 1-D. (no need to add extra axis and transpose) Josef
Josef
- Sebastian
Best,
Matthew _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

This relationship between outer an dot only holds for vectors. For tensors, and other kinds of vector spaces, I'm not sure if outer products and dot products have anything to do with each other. On Fri, Apr 17, 2015 at 11:11 AM, <josef.pktd@gmail.com> wrote:
On Fri, Apr 17, 2015 at 10:59 AM, Sebastian Berg <sebastian@sipsolutions.net> wrote:
On Fr, 2015-04-17 at 10:47 -0400, josef.pktd@gmail.com wrote:
On Fri, Apr 17, 2015 at 10:07 AM, Sebastian Berg <sebastian@sipsolutions.net> wrote:
On Do, 2015-04-16 at 15:28 -0700, Matthew Brett wrote:
Hi,
<snip>
So, how about a slight modification of your proposal?
1) Raise deprecation warning for np.outer for non 1D arrays for a few versions, with depraction in favor of np.multiply.outer, then 2) Raise error for np.outer on non 1D arrays
I think that was Neil's proposal a bit earlier, too. +1 for it in any case, since at least for the moment I doubt outer is used a lot for non 1-d arrays. Possible step 3) make it work on higher dims after a long period.
sounds ok to me
Some random comments of what I remember or guess in terms of usage
I think there are at most very few np.outer usages with 2d or higher dimension. (statsmodels has two models that switch between 2d and 1d parameterization where we don't use outer but it has similar characteristics. However, we need to control the ravel order, which IIRC is Fortran)
The current behavior of 0-D scalars in the initial post might be useful if a numpy function returns a scalar instead of a 1-D array in size=1. np.diag which is a common case, doesn't return a scalar (in my version of numpy).
I don't know any use case where I would ever want to have the 2d behavior of np.multiply.outer. I guess we will or would have applications for outer along an axis, for example if x.shape = (100, 10), then we have x[:,None, :] * x[:, :, None] (I guess) Something like this shows up reasonably often in econometrics as "Outer Product". However in most cases we can avoid constructing this matrix and get the final results in a more memory efficient or faster way. (example an array of covariance matrices)
So basically outer product of stacked vectors (fitting basically into how np.linalg functions now work). I think that might be a good idea, but even then we first need to do the deprecation and it would be a long term project. Or you add np.linalg.outer or such sooner and in the longer run it will be an alias to that instead of np.multiple.outer.
Essentially yes, but I don't have an opinion about location or implementation in numpy, nor do I know enough.
I always considered np.outer conceptually as belonging to linalg that provides a more convenient interface than np.dot if both arrays are 1-D. (no need to add extra axis and transpose)
Josef
Josef
- Sebastian
Best,
Matthew _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

Neil, please reply inline or at the bottom which is customary for numpy scipy related mailing lists. It's sometimes difficult to figure out what the context of your reply is. (and the context is all over the place) On Fri, Apr 17, 2015 at 11:30 AM, Neil Girdhar <mistersheik@gmail.com> wrote:
This relationship between outer an dot only holds for vectors. For tensors, and other kinds of vector spaces, I'm not sure if outer products and dot products have anything to do with each other.
That may be the case, and I never figured out what to do with dot in more than 2 dimensions. 90% (a guess) of what I work on or see is in a 2-D or vectorized 3-D world with 2-D linalg, or can be reduced to it. (general tensor algebra creates endless loops in my brain :) Josef
On Fri, Apr 17, 2015 at 11:11 AM, <josef.pktd@gmail.com> wrote:
On Fri, Apr 17, 2015 at 10:59 AM, Sebastian Berg <sebastian@sipsolutions.net> wrote:
On Fr, 2015-04-17 at 10:47 -0400, josef.pktd@gmail.com wrote:
On Fri, Apr 17, 2015 at 10:07 AM, Sebastian Berg <sebastian@sipsolutions.net> wrote:
On Do, 2015-04-16 at 15:28 -0700, Matthew Brett wrote:
Hi,
<snip>
So, how about a slight modification of your proposal?
1) Raise deprecation warning for np.outer for non 1D arrays for a few versions, with depraction in favor of np.multiply.outer, then 2) Raise error for np.outer on non 1D arrays
I think that was Neil's proposal a bit earlier, too. +1 for it in any case, since at least for the moment I doubt outer is used a lot for non 1-d arrays. Possible step 3) make it work on higher dims after a long period.
sounds ok to me
Some random comments of what I remember or guess in terms of usage
I think there are at most very few np.outer usages with 2d or higher dimension. (statsmodels has two models that switch between 2d and 1d parameterization where we don't use outer but it has similar characteristics. However, we need to control the ravel order, which IIRC is Fortran)
The current behavior of 0-D scalars in the initial post might be useful if a numpy function returns a scalar instead of a 1-D array in size=1. np.diag which is a common case, doesn't return a scalar (in my version of numpy).
I don't know any use case where I would ever want to have the 2d behavior of np.multiply.outer. I guess we will or would have applications for outer along an axis, for example if x.shape = (100, 10), then we have x[:,None, :] * x[:, :, None] (I guess) Something like this shows up reasonably often in econometrics as "Outer Product". However in most cases we can avoid constructing this matrix and get the final results in a more memory efficient or faster way. (example an array of covariance matrices)
So basically outer product of stacked vectors (fitting basically into how np.linalg functions now work). I think that might be a good idea, but even then we first need to do the deprecation and it would be a long term project. Or you add np.linalg.outer or such sooner and in the longer run it will be an alias to that instead of np.multiple.outer.
Essentially yes, but I don't have an opinion about location or implementation in numpy, nor do I know enough.
I always considered np.outer conceptually as belonging to linalg that provides a more convenient interface than np.dot if both arrays are 1-D. (no need to add extra axis and transpose)
Josef
Josef
- Sebastian
Best,
Matthew _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Fri, Apr 17, 2015 at 10:47 AM, <josef.pktd@gmail.com> wrote:
On Fri, Apr 17, 2015 at 10:07 AM, Sebastian Berg <sebastian@sipsolutions.net> wrote:
On Do, 2015-04-16 at 15:28 -0700, Matthew Brett wrote:
Hi,
<snip>
So, how about a slight modification of your proposal?
1) Raise deprecation warning for np.outer for non 1D arrays for a few versions, with depraction in favor of np.multiply.outer, then 2) Raise error for np.outer on non 1D arrays
I think that was Neil's proposal a bit earlier, too. +1 for it in any case, since at least for the moment I doubt outer is used a lot for non 1-d arrays. Possible step 3) make it work on higher dims after a long period.
sounds ok to me
Some random comments of what I remember or guess in terms of usage
I think there are at most very few np.outer usages with 2d or higher dimension. (statsmodels has two models that switch between 2d and 1d parameterization where we don't use outer but it has similar characteristics. However, we need to control the ravel order, which IIRC is Fortran)
The current behavior of 0-D scalars in the initial post might be useful if a numpy function returns a scalar instead of a 1-D array in size=1. np.diag which is a common case, doesn't return a scalar (in my version of numpy).
I don't know any use case where I would ever want to have the 2d behavior of np.multiply.outer.
My use case is pretty simple. Given an input vector x, and a weight matrix W, and a model y=Wx, I calculate the gradient of the loss L with respect W. It is the outer product of x with the vector of gradients dL/dy. So the code is simply: W -= outer(x, dL_by_dy) Sometimes, I have some x_indices and y_indices. Now I want to do: W[x_indices, y_indices] -= outer(x[x_indices], dL_by_dy[y_indices]) Unfortunately, if x_indices or y_indices are "int" or slice in some way that removes a dimension, the left side will have fewer dimensions than the right. np.multipy.outer does the right thing without the ugly cases: if isinstance(x_indices, int): … # ugly hacks follow. I guess we will or would have applications for outer along an axis,
for example if x.shape = (100, 10), then we have x[:,None, :] * x[:, :, None] (I guess) Something like this shows up reasonably often in econometrics as "Outer Product". However in most cases we can avoid constructing this matrix and get the final results in a more memory efficient or faster way. (example an array of covariance matrices)
Not sure I see this. outer(a, b) should return something that has shape: (a.shape + b.shape). If you're doing it "along an axis", you mean you're reshuffling the resulting shape vector?
Josef
- Sebastian
Best,
Matthew _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

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

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

On Fri, Apr 17, 2015 at 12:16 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
On Fri, Apr 17, 2015 at 12:09 PM, <josef.pktd@gmail.com> wrote:
On Fri, Apr 17, 2015 at 11:22 AM, Neil Girdhar <mistersheik@gmail.com> wrote:
On Fri, Apr 17, 2015 at 10:47 AM, <josef.pktd@gmail.com> wrote:
On Fri, Apr 17, 2015 at 10:07 AM, Sebastian Berg <sebastian@sipsolutions.net> wrote:
On Do, 2015-04-16 at 15:28 -0700, Matthew Brett wrote:
Hi,
<snip>
So, how about a slight modification of your proposal?
1) Raise deprecation warning for np.outer for non 1D arrays for a few versions, with depraction in favor of np.multiply.outer, then 2) Raise error for np.outer on non 1D arrays
I think that was Neil's proposal a bit earlier, too. +1 for it in any case, since at least for the moment I doubt outer is used a lot for non 1-d arrays. Possible step 3) make it work on higher dims after a long period.
sounds ok to me
Some random comments of what I remember or guess in terms of usage
I think there are at most very few np.outer usages with 2d or higher dimension. (statsmodels has two models that switch between 2d and 1d parameterization where we don't use outer but it has similar characteristics. However, we need to control the ravel order, which IIRC is Fortran)
The current behavior of 0-D scalars in the initial post might be useful if a numpy function returns a scalar instead of a 1-D array in size=1. np.diag which is a common case, doesn't return a scalar (in my version of numpy).
I don't know any use case where I would ever want to have the 2d behavior of np.multiply.outer.
I only understand part of your example, but it looks similar to what we are doing in statsmodels.
My use case is pretty simple. Given an input vector x, and a weight matrix W, and a model y=Wx, I calculate the gradient of the loss L with respect W. It is the outer product of x with the vector of gradients dL/dy. So the code is simply:
W -= outer(x, dL_by_dy)
if you sum/subtract over all the values, isn't this the same as np.dot(x, dL_by_dy)
What? Matrix subtraction is element-wise:
In [1]: x = np.array([2,3,4])
In [2]: dL_by_dy = np.array([7,9])
In [5]: W = np.zeros((3, 2))
In [6]: W -= np.outer(x, dL_by_dy)
In [7]: W Out[7]: array([[-14., -18.], [-21., -27.], [-28., -36.]])
Ok, different use case mine are more like variations on the following
a1 = np.arange(18).reshape(6,3) a2 = np.arange(12).reshape(6, 2) index = [1, 2, 5]
text book version
np.sum([np.outer(a1[i], a2[i]) for i in index], 0) array([[180, 204], [196, 223], [212, 242]])
simpler
np.dot(a1[index].T, a2[index]) array([[180, 204], [196, 223], [212, 242]])
Sometimes, I have some x_indices and y_indices. Now I want to do:
W[x_indices, y_indices] -= outer(x[x_indices], dL_by_dy[y_indices])
Unfortunately, if x_indices or y_indices are "int" or slice in some way that removes a dimension, the left side will have fewer dimensions than the right. np.multipy.outer does the right thing without the ugly cases:
if isinstance(x_indices, int): … # ugly hacks follow.
My usual hacks are either to use np.atleast_1d or np.atleast_1d or np.squeeze if there is shape mismatch in some cases.
Yes, but in this case, the left side is the problem, which has too few dimensions. So atleast_1d doesn't work. I was conditionally squeezing, but that is extremely ugly. Especially if you're conditionally squeezing based on both x_indices and y_indices.
I don't remember if I ever used something like this
a1[0, 1] 1 a1[np.atleast_1d(0), np.atleast_1d(1)] array([1])
a1[np.atleast_1d(0), np.atleast_1d(1)] = [[100]]
a1[0, 1] = [[100]] Traceback (most recent call last): File "<pyshell#314>", line 1, in <module> a1[0, 1] = [[100]] ValueError: setting an array element with a sequence.
Josef
I guess we will or would have applications for outer along an axis, for example if x.shape = (100, 10), then we have x[:,None, :] * x[:, :, None] (I guess) Something like this shows up reasonably often in econometrics as "Outer Product". However in most cases we can avoid constructing this matrix and get the final results in a more memory efficient or faster way. (example an array of covariance matrices)
Not sure I see this. outer(a, b) should return something that has shape: (a.shape + b.shape). If you're doing it "along an axis", you mean you're reshuffling the resulting shape vector?
No I'm not reshaping the full tensor product.
It's a vectorized version of looping over independent outer products
np.array([outer(xi, yi) for xi,yi in zip(x, y)]) (which I would never use with outer)
but I have code that works similar for a reduce (or reduce_at) loop over this.
Josef
Josef
- Sebastian
Best,
Matthew _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Fr, 2015-04-17 at 12:40 -0400, josef.pktd@gmail.com wrote:
On Fri, Apr 17, 2015 at 12:16 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
On Fri, Apr 17, 2015 at 12:09 PM, <josef.pktd@gmail.com> wrote:
On Fri, Apr 17, 2015 at 11:22 AM, Neil Girdhar <mistersheik@gmail.com> wrote:
On Fri, Apr 17, 2015 at 10:47 AM, <josef.pktd@gmail.com> wrote:
On Fri, Apr 17, 2015 at 10:07 AM, Sebastian Berg <sebastian@sipsolutions.net> wrote:
On Do, 2015-04-16 at 15:28 -0700, Matthew Brett wrote: > Hi, > <snip> > > So, how about a slight modification of your proposal? > > 1) Raise deprecation warning for np.outer for non 1D arrays for a > few > versions, with depraction in favor of np.multiply.outer, then > 2) Raise error for np.outer on non 1D arrays >
I think that was Neil's proposal a bit earlier, too. +1 for it in any case, since at least for the moment I doubt outer is used a lot for non 1-d arrays. Possible step 3) make it work on higher dims after a long period.
sounds ok to me
Some random comments of what I remember or guess in terms of usage
I think there are at most very few np.outer usages with 2d or higher dimension. (statsmodels has two models that switch between 2d and 1d parameterization where we don't use outer but it has similar characteristics. However, we need to control the ravel order, which IIRC is Fortran)
The current behavior of 0-D scalars in the initial post might be useful if a numpy function returns a scalar instead of a 1-D array in size=1. np.diag which is a common case, doesn't return a scalar (in my version of numpy).
I don't know any use case where I would ever want to have the 2d behavior of np.multiply.outer.
I only understand part of your example, but it looks similar to what we are doing in statsmodels.
My use case is pretty simple. Given an input vector x, and a weight matrix W, and a model y=Wx, I calculate the gradient of the loss L with respect W. It is the outer product of x with the vector of gradients dL/dy. So the code is simply:
W -= outer(x, dL_by_dy)
if you sum/subtract over all the values, isn't this the same as np.dot(x, dL_by_dy)
What? Matrix subtraction is element-wise:
In [1]: x = np.array([2,3,4])
In [2]: dL_by_dy = np.array([7,9])
In [5]: W = np.zeros((3, 2))
In [6]: W -= np.outer(x, dL_by_dy)
In [7]: W Out[7]: array([[-14., -18.], [-21., -27.], [-28., -36.]])
Ok, different use case
mine are more like variations on the following
a1 = np.arange(18).reshape(6,3) a2 = np.arange(12).reshape(6, 2) index = [1, 2, 5]
text book version
np.sum([np.outer(a1[i], a2[i]) for i in index], 0) array([[180, 204], [196, 223], [212, 242]])
simpler
np.dot(a1[index].T, a2[index]) array([[180, 204], [196, 223], [212, 242]])
Sometimes, I have some x_indices and y_indices. Now I want to do:
W[x_indices, y_indices] -= outer(x[x_indices], dL_by_dy[y_indices])
Unfortunately, if x_indices or y_indices are "int" or slice in some way that removes a dimension, the left side will have fewer dimensions than the right. np.multipy.outer does the right thing without the ugly cases:
if isinstance(x_indices, int): … # ugly hacks follow.
My usual hacks are either to use np.atleast_1d or np.atleast_1d or np.squeeze if there is shape mismatch in some cases.
Yes, but in this case, the left side is the problem, which has too few dimensions. So atleast_1d doesn't work. I was conditionally squeezing, but that is extremely ugly. Especially if you're conditionally squeezing based on both x_indices and y_indices.
I don't remember if I ever used something like this
a1[0, 1] 1 a1[np.atleast_1d(0), np.atleast_1d(1)] array([1])
a1[np.atleast_1d(0), np.atleast_1d(1)] = [[100]]
a1[0, 1] = [[100]] Traceback (most recent call last): File "<pyshell#314>", line 1, in <module> a1[0, 1] = [[100]] ValueError: setting an array element with a sequence.
Hehe, yeah, that difference. But if you really want that, you can usually do a1[0, 1, ...] if you don't mind the ugliness.
Josef
I guess we will or would have applications for outer along an axis, for example if x.shape = (100, 10), then we have x[:,None, :] * x[:, :, None] (I guess) Something like this shows up reasonably often in econometrics as "Outer Product". However in most cases we can avoid constructing this matrix and get the final results in a more memory efficient or faster way. (example an array of covariance matrices)
Not sure I see this. outer(a, b) should return something that has shape: (a.shape + b.shape). If you're doing it "along an axis", you mean you're reshuffling the resulting shape vector?
No I'm not reshaping the full tensor product.
It's a vectorized version of looping over independent outer products
np.array([outer(xi, yi) for xi,yi in zip(x, y)]) (which I would never use with outer)
but I have code that works similar for a reduce (or reduce_at) loop over this.
Josef
Josef
- Sebastian
> Best, > > Matthew > _______________________________________________ > NumPy-Discussion mailing list > NumPy-Discussion@scipy.org > http://mail.scipy.org/mailman/listinfo/numpy-discussion >
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Fri, Apr 17, 2015 at 2:56 PM, Sebastian Berg <sebastian@sipsolutions.net> wrote:
On Fr, 2015-04-17 at 12:40 -0400, josef.pktd@gmail.com wrote:
On Fri, Apr 17, 2015 at 12:16 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
On Fri, Apr 17, 2015 at 12:09 PM, <josef.pktd@gmail.com> wrote:
On Fri, Apr 17, 2015 at 11:22 AM, Neil Girdhar <mistersheik@gmail.com> wrote:
On Fri, Apr 17, 2015 at 10:47 AM, <josef.pktd@gmail.com> wrote:
On Fri, Apr 17, 2015 at 10:07 AM, Sebastian Berg <sebastian@sipsolutions.net> wrote: > On Do, 2015-04-16 at 15:28 -0700, Matthew Brett wrote: >> Hi, >> > <snip> >> >> So, how about a slight modification of your proposal? >> >> 1) Raise deprecation warning for np.outer for non 1D arrays for a >> few >> versions, with depraction in favor of np.multiply.outer, then >> 2) Raise error for np.outer on non 1D arrays >> > > I think that was Neil's proposal a bit earlier, too. +1 for it in any > case, since at least for the moment I doubt outer is used a lot for > non > 1-d arrays. Possible step 3) make it work on higher dims after a long > period.
sounds ok to me
Some random comments of what I remember or guess in terms of usage
I think there are at most very few np.outer usages with 2d or higher dimension. (statsmodels has two models that switch between 2d and 1d parameterization where we don't use outer but it has similar characteristics. However, we need to control the ravel order, which IIRC is Fortran)
The current behavior of 0-D scalars in the initial post might be useful if a numpy function returns a scalar instead of a 1-D array in size=1. np.diag which is a common case, doesn't return a scalar (in my version of numpy).
I don't know any use case where I would ever want to have the 2d behavior of np.multiply.outer.
I only understand part of your example, but it looks similar to what we are doing in statsmodels.
My use case is pretty simple. Given an input vector x, and a weight matrix W, and a model y=Wx, I calculate the gradient of the loss L with respect W. It is the outer product of x with the vector of gradients dL/dy. So the code is simply:
W -= outer(x, dL_by_dy)
if you sum/subtract over all the values, isn't this the same as np.dot(x, dL_by_dy)
What? Matrix subtraction is element-wise:
In [1]: x = np.array([2,3,4])
In [2]: dL_by_dy = np.array([7,9])
In [5]: W = np.zeros((3, 2))
In [6]: W -= np.outer(x, dL_by_dy)
In [7]: W Out[7]: array([[-14., -18.], [-21., -27.], [-28., -36.]])
Ok, different use case
mine are more like variations on the following
a1 = np.arange(18).reshape(6,3) a2 = np.arange(12).reshape(6, 2) index = [1, 2, 5]
text book version
np.sum([np.outer(a1[i], a2[i]) for i in index], 0) array([[180, 204], [196, 223], [212, 242]])
simpler
np.dot(a1[index].T, a2[index]) array([[180, 204], [196, 223], [212, 242]])
Sometimes, I have some x_indices and y_indices. Now I want to do:
W[x_indices, y_indices] -= outer(x[x_indices], dL_by_dy[y_indices])
Unfortunately, if x_indices or y_indices are "int" or slice in some way that removes a dimension, the left side will have fewer dimensions than the right. np.multipy.outer does the right thing without the ugly cases:
if isinstance(x_indices, int): … # ugly hacks follow.
My usual hacks are either to use np.atleast_1d or np.atleast_1d or np.squeeze if there is shape mismatch in some cases.
Yes, but in this case, the left side is the problem, which has too few dimensions. So atleast_1d doesn't work. I was conditionally squeezing, but that is extremely ugly. Especially if you're conditionally squeezing based on both x_indices and y_indices.
I don't remember if I ever used something like this
a1[0, 1] 1 a1[np.atleast_1d(0), np.atleast_1d(1)] array([1])
a1[np.atleast_1d(0), np.atleast_1d(1)] = [[100]]
a1[0, 1] = [[100]] Traceback (most recent call last): File "<pyshell#314>", line 1, in <module> a1[0, 1] = [[100]] ValueError: setting an array element with a sequence.
Hehe, yeah, that difference. But if you really want that, you can usually do a1[0, 1, ...] if you don't mind the ugliness.
I'm not sure what you mean, although it sounds like a nice trick. This doesn't work for me
a1[0, 1, ...] = [[100]] Traceback (most recent call last): File "<pyshell#315>", line 1, in <module> a1[0, 1, ...] = [[100]] ValueError: assignment to 0-d array
np.__version__ '1.9.2rc1' a1[0, 1,
Josef
Josef
I guess we will or would have applications for outer along an axis, for example if x.shape = (100, 10), then we have x[:,None, :] * x[:, :, None] (I guess) Something like this shows up reasonably often in econometrics as "Outer Product". However in most cases we can avoid constructing this matrix and get the final results in a more memory efficient or faster way. (example an array of covariance matrices)
Not sure I see this. outer(a, b) should return something that has shape: (a.shape + b.shape). If you're doing it "along an axis", you mean you're reshuffling the resulting shape vector?
No I'm not reshaping the full tensor product.
It's a vectorized version of looping over independent outer products
np.array([outer(xi, yi) for xi,yi in zip(x, y)]) (which I would never use with outer)
but I have code that works similar for a reduce (or reduce_at) loop over this.
Josef
Josef
> > - Sebastian > > >> Best, >> >> Matthew >> _______________________________________________ >> NumPy-Discussion mailing list >> NumPy-Discussion@scipy.org >> http://mail.scipy.org/mailman/listinfo/numpy-discussion >> > > > _______________________________________________ > NumPy-Discussion mailing list > NumPy-Discussion@scipy.org > http://mail.scipy.org/mailman/listinfo/numpy-discussion > _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Fr, 2015-04-17 at 15:18 -0400, josef.pktd@gmail.com wrote:
On Fri, Apr 17, 2015 at 2:56 PM, Sebastian Berg <snip>
Hehe, yeah, that difference. But if you really want that, you can usually do a1[0, 1, ...] if you don't mind the ugliness.
I'm not sure what you mean, although it sounds like a nice trick. This doesn't work for me
Oh, mindslip. I thought the problem was that maybe scalar assignment does not remove trailing dimensions. But the actual reason was that you do not have an array on the right hand side. And the assignment code isn't sure if you might want to do object assignment in that case, so it can't do the funny broadcasting of the left hand side (or trailing dimension removing, whichever way around you like to think of it).
a1[0, 1, ...] = [[100]] Traceback (most recent call last): File "<pyshell#315>", line 1, in <module> a1[0, 1, ...] = [[100]] ValueError: assignment to 0-d array
np.__version__ '1.9.2rc1' a1[0, 1,
Josef
Josef
> I guess we will or would have applications for outer along an axis, > for example if x.shape = (100, 10), then we have > x[:,None, :] * x[:, :, None] (I guess) > Something like this shows up reasonably often in econometrics as > "Outer Product". However in most cases we can avoid constructing this > matrix and get the final results in a more memory efficient or faster > way. > (example an array of covariance matrices)
Not sure I see this. outer(a, b) should return something that has shape: (a.shape + b.shape). If you're doing it "along an axis", you mean you're reshuffling the resulting shape vector?
No I'm not reshaping the full tensor product.
It's a vectorized version of looping over independent outer products
np.array([outer(xi, yi) for xi,yi in zip(x, y)]) (which I would never use with outer)
but I have code that works similar for a reduce (or reduce_at) loop over this.
Josef
> > > Josef > > > > > > > > - Sebastian > > > > > >> Best, > >> > >> Matthew > >> _______________________________________________ > >> NumPy-Discussion mailing list > >> NumPy-Discussion@scipy.org > >> http://mail.scipy.org/mailman/listinfo/numpy-discussion > >> > > > > > > _______________________________________________ > > NumPy-Discussion mailing list > > NumPy-Discussion@scipy.org > > http://mail.scipy.org/mailman/listinfo/numpy-discussion > > > _______________________________________________ > NumPy-Discussion mailing list > NumPy-Discussion@scipy.org > http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Fri, Apr 17, 2015 at 4:03 PM, Sebastian Berg <sebastian@sipsolutions.net> wrote:
On Fr, 2015-04-17 at 15:18 -0400, josef.pktd@gmail.com wrote:
On Fri, Apr 17, 2015 at 2:56 PM, Sebastian Berg <snip>
Hehe, yeah, that difference. But if you really want that, you can usually do a1[0, 1, ...] if you don't mind the ugliness.
I'm not sure what you mean, although it sounds like a nice trick. This doesn't work for me
Oh, mindslip. I thought the problem was that maybe scalar assignment does not remove trailing dimensions. But the actual reason was that you do not have an array on the right hand side. And the assignment code isn't sure if you might want to do object assignment in that case, so it can't do the funny broadcasting of the left hand side (or trailing dimension removing, whichever way around you like to think of it).
Now I'm getting confused I had thought that these two are the same
a1[0, 1] = np.array([[100]]) a1[0, 1] = [[100]]
but trying it out and from your explanation, they are not I thought Neil's initial use case was that a1[0, 1] = np.outer(5, 1) doesn't work, because of
np.outer(5, 1).shape (1, 1)
But that works for me. In any case, the thread is getting long, and I explained my perception of use cases for np.outer. Josef
a1[0, 1, ...] = [[100]] Traceback (most recent call last): File "<pyshell#315>", line 1, in <module> a1[0, 1, ...] = [[100]] ValueError: assignment to 0-d array
np.__version__ '1.9.2rc1' a1[0, 1,
Josef
Josef
> >> I guess we will or would have applications for outer along an axis, >> for example if x.shape = (100, 10), then we have >> x[:,None, :] * x[:, :, None] (I guess) >> Something like this shows up reasonably often in econometrics as >> "Outer Product". However in most cases we can avoid constructing this >> matrix and get the final results in a more memory efficient or faster >> way. >> (example an array of covariance matrices) > > > Not sure I see this. outer(a, b) should return something that has > shape: > (a.shape + b.shape). If you're doing it "along an axis", you mean > you're > reshuffling the resulting shape vector?
No I'm not reshaping the full tensor product.
It's a vectorized version of looping over independent outer products
np.array([outer(xi, yi) for xi,yi in zip(x, y)]) (which I would never use with outer)
but I have code that works similar for a reduce (or reduce_at) loop over this.
Josef
>> >> >> Josef >> >> >> >> >> > >> > - Sebastian >> > >> > >> >> Best, >> >> >> >> Matthew >> >> _______________________________________________ >> >> NumPy-Discussion mailing list >> >> NumPy-Discussion@scipy.org >> >> http://mail.scipy.org/mailman/listinfo/numpy-discussion >> >> >> > >> > >> > _______________________________________________ >> > NumPy-Discussion mailing list >> > NumPy-Discussion@scipy.org >> > http://mail.scipy.org/mailman/listinfo/numpy-discussion >> > >> _______________________________________________ >> NumPy-Discussion mailing list >> NumPy-Discussion@scipy.org >> http://mail.scipy.org/mailman/listinfo/numpy-discussion > > > > _______________________________________________ > NumPy-Discussion mailing list > NumPy-Discussion@scipy.org > http://mail.scipy.org/mailman/listinfo/numpy-discussion > _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Fr, 2015-04-17 at 20:56 +0200, Sebastian Berg wrote:
On Fr, 2015-04-17 at 12:40 -0400, josef.pktd@gmail.com wrote:
On Fri, Apr 17, 2015 at 12:16 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
On Fri, Apr 17, 2015 at 12:09 PM, <josef.pktd@gmail.com> wrote:
On Fri, Apr 17, 2015 at 11:22 AM, Neil Girdhar <mistersheik@gmail.com> wrote:
On Fri, Apr 17, 2015 at 10:47 AM, <josef.pktd@gmail.com> wrote:
On Fri, Apr 17, 2015 at 10:07 AM, Sebastian Berg <sebastian@sipsolutions.net> wrote: > On Do, 2015-04-16 at 15:28 -0700, Matthew Brett wrote: >> Hi, >> > <snip> >> >> So, how about a slight modification of your proposal? >> >> 1) Raise deprecation warning for np.outer for non 1D arrays for a >> few >> versions, with depraction in favor of np.multiply.outer, then >> 2) Raise error for np.outer on non 1D arrays >> > > I think that was Neil's proposal a bit earlier, too. +1 for it in any > case, since at least for the moment I doubt outer is used a lot for > non > 1-d arrays. Possible step 3) make it work on higher dims after a long > period.
sounds ok to me
Some random comments of what I remember or guess in terms of usage
I think there are at most very few np.outer usages with 2d or higher dimension. (statsmodels has two models that switch between 2d and 1d parameterization where we don't use outer but it has similar characteristics. However, we need to control the ravel order, which IIRC is Fortran)
The current behavior of 0-D scalars in the initial post might be useful if a numpy function returns a scalar instead of a 1-D array in size=1. np.diag which is a common case, doesn't return a scalar (in my version of numpy).
I don't know any use case where I would ever want to have the 2d behavior of np.multiply.outer.
I only understand part of your example, but it looks similar to what we are doing in statsmodels.
My use case is pretty simple. Given an input vector x, and a weight matrix W, and a model y=Wx, I calculate the gradient of the loss L with respect W. It is the outer product of x with the vector of gradients dL/dy. So the code is simply:
W -= outer(x, dL_by_dy)
if you sum/subtract over all the values, isn't this the same as np.dot(x, dL_by_dy)
What? Matrix subtraction is element-wise:
In [1]: x = np.array([2,3,4])
In [2]: dL_by_dy = np.array([7,9])
In [5]: W = np.zeros((3, 2))
In [6]: W -= np.outer(x, dL_by_dy)
In [7]: W Out[7]: array([[-14., -18.], [-21., -27.], [-28., -36.]])
Ok, different use case
mine are more like variations on the following
a1 = np.arange(18).reshape(6,3) a2 = np.arange(12).reshape(6, 2) index = [1, 2, 5]
text book version
np.sum([np.outer(a1[i], a2[i]) for i in index], 0) array([[180, 204], [196, 223], [212, 242]])
simpler
np.dot(a1[index].T, a2[index]) array([[180, 204], [196, 223], [212, 242]])
Sometimes, I have some x_indices and y_indices. Now I want to do:
W[x_indices, y_indices] -= outer(x[x_indices], dL_by_dy[y_indices])
Unfortunately, if x_indices or y_indices are "int" or slice in some way that removes a dimension, the left side will have fewer dimensions than the right. np.multipy.outer does the right thing without the ugly cases:
if isinstance(x_indices, int): … # ugly hacks follow.
My usual hacks are either to use np.atleast_1d or np.atleast_1d or np.squeeze if there is shape mismatch in some cases.
Yes, but in this case, the left side is the problem, which has too few dimensions. So atleast_1d doesn't work. I was conditionally squeezing, but that is extremely ugly. Especially if you're conditionally squeezing based on both x_indices and y_indices.
I don't remember if I ever used something like this
a1[0, 1] 1 a1[np.atleast_1d(0), np.atleast_1d(1)] array([1])
a1[np.atleast_1d(0), np.atleast_1d(1)] = [[100]]
a1[0, 1] = [[100]] Traceback (most recent call last): File "<pyshell#314>", line 1, in <module> a1[0, 1] = [[100]] ValueError: setting an array element with a sequence.
Hehe, yeah, that difference. But if you really want that, you can usually do a1[0, 1, ...] if you don't mind the ugliness.
Though actually I think I would usually prefer the other way around: a1[None, None, 0, 1] = [[100]] or instead a1[0, 1] = np.array([[100]])[0, 0]
Josef
I guess we will or would have applications for outer along an axis, for example if x.shape = (100, 10), then we have x[:,None, :] * x[:, :, None] (I guess) Something like this shows up reasonably often in econometrics as "Outer Product". However in most cases we can avoid constructing this matrix and get the final results in a more memory efficient or faster way. (example an array of covariance matrices)
Not sure I see this. outer(a, b) should return something that has shape: (a.shape + b.shape). If you're doing it "along an axis", you mean you're reshuffling the resulting shape vector?
No I'm not reshaping the full tensor product.
It's a vectorized version of looping over independent outer products
np.array([outer(xi, yi) for xi,yi in zip(x, y)]) (which I would never use with outer)
but I have code that works similar for a reduce (or reduce_at) loop over this.
Josef
Josef
> > - Sebastian > > >> Best, >> >> Matthew >> _______________________________________________ >> NumPy-Discussion mailing list >> NumPy-Discussion@scipy.org >> http://mail.scipy.org/mailman/listinfo/numpy-discussion >> > > > _______________________________________________ > NumPy-Discussion mailing list > NumPy-Discussion@scipy.org > http://mail.scipy.org/mailman/listinfo/numpy-discussion > _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

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

On Thu, Apr 16, 2015 at 6:19 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
Actually, looking at the docs, numpy.outer is *only* defined for 1-d vectors. Should anyone who used it with multi-dimensional arrays have an expectation that it will keep working in the same way?
Yes. Generally what we do is more important than what we say we do. Changing behaviour can break code. Changing docs can change whose "fault" this is, but broken code is still broken code. And if you put on your user hat, what do you do when numpy acts weird -- shake your fist at the heavens and give up, or sigh and update your code to match? It's pretty common for even undocumented behaviour to still be depended on. Also FWIW, np.outer's docstring says "Input is flattened if not already 1-dimensional", so we actually did document this. -n -- Nathaniel J. Smith -- http://vorpus.org

On Thu, Apr 16, 2015 at 6:32 PM, Nathaniel Smith <njs@pobox.com> wrote:
On Thu, Apr 16, 2015 at 6:19 PM, Neil Girdhar <mistersheik@gmail.com> wrote:
Actually, looking at the docs, numpy.outer is *only* defined for 1-d vectors. Should anyone who used it with multi-dimensional arrays have an expectation that it will keep working in the same way?
Yes. Generally what we do is more important than what we say we do. Changing behaviour can break code. Changing docs can change whose "fault" this is, but broken code is still broken code. And if you put on your user hat, what do you do when numpy acts weird -- shake your fist at the heavens and give up, or sigh and update your code to match? It's pretty common for even undocumented behaviour to still be depended on.
Also FWIW, np.outer's docstring says "Input is flattened if not already 1-dimensional", so we actually did document this.
Ah, yeah, somehow I missed that!
-n
-- Nathaniel J. Smith -- http://vorpus.org _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
participants (5)
-
josef.pktd@gmail.com
-
Matthew Brett
-
Nathaniel Smith
-
Neil Girdhar
-
Sebastian Berg