On Fri, 2013-03-01 at 13:34 +0000, Nathaniel Smith wrote: > On Fri, Mar 1, 2013 at 12:33 PM, Henry Gomersall <[email protected]> wrote: > > On Fri, 2013-03-01 at 13:25 +0100, Sebastian Berg wrote: > >> there has been a request on the issue tracker for a step parameter to > >> linspace. This is of course tricky with the imprecision of floating > >> point numbers. > > > > How is that different to arange? Either you specify the number of points > > with linspace, or you specify the step with arange. Is there a third > > option? > > arange is designed for ints and gives you a half-open interval, > linspace is designed for floats and gives you a closed interval. This > means that when arange is used on floats, it does weird things that > linspace doesn't: > > In [11]: eps = np.finfo(float).eps > > In [12]: np.arange(0, 1, step=0.2) > Out[12]: array([ 0. , 0.2, 0.4, 0.6, 0.8]) > > In [13]: np.arange(0, 1 + eps, step=0.2) > Out[13]: array([ 0. , 0.2, 0.4, 0.6, 0.8, 1. ]) > > In [14]: np.linspace(0, 1, 6) > Out[14]: array([ 0. , 0.2, 0.4, 0.6, 0.8, 1. ]) > > In [15]: np.linspace(0, 1 + eps, 6) > Out[15]: array([ 0. , 0.2, 0.4, 0.6, 0.8, 1. ]) > > The half-open/closed thing also has effects on what kind of api is > reasonable. arange(0, 1, step=0.8) makes perfect sense (it acts like > python range(0, 10, step=8)). linspace(0, 1, step=0.8) is just > incoherent, though, because linspace guarantees that both the start > and end points are included. > > > My usual hack to deal with the numerical bounds issue is to add/subtract > > half the step. > > Right. Which is exactly the sort of annoying, content-free code that a > library is supposed to handle for you, so you can save mental energy > for more important things :-). > > The problem is to figure out exactly how strict we should be. Like, > presumably linspace(0, 1, step=0.8) should fail, rather than round 0.8 > to 0.5 or 1. That would clearly violate "in the face of ambiguity, > refuse the temptation to guess". > > OTOH, as Sebastian points out, requiring that the step be *exactly* a > divisor of the value (stop - start), within 1 ULP, is probably > obnoxious. > > Would anything bad happen if we just required that, say, (stop - > start)/step had to be within "np.allclose" of an integer, i.e., to > some reasonable relative and absolute precision, and then rounded the > number of steps to match that integer exactly?
I was a bit worried about what happens for huge a number of steps. Have to rethink a bit about it, but I guess one should be able to relax it... or maybe someone here has a nice idea on how to relax it. It seems to me that there is a bit of a trade off if you get into the millions of steps range, because absolute errors that make sense for few steps are suddenly in the range integers. > > -n > _______________________________________________ > NumPy-Discussion mailing list > [email protected] > http://mail.scipy.org/mailman/listinfo/numpy-discussion > _______________________________________________ NumPy-Discussion mailing list [email protected] http://mail.scipy.org/mailman/listinfo/numpy-discussion
