Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ordinal range implementation, fixes #5585 #6326

Merged
merged 11 commits into from
Apr 1, 2014
Prev Previous commit
Next Next commit
nearly finish OrdinalRange
still not clear what to do with floating point in StepRange
JeffBezanson committed Apr 1, 2014
commit e733cf157aa0cc9a735b01d9a51971a5f7742c8b
16 changes: 8 additions & 8 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
@@ -62,8 +62,8 @@ end
checkbounds(sz::Int, i::Int) = 1 <= i <= sz || throw(BoundsError())
checkbounds(sz::Int, i::Real) = checkbounds(sz, to_index(i))
checkbounds(sz::Int, I::AbstractVector{Bool}) = length(I) == sz || throw(BoundsError())
checkbounds(sz::Int, r::Ranges{Int}) = isempty(r) || (minimum(r) >= 1 && maximum(r) <= sz) || throw(BoundsError())
checkbounds{T<:Real}(sz::Int, r::Ranges{T}) = checkbounds(sz, to_index(r))
checkbounds(sz::Int, r::Range{Int}) = isempty(r) || (minimum(r) >= 1 && maximum(r) <= sz) || throw(BoundsError())
checkbounds{T<:Real}(sz::Int, r::Range{T}) = checkbounds(sz, to_index(r))

function checkbounds{T <: Real}(sz::Int, I::AbstractArray{T})
for i in I
@@ -321,7 +321,7 @@ full(x::AbstractArray) = x

for fn in _numeric_conversion_func_names
@eval begin
$fn(r::Range ) = Range($fn(r.start), $fn(r.step), r.len)
$fn(r::StepRange) = StepRange($fn(r.start), $fn(r.step), $fn(last(r)))
$fn(r::Range1) = Range1($fn(r.start), $fn(last(r)))
$fn(r::FloatRange) = FloatRange($fn(r.start), $fn(r.step), r.len, $fn(r.divisor))
end
@@ -451,21 +451,21 @@ end

## get (getindex with a default value) ##

typealias RangeVecIntList{A<:AbstractVector{Int}} Union((Union(Ranges, AbstractVector{Int})...), AbstractVector{Range1{Int}}, AbstractVector{Range{Int}}, AbstractVector{A})
typealias RangeVecIntList{A<:AbstractVector{Int}} Union((Union(Range, AbstractVector{Int})...), AbstractVector{Range1{Int}}, AbstractVector{Range{Int}}, AbstractVector{A})

get(A::AbstractArray, i::Integer, default) = in_bounds(length(A), i) ? A[i] : default
get(A::AbstractArray, I::(), default) = similar(A, typeof(default), 0)
get(A::AbstractArray, I::Dims, default) = in_bounds(size(A), I...) ? A[I...] : default

function get!{T}(X::AbstractArray{T}, A::AbstractArray, I::Union(Ranges, AbstractVector{Int}), default::T)
function get!{T}(X::AbstractArray{T}, A::AbstractArray, I::Union(Range, AbstractVector{Int}), default::T)
ind = findin(I, 1:length(A))
X[ind] = A[I[ind]]
X[1:first(ind)-1] = default
X[last(ind)+1:length(X)] = default
X
end

get(A::AbstractArray, I::Ranges, default) = get!(similar(A, typeof(default), length(I)), A, I, default)
get(A::AbstractArray, I::Range, default) = get!(similar(A, typeof(default), length(I)), A, I, default)

function get!{T}(X::AbstractArray{T}, A::AbstractArray, I::RangeVecIntList, default::T)
fill!(X, default)
@@ -823,7 +823,7 @@ function isequal(A::AbstractArray, B::AbstractArray)
if size(A) != size(B)
return false
end
if isa(A,Ranges) != isa(B,Ranges)
if isa(A,Range) != isa(B,Range)
return false
end
for i = 1:length(A)
@@ -847,7 +847,7 @@ function (==)(A::AbstractArray, B::AbstractArray)
if size(A) != size(B)
return false
end
if isa(A,Ranges) != isa(B,Ranges)
if isa(A,Range) != isa(B,Range)
return false
end
for i = 1:length(A)
12 changes: 6 additions & 6 deletions base/array.jl
Original file line number Diff line number Diff line change
@@ -118,11 +118,11 @@ end
getindex(T::(Type...)) = Array(T,0)

# T[a:b] and T[a:s:b] also contruct typed ranges
function getindex{T<:Number}(::Type{T}, r::Ranges)
function getindex{T<:Number}(::Type{T}, r::Range)
copy!(Array(T,length(r)), r)
end

