Skip to content

Commit

Permalink
Missing operations for LinSpace. Fix JuliaLang#11049
Browse files Browse the repository at this point in the history
  • Loading branch information
yuyichao authored and mbauman committed Jun 5, 2015
1 parent 0277c36 commit 9c7c34f
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
30 changes: 30 additions & 0 deletions base/range.jl
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,15 @@ function unsafe_getindex(r::FloatRange, s::OrdinalRange)
FloatRange(r.start + (first(s)-1)*r.step, step(s)*r.step, length(s), r.divisor)
end

function getindex{T}(r::LinSpace{T}, s::OrdinalRange)
sl::T = check_indexingrange(s, r)
ifirst = first(s)
ilast = last(s)
vfirst::T = ((r.len - ifirst) * r.start + (ifirst - 1) * r.stop) / r.divisor
vlast::T = ((r.len - ilast) * r.start + (ilast - 1) * r.stop) / r.divisor
return linspace(vfirst, vlast, sl)
end

function show(io::IO, r::Range)
print(io, repr(first(r)), ':', repr(step(r)), ':', repr(last(r)))
end
Expand Down Expand Up @@ -530,27 +539,34 @@ end

-(r::OrdinalRange) = range(-r.start, -step(r), length(r))
-(r::FloatRange) = FloatRange(-r.start, -r.step, r.len, r.divisor)
-(r::LinSpace) = LinSpace(-r.start, -r.stop, r.len, r.divisor)

.+(x::Real, r::UnitRange) = range(x + r.start, length(r))
.+(x::Real, r::Range) = (x+first(r)):step(r):(x+last(r))
#.+(x::Real, r::StepRange) = range(x + r.start, r.step, length(r))
.+(x::Real, r::FloatRange) = FloatRange(r.divisor*x + r.start, r.step, r.len, r.divisor)
.+(x::Real, r::LinSpace) = LinSpace(x + r.start, x + r.stop, r.len, r.divisor)
.+(r::Range, x::Real) = x + r
#.+(r::FloatRange, x::Real) = x + r

.-(x::Real, r::Range) = (x-first(r)):-step(r):(x-last(r))
.-(x::Real, r::FloatRange) = FloatRange(r.divisor*x - r.start, -r.step, r.len, r.divisor)
.-(x::Real, r::LinSpace) = LinSpace(x - r.start, x - r.stop, r.len, r.divisor)
.-(r::UnitRange, x::Real) = range(r.start-x, length(r))
.-(r::StepRange , x::Real) = range(r.start-x, r.step, length(r))
.-(r::FloatRange, x::Real) = FloatRange(r.start - r.divisor*x, r.step, r.len, r.divisor)
.-(r::LinSpace, x::Real) = LinSpace(r.start - x, r.stop - x, r.len, r.divisor)

.*(x::Real, r::OrdinalRange) = range(x*r.start, x*step(r), length(r))
.*(x::Real, r::FloatRange) = FloatRange(x*r.start, x*r.step, r.len, r.divisor)
.*(x::Real, r::LinSpace) = LinSpace(x * r.start, x * r.stop, r.len, r.divisor)
.*(r::Range, x::Real) = x .* r
.*(r::FloatRange, x::Real) = x .* r
.*(r::LinSpace, x::Real) = x .* r

./(r::OrdinalRange, x::Real) = range(r.start/x, step(r)/x, length(r))
./(r::FloatRange, x::Real) = FloatRange(r.start/x, r.step/x, r.len, r.divisor)
./(r::LinSpace, x::Real) = LinSpace(r.start / x, r.stop / x, r.len, r.divisor)

promote_rule{T1,T2}(::Type{UnitRange{T1}},::Type{UnitRange{T2}}) =
UnitRange{promote_type(T1,T2)}
Expand Down Expand Up @@ -581,6 +597,19 @@ convert{T}(::Type{FloatRange{T}}, r::OrdinalRange) =
convert{T}(::Type{FloatRange}, r::OrdinalRange{T}) =
FloatRange{typeof(float(first(r)))}(first(r), step(r), length(r), one(T))

