From 0c19ae27e9341bbc95b1eecd14f2112b80ebc896 Mon Sep 17 00:00:00 2001 From: Stefan Karpinski Date: Wed, 7 Jan 2015 11:00:36 -0500 Subject: [PATCH] linspace: try to "lift" linspace the float ranges are [close #9637] --- base/array.jl | 25 ++++++++++++++++++++++++- test/ranges.jl | 4 +++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/base/array.jl b/base/array.jl index 514aae76957ae..75094cd2a25ca 100644 --- a/base/array.jl +++ b/base/array.jl @@ -217,13 +217,36 @@ function linspace(start::Real, stop::Real, n::Integer) end n -= 1 S = promote_type(T, Float64) - for i=0:n + for i = 0:n a[i+1] = start*(convert(S, (n-i))/n) + stop*(convert(S, i)/n) end a end linspace(start::Real, stop::Real) = linspace(start, stop, 100) +function linspace{T<:FloatingPoint}(start::T, stop::T, n::Int) + n == 1 && return [start] + n -= 1 + a0, b = rat(start) + a = convert(T,a0) + if a/convert(T,b) == start + c0, d = rat(stop) + c = convert(T,c0) + if c/convert(T,d) == stop + e = lcm(b,d) + a *= div(e,b) + c *= div(e,d) + ne = convert(T,n*e) + if a*n/ne == start && c*n/ne == stop + return [ (a*(n-k) + c*k)/ne for k=0:n ] + end + end + end + return [ start*((n-k)/n) + stop*(k/n) for k=0:n ] +end +linspace(start::FloatingPoint, stop::FloatingPoint, n::Integer) = + linspace(promote(start, stop)..., Int(n)) + logspace(start::Real, stop::Real, n::Integer) = 10.^linspace(start, stop, n) logspace(start::Real, stop::Real) = logspace(start, stop, 50) diff --git a/test/ranges.jl b/test/ranges.jl index f1517ec7fbdc7..856116648f24b 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -248,8 +248,10 @@ for T = (Float32, Float64,),# BigFloat), start = convert(T,a)/den step = convert(T,s)/den stop = convert(T,(a+(n-1)*s))/den + vals = T[a:s:a+(n-1)*s]./den r = start:step:stop - @test [r] == T[a:s:a+(n-1)*s]./den + @test [r] == vals + @test linspace(start, stop, n) == vals # issue #7420 n = length(r) @test [r[1:n]] == [r]