function getindex{T<:Number}(::Type{T}, r1::Ranges, rs::Ranges...)
function getindex{T<:Number}(::Type{T}, r1::Range, rs::Range...)
a = Array(T,length(r1)+sum(length,rs))
o = 1
copy!(a, o, r1)
@@ -261,10 +261,10 @@ end
function getindex{T<:Real}(A::Array, I::AbstractVector{T})
return [ A[i] for i in to_index(I) ]
end
function getindex{T<:Real}(A::Ranges, I::AbstractVector{T})
function getindex{T<:Real}(A::Range, I::AbstractVector{T})
return [ A[i] for i in to_index(I) ]
end
function getindex(A::Ranges, I::AbstractVector{Bool})
function getindex(A::Range, I::AbstractVector{Bool})
checkbounds(A, I)
return [ A[i] for i in to_index(I) ]
end
@@ -716,7 +716,7 @@ for f in (:+, :-, :div, :mod, :&, :|, :$)
return F
end
# interaction with Ranges
function ($f){S,T<:Real}(A::StridedArray{S}, B::Ranges{T})
function ($f){S,T<:Real}(A::StridedArray{S}, B::Range{T})
F = similar(A, promote_type(S,T), promote_shape(size(A),size(B)))
i = 1
for b in B
@@ -725,7 +725,7 @@ for f in (:+, :-, :div, :mod, :&, :|, :$)
end
return F
end
function ($f){S<:Real,T}(A::Ranges{S}, B::StridedArray{T})
function ($f){S<:Real,T}(A::Range{S}, B::StridedArray{T})
F = similar(B, promote_type(S,T), promote_shape(size(A),size(B)))
i = 1
for a in A
2 changes: 1 addition & 1 deletion base/constants.jl
Original file line number Diff line number Diff line change
@@ -68,7 +68,7 @@ const golden = φ
for T in (MathConst, Rational, Integer, Number)
^(::MathConst{:e}, x::T) = exp(x)
end
for T in (Ranges, BitArray, SparseMatrixCSC, StridedArray, AbstractArray)
for T in (Range, BitArray, SparseMatrixCSC, StridedArray, AbstractArray)
.^(::MathConst{:e}, x::T) = exp(x)
end
^(::MathConst{:e}, x::AbstractMatrix) = expm(x)
3 changes: 2 additions & 1 deletion base/exports.jl
Original file line number Diff line number Diff line change
@@ -70,6 +70,7 @@ export
Matrix,
MergeSort,
ObjectIdDict,
OrdinalRange,
PollingFileWatcher,
ProcessGroup,
QR,
@@ -78,7 +79,6 @@ export
Range,
Range1,
RangeIndex,
Ranges,
Rational,
Regex,
RegexMatch,
@@ -97,6 +97,7 @@ export
SharedArray,
SparseMatrixCSC,
StatStruct,
StepRange,
StridedArray,
StridedMatrix,
StridedVecOrMat,
4 changes: 2 additions & 2 deletions base/linalg/dense.jl
Original file line number Diff line number Diff line change
@@ -70,9 +70,9 @@ end

function diagind(m::Integer, n::Integer, k::Integer=0)
if 0 < k < n
return Range(k*m+1,m+1,min(m,n-k))
return (k*m+1):(m+1):(k*m + min(m,n-k))
elseif 0 <= -k <= m
return Range(1-k,m+1,min(m+k,n))
return (1-l):(m+1):(-k + min(m+k,n))
end
throw(BoundsError())
end
4 changes: 2 additions & 2 deletions base/linalg/tridiag.jl
Original file line number Diff line number Diff line change
@@ -254,7 +254,7 @@ end
# Allocation-free variants
# Note that solve is non-aliasing, so you can use the same array for
# input and output
function solve!{T<:BlasFloat}(x::AbstractArray{T}, xrng::Ranges{Int}, M::Tridiagonal{T}, rhs::AbstractArray{T}, rhsrng::Ranges{Int})
function solve!{T<:BlasFloat}(x::AbstractArray{T}, xrng::Range{Int}, M::Tridiagonal{T}, rhs::AbstractArray{T}, rhsrng::Range{Int})
d = M.d
N = length(d)
if length(xrng) != N || length(rhsrng) != N
@@ -319,7 +319,7 @@ end
\(M::Tridiagonal, rhs::StridedVecOrMat) = solve(M, rhs)