promote_rule{T1,T2}(::Type{LinSpace{T1}},::Type{LinSpace{T2}}) =
LinSpace{promote_type(T1,T2)}
convert{T}(::Type{LinSpace{T}}, r::LinSpace{T}) = r
convert{T}(::Type{LinSpace{T}}, r::LinSpace) =
LinSpace{T}(r.start, r.stop, r.len, r.divisor)

promote_rule{F,OR<:OrdinalRange}(::Type{LinSpace{F}}, ::Type{OR}) =
LinSpace{promote_type(F,eltype(OR))}
convert{T}(::Type{LinSpace{T}}, r::OrdinalRange) =
linspace(convert(T, first(r)), convert(T, last(r)), convert(T, length(r)))
convert{T}(::Type{LinSpace}, r::OrdinalRange{T}) =
convert(LinSpace{typeof(float(first(r)))}, r)


# +/- of ranges is defined in operators.jl (to be able to use @eval etc.)

Expand Down Expand Up @@ -622,6 +651,7 @@ collect(r::Range) = vcat(r)

reverse(r::OrdinalRange) = colon(last(r), -step(r), first(r))
reverse(r::FloatRange) = FloatRange(r.start + (r.len-1)*r.step, -r.step, r.len, r.divisor)
reverse(r::LinSpace) = LinSpace(r.stop, r.start, r.len, r.divisor)

## sorting ##

Expand Down
44 changes: 44 additions & 0 deletions test/ranges.jl
Original file line number Diff line number Diff line change
Expand Up @@ -541,3 +541,47 @@ for x in r
i += 2
end
@test i == 7

# Issue 11049 and related
@test promote(linspace(0f0, 1f0, 3), linspace(0., 5., 2)) ===
(linspace(0., 1., 3), linspace(0., 5., 2))
@test convert(LinSpace{Float64}, linspace(0., 1., 3)) === linspace(0., 1., 3)
@test convert(LinSpace{Float64}, linspace(0f0, 1f0, 3)) === linspace(0., 1., 3)

@test promote(linspace(0., 1., 3), 0:5) === (linspace(0., 1., 3),
linspace(0., 5., 6))
@test convert(LinSpace{Float64}, 0:5) === linspace(0., 5., 6)
@test convert(LinSpace{Float64}, 0:1:5) === linspace(0., 5., 6)
@test convert(LinSpace, 0:5) === linspace(0., 5., 6)
@test convert(LinSpace, 0:1:5) === linspace(0., 5., 6)

function test_range_index(r, s)
@test typeof(r[s]) == typeof(r)
@test [r;][s] == [r[s];]
end
test_range_index(linspace(0.1, 0.3, 3), 1:2)
test_range_index(linspace(0.1, 0.3, 3), 1:0)
test_range_index(linspace(1.0, 1.0, 1), 1:1)
test_range_index(linspace(1.0, 1.0, 1), 1:0)
test_range_index(linspace(1.0, 2.0, 0), 1:0)

function test_linspace_identity(r, mr)
@test -r == mr
@test isa(-r, LinSpace)

@test 1 + r + (-1) == r
@test isa(1 + r + (-1), LinSpace)
@test 1 - r - 1 == mr
@test isa(1 - r - 1, LinSpace)

@test 1 * r * 1 == r
@test isa(1 * r * 1, LinSpace)
@test r / 1 == r
@test isa(r / 1, LinSpace)
end

test_linspace_identity(linspace(1.0, 27.0, 1275), linspace(-1.0, -27.0, 1275))

@test reverse(linspace(1.0, 27.0, 1275)) == linspace(27.0, 1.0, 1275)
@test [reverse(linspace(1.0, 27.0, 1275));] ==
reverse([linspace(1.0, 27.0, 1275);])

0 comments on commit 9c7c34f

Please sign in to comment.