Vectorized version of numpy.linspace
![](https://secure.gravatar.com/avatar/93a76a800ef6c5919baa8ba91120ee98.jpg?s=120&d=mm&r=g)
It recently came up on GitHub (at part of the discussion in https://github.com/numpy/numpy/issues/12379) that numpy.linspace could, at least in principle, be modified to support array inputs: It looks like this has been requested on StackOverflow, too: https://stackoverflow.com/questions/46694167/vectorized-numpy-linspace-acros... My tentative proposal: - "start" and "stop" are broadcast against each other to form start/stop arrays. (Or we could require that start/stop have matching shape.) - A new dimension of size "num" is inserted into the result, either along the first or last axis. - A new keyword argument "axis" could control where the axis is inserted in the result. - Vectorization support should be added in the same way to geomspace and logspace. Does this seem like a good idea? It's a relatively simple generalization, and one that I, at least, would find useful (I can think of a use-case in my own code that came up just last week). I doubt I'll have time to implement this myself in the near future, but I thought I would get the discussion going -- this might be a good project for a new contributor to work on. Cheers, Stephan
![](https://secure.gravatar.com/avatar/5f88830d19f9c83e2ddfd913496c5025.jpg?s=120&d=mm&r=g)
On Wed, Nov 14, 2018 at 8:57 AM Stephan Hoyer <shoyer@gmail.com> wrote:
It recently came up on GitHub (at part of the discussion in https://github.com/numpy/numpy/issues/12379) that numpy.linspace could, at least in principle, be modified to support array inputs:
It looks like this has been requested on StackOverflow, too:
https://stackoverflow.com/questions/46694167/vectorized-numpy-linspace-acros...
My tentative proposal: - "start" and "stop" are broadcast against each other to form start/stop arrays. (Or we could require that start/stop have matching shape.) - A new dimension of size "num" is inserted into the result, either along the first or last axis. - A new keyword argument "axis" could control where the axis is inserted in the result. - Vectorization support should be added in the same way to geomspace and logspace.
Does this seem like a good idea? It's a relatively simple generalization, and one that I, at least, would find useful (I can think of a use-case in my own code that came up just last week).
This feels a bit forced. There's not much relevance to the minor performance gain, and for code clarity it probably also wouldn't help (actually it hurts usability for 99.x% of use cases by making the doc more complicated). Not sure that it really would require a new axis argument, as Marten said on the issue. Also, the num keyword cannot be vectorized, unless one returns a list of arrays, which would actually be more natural here than a 2-D array. So, at best a don't care for me - I'm -0.5. Cheers, Ralf
I doubt I'll have time to implement this myself in the near future, but I thought I would get the discussion going -- this might be a good project for a new contributor to work on.
Cheers, Stephan
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
![](https://secure.gravatar.com/avatar/953cf098dfb066db328c01a724256cde.jpg?s=120&d=mm&r=g)
On Wed, 14 Nov 2018 at 17:29, Ralf Gommers <ralf.gommers@gmail.com> wrote:
On Wed, Nov 14, 2018 at 8:57 AM Stephan Hoyer <shoyer@gmail.com> wrote:
It recently came up on GitHub (at part of the discussion in https://github.com/numpy/numpy/issues/12379) that numpy.linspace could, at least in principle, be modified to support array inputs:
It looks like this has been requested on StackOverflow, too: https://stackoverflow.com/questions/46694167/vectorized-numpy-linspace-acros...
My tentative proposal: - "start" and "stop" are broadcast against each other to form start/stop arrays. (Or we could require that start/stop have matching shape.) - A new dimension of size "num" is inserted into the result, either along the first or last axis. - A new keyword argument "axis" could control where the axis is inserted in the result. - Vectorization support should be added in the same way to geomspace and logspace.
Does this seem like a good idea? It's a relatively simple generalization, and one that I, at least, would find useful (I can think of a use-case in my own code that came up just last week).
This feels a bit forced. There's not much relevance to the minor performance gain, and for code clarity it probably also wouldn't help (actually it hurts usability for 99.x% of use cases by making the doc more complicated). Not sure that it really would require a new axis argument, as Marten said on the issue. Also, the num keyword cannot be vectorized, unless one returns a list of arrays, which would actually be more natural here than a 2-D array.
So, at best a don't care for me - I'm -0.5.
For what it's worth, I had a use case for this in the past week, when I needed many simple linear interpolations between two values (thus a linspace) with only the value of boundary points varying. However, this was the first time I've ever needed it, and I found a recipe on Stack Overflow within minutes (https://stackoverflow.com/a/42617889/974555) so it wasn't a big deal that it wasn't available in core numpy. Gerrit.
![](https://secure.gravatar.com/avatar/5e44e61af952612c3c45385b62806c67.jpg?s=120&d=mm&r=g)
On Wed, Nov 14, 2018 at 8:57 AM Stephan Hoyer <shoyer@gmail.com> wrote:
It recently came up on GitHub (at part of the discussion in
https://github.com/numpy/numpy/issues/12379) that numpy.linspace could, at least in principle, be modified to support array inputs:
It looks like this has been requested on StackOverflow, too:
https://stackoverflow.com/questions/46694167/vectorized-numpy-linspace-acros...
My tentative proposal: - "start" and "stop" are broadcast against each other to form start/stop
arrays. (Or we could require that start/stop have matching shape.)
- A new dimension of size "num" is inserted into the result, either along the first or last axis. - A new keyword argument "axis" could control where the axis is inserted in the result. - Vectorization support should be added in the same way to geomspace and logspace.
Does this seem like a good idea? It's a relatively simple generalization, and one that I, at least, would find useful (I can think of a use-case in my own code that came up just last week).
This feels a bit forced. There's not much relevance to the minor
I put in an issue a while ago, https://github.com/numpy/numpy/issues/8839 My use case was somwhat similar to meshgrid but with a nonrectangular domain. Not terribly hard to code, but my expectation is that numpy functions should always allow broadcasting if that operation makes sense. On Nov 14, 2018 12:42 PM, "Gerrit Holl" <gerrit.holl@gmail.com> wrote: On Wed, 14 Nov 2018 at 17:29, Ralf Gommers <ralf.gommers@gmail.com> wrote: performance gain, and for code clarity it probably also wouldn't help (actually it hurts usability for 99.x% of use cases by making the doc more complicated). Not sure that it really would require a new axis argument, as Marten said on the issue. Also, the num keyword cannot be vectorized, unless one returns a list of arrays, which would actually be more natural here than a 2-D array.
So, at best a don't care for me - I'm -0.5.
For what it's worth, I had a use case for this in the past week, when I needed many simple linear interpolations between two values (thus a linspace) with only the value of boundary points varying. However, this was the first time I've ever needed it, and I found a recipe on Stack Overflow within minutes (https://stackoverflow.com/a/42617889/974555) so it wasn't a big deal that it wasn't available in core numpy. Gerrit. _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
![](https://secure.gravatar.com/avatar/851ff10fbb1363b7d6111ac60194cc1c.jpg?s=120&d=mm&r=g)
Just to add: nothing conceptually is strange for start and end to be arrays. Indeed, the code would work for arrays as is if it didn't check the `step == 0` case to handle denormals (arguably an even less common case than array-like inputs...), and made a trivial change to get the new axis to be at the start. (I guess I'm agreeing with Matthew here that if conceptually things make sense for arrays, then it should just work; there are of course counterexample, such as `np.arange`, for which array-valued input makes even less sense than allowing float and complex).
![](https://secure.gravatar.com/avatar/5b5090abb749b7a84d70f08b1219f47d.jpg?s=120&d=mm&r=g)
On 14.11.18 17:57, Stephan Hoyer wrote:
It recently came up on GitHub (at part of the discussion in https://github.com/numpy/numpy/issues/12379) that numpy.linspace could, at least in principle, be modified to support array inputs:
It looks like this has been requested on StackOverflow, too: https://stackoverflow.com/questions/46694167/vectorized-numpy-linspace-acros...
My tentative proposal: - "start" and "stop" are broadcast against each other to form start/stop arrays. (Or we could require that start/stop have matching shape.) - A new dimension of size "num" is inserted into the result, either along the first or last axis. - A new keyword argument "axis" could control where the axis is inserted in the result. - Vectorization support should be added in the same way to geomspace and logspace.
This reminds me of a function [1] I wrote which I think has a lot of similarities to what Stephan describes here. It is currently part of a PR to rewrite numpy.pad [2]. Maybe that's helpful to know depending on how this discussion resolves. :) Best regards, Lars [1] https://github.com/lagru/numpy/blob/605fc1d7f871b1c8cf2783f594dee88cdf96d7ec... [2] https://github.com/numpy/numpy/pull/11358
![](https://secure.gravatar.com/avatar/851ff10fbb1363b7d6111ac60194cc1c.jpg?s=120&d=mm&r=g)
Code being better than words: see https://github.com/numpy/numpy/pull/12388 for an implementation. The change in the code proper is very small, though it is worrying that it causes two rather unrelated tests too fail (even if arguably both tests were wrong). Note that this does not give flexibility to put the axis where one wants; as written, the code made putting it at the start the obvious solution, as it avoids doing anything with the shapes of start and stop. -- Marten
![](https://secure.gravatar.com/avatar/b4f6d4f8b501cb05fd054944a166a121.jpg?s=120&d=mm&r=g)
On Wed, 2018-11-14 at 14:32 -0500, Marten van Kerkwijk wrote:
Code being better than words: see https://github.com/numpy/numpy/pull/12388 for an implementation. The change in the code proper is very small, though it is worrying that it causes two rather unrelated tests too fail (even if arguably both tests were wrong).
Note that this does not give flexibility to put the axis where one wants; as written, the code made putting it at the start the obvious solution, as it avoids doing anything with the shapes of start and stop.
Hehe, my first gut feeling was the last axis to be the obvious one ;). This has been discussed before (but what hasn't) I believe, probably some old issue or even PR somewhere. I am mildly in favor, just because there is probably not much reason against an easy vectorization. Doesn't need to be advertised much in the docs anyway. Although it might be good to settle the "obvious" part in case I am not alone in first thinking of -1 being the obvious default. I would probably skip the axis argument for now, unless someone actually has a use case. I think this used to half work at some point, but it was probably so broken that we can just make it well defined? - Sebastian
-- Marten _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
![](https://secure.gravatar.com/avatar/93a76a800ef6c5919baa8ba91120ee98.jpg?s=120&d=mm&r=g)
On Wed, Nov 14, 2018 at 2:35 PM Sebastian Berg <sebastian@sipsolutions.net> wrote:
On Wed, 2018-11-14 at 14:32 -0500, Marten van Kerkwijk wrote:
Code being better than words: see https://github.com/numpy/numpy/pull/12388 for an implementation. The change in the code proper is very small, though it is worrying that it causes two rather unrelated tests too fail (even if arguably both tests were wrong).
Note that this does not give flexibility to put the axis where one wants; as written, the code made putting it at the start the obvious solution, as it avoids doing anything with the shapes of start and stop.
Hehe, my first gut feeling was the last axis to be the obvious one ;). This has been discussed before (but what hasn't) I believe, probably some old issue or even PR somewhere. I am mildly in favor, just because there is probably not much reason against an easy vectorization. Doesn't need to be advertised much in the docs anyway. Although it might be good to settle the "obvious" part in case I am not alone in first thinking of -1 being the obvious default. I would probably skip the axis argument for now, unless someone actually has a use case.
Indeed -- I think the best argument for adding an "axis" argument is that it allows people to be explicit about where the axis ends up, e.g., both np.linspace(start, stop, num=5, axis=0) and np.linspace(start, stop, num=5, axis=-1) make their intent quite clear. To me, axis=0 feels like the right default, matching np.concatenate and np.stack. But NumPy already has split conventions for this sort of thing (e.g., gufuncs add axes at the end), so I like the explicit option.
![](https://secure.gravatar.com/avatar/b4f6d4f8b501cb05fd054944a166a121.jpg?s=120&d=mm&r=g)
On Wed, 2018-11-14 at 14:46 -0800, Stephan Hoyer wrote:
On Wed, Nov 14, 2018 at 2:35 PM Sebastian Berg < sebastian@sipsolutions.net> wrote:
On Wed, 2018-11-14 at 14:32 -0500, Marten van Kerkwijk wrote:
<snip>
some old issue or even PR somewhere. I am mildly in favor, just because there is probably not much reason against an easy vectorization. Doesn't need to be advertised much in the docs anyway. Although it might be good to settle the "obvious" part in case I am not alone in first thinking of -1 being the obvious default. I would probably skip the axis argument for now, unless someone actually has a use case.
Indeed -- I think the best argument for adding an "axis" argument is that it allows people to be explicit about where the axis ends up, e.g., both np.linspace(start, stop, num=5, axis=0) and np.linspace(start, stop, num=5, axis=-1) make their intent quite clear.
To me, axis=0 feels like the right default, matching np.concatenate and np.stack. But NumPy already has split conventions for this sort of thing (e.g., gufuncs add axes at the end), so I like the explicit option.
I think that argument goes both ways. Because linspace with an array input can be seen as stacking the linear ramps and not stacking some interpolated intermediate values from start/stop. (Sure, it is more then one dimension, but I would seriously argue the linear ramps are the basic building block and not the input start/stop arrays.) - Sebastian
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
![](https://secure.gravatar.com/avatar/851ff10fbb1363b7d6111ac60194cc1c.jpg?s=120&d=mm&r=g)
On Wed, Nov 14, 2018 at 1:21 PM Lars Grüter <lagru@mailbox.org> wrote: <snip>
This reminds me of a function [1] I wrote which I think has a lot of similarities to what Stephan describes here. It is currently part of a PR to rewrite numpy.pad [2].
If we start to write the equivalent internally, then perhaps we should
indeed expose it! Would my trial indeed help, or is it insufficient? (Sorry for not checking myself in detail; it is not immediately obvious.) -- Marten
participants (7)
-
Gerrit Holl
-
Lars Grüter
-
Marten van Kerkwijk
-
Matthew Harrigan
-
Ralf Gommers
-
Sebastian Berg
-
Stephan Hoyer