# Tridiagonal multiplication
function mult(x::AbstractArray, xrng::Ranges{Int}, M::Tridiagonal, v::AbstractArray, vrng::Ranges{Int})
function mult(x::AbstractArray, xrng::Range{Int}, M::Tridiagonal, v::AbstractArray, vrng::Range{Int})
dl = M.dl
d = M.d
du = M.du
2 changes: 1 addition & 1 deletion base/linalg/woodbury.jl
Original file line number Diff line number Diff line change
@@ -78,7 +78,7 @@ det(W::Woodbury)=det(W.A)*det(W.C)/det(W.Cp)

# Allocation-free solver for arbitrary strides (requires that W.A has a
# non-aliasing "solve" routine, e.g., is Tridiagonal)
function solve!(x::AbstractArray, xrng::Ranges{Int}, W::Woodbury, rhs::AbstractArray, rhsrng::Ranges{Int})
function solve!(x::AbstractArray, xrng::Range{Int}, W::Woodbury, rhs::AbstractArray, rhsrng::Range{Int})
solve!(W.tmpN1, 1:length(W.tmpN1), W.A, rhs, rhsrng)
A_mul_B!(W.tmpk1, W.V, W.tmpN1)
A_mul_B!(W.tmpk2, W.Cp, W.tmpk1)
4 changes: 1 addition & 3 deletions base/multidimensional.jl
Original file line number Diff line number Diff line change
@@ -5,9 +5,8 @@
nothing
end


unsafe_getindex(v::Real, ind::Int) = v
unsafe_getindex(v::Ranges, ind::Int) = first(v) + (ind-1)*step(v)
unsafe_getindex(v::Range, ind::Int) = first(v) + (ind-1)*step(v)
unsafe_getindex(v::BitArray, ind::Int) = Base.unsafe_bitgetindex(v.chunks, ind)
unsafe_getindex(v::AbstractArray, ind::Int) = v[ind]
unsafe_getindex(v, ind::Real) = unsafe_getindex(v, to_index(ind))
@@ -16,7 +15,6 @@ unsafe_setindex!{T}(v::AbstractArray{T}, x::T, ind::Int) = (v[ind] = x; v)
unsafe_setindex!(v::BitArray, x::Bool, ind::Int) = (Base.unsafe_bitsetindex!(v.chunks, x, ind); v)
unsafe_setindex!{T}(v::AbstractArray{T}, x::T, ind::Real) = unsafe_setindex!(v, x, to_index(ind))


# Version that uses cartesian indexing for src
@ngenerate N typeof(dest) function _getindex!(dest::Array, src::AbstractArray, I::NTuple{N,Union(Int,AbstractVector)}...)
checksize(dest, I...)
8 changes: 4 additions & 4 deletions base/random.jl
Original file line number Diff line number Diff line change
@@ -168,7 +168,7 @@ function rand{T<:Integer,U<:Unsigned}(g::RandIntGen{T,U})
end

rand{T<:Union(Signed,Unsigned,Bool,Char)}(r::Range1{T}) = rand(RandIntGen(r))
rand{T<:Real}(r::Ranges{T}) = convert(T, first(r) + rand(0:(length(r)-1)) * step(r))
rand{T<:Real}(r::Range{T}) = convert(T, first(r) + rand(0:(length(r)-1)) * step(r))

function rand!(g::RandIntGen, A::AbstractArray)
for i = 1 : length(A)
@@ -179,7 +179,7 @@ end

rand!{T<:Union(Signed,Unsigned,Bool,Char)}(r::Range1{T}, A::AbstractArray) = rand!(RandIntGen(r), A)

function rand!{T<:Real}(r::Ranges{T}, A::AbstractArray)
function rand!{T<:Real}(r::Range{T}, A::AbstractArray)
g = RandIntGen(0:(length(r)-1))
f = first(r)
s = step(r)
@@ -195,8 +195,8 @@ function rand!{T<:Real}(r::Ranges{T}, A::AbstractArray)
return A
end

rand{T<:Real}(r::Ranges{T}, dims::Dims) = rand!(r, Array(T, dims))
rand(r::Ranges, dims::Int...) = rand(r, dims)
rand{T<:Real}(r::Range{T}, dims::Dims) = rand!(r, Array(T, dims))
rand(r::Range, dims::Int...) = rand(r, dims)


## random Bools
240 changes: 120 additions & 120 deletions base/range.jl

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion base/replutil.jl
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ function writemime(io::IO, ::MIME"text/plain", f::Function)
end

function writemime(io::IO, ::MIME"text/plain", v::AbstractVector)
if isa(v, Ranges)
if isa(v, Range)
show(io, v)
else
print(io, summary(v))
10 changes: 5 additions & 5 deletions base/sort.jl
Original file line number Diff line number Diff line change
@@ -174,7 +174,7 @@ function searchsorted(v::AbstractVector, x, lo::Int, hi::Int, o::Ordering)
return lo+1:hi-1
end

