Added Within function.

Within is useful for finding the bin of a datapoint, for example when making a histogram or otherwise trying to find similar points. This commit adds the function and tests.

On Oct 12, 2014, at 2:44 AM, Dan Kortschak <notifications@github.com> wrote:

> In floats.go:
> 
> > @@ -655,3 +655,32 @@ func Sum(s []float64) float64 {
> >  	}
> >  	return sum
> >  }
> > +
> > +// Within returns the first index i where s[i] <= v < s[i+1]. As a special case, Within
> > +// returns len(s)-1 if v == s[len(s)-1]. Within can be useful for binning data
> > +// in non-uniform grids. Within panics if:
> > +// - len(s) < 2
> > +// - s is not sorted
> > +// - v is NaN
> > +// - v < s[0]
> > +// - v > s[len(s)-1]
> It seems to me that returning -1 as an index for v that is not found is more useful than panicking. If the result is used and the bin has not been found, the panic would occur anyway (this is how similar functions behave in the standard library).
> 
Why is this function different that NearestWithinSpan (which panics if out of bounds instead of returning NaN)? Because it returns an integer.
> I would also see s[i] <= v when i == len(s) as being a valid (if not particularly useful) result.
> 
Sorry, you are suggesting returning len(s) when v == s[len(s) - 1]? I think supporting the <= on the upper end is useful, for example

floats.LogSpan(bounds, minData, maxData)

idx = floats.Within(bounds, maxData)

You’d otherwise have to add epsilon to the upper range of your data.

> I don't think we should be using panic to say what is sensible, but rather what is possible.
> 
Agreed. By that logic though, shouldn’t NearestWithinSpan return -1 for out of bounds as well? 
> This leaves a significanly reduced set of cases that panic:
> 
> len(s) == 0
> s is not sorted
> In all other cases listed above, the result is -1. (These would naturally occur, but can be optimised as returns in the conditions below).
> 
I assume you mean len(s) < 2? 
> I would also suggest that some benchmarking be done to see if sort.Search helps (or hand crafted binary search) for some values of len(s). If it does, then there should be a len(s)-based condition to decide whether to use range or sort.Search.
> 
Good idea
> @jonlawlor Nothing wrong with panic("unreachable") in general, but here it would go away if the above comments are acted on.
> 
> —
> Reply to this email directly or view it on GitHub.
>