That's a great solution. I think the only other alternative would be to return an array instead of a range, which would be unfortunate.
On Wednesday, July 2, 2014 9:50:34 AM UTC-4, Ivar Nesje wrote: > > Hmm... Everything with floating point ranges is inherently difficult, > because we want to give users the full accuracy (not cheat like Matlab > does). > > In order for the slicing behaviour to be exactly right, it seems to me > that we would need to store a start and a step increment, so that the > calculation for all the indexed values becomes unchanged when the range is > indexed with a range. > > Maybe we could have a Offset type that could wrap the FloatRange (and > other objects too) > > immutable Offset{T} > itr::T > start::Int > step::Int > end > > function getindex(o::Offset, i::Int) > getindex(o.itr, start+i*step) > end > > Ivar > > kl. 15:11:18 UTC+2 onsdag 2. juli 2014 skrev Peter Simon følgende: >> >> Thanks. I had mistakenly thought that linrange would retain the exact >> value of its end points, as does linspace. >> >> My actual application is to reproduce the functionality of Matlab's >> optional histc output: >> >> [n,bin] = histc(x, edges) >> >> >> Here, (using Matlab notation), bin is an integer-valued vector of the >> same length as x such that bin(i) indicates which "bin" of edges is >> occupied by x(i). My Julian attempt at reproducing this function used a >> range named edges: >> >> edges = linrange(minimum(x), maximum(x), 20) >> bin = [find(edges[1:end-1] .<= t .<= edges[2:end])[1] for t in x] >> >> >> >> and it failed due to the issue demonstrated in my first post. I think >> that I could use linspace instead of linrange, but for other reasons a >> range is preferable in this application. Do we already have this binning >> functionality in some other built-in function? I checked Julia's hist(), >> but it provides only the first output of Matlab's bin. >> >> Thanks, >> --Peter >> >> On Tuesday, July 1, 2014 11:59:44 PM UTC-7, Ivar Nesje wrote: >>> >>> It is not a shocker to me. The problem is that Floating point numbers >>> represent binary fractions, and there is no way for linrange() to actually >>> get equidistant values you are looking for. It has to do approximations, >>> and thus it will sometimes miss closest possible value. That means equality >>> checks on floating point numbers should be used with extreme care. >>> >>> Our implementation reuses the old step size when indexing a FloatRange >>> with a range, but we could probably do better if we tried to keep the last >>> point equal. >>> >>> I reopened https://github.com/JuliaLang/julia/issues/7420 to keep track >>> of this issue. >>> >>> Ivar >>> >>> kl. 07:07:25 UTC+2 onsdag 2. juli 2014 skrev Peter Simon følgende: >>>> >>>> The final result below seems really strange to me. A bug? >>>> >>>> julia> x = linrange(1,10,20) >>>> 1.0:0.47368421052631576:10.0 >>>> >>>> >>>> julia> 10 .<= x # Gives expected result >>>> 20-element BitArray{1}: >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> true >>>> >>>> julia> 10 .<= x[end] # Gives expected result >>>> true >>>> >>>> julia> 10 .<= x[2:end] # The last entry in this result is a shocker >>>> to me! >>>> 19-element BitArray{1}: >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> false >>>> >>>> >>>> >>>> Here is the version info: >>>> >>>> >>>> julia> versioninfo() >>>> Julia Version 0.3.0-prerelease+3987 >>>> Commit 7dd97fa (2014-06-30 23:12 UTC) >>>> Platform Info: >>>> System: Windows (x86_64-w64-mingw32) >>>> CPU: Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz >>>> WORD_SIZE: 64 >>>> BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY) >>>> LAPACK: libopenblas >>>> LIBM: libopenlibm >>>> >>>>