Skip to content

Commit

Permalink
sorting: add rev boolean keyword to reverse any sort ordering.
Browse files Browse the repository at this point in the history
Also added lt, by, order, rev keywords to the searchsorted* funcs.
  • Loading branch information
StefanKarpinski committed Jul 11, 2013
1 parent 3326e0c commit 7bab350
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 60 deletions.
2 changes: 1 addition & 1 deletion base/darray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function defaultdist(dims, procs)
dims = [dims...]
chunks = ones(Int, length(dims))
np = length(procs)
f = sort!(collect(keys(factor(np))), order=Sort.Reverse)
f = sort!(collect(keys(factor(np))), rev=true)
k = 1
while np > 1
# repeatedly allocate largest factor to largest dim
Expand Down
61 changes: 34 additions & 27 deletions base/sort.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,10 @@ lt(o::ReverseOrdering, a, b) = lt(o.fwd,b,a)
lt(o::By, a, b) = isless(o.by(a),o.by(b))
lt(o::Lt, a, b) = o.lt(a,b)

ord(lt::Function, by::Function, order::Ordering) =
(lt === isless) & (by === identity) ? order :
(lt === isless) ? By(by) : Lt(lt)
function ord(lt::Function, by::Function, order::Ordering, rev::Bool)
o = (lt===isless) & (by===identity) ? order : (lt===isless) ? By(by) : Lt(lt)
rev ? ReverseOrdering(o) : o
end

## functions requiring only ordering ##

Expand All @@ -78,8 +79,9 @@ function issorted(itr, order::Ordering)
end
return true
end
issorted(itr; lt::Function=isless, by::Function=identity, order::Ordering=Forward) =
issorted(itr, ord(lt,by,order))
issorted(itr;
lt::Function=isless, by::Function=identity, order::Ordering=Forward, rev::Bool=false) =
issorted(itr, ord(lt,by,order,rev))

function select!(v::AbstractVector, k::Int, lo::Int, hi::Int, o::Ordering)
lo <= k <= hi || error("select index $k is out of range $lo:$hi")
Expand Down Expand Up @@ -142,8 +144,8 @@ end

select!(v::AbstractVector, k, o::Ordering) = select!(v,k,1,length(v),o)
select!(v::AbstractVector, k;
lt::Function=isless, by::Function=identity, order::Ordering=Forward) =
select!(v, k, ord(lt,by,order))
lt::Function=isless, by::Function=identity, order::Ordering=Forward, rev::Bool=false) =
select!(v, k, ord(lt,by,order,rev))

select(v::AbstractVector, k; kws...) = select!(copy(v), k; kws...)

Expand Down Expand Up @@ -203,46 +205,51 @@ function searchsorted(v::AbstractVector, x, lo::Int, hi::Int, o::Ordering)
return lo+1:hi-1
end

for s in {:searchsortedfirst, :searchsortedlast, :searchsorted}
@eval $s(v::AbstractVector, x; order::Ordering=Forward) = $s(v,x,1,length(v),order)
end

function searchsortedlast{T<:Real}(a::Ranges{T}, x::Real; order::Ordering=Forward)
function searchsortedlast{T<:Real}(a::Ranges{T}, x::Real, o::Ordering=Forward)
if step(a) == 0
lt(order, x, first(a)) ? 0 : length(a)
lt(o, x, first(a)) ? 0 : length(a)
else
n = max(min(iround((x-first(a))/step(a))+1,length(a)),1)
lt(order, x, a[n]) ? n-1 : n
lt(o, x, a[n]) ? n-1 : n
end
end

function searchsortedfirst{T<:Real}(a::Ranges{T}, x::Real; order::Ordering=Forward)
function searchsortedfirst{T<:Real}(a::Ranges{T}, x::Real, o::Ordering=Forward)
if step(a) == 0
lt(order, first(a), x) ? length(a)+1 : 1
lt(o, first(a), x) ? length(a)+1 : 1
else
n = max(min(iround((x-first(a))/step(a))+1,length(a)),1)
lt(order, a[n] ,x) ? n+1 : n
lt(o, a[n] ,x) ? n+1 : n
end
end

function searchsortedlast{T<:Integer}(a::Ranges{T}, x::Real; order::Ordering=Forward)
function searchsortedlast{T<:Integer}(a::Ranges{T}, x::Real, o::Ordering=Forward)
if step(a) == 0
lt(order, x, first(a)) ? 0 : length(a)
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; order::Ordering=Forward)
function searchsortedfirst{T<:Integer}(a::Ranges{T}, x::Real, o::Ordering=Forward)
if step(a) == 0
lt(order, first(a), x) ? length(a)+1 : 1
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; order::Ordering=Forward) =
searchsortedfirst(a,x,order=order):searchsortedlast(a,x,order=order)
searchsorted{T<:Real}(a::Ranges{T}, x::Real; kws...) =
searchsortedfirst(a,x; kws...):searchsortedlast(a,x; kws...)

for s in {:searchsortedfirst, :searchsortedlast, :searchsorted}
@eval begin
$s(v::AbstractVector, x, o::Ordering) = $s(v,x,1,length(v),o)
$s(v::AbstractVector, x;
lt::Function=isless, by::Function=identity, order::Ordering=Forward, rev::Bool=false) =
$s(v,x,ord(lt,by,order,rev))
end
end

## sorting algorithms ##

Expand Down Expand Up @@ -353,12 +360,12 @@ defalg{T<:Number}(v::AbstractArray{T}) = DEFAULT_UNSTABLE

sort!(v::AbstractVector, alg::Algorithm, order::Ordering) = sort!(v,1,length(v),alg,order)
sort!(v::AbstractVector; alg::Algorithm=defalg(v),
lt::Function=isless, by::Function=identity, order::Ordering=Forward) =
sort!(v, alg, ord(lt,by,order))
lt::Function=isless, by::Function=identity, order::Ordering=Forward, rev::Bool=false) =
sort!(v, alg, ord(lt,by,order,rev))

sortperm(v::AbstractVector; alg::Algorithm=defalg(v),
lt::Function=isless, by::Function=identity, order::Ordering=Forward) =
sort!([1:length(v)], alg, Perm(ord(lt,by,order),v))
lt::Function=isless, by::Function=identity, order::Ordering=Forward, rev::Bool=false) =
sort!([1:length(v)], alg, Perm(ord(lt,by,order,rev),v))

sort(v::AbstractVector; kws...) = sort!(copy(v); kws...)

Expand Down
4 changes: 2 additions & 2 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -430,11 +430,11 @@ begin
@test isless(asc[:,1],asc[:,2])
@test isless(asc[:,2],asc[:,3])

asr = sortrows(a, order=Sort.Reverse)
asr = sortrows(a, rev=true)
@test isless(asr[2,:],asr[1,:])
@test isless(asr[3,:],asr[2,:])

asc = sortcols(a, order=Sort.Reverse)
asc = sortcols(a, rev=true)
@test isless(asc[:,2],asc[:,1])
@test isless(asc[:,3],asc[:,2])

Expand Down
60 changes: 30 additions & 30 deletions test/sorting.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@test sort([2,3,1]) == [1,2,3]
@test sort([2,3,1], order=Sort.Reverse) == [3,2,1]
@test sort([2,3,1], rev=true) == [3,2,1]
@test sortperm([2,3,1]) == [3,1,2]
@test !issorted([2,3,1])
@test issorted([1,2,3])
Expand Down Expand Up @@ -30,41 +30,41 @@ rg_r = 57:-1:49; rgv_r = [rg_r]
for i = 47:59
@test searchsortedfirst(rg, i) == searchsortedfirst(rgv, i)
@test searchsortedlast(rg, i) == searchsortedlast(rgv, i)
@test searchsortedfirst(rg_r, i, order=Sort.Reverse) ==
searchsortedfirst(rgv_r, i, order=Sort.Reverse)
@test searchsortedlast(rg_r, i, order=Sort.Reverse) ==
searchsortedlast(rgv_r, i, order=Sort.Reverse)
@test searchsortedfirst(rg_r, i, rev=true) ==
searchsortedfirst(rgv_r, i, rev=true)
@test searchsortedlast(rg_r, i, rev=true) ==
searchsortedlast(rgv_r, i, rev=true)
end
rg = 1:2:17; rgv = [rg]
rg_r = 17:-2:1; rgv_r = [rg_r]
for i = -1:19
@test searchsortedfirst(rg, i) == searchsortedfirst(rgv, i)
@test searchsortedlast(rg, i) == searchsortedlast(rgv, i)
@test searchsortedfirst(rg_r, i, order=Sort.Reverse) ==
searchsortedfirst(rgv_r, i, order=Sort.Reverse)
@test searchsortedlast(rg_r, i, order=Sort.Reverse) ==
searchsortedlast(rgv_r, i, order=Sort.Reverse)
@test searchsortedfirst(rg_r, i, rev=true) ==
searchsortedfirst(rgv_r, i, rev=true)
@test searchsortedlast(rg_r, i, rev=true) ==
searchsortedlast(rgv_r, i, rev=true)
end
rg = -3:0.5:2; rgv = [rg]
rg_r = 2:-0.5:-3; rgv_r = [rg_r]
for i = -5:.5:4
@test searchsortedfirst(rg, i) == searchsortedfirst(rgv, i)
@test searchsortedlast(rg, i) == searchsortedlast(rgv, i)
@test searchsortedfirst(rg_r, i, order=Sort.Reverse) ==
searchsortedfirst(rgv_r, i, order=Sort.Reverse)
@test searchsortedlast(rg_r, i, order=Sort.Reverse) ==
searchsortedlast(rgv_r, i, order=Sort.Reverse)
@test searchsortedfirst(rg_r, i, rev=true) ==
searchsortedfirst(rgv_r, i, rev=true)
@test searchsortedlast(rg_r, i, rev=true) ==
searchsortedlast(rgv_r, i, rev=true)
end

rg = 3+0*(1:5); rgv = [rg]
rg_r = rg; rgv_r = [rg_r]
for i = 2:4
@test searchsortedfirst(rg, i) == searchsortedfirst(rgv, i)
@test searchsortedlast(rg, i) == searchsortedlast(rgv, i)
@test searchsortedfirst(rg_r, i, order=Sort.Reverse) ==
searchsortedfirst(rgv_r, i, order=Sort.Reverse)
@test searchsortedlast(rg_r, i, order=Sort.Reverse) ==
searchsortedlast(rgv_r, i, order=Sort.Reverse)
@test searchsortedfirst(rg_r, i, rev=true) ==
searchsortedfirst(rgv_r, i, rev=true)
@test searchsortedlast(rg_r, i, rev=true) ==
searchsortedlast(rgv_r, i, rev=true)
end

rg = 0.0:0.01:1.0
Expand All @@ -80,13 +80,13 @@ end

rg_r = reverse(rg)
for i = 1:100
@test searchsortedfirst(rg_r, rg_r[i], order=Sort.Reverse) == i
@test searchsortedfirst(rg_r, prevfloat(rg_r[i]), order=Sort.Reverse) == i+1
@test searchsortedfirst(rg_r, nextfloat(rg_r[i]), order=Sort.Reverse) == i
@test searchsortedfirst(rg_r, rg_r[i], rev=true) == i
@test searchsortedfirst(rg_r, prevfloat(rg_r[i]), rev=true) == i+1
@test searchsortedfirst(rg_r, nextfloat(rg_r[i]), rev=true) == i

@test searchsortedlast(rg_r, rg_r[i], order=Sort.Reverse) == i
@test searchsortedlast(rg_r, prevfloat(rg_r[i]), order=Sort.Reverse) == i
@test searchsortedlast(rg_r, nextfloat(rg_r[i]), order=Sort.Reverse) == i-1
@test searchsortedlast(rg_r, rg_r[i], rev=true) == i
@test searchsortedlast(rg_r, prevfloat(rg_r[i]), rev=true) == i
@test searchsortedlast(rg_r, nextfloat(rg_r[i]), rev=true) == i-1
end

a = rand(1:10000, 1000)
Expand All @@ -99,11 +99,11 @@ for alg in [InsertionSort, MergeSort, TimSort]
@test issorted(b)
@test a[ix] == b

b = sort(a, alg=alg, order=Sort.Reverse)
@test issorted(b, order=Sort.Reverse)
ix = sortperm(a, alg=alg, order=Sort.Reverse)
b = sort(a, alg=alg, rev=true)
@test issorted(b, rev=true)
ix = sortperm(a, alg=alg, rev=true)
b = a[ix]
@test issorted(b, order=Sort.Reverse)
@test issorted(b, rev=true)
@test a[ix] == b

b = sort(a, alg=alg, by=x->1/x)
Expand All @@ -129,12 +129,12 @@ end

b = sort(a, alg=QuickSort)
@test issorted(b)
b = sort(a, alg=QuickSort, order=Sort.Reverse)
@test issorted(b, order=Sort.Reverse)
b = sort(a, alg=QuickSort, rev=true)
@test issorted(b, rev=true)
b = sort(a, alg=QuickSort, by=x->1/x)
@test issorted(b, by=x->1/x)

@test select([3,6,30,1,9], 2, order=Sort.Reverse) == 9
@test select([3,6,30,1,9], 2, rev=true) == 9
@test select([3,6,30,1,9], 2, by=x->1/x) == 9

## more advanced sorting tests ##
Expand Down

0 comments on commit 7bab350

Please sign in to comment.