function searchsortedlast{T<:Real}(a::Ranges{T}, x::Real, o::Ordering=Forward)
function searchsortedlast{T<:Real}(a::Range{T}, x::Real, o::Ordering=Forward)
if step(a) == 0
lt(o, x, first(a)) ? 0 : length(a)
else
@@ -183,7 +183,7 @@ function searchsortedlast{T<:Real}(a::Ranges{T}, x::Real, o::Ordering=Forward)
end
end

function searchsortedfirst{T<:Real}(a::Ranges{T}, x::Real, o::Ordering=Forward)
function searchsortedfirst{T<:Real}(a::Range{T}, x::Real, o::Ordering=Forward)
if step(a) == 0
lt(o, first(a), x) ? length(a)+1 : 1
else
@@ -192,23 +192,23 @@ function searchsortedfirst{T<:Real}(a::Ranges{T}, x::Real, o::Ordering=Forward)
end
end

function searchsortedlast{T<:Integer}(a::Ranges{T}, x::Real, o::Ordering=Forward)
function searchsortedlast{T<:Integer}(a::Range{T}, x::Real, o::Ordering=Forward)
if step(a) == 0
lt(o, x, first(a)) ? 0 : length(a)
else
max(min(fld(ifloor(x)-first(a),step(a))+1,length(a)),0)
end
end

function searchsortedfirst{T<:Integer}(a::Ranges{T}, x::Real, o::Ordering=Forward)
function searchsortedfirst{T<:Integer}(a::Range{T}, x::Real, o::Ordering=Forward)
if step(a) == 0
lt(o, first(a), x) ? length(a)+1 : 1
else
max(min(-fld(ifloor(-x)+first(a),step(a))+1,length(a)+1),1)
end
end

searchsorted{T<:Real}(a::Ranges{T}, x::Real; kws...) =
searchsorted{T<:Real}(a::Range{T}, x::Real; kws...) =
searchsortedfirst(a,x; kws...):searchsortedlast(a,x; kws...)

for s in {:searchsortedfirst, :searchsortedlast, :searchsorted}
14 changes: 7 additions & 7 deletions base/statistics.jl
Original file line number Diff line number Diff line change
@@ -115,9 +115,9 @@ end

## variances over ranges

varm(v::Ranges, m::Number) = var(v)
varm(v::Range, m::Number) = var(v)

function var(v::Ranges)
function var(v::Range)
s = step(v)
l = length(v)
if l == 0 || l == 1
@@ -378,7 +378,7 @@ end

function histrange{T<:FloatingPoint,N}(v::AbstractArray{T,N}, n::Integer)
if length(v) == 0
return Range(0.0,1.0,1)
return 0.0:1.0:0.0
end
lo, hi = minimum(v), maximum(v)
if hi == lo
@@ -396,12 +396,12 @@ function histrange{T<:FloatingPoint,N}(v::AbstractArray{T,N}, n::Integer)
end
end
start = step*(ceil(lo/step)-1)
Range(start,step,1+iceil((hi - start)/step))
start:step:(start + iceil((hi - start)/step))
end

function histrange{T<:Integer,N}(v::AbstractArray{T,N}, n::Integer)
if length(v) == 0
return Range(0,1,1)
return 0:1:0
end
lo, hi = minimum(v), maximum(v)
if hi == lo
@@ -421,11 +421,11 @@ function histrange{T<:Integer,N}(v::AbstractArray{T,N}, n::Integer)
end
end
start = step*(iceil(lo/step)-1)
Range(start,step,1+iceil((hi - start)/step))
start:step:(start + iceil((hi - start)/step))
end

## midpoints of intervals
midpoints(r::Ranges) = r[1:length(r)-1] + 0.5*step(r)
midpoints(r::Range) = r[1:length(r)-1] + 0.5*step(r)
midpoints(v::AbstractVector) = [0.5*(v[i] + v[i+1]) for i in 1:length(v)-1]

## hist ##
2 changes: 1 addition & 1 deletion test/euler.jl
Original file line number Diff line number Diff line change
@@ -76,7 +76,7 @@ function euler11(grid,n)
j = n:size(grid,2)-n+1,
di = -1:1, dj = -1:1
di == dj == 0 && continue
idx = sub2ind(size(grid),Range(i,di,n),Range(j,dj,n))
idx = sub2ind(size(grid),i:di:(i+n-1),j:dj:(j+n-1))
m = max(m,prod(grid[idx]))
end
return m
37 changes: 18 additions & 19 deletions test/ranges.jl
Original file line number Diff line number Diff line change
@@ -36,12 +36,12 @@ let
r = 15:-2:-38
@test findin(r, span) == 1:6
end
@test isempty(findin(5+0*(1:6), 2:4))
@test findin(5+0*(1:6), 2:5) == 1:6
@test findin(5+0*(1:6), 2:7) == 1:6
@test findin(5+0*(1:6), 5:7) == 1:6
@test isempty(findin(5+0*(1:6), 6:7))
@test findin(5+0*(1:6), 5:5) == 1:6
#@test isempty(findin(5+0*(1:6), 2:4))
#@test findin(5+0*(1:6), 2:5) == 1:6
#@test findin(5+0*(1:6), 2:7) == 1:6
#@test findin(5+0*(1:6), 5:7) == 1:6
#@test isempty(findin(5+0*(1:6), 6:7))
#@test findin(5+0*(1:6), 5:5) == 1:6

@test intersect(1:5, 2:3) == 2:3
@test intersect(-3:5, 2:8) == 2:5
@@ -58,14 +58,14 @@ end
@test isempty(intersect(-5:5, -6:13:20))
@test isempty(intersect(1:11, 15:4:-2))
@test isempty(intersect(11:1, 15:-4:-2))
@test intersect(-5:5, 1+0*(1:3)) == 1:1
@test isempty(intersect(-5:5, 6+0*(1:3)))
#@test intersect(-5:5, 1+0*(1:3)) == 1:1
#@test isempty(intersect(-5:5, 6+0*(1:3)))
@test intersect(-15:4:7, -10:-2) == -7:4:-3
@test intersect(13:-2:1, -2:8) == 7:-2:1
@test isempty(intersect(13:2:1, -2:8))
@test isempty(intersect(13:-2:1, 8:-2))
@test intersect(5+0*(1:4), 2:8) == 5+0*(1:4)
@test isempty(intersect(5+0*(1:4), -7:3))
#@test intersect(5+0*(1:4), 2:8) == 5+0*(1:4)
#@test isempty(intersect(5+0*(1:4), -7:3))
@test intersect(0:3:24, 0:4:24) == 0:12:24
@test intersect(0:4:24, 0:3:24) == 0:12:24
@test intersect(0:3:24, 24:-4:0) == 0:12:24
@@ -76,17 +76,17 @@ end
@test isempty(intersect(1:6:2400, 0:4:2400))
@test intersect(-51:5:100, -33:7:125) == -26:35:79
@test intersect(-51:5:100, -32:7:125) == -11:35:94
@test intersect(0:6:24, 6+0*(0:4:24)) == 6:6:6
@test intersect(12+0*(0:6:24), 0:4:24) == Range(12, 0, 5)
@test isempty(intersect(6+0*(0:6:24), 0:4:24))
#@test intersect(0:6:24, 6+0*(0:4:24)) == 6:6:6
#@test intersect(12+0*(0:6:24), 0:4:24) == Range(12, 0, 5)
#@test isempty(intersect(6+0*(0:6:24), 0:4:24))
@test intersect(-10:3:24, -10:3:24) == -10:3:23
@test isempty(intersect(-11:3:24, -10:3:24))

@test !(3.5 in 1:5)
@test (3 in 1:5)
@test (3 in 5:-1:1)
@test (3 in 3+0*(1:5))
@test !(4 in 3+0*(1:5))
#@test (3 in 3+0*(1:5))
#@test !(4 in 3+0*(1:5))

r = 0.0:0.01:1.0
@test (r[30] in r)
@@ -223,13 +223,12 @@ for T = (Float32, Float64,),# BigFloat),
end

# near-equal ranges
@test 0.0:0.1:1.0 != Range(0.0,0.1,11)
@test 0.0:0.1:1.0 != 0.0f0:0.1f0:1.0f0

# comparing and hashing ranges
let
Rs = {1:2, int32(1:3:17), int64(1:3:17), 1:0, 17:-3:0,
0.0:0.1:1.0, Range(0.0,0.1,11),
float32(0.0:0.1:1.0), float32(Range(0.0,0.1,11))}
0.0:0.1:1.0, float32(0.0:0.1:1.0)}
for r in Rs
ar = collect(r)
@test r != ar
@@ -246,4 +245,4 @@ end

# issue #2959
@test 1.0:1.5 == 1.0:1.0:1.5 == 1.0:1.0
@test 1.0:(.3-.1)/.1 == 1.0:2.0
#@test 1.0:(.3-.1)/.1 == 1.0:2.0