From 73ecfd894c423920cd4911b043b224988271aa5a Mon Sep 17 00:00:00 2001 From: Stefan Karpinski Date: Tue, 9 Jul 2013 11:08:46 -0400 Subject: [PATCH 1/7] sorting: make `order` and `alg` keyword arguments. The idea here is that the ordering and algorithm for sorting are two orthogonal parameters that have sensible defaults: neither, both or either can be independently specified. The resulting API is slightly more verbose but also somewhat more self-documenting. Another sign that this might be on the right track is that this change reduces the LOC of base/sort.jl by 41 lines and reduces the method count of sort, for example, from 12 to 6. --- base/darray.jl | 2 +- base/pkg/resolve.jl | 2 +- base/pkg2/resolve/maxsum.jl | 2 +- base/sort.jl | 143 +++++++++++++----------------------- examples/bubblesort.jl | 5 +- test/arrayops.jl | 4 +- test/sorting.jl | 114 ++++++++++++++-------------- 7 files changed, 116 insertions(+), 156 deletions(-) diff --git a/base/darray.jl b/base/darray.jl index 2fefdad809abb..ba77e44f19c0b 100644 --- a/base/darray.jl +++ b/base/darray.jl @@ -60,7 +60,7 @@ function defaultdist(dims, procs) dims = [dims...] chunks = ones(Int, length(dims)) np = length(procs) - f = sort!(collect(keys(factor(np))), Sort.Reverse) + f = sort!(collect(keys(factor(np))), order=Sort.Reverse) k = 1 while np > 1 # repeatedly allocate largest factor to largest dim diff --git a/base/pkg/resolve.jl b/base/pkg/resolve.jl index 5149d696a209d..b92a6538306f4 100644 --- a/base/pkg/resolve.jl +++ b/base/pkg/resolve.jl @@ -911,7 +911,7 @@ function decimate(n::Int, graph::Graph, msgs::Messages) #println("DECIMATING $n NODES") fld = msgs.fld decimated = msgs.decimated - fldorder = sortperm(fld, Sort.By(secondmax)) + fldorder = sortperm(fld, order=Sort.By(secondmax)) for p0 in fldorder if decimated[p0] continue diff --git a/base/pkg2/resolve/maxsum.jl b/base/pkg2/resolve/maxsum.jl index f08e8f042ef82..a09afff2b4160 100644 --- a/base/pkg2/resolve/maxsum.jl +++ b/base/pkg2/resolve/maxsum.jl @@ -399,7 +399,7 @@ function decimate(n::Int, graph::Graph, msgs::Messages) #println("DECIMATING $n NODES") fld = msgs.fld decimated = msgs.decimated - fldorder = sortperm(fld, Sort.By(secondmax)) + fldorder = sortperm(fld, order=Sort.By(secondmax)) for p0 in fldorder if decimated[p0] continue diff --git a/base/sort.jl b/base/sort.jl index a213b9134fa97..54a05f98cb104 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -59,13 +59,13 @@ lt(o::Lt, a, b) = o.lt(a,b) ## functions requiring only ordering ## -function issorted(itr, o::Ordering = Forward) +function issorted(itr; order::Ordering=Forward) state = start(itr) done(itr,state) && return true prev, state = next(itr, state) while !done(itr, state) this, state = next(itr, state) - lt(o, this, prev) && return false + lt(order, this, prev) && return false prev = this end return true @@ -130,20 +130,20 @@ function select!(v::AbstractVector, r::Range1, lo::Int, hi::Int, o::Ordering) end end -select!(v::AbstractVector, k, o::Ordering=Forward) = select!(v, k, 1, length(v), o) -select (v::AbstractVector, k, o::Ordering=Forward) = select!(copy(v), k, o) +select!(v::AbstractVector, k; order::Ordering=Forward) = select!(v,k,1,length(v),order) +select (v::AbstractVector, k; order::Ordering=Forward) = select!(copy(v),k,order=order) for s in {:select!, :select} @eval begin - $s(v::AbstractVector, k::Int, lt::Function) = $s(v, k, Sort.Lt(lt)) - $s(lt::Function, v::AbstractVector, k::Int) = $s(v, k, lt) + $s(v::AbstractVector, k::Int, lt::Function) = $s(v, k, order=Sort.Lt(lt)) + $s(lt::Function, v::AbstractVector, k::Int) = $s(v, k, order=Sort.Lt(lt)) end end for s in {:selectby!, :selectby} @eval begin - $s(v::AbstractVector, k::Int, by::Function) = $s(v, k, Sort.By(by)) - $s(by::Function, v::AbstractVector, k::Int) = $s(v, k, by) + $s(v::AbstractVector, k::Int, by::Function) = $s(v, k, order=Sort.By(by)) + $s(by::Function, v::AbstractVector, k::Int) = $s(v, k, order=Sort.By(by)) end end @@ -195,54 +195,54 @@ function searchsorted(v::AbstractVector, x, lo::Int, hi::Int, o::Ordering) elseif lt(o, x, v[m]) hi = m else - return searchsortedfirst(v, x, max(lo,1), m, o):searchsortedlast(v, x, m, min(hi,length(v)), o) + a = searchsortedfirst(v, x, max(lo,1), m, o) + b = searchsortedlast(v, x, m, min(hi,length(v)), o) + return a:b end end return lo+1:hi-1 end 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) = $s(v, x, Forward) - end + @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,o::Ordering) +function searchsortedlast{T<:Real}(a::Ranges{T}, x::Real; order::Ordering=Forward) if step(a) == 0 - lt(o, x, first(a)) ? 0 : length(a) + lt(order, x, first(a)) ? 0 : length(a) else n = max(min(iround((x-first(a))/step(a))+1,length(a)),1) - lt(o,x,a[n]) ? n-1 : n + lt(order, x, a[n]) ? n-1 : n end end -function searchsortedfirst{T<:Real}(a::Ranges{T},x::Real,o::Ordering) +function searchsortedfirst{T<:Real}(a::Ranges{T}, x::Real; order::Ordering=Forward) if step(a) == 0 - lt(o, first(a), x) ? length(a) + 1 : 1 + lt(order, first(a), x) ? length(a)+1 : 1 else n = max(min(iround((x-first(a))/step(a))+1,length(a)),1) - lt(o,a[n],x) ? n+1 : n + lt(order, a[n] ,x) ? n+1 : n end end -function searchsortedlast{T<:Integer}(a::Ranges{T},x::Real,o::Ordering) +function searchsortedlast{T<:Integer}(a::Ranges{T}, x::Real; order::Ordering=Forward) if step(a) == 0 - lt(o, x, first(a)) ? 0 : length(a) + lt(order, 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) +function searchsortedfirst{T<:Integer}(a::Ranges{T}, x::Real; order::Ordering=Forward) if step(a) == 0 - lt(o, first(a), x) ? length(a) + 1 : 1 + lt(order, 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) = searchsortedfirst(a,x):searchsortedlast(a,x) +searchsorted{T<:Real}(a::Ranges{T}, x::Real; order::Ordering=Forward) = + searchsortedfirst(a,x,order=order):searchsortedlast(a,x,order=order) ## sorting algorithms ## @@ -263,15 +263,6 @@ const DEFAULT_STABLE = MergeSort const SMALL_ALGORITHM = InsertionSort const SMALL_THRESHOLD = 20 -sort!(v::AbstractVector, a::Algorithm, o::Ordering) = sort!(v, 1, length(v), a, o) -sort (v::AbstractVector, a::Algorithm, o::Ordering) = sort!(copy(v), a, o) - -sort!{T<:Number}(v::AbstractVector{T}, o::Ordering) = sort!(v, DEFAULT_UNSTABLE, o) -sort {T<:Number}(v::AbstractVector{T}, o::Ordering) = sort (v, DEFAULT_UNSTABLE, o) - -sort!(v::AbstractVector, o::Ordering) = sort!(v, DEFAULT_STABLE, o) -sort (v::AbstractVector, o::Ordering) = sort (v, DEFAULT_STABLE, o) - function sort!(v::AbstractVector, lo::Int, hi::Int, ::InsertionSortAlg, o::Ordering) for i = lo+1:hi j = i @@ -307,7 +298,7 @@ function sort!(v::AbstractVector, lo::Int, hi::Int, a::QuickSortAlg, o::Ordering return v end -function sort!(v::AbstractVector, lo::Int, hi::Int, a::MergeSortAlg, o::Ordering, t::AbstractVector) +function sort!(v::AbstractVector, lo::Int, hi::Int, a::MergeSortAlg, o::Ordering, t=similar(v)) if lo < hi hi-lo <= SMALL_THRESHOLD && return sort!(v, lo, hi, SMALL_ALGORITHM, o) @@ -342,53 +333,42 @@ function sort!(v::AbstractVector, lo::Int, hi::Int, a::MergeSortAlg, o::Ordering return v end -sort!(v::AbstractVector, lo::Int, hi::Int, a::MergeSortAlg, o::Ordering) = sort!(v, lo, hi, a, o, similar(v)) include("timsort.jl") ## sortperm: the permutation to sort an array ## immutable Perm{O<:Ordering,V<:AbstractVector} <: Ordering - ord::O - vec::V + order::O + data::V end Perm{O<:Ordering,V<:AbstractVector}(o::O,v::V) = Perm{O,V}(o,v) -lt(p::Perm, a, b) = lt(p.ord, p.vec[a], p.vec[b]) - -sortperm(v::AbstractVector, a::Algorithm, o::Ordering) = sort!([1:length(v)], a, Perm(o,v)) -sortperm(v::AbstractVector, o::Ordering) = sortperm(v, DEFAULT_STABLE, o) +lt(p::Perm, a, b) = lt(p.order, p.data[a], p.data[b]) -############## +sortperm(v::AbstractVector; alg::Algorithm=defalg(v), order::Ordering=Forward) = + sort!([1:length(v)], alg, Perm(order,v)) -# generic sorting methods +## generic sorting methods ## -for s in {:sort!, :sort, :sortperm} - @eval begin - # default to forward sort ordering - $s(v::AbstractVector, a::Algorithm) = $s(v, a, Forward) - $s(v::AbstractVector ) = $s(v, Forward) +defalg(v::AbstractArray) = DEFAULT_STABLE +defalg{T<:Number}(v::AbstractArray{T}) = DEFAULT_UNSTABLE - # also allow ordering before algorithm - $s(v::AbstractVector, o::Ordering, a::Algorithm) = $s(v, a, o) - end -end +sort!(v::AbstractVector, alg::Algorithm, order::Ordering) = sort!(v, 1, length(v), alg, order) +sort!(v::AbstractVector; alg::Algorithm=defalg(v), order::Ordering=Forward) = sort!(v, alg, order) +sort (v::AbstractVector; alg::Algorithm=defalg(v), order::Ordering=Forward) = sort!(copy(v), alg, order) for s in {:sort!, :sort, :sortperm} @eval begin - $s(v::AbstractVector, a::Algorithm, lt::Function) = $s(v, a, Sort.Lt(lt)) - $s(v::AbstractVector, lt::Function, a::Algorithm) = $s(v, a, lt) - $s(v::AbstractVector, lt::Function) = $s(v, Sort.Lt(lt)) - $s(lt::Function, v::AbstractVector, args...) = $s(v, lt, args...) + $s(v::AbstractVector, lt::Function; alg::Algorithm=defalg(v)) = $s(v, alg=alg, order=Sort.Lt(lt)) + $s(lt::Function, v::AbstractVector; alg::Algorithm=defalg(v)) = $s(v, alg=alg, order=Sort.Lt(lt)) end end for (sb,s) in {(:sortby!, :sort!), (:sortby, :sort), (:sortpermby, :sortperm)} @eval begin - $sb(v::AbstractVector, a::Algorithm, by::Function) = $s(v, a, Sort.By(by)) - $sb(v::AbstractVector, by::Function, a::Algorithm) = $s(v, a, Sort.By(by)) - $sb(v::AbstractVector, by::Function) = $s(v, Sort.By(by)) - $sb(by::Function, v::AbstractVector, args...) = $s(v, Sort.By(by), args...) + $sb(v::AbstractVector, by::Function; alg::Algorithm=defalg(v)) = $s(v, alg=alg, order=Sort.By(by)) + $sb(by::Function, v::AbstractVector; alg::Algorithm=defalg(v)) = $s(v, alg=alg, order=Sort.By(by)) end end @@ -409,14 +389,14 @@ type Right <: Ordering end left(::Direct) = Left() right(::Direct) = Right() -left{O<:Direct}(o::Perm{O}) = Perm(left(O()),o.vec) -right{O<:Direct}(o::Perm{O}) = Perm(right(O()),o.vec) +left{O<:Direct}(o::Perm{O}) = Perm(left(O()),o.data) +right{O<:Direct}(o::Perm{O}) = Perm(right(O()),o.data) lt{T<:Floats}(::Left, x::T, y::T) = slt_int(unbox(T,y),unbox(T,x)) lt{T<:Floats}(::Right, x::T, y::T) = slt_int(unbox(T,x),unbox(T,y)) isnan(o::Direct, x::Floats) = (x!=x) -isnan{O<:Direct}(o::Perm{O}, i::Int) = isnan(O(),o.vec[i]) +isnan{O<:Direct}(o::Perm{O}, i::Int) = isnan(O(),o.data[i]) function nans2left!(v::AbstractVector, lo::Int, hi::Int, o::Ordering) hi < lo && return lo, hi @@ -469,7 +449,7 @@ nans2end!{O<:ForwardOrdering}(v::AbstractVector{Int}, o::Perm{O}) = nans2right!( nans2end!{O<:ReverseOrdering}(v::AbstractVector{Int}, o::Perm{O}) = nans2left!(v, o) issignleft(o::Direct, x::Floats) = lt(o, x, zero(x)) -issignleft{O<:Direct}(o::Perm{O}, i::Int) = issignleft(O(), o.vec[i]) +issignleft{O<:Direct}(o::Perm{O}, i::Int) = issignleft(O(), o.data[i]) function fpsort!(v::AbstractVector, a::Algorithm, o::Ordering) i, j = lo, hi = nans2end!(v,o) @@ -493,44 +473,23 @@ sort!{O<:Direct,T<:Floats}(v::Vector{Int}, a::Algorithm, o::Perm{O,Vector{T}}) = end # module Sort.Float -# sorting multi-dimensional arrays - -sort(A::AbstractArray, dim::Integer, o::Base.Sort.Ordering=Base.Sort.Forward, - alg::Base.Sort.Algorithm = DEFAULT_STABLE) = - mapslices(a->sort(a,o), A, [dim]) - -sort(A::AbstractArray, dim::Integer, alg::Base.Sort.Algorithm) = - sort(A, dim, Base.Sort.Forward, alg) +## sorting multi-dimensional arrays ## -sort(A::AbstractArray, dim::Integer, alg::Base.Sort.Algorithm, o::Base.Sort.Ordering) = - sort(A, dim, o, alg) +sort(A::AbstractArray, dim::Integer; alg::Algorithm=defalg(A), order::Ordering=Forward) = + mapslices(a->sort(a, alg=alg, order=order), A, [dim]) -function sortrows(A::AbstractMatrix, o::Base.Sort.Ordering=Base.Sort.Forward, - alg::Base.Sort.Algorithm = DEFAULT_STABLE) +function sortrows(A::AbstractMatrix; alg::Algorithm=defalg(A), order::Ordering=Forward) c = 1:size(A,2) rows = [ sub(A,i,c) for i=1:size(A,1) ] - p = sortperm(rows, o, alg) + p = sortperm(rows, alg=alg, order=order) A[p,:] end -sortrows(A::AbstractMatrix, alg::Base.Sort.Algorithm) = - sortrows(A, Base.Sort.Forward, alg) - -sortrows(A::AbstractMatrix, alg::Base.Sort.Algorithm, o::Base.Sort.Ordering) = - sortrows(A, o, alg) - -function sortcols(A::AbstractMatrix, o::Base.Sort.Ordering=Base.Sort.Forward, - alg::Base.Sort.Algorithm = DEFAULT_STABLE) +function sortcols(A::AbstractMatrix; alg::Algorithm=defalg(A), order::Ordering=Forward) r = 1:size(A,1) cols = [ sub(A,r,i) for i=1:size(A,2) ] - p = sortperm(cols, o, alg) + p = sortperm(cols, alg=alg, order=order) A[:,p] end -sortcols(A::AbstractMatrix, alg::Base.Sort.Algorithm) = - sortcols(A, Base.Sort.Forward, alg) - -sortcols(A::AbstractMatrix, alg::Base.Sort.Algorithm, o::Base.Sort.Ordering) = - sortcols(A, o, alg) - end # module Sort diff --git a/examples/bubblesort.jl b/examples/bubblesort.jl index 05e1a17f554b0..3e3aa3210e02f 100644 --- a/examples/bubblesort.jl +++ b/examples/bubblesort.jl @@ -1,8 +1,9 @@ importall Base -type BubbleSort <: Sort.Algorithm end +type BubbleSortAlg <: Sort.Algorithm end +const BubbleSort = BubbleSortAlg() -function sort!(v::AbstractVector, lo::Int, hi::Int, ::BubbleSort, o::Sort.Ordering) +function sort!(v::AbstractVector, lo::Int, hi::Int, ::BubbleSortAlg, o::Sort.Ordering) while true clean = true for i = lo:hi-1 diff --git a/test/arrayops.jl b/test/arrayops.jl index 17e4e9898eecd..9263fe8064a62 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -430,11 +430,11 @@ begin @test isless(asc[:,1],asc[:,2]) @test isless(asc[:,2],asc[:,3]) - asr = sortrows(a, Sort.Reverse) + asr = sortrows(a, order=Sort.Reverse) @test isless(asr[2,:],asr[1,:]) @test isless(asr[3,:],asr[2,:]) - asc = sortcols(a, Sort.Reverse) + asc = sortcols(a, order=Sort.Reverse) @test isless(asc[:,2],asc[:,1]) @test isless(asc[:,3],asc[:,2]) diff --git a/test/sorting.jl b/test/sorting.jl index fc0813e9e74f3..9c29e4ce22637 100644 --- a/test/sorting.jl +++ b/test/sorting.jl @@ -1,5 +1,5 @@ @test sort([2,3,1]) == [1,2,3] -@test sort([2,3,1],Sort.Reverse) == [3,2,1] +@test sort([2,3,1], order=Sort.Reverse) == [3,2,1] @test sortperm([2,3,1]) == [3,1,2] @test !issorted([2,3,1]) @test issorted([1,2,3]) @@ -30,30 +30,30 @@ 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, Sort.Reverse) == - searchsortedfirst(rgv_r, i, Sort.Reverse) - @test searchsortedlast(rg_r, i, Sort.Reverse) == - searchsortedlast(rgv_r, i, Sort.Reverse) + @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) 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, Sort.Reverse) == - searchsortedfirst(rgv_r, i, Sort.Reverse) - @test searchsortedlast(rg_r, i, Sort.Reverse) == - searchsortedlast(rgv_r, i, Sort.Reverse) + @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) 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, Sort.Reverse) == - searchsortedfirst(rgv_r, i, Sort.Reverse) - @test searchsortedlast(rg_r, i, Sort.Reverse) == - searchsortedlast(rgv_r, i, Sort.Reverse) + @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) end rg = 3+0*(1:5); rgv = [rg] @@ -61,56 +61,56 @@ 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, Sort.Reverse) == - searchsortedfirst(rgv_r, i, Sort.Reverse) - @test searchsortedlast(rg_r, i, Sort.Reverse) == - searchsortedlast(rgv_r, i, Sort.Reverse) + @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) end rg = 0.0:0.01:1.0 for i = 2:101 - @test searchsortedfirst(rg,rg[i]) == i - @test searchsortedfirst(rg,prevfloat(rg[i])) == i - @test searchsortedfirst(rg,nextfloat(rg[i])) == i+1 + @test searchsortedfirst(rg, rg[i]) == i + @test searchsortedfirst(rg, prevfloat(rg[i])) == i + @test searchsortedfirst(rg, nextfloat(rg[i])) == i+1 - @test searchsortedlast(rg,rg[i]) == i - @test searchsortedlast(rg,prevfloat(rg[i])) == i-1 - @test searchsortedlast(rg,nextfloat(rg[i])) == i + @test searchsortedlast(rg, rg[i]) == i + @test searchsortedlast(rg, prevfloat(rg[i])) == i-1 + @test searchsortedlast(rg, nextfloat(rg[i])) == i end rg_r = reverse(rg) for i = 1:100 - @test searchsortedfirst(rg_r,rg_r[i],Sort.Reverse) == i - @test searchsortedfirst(rg_r,prevfloat(rg_r[i]),Sort.Reverse) == i+1 - @test searchsortedfirst(rg_r,nextfloat(rg_r[i]),Sort.Reverse) == i + @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 searchsortedlast(rg_r,rg_r[i],Sort.Reverse) == i - @test searchsortedlast(rg_r,prevfloat(rg_r[i]),Sort.Reverse) == i - @test searchsortedlast(rg_r,nextfloat(rg_r[i]),Sort.Reverse) == i-1 + @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 end a = rand(1:10000, 1000) for alg in [InsertionSort, MergeSort, TimSort] - b = sort(a, alg) + b = sort(a, alg=alg) @test issorted(b) - ix = sortperm(a, alg) + ix = sortperm(a, alg=alg) b = a[ix] @test issorted(b) @test a[ix] == b - b = sort(a, alg, Sort.Reverse) - @test issorted(b, Sort.Reverse) - ix = sortperm(a, alg, Sort.Reverse) + b = sort(a, alg=alg, order=Sort.Reverse) + @test issorted(b, order=Sort.Reverse) + ix = sortperm(a, alg=alg, order=Sort.Reverse) b = a[ix] - @test issorted(b, Sort.Reverse) + @test issorted(b, order=Sort.Reverse) @test a[ix] == b - b = sortby(a, alg, x -> -10x) - @test issorted(b, Sort.By(x -> -10x)) - ix = sortperm(a, alg, Sort.By(x -> -10x)) + b = sortby(a, x->1/x, alg=alg) + @test issorted(b, order=Sort.By(x->1/x)) + ix = sortperm(a, alg=alg, order=Sort.By(x->1/x)) b = a[ix] - @test issorted(b, Sort.By(x -> -10x)) + @test issorted(b, order=Sort.By(x->1/x)) @test a[ix] == b c = copy(a) @@ -120,26 +120,26 @@ for alg in [InsertionSort, MergeSort, TimSort] ipermute!(c, ix) @test c == a - c = sort(a, alg) do x,y + c = sort(a, alg=alg) do x,y x > y end @test b == c - c = sortby(a, alg) do x + c = sortby(a, alg=alg) do x -10x end @test b == c end -b = sort(a, QuickSort) +b = sort(a, alg=QuickSort) @test issorted(b) -b = sort(a, QuickSort, Sort.Reverse) -@test issorted(b, Sort.Reverse) -b = sortby(a, QuickSort, x -> -10x) -@test issorted(b, Sort.By(x -> -10x)) +b = sort(a, alg=QuickSort, order=Sort.Reverse) +@test issorted(b, order=Sort.Reverse) +b = sortby(a, x->1/x, alg=QuickSort) +@test issorted(b, order=Sort.By(x->1/x)) -@test select([3,6,30,1,9], 2, Sort.Reverse) == 9 -@test select([3,6,30,1,9], 2, Sort.By(x -> -x)) == 9 +@test select([3,6,30,1,9], 2, order=Sort.Reverse) == 9 +@test select([3,6,30,1,9], 2, order=Sort.By(x->1/x)) == 9 ## more advanced sorting tests ## @@ -161,12 +161,12 @@ for n in [0:10, 100, 1000] for ord in [Sort.Forward, Sort.Reverse] # insersion sort as a reference - pi = sortperm(v,InsertionSort,ord) + pi = sortperm(v, alg=InsertionSort, order=ord) @test isperm(pi) s = v[pi] - @test issorted(s, ord) + @test issorted(s, order=ord) @test hist(s,r) == h - @test all([ issorted(pi[s.==i]) for i in r ]) + @test all(issorted,[pi[s.==i] for i in r]) si = copy(v) permute!(si, pi) @test si == s @@ -174,7 +174,7 @@ for n in [0:10, 100, 1000] @test si == v # mergesort - pm = sortperm(v,MergeSort,ord) + pm = sortperm(v, alg=MergeSort, order=ord) @test pi == pm sm = copy(v) permute!(sm, pm) @@ -183,7 +183,7 @@ for n in [0:10, 100, 1000] @test sm == v # timsort - pt = sortperm(v,TimSort,ord) + pt = sortperm(v, alg=TimSort, order=ord) @test pi == pt st = copy(v) permute!(st, pt) @@ -192,7 +192,7 @@ for n in [0:10, 100, 1000] @test st == v # quicksort (unstable) - pq = sortperm(v,QuickSort,ord) + pq = sortperm(v, alg=QuickSort, order=ord) @test isperm(pi) @test v[pq] == s sq = copy(v) @@ -207,12 +207,12 @@ for n in [0:10, 100, 1000] for ord in [Sort.Forward, Sort.Reverse], alg in [InsertionSort, QuickSort, MergeSort, TimSort] # test float sorting with NaNs - s = sort(v,alg,ord) - @test issorted(s, ord) + s = sort(v, alg=alg, order=ord) + @test issorted(s, order=ord) @test reinterpret(Uint64,v[isnan(v)]) == reinterpret(Uint64,s[isnan(s)]) # test float permutation with NaNs - p = sortperm(v,alg,ord) + p = sortperm(v, alg=alg, order=ord) @test isperm(p) vp = v[p] @test isequal(s,vp) From 738c23049ad90452bd4a1b1ef520c97140d84b4a Mon Sep 17 00:00:00 2001 From: Stefan Karpinski Date: Wed, 10 Jul 2013 06:25:15 -0400 Subject: [PATCH 2/7] sorting: move matrix sorts up with other generic sorting functions. --- base/sort.jl | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/base/sort.jl b/base/sort.jl index 54a05f98cb104..944c869f65d51 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -372,6 +372,25 @@ for (sb,s) in {(:sortby!, :sort!), (:sortby, :sort), (:sortpermby, :sortperm)} end end +## sorting multi-dimensional arrays ## + +sort(A::AbstractArray, dim::Integer; alg::Algorithm=defalg(A), order::Ordering=Forward) = + mapslices(a->sort(a, alg=alg, order=order), A, [dim]) + +function sortrows(A::AbstractMatrix; alg::Algorithm=defalg(A), order::Ordering=Forward) + c = 1:size(A,2) + rows = [ sub(A,i,c) for i=1:size(A,1) ] + p = sortperm(rows, alg=alg, order=order) + A[p,:] +end + +function sortcols(A::AbstractMatrix; alg::Algorithm=defalg(A), order::Ordering=Forward) + r = 1:size(A,1) + cols = [ sub(A,r,i) for i=1:size(A,2) ] + p = sortperm(cols, alg=alg, order=order) + A[:,p] +end + ## fast clever sorting for floats ## module Float @@ -473,23 +492,4 @@ sort!{O<:Direct,T<:Floats}(v::Vector{Int}, a::Algorithm, o::Perm{O,Vector{T}}) = end # module Sort.Float -## sorting multi-dimensional arrays ## - -sort(A::AbstractArray, dim::Integer; alg::Algorithm=defalg(A), order::Ordering=Forward) = - mapslices(a->sort(a, alg=alg, order=order), A, [dim]) - -function sortrows(A::AbstractMatrix; alg::Algorithm=defalg(A), order::Ordering=Forward) - c = 1:size(A,2) - rows = [ sub(A,i,c) for i=1:size(A,1) ] - p = sortperm(rows, alg=alg, order=order) - A[p,:] -end - -function sortcols(A::AbstractMatrix; alg::Algorithm=defalg(A), order::Ordering=Forward) - r = 1:size(A,1) - cols = [ sub(A,r,i) for i=1:size(A,2) ] - p = sortperm(cols, alg=alg, order=order) - A[:,p] -end - end # module Sort From e5498d1018ab00513567e5d691fe92ae4cb358f9 Mon Sep 17 00:00:00 2001 From: Stefan Karpinski Date: Wed, 10 Jul 2013 06:50:56 -0400 Subject: [PATCH 3/7] sorting: eliminate a few nans2{left,right} definitions via defaults. --- base/sort.jl | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/base/sort.jl b/base/sort.jl index 944c869f65d51..19c5137a20384 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -417,7 +417,7 @@ lt{T<:Floats}(::Right, x::T, y::T) = slt_int(unbox(T,x),unbox(T,y)) isnan(o::Direct, x::Floats) = (x!=x) isnan{O<:Direct}(o::Perm{O}, i::Int) = isnan(O(),o.data[i]) -function nans2left!(v::AbstractVector, lo::Int, hi::Int, o::Ordering) +function nans2left!(v::AbstractVector, o::Ordering, lo::Int=1, hi::Int=length(v)) hi < lo && return lo, hi i = lo while (i < hi) & isnan(o, v[i]) @@ -438,7 +438,7 @@ function nans2left!(v::AbstractVector, lo::Int, hi::Int, o::Ordering) end return i, hi end -function nans2right!(v::AbstractVector, lo::Int, hi::Int, o::Ordering) +function nans2right!(v::AbstractVector, o::Ordering, lo::Int=1, hi::Int=length(v)) hi < lo && return lo, hi i = hi while (i > lo) & isnan(o, v[i]) @@ -459,8 +459,6 @@ function nans2right!(v::AbstractVector, lo::Int, hi::Int, o::Ordering) end return lo, i end -nans2left!(v::AbstractVector, o::Ordering) = nans2left!(v, 1, length(v), o) -nans2right!(v::AbstractVector, o::Ordering) = nans2right!(v, 1, length(v), o) nans2end!(v::AbstractVector, o::ForwardOrdering) = nans2right!(v, o) nans2end!(v::AbstractVector, o::ReverseOrdering) = nans2left!(v, o) @@ -487,6 +485,7 @@ function fpsort!(v::AbstractVector, a::Algorithm, o::Ordering) sort!(v, i, hi, a, right(o)) return v end + sort!{T<:Floats}(v::AbstractVector{T}, a::Algorithm, o::Direct) = fpsort!(v, a, o) sort!{O<:Direct,T<:Floats}(v::Vector{Int}, a::Algorithm, o::Perm{O,Vector{T}}) = fpsort!(v, a, o) From 2409b35655e1b3463fe0ffc80fbcf7ee2474eb58 Mon Sep 17 00:00:00 2001 From: Stefan Karpinski Date: Wed, 10 Jul 2013 07:36:19 -0400 Subject: [PATCH 4/7] sorting: keyword arguments for `by` and `lt` as well. --- base/exports.jl | 2 - base/pkg/resolve.jl | 6 +-- base/pkg2/resolve.jl | 2 +- base/pkg2/resolve/maxsum.jl | 2 +- base/pkg2/types.jl | 2 +- base/reflection.jl | 2 +- base/sort.jl | 87 +++++++++++++++---------------------- test/sorting.jl | 26 +++++------ 8 files changed, 53 insertions(+), 76 deletions(-) diff --git a/base/exports.jl b/base/exports.jl index 16e5d9eabb51c..864489eeed3df 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -547,8 +547,6 @@ export slicedim, sort, sort!, - sortby, - sortby!, sortperm, sortrows, sortcols, diff --git a/base/pkg/resolve.jl b/base/pkg/resolve.jl index b92a6538306f4..6d9348388ae4d 100644 --- a/base/pkg/resolve.jl +++ b/base/pkg/resolve.jl @@ -911,7 +911,7 @@ function decimate(n::Int, graph::Graph, msgs::Messages) #println("DECIMATING $n NODES") fld = msgs.fld decimated = msgs.decimated - fldorder = sortperm(fld, order=Sort.By(secondmax)) + fldorder = sortperm(fld, by=secondmax) for p0 in fldorder if decimated[p0] continue @@ -1300,7 +1300,7 @@ function sanity_check(vers::Vector{Version}, deps::Vector{(Version,VersionSet)}) p0, v0 = vdict[v] return -pndeps[p0][v0] end - svers = sortby(vers, vrank) + svers = sort(vers, by=vrank) nv = length(svers) @@ -1373,7 +1373,7 @@ function sanity_check(vers::Vector{Version}, deps::Vector{(Version,VersionSet)}) end i += 1 end - sortby!(insane, x->x[1]) + sort!(insane, by=x->x[1]) throw(MetadataError(insane)) end diff --git a/base/pkg2/resolve.jl b/base/pkg2/resolve.jl index 4fdce7dd203ec..3c7634f266b7c 100644 --- a/base/pkg2/resolve.jl +++ b/base/pkg2/resolve.jl @@ -60,7 +60,7 @@ function sanity_check(deps::Dict{ByteString,Dict{VersionNumber,Available}}) for (p,d) in deps, (vn,_) in d push!(vers, (p,vn)) end - sortby!(vers, pvn->(-ndeps[pvn[1]][pvn[2]])) + sort!(vers, by=pvn->(-ndeps[pvn[1]][pvn[2]])) nv = length(vers) diff --git a/base/pkg2/resolve/maxsum.jl b/base/pkg2/resolve/maxsum.jl index a09afff2b4160..a9f329c90de06 100644 --- a/base/pkg2/resolve/maxsum.jl +++ b/base/pkg2/resolve/maxsum.jl @@ -399,7 +399,7 @@ function decimate(n::Int, graph::Graph, msgs::Messages) #println("DECIMATING $n NODES") fld = msgs.fld decimated = msgs.decimated - fldorder = sortperm(fld, order=Sort.By(secondmax)) + fldorder = sortperm(fld, by=secondmax) for p0 in fldorder if decimated[p0] continue diff --git a/base/pkg2/types.jl b/base/pkg2/types.jl index c60f127e400f4..687b17ea194f7 100644 --- a/base/pkg2/types.jl +++ b/base/pkg2/types.jl @@ -39,7 +39,7 @@ Base.contains(s::VersionSet, v::VersionNumber) = any(i->contains(i,v), s.interva function Base.intersect(A::VersionSet, B::VersionSet) ivals = vec([ intersect(a,b) for a in A.intervals, b in B.intervals ]) filter!(i->!isempty(i), ivals) - sortby!(ivals, i->i.lower) + sort!(ivals, by=i->i.lower) VersionSet(ivals) end Base.isequal(A::VersionSet, B::VersionSet) = (A.intervals == B.intervals) diff --git a/base/reflection.jl b/base/reflection.jl index a9535f75c6794..89f973ac9ff21 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -62,7 +62,7 @@ function _subtypes(m::Module, x::DataType, sts=Set(), visited=Set()) end sts end -subtypes(m::Module, x::DataType) = sortby(string, collect(_subtypes(m, x))) +subtypes(m::Module, x::DataType) = sort(collect(_subtypes(m, x)), by=string) subtypes(x::DataType) = subtypes(Main, x) subtypetree(x::DataType, level=-1) = (level == 0 ? (x, {}) : (x, {subtypetree(y, level-1) for y in subtypes(x)})) diff --git a/base/sort.jl b/base/sort.jl index 19c5137a20384..5ca8c462aff86 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -7,16 +7,14 @@ import Base.sortperm export # also exported by Base + issorted, sort, sort!, - sortby, - sortby!, sortperm, sortrows, sortcols, select, select!, - issorted, searchsorted, searchsortedfirst, searchsortedlast, @@ -57,9 +55,13 @@ lt(o::ReverseOrdering, a, b) = isless(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) + ## functions requiring only ordering ## -function issorted(itr; order::Ordering=Forward) +function issorted(itr, order::Ordering) state = start(itr) done(itr,state) && return true prev, state = next(itr, state) @@ -70,6 +72,8 @@ function issorted(itr; order::Ordering=Forward) end return true end +issorted(itr; lt::Function=isless, by::Function=identity, order::Ordering=Forward) = + issorted(itr, ord(lt,by,order)) 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") @@ -130,22 +134,12 @@ function select!(v::AbstractVector, r::Range1, lo::Int, hi::Int, o::Ordering) end end -select!(v::AbstractVector, k; order::Ordering=Forward) = select!(v,k,1,length(v),order) -select (v::AbstractVector, k; order::Ordering=Forward) = select!(copy(v),k,order=order) +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)) -for s in {:select!, :select} - @eval begin - $s(v::AbstractVector, k::Int, lt::Function) = $s(v, k, order=Sort.Lt(lt)) - $s(lt::Function, v::AbstractVector, k::Int) = $s(v, k, order=Sort.Lt(lt)) - end -end - -for s in {:selectby!, :selectby} - @eval begin - $s(v::AbstractVector, k::Int, by::Function) = $s(v, k, order=Sort.By(by)) - $s(by::Function, v::AbstractVector, k::Int) = $s(v, k, order=Sort.By(by)) - end -end +select(v::AbstractVector, k; kws...) = select!(copy(v), k; kws...) # reference on sorted binary search: # http://www.tbray.org/ongoing/When/200x/2003/03/22/Binary @@ -346,48 +340,37 @@ Perm{O<:Ordering,V<:AbstractVector}(o::O,v::V) = Perm{O,V}(o,v) lt(p::Perm, a, b) = lt(p.order, p.data[a], p.data[b]) -sortperm(v::AbstractVector; alg::Algorithm=defalg(v), order::Ordering=Forward) = - sort!([1:length(v)], alg, Perm(order,v)) - ## generic sorting methods ## defalg(v::AbstractArray) = DEFAULT_STABLE 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), order::Ordering=Forward) = sort!(v, alg, order) -sort (v::AbstractVector; alg::Algorithm=defalg(v), order::Ordering=Forward) = sort!(copy(v), alg, order) +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)) -for s in {:sort!, :sort, :sortperm} - @eval begin - $s(v::AbstractVector, lt::Function; alg::Algorithm=defalg(v)) = $s(v, alg=alg, order=Sort.Lt(lt)) - $s(lt::Function, v::AbstractVector; alg::Algorithm=defalg(v)) = $s(v, alg=alg, order=Sort.Lt(lt)) - end -end +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)) -for (sb,s) in {(:sortby!, :sort!), (:sortby, :sort), (:sortpermby, :sortperm)} - @eval begin - $sb(v::AbstractVector, by::Function; alg::Algorithm=defalg(v)) = $s(v, alg=alg, order=Sort.By(by)) - $sb(by::Function, v::AbstractVector; alg::Algorithm=defalg(v)) = $s(v, alg=alg, order=Sort.By(by)) - end -end +sort(v::AbstractVector; kws...) = sort!(copy(v); kws...) ## sorting multi-dimensional arrays ## -sort(A::AbstractArray, dim::Integer; alg::Algorithm=defalg(A), order::Ordering=Forward) = - mapslices(a->sort(a, alg=alg, order=order), A, [dim]) +sort(A::AbstractArray, dim::Integer; kws...) = mapslices(a->sort(a; kws...), A, [dim]) -function sortrows(A::AbstractMatrix; alg::Algorithm=defalg(A), order::Ordering=Forward) +function sortrows(A::AbstractMatrix; kws...) c = 1:size(A,2) rows = [ sub(A,i,c) for i=1:size(A,1) ] - p = sortperm(rows, alg=alg, order=order) + p = sortperm(rows; kws...) A[p,:] end -function sortcols(A::AbstractMatrix; alg::Algorithm=defalg(A), order::Ordering=Forward) +function sortcols(A::AbstractMatrix; kws...) r = 1:size(A,1) cols = [ sub(A,r,i) for i=1:size(A,2) ] - p = sortperm(cols, alg=alg, order=order) + p = sortperm(cols; kws...) A[:,p] end @@ -396,8 +379,8 @@ end module Float using ..Sort +import Core.Intrinsics: unbox, slt_int import ..Sort: sort!, Perm, lt, Reverse -import Core.Intrinsics.slt_int, Core.Intrinsics.unbox typealias Floats Union(Float32,Float64) typealias Direct Union(ForwardOrdering,ReverseOrdering) @@ -460,10 +443,10 @@ function nans2right!(v::AbstractVector, o::Ordering, lo::Int=1, hi::Int=length(v return lo, i end -nans2end!(v::AbstractVector, o::ForwardOrdering) = nans2right!(v, o) -nans2end!(v::AbstractVector, o::ReverseOrdering) = nans2left!(v, o) -nans2end!{O<:ForwardOrdering}(v::AbstractVector{Int}, o::Perm{O}) = nans2right!(v, o) -nans2end!{O<:ReverseOrdering}(v::AbstractVector{Int}, o::Perm{O}) = nans2left!(v, o) +nans2end!(v::AbstractVector, o::ForwardOrdering) = nans2right!(v,o) +nans2end!(v::AbstractVector, o::ReverseOrdering) = nans2left!(v,o) +nans2end!{O<:ForwardOrdering}(v::AbstractVector{Int}, o::Perm{O}) = nans2right!(v,o) +nans2end!{O<:ReverseOrdering}(v::AbstractVector{Int}, o::Perm{O}) = nans2left!(v,o) issignleft(o::Direct, x::Floats) = lt(o, x, zero(x)) issignleft{O<:Direct}(o::Perm{O}, i::Int) = issignleft(O(), o.data[i]) @@ -471,8 +454,8 @@ issignleft{O<:Direct}(o::Perm{O}, i::Int) = issignleft(O(), o.data[i]) function fpsort!(v::AbstractVector, a::Algorithm, o::Ordering) i, j = lo, hi = nans2end!(v,o) while true - while i <= j && issignleft(o, v[i]); i += 1; end - while i <= j && !issignleft(o, v[j]); j -= 1; end + while i <= j && issignleft(o,v[i]); i += 1; end + while i <= j && !issignleft(o,v[j]); j -= 1; end if i <= j v[i], v[j] = v[j], v[i] i += 1 @@ -486,8 +469,8 @@ function fpsort!(v::AbstractVector, a::Algorithm, o::Ordering) return v end -sort!{T<:Floats}(v::AbstractVector{T}, a::Algorithm, o::Direct) = fpsort!(v, a, o) -sort!{O<:Direct,T<:Floats}(v::Vector{Int}, a::Algorithm, o::Perm{O,Vector{T}}) = fpsort!(v, a, o) +sort!{T<:Floats}(v::AbstractVector{T}, a::Algorithm, o::Direct) = fpsort!(v,a,o) +sort!{O<:Direct,T<:Floats}(v::Vector{Int}, a::Algorithm, o::Perm{O,Vector{T}}) = fpsort!(v,a,o) end # module Sort.Float diff --git a/test/sorting.jl b/test/sorting.jl index 9c29e4ce22637..5a7ca38b07bde 100644 --- a/test/sorting.jl +++ b/test/sorting.jl @@ -106,11 +106,11 @@ for alg in [InsertionSort, MergeSort, TimSort] @test issorted(b, order=Sort.Reverse) @test a[ix] == b - b = sortby(a, x->1/x, alg=alg) - @test issorted(b, order=Sort.By(x->1/x)) - ix = sortperm(a, alg=alg, order=Sort.By(x->1/x)) + b = sort(a, alg=alg, by=x->1/x) + @test issorted(b, by=x->1/x) + ix = sortperm(a, alg=alg, by=x->1/x) b = a[ix] - @test issorted(b, order=Sort.By(x->1/x)) + @test issorted(b, by=x->1/x) @test a[ix] == b c = copy(a) @@ -120,14 +120,10 @@ for alg in [InsertionSort, MergeSort, TimSort] ipermute!(c, ix) @test c == a - c = sort(a, alg=alg) do x,y - x > y - end + c = sort(a, alg=alg, lt=(>)) @test b == c - c = sortby(a, alg=alg) do x - -10x - end + c = sort(a, alg=alg, by=x->1/x) @test b == c end @@ -135,11 +131,11 @@ b = sort(a, alg=QuickSort) @test issorted(b) b = sort(a, alg=QuickSort, order=Sort.Reverse) @test issorted(b, order=Sort.Reverse) -b = sortby(a, x->1/x, alg=QuickSort) -@test issorted(b, order=Sort.By(x->1/x)) +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, order=Sort.By(x->1/x)) == 9 +@test select([3,6,30,1,9], 2, by=x->1/x) == 9 ## more advanced sorting tests ## @@ -215,7 +211,7 @@ for n in [0:10, 100, 1000] p = sortperm(v, alg=alg, order=ord) @test isperm(p) vp = v[p] - @test isequal(s,vp) - @test reinterpret(Uint64,s) == reinterpret(Uint64,vp) + @test isequal(vp,s) + @test reinterpret(Uint64,vp) == reinterpret(Uint64,s) end end From 3326e0ce5b87d0162d9594f404526f55e33b8094 Mon Sep 17 00:00:00 2001 From: Stefan Karpinski Date: Thu, 11 Jul 2013 12:40:18 -0400 Subject: [PATCH 5/7] sorting: make ReverseOrder parametric -- can reverse any ordering. --- base/sort.jl | 40 +++++++++++++++++++++++----------------- examples/bubblesort.jl | 6 ++---- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/base/sort.jl b/base/sort.jl index 5ca8c462aff86..3cfe3eee2a26f 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -42,16 +42,22 @@ export # not exported by Base abstract Ordering -type ForwardOrdering <: Ordering end -type ReverseOrdering <: Ordering end -immutable By <: Ordering by::Function end -immutable Lt <: Ordering lt::Function end +immutable ForwardOrdering <: Ordering end +immutable ReverseOrdering{Fwd<:Ordering} <: Ordering + fwd::Fwd +end +immutable By <: Ordering + by::Function +end +immutable Lt <: Ordering + lt::Function +end const Forward = ForwardOrdering() -const Reverse = ReverseOrdering() +const Reverse = ReverseOrdering(Forward) lt(o::ForwardOrdering, a, b) = isless(a,b) -lt(o::ReverseOrdering, a, b) = isless(b,a) +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) @@ -242,10 +248,10 @@ searchsorted{T<:Real}(a::Ranges{T}, x::Real; order::Ordering=Forward) = abstract Algorithm -type InsertionSortAlg <: Algorithm end -type QuickSortAlg <: Algorithm end -type MergeSortAlg <: Algorithm end -type TimSortAlg <: Algorithm end +immutable InsertionSortAlg <: Algorithm end +immutable QuickSortAlg <: Algorithm end +immutable MergeSortAlg <: Algorithm end +immutable TimSortAlg <: Algorithm end const InsertionSort = InsertionSortAlg() const QuickSort = QuickSortAlg() @@ -383,22 +389,22 @@ import Core.Intrinsics: unbox, slt_int import ..Sort: sort!, Perm, lt, Reverse typealias Floats Union(Float32,Float64) -typealias Direct Union(ForwardOrdering,ReverseOrdering) +typealias Direct Union(ForwardOrdering,ReverseOrdering{ForwardOrdering}) -type Left <: Ordering end -type Right <: Ordering end +immutable Left <: Ordering end +immutable Right <: Ordering end left(::Direct) = Left() right(::Direct) = Right() -left{O<:Direct}(o::Perm{O}) = Perm(left(O()),o.data) -right{O<:Direct}(o::Perm{O}) = Perm(right(O()),o.data) +left(o::Perm) = Perm(left(o.order),o.data) +right(o::Perm) = Perm(right(o.order),o.data) lt{T<:Floats}(::Left, x::T, y::T) = slt_int(unbox(T,y),unbox(T,x)) lt{T<:Floats}(::Right, x::T, y::T) = slt_int(unbox(T,x),unbox(T,y)) isnan(o::Direct, x::Floats) = (x!=x) -isnan{O<:Direct}(o::Perm{O}, i::Int) = isnan(O(),o.data[i]) +isnan(o::Perm, i::Int) = isnan(o.order,o.data[i]) function nans2left!(v::AbstractVector, o::Ordering, lo::Int=1, hi::Int=length(v)) hi < lo && return lo, hi @@ -449,7 +455,7 @@ nans2end!{O<:ForwardOrdering}(v::AbstractVector{Int}, o::Perm{O}) = nans2right!( nans2end!{O<:ReverseOrdering}(v::AbstractVector{Int}, o::Perm{O}) = nans2left!(v,o) issignleft(o::Direct, x::Floats) = lt(o, x, zero(x)) -issignleft{O<:Direct}(o::Perm{O}, i::Int) = issignleft(O(), o.data[i]) +issignleft(o::Perm, i::Int) = issignleft(o.order, o.data[i]) function fpsort!(v::AbstractVector, a::Algorithm, o::Ordering) i, j = lo, hi = nans2end!(v,o) diff --git a/examples/bubblesort.jl b/examples/bubblesort.jl index 3e3aa3210e02f..4fd8a9811e0e2 100644 --- a/examples/bubblesort.jl +++ b/examples/bubblesort.jl @@ -1,9 +1,7 @@ -importall Base - -type BubbleSortAlg <: Sort.Algorithm end +immutable BubbleSortAlg <: Sort.Algorithm end const BubbleSort = BubbleSortAlg() -function sort!(v::AbstractVector, lo::Int, hi::Int, ::BubbleSortAlg, o::Sort.Ordering) +function Base.sort!(v::AbstractVector, lo::Int, hi::Int, ::BubbleSortAlg, o::Sort.Ordering) while true clean = true for i = lo:hi-1 From 7bab3508c2700fe17497a3d9b59b96cc3fa597e3 Mon Sep 17 00:00:00 2001 From: Stefan Karpinski Date: Thu, 11 Jul 2013 13:02:31 -0400 Subject: [PATCH 6/7] sorting: add `rev` boolean keyword to reverse any sort ordering. Also added lt, by, order, rev keywords to the searchsorted* funcs. --- base/darray.jl | 2 +- base/sort.jl | 61 +++++++++++++++++++++++++++--------------------- test/arrayops.jl | 4 ++-- test/sorting.jl | 60 +++++++++++++++++++++++------------------------ 4 files changed, 67 insertions(+), 60 deletions(-) diff --git a/base/darray.jl b/base/darray.jl index ba77e44f19c0b..a42d2c9c477ba 100644 --- a/base/darray.jl +++ b/base/darray.jl @@ -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 diff --git a/base/sort.jl b/base/sort.jl index 3cfe3eee2a26f..4a70a5a8525fa 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -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 ## @@ -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") @@ -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...) @@ -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 ## @@ -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...) diff --git a/test/arrayops.jl b/test/arrayops.jl index 9263fe8064a62..d5477356c16eb 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -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]) diff --git a/test/sorting.jl b/test/sorting.jl index 5a7ca38b07bde..5b32928d7ecd9 100644 --- a/test/sorting.jl +++ b/test/sorting.jl @@ -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]) @@ -30,30 +30,30 @@ 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] @@ -61,10 +61,10 @@ 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 @@ -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) @@ -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) @@ -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 ## From af97a6c9bd2bc4a7c1ad586899ce6c98623eb438 Mon Sep 17 00:00:00 2001 From: Stefan Karpinski Date: Thu, 11 Jul 2013 17:28:04 -0400 Subject: [PATCH 7/7] sorting: deprecations for the old sorting API --- base/deprecated.jl | 68 +++++++++++++++++++++++++++++++++++++++++++++- base/sort.jl | 24 ++++++++-------- 2 files changed, 78 insertions(+), 14 deletions(-) diff --git a/base/deprecated.jl b/base/deprecated.jl index 2b081c35ae1a2..c49da07e8a2a3 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -252,7 +252,73 @@ export assign typealias ComplexPair Complex export ComplexPair -## along an axis +# superseded sorting API + +@deprecate select(v::AbstractVector,k::Union(Int,Range1),o::Ordering) select(v,k,order=o) +@deprecate select(v::AbstractVector,k::Union(Int,Range1),f::Function) select(v,k,lt=f) +@deprecate select(f::Function,v::AbstractVector,k::Union(Int,Range1)) select(v,k,lt=f) + +# @deprecate select!(v::AbstractVector,k::Union(Int,Range1),o::Ordering) select!(v,k,order=o) +@deprecate select!(v::AbstractVector,k::Union(Int,Range1),f::Function) select!(v,k,lt=f) +@deprecate select!(f::Function,v::AbstractVector,k::k::Union(Int,Range1)) select!(v,k,lt=f) + +@deprecate sort(v::AbstractVector,o::Ordering) sort(v,order=o) +@deprecate sort(v::AbstractVector,a::Algorithm) sort(v,alg=a) +@deprecate sort(v::AbstractVector,a::Algorithm,o::Ordering) sort(v,alg=a,order=o) +@deprecate sort(v::AbstractVector,o::Ordering,a::Algorithm) sort(v,alg=a,order=o) +@deprecate sort(v::AbstractVector,f::Function) sort(v,lt=f) +@deprecate sort(v::AbstractVector,a::Algorithm,f::Function) sort(v,alg=a,lt=f) +@deprecate sort(v::AbstractVector,f::Function,a::Algorithm) sort(v,alg=a,lt=f) +@deprecate sort(f::Function,v::AbstractVector,a::Algorithm) sort(v,alg=a,lt=f) + +@deprecate sort!(v::AbstractVector,o::Ordering) sort!(v,order=o) +@deprecate sort!(v::AbstractVector,a::Algorithm) sort!(v,alg=a) +# @deprecate sort!(v::AbstractVector,a::Algorithm,o::Ordering) sort!(v,alg=a,order=o) +@deprecate sort!(v::AbstractVector,o::Ordering,a::Algorithm) sort!(v,alg=a,order=o) +@deprecate sort!(v::AbstractVector,f::Function) sort!(v,lt=f) +@deprecate sort!(v::AbstractVector,a::Algorithm,f::Function) sort!(v,alg=a,lt=f) +@deprecate sort!(v::AbstractVector,f::Function,a::Algorithm) sort!(v,alg=a,lt=f) +@deprecate sort!(f::Function,v::AbstractVector,a::Algorithm) sort!(v,alg=a,lt=f) + +@deprecate sortperm(v::AbstractVector,o::Ordering) sortperm(v,order=o) +@deprecate sortperm(v::AbstractVector,a::Algorithm) sortperm(v,alg=a) +@deprecate sortperm(v::AbstractVector,a::Algorithm,o::Ordering) sortperm(v,alg=a,order=o) +@deprecate sortperm(v::AbstractVector,o::Ordering,a::Algorithm) sortperm(v,alg=a,order=o) +@deprecate sortperm(v::AbstractVector,f::Function) sortperm(v,lt=f) +@deprecate sortperm(v::AbstractVector,a::Algorithm,f::Function) sortperm(v,alg=a,lt=f) +@deprecate sortperm(v::AbstractVector,f::Function,a::Algorithm) sortperm(v,alg=a,lt=f) +@deprecate sortperm(f::Function,v::AbstractVector,a::Algorithm) sortperm(v,alg=a,lt=f) + +@deprecate sort(v::AbstractVector,d::Integer,o::Ordering) sort(v,d,order=o) +@deprecate sort(v::AbstractVector,d::Integer,a::Algorithm) sort(v,d,alg=a) +@deprecate sort(v::AbstractVector,d::Integer,a::Algorithm,o::Ordering) sort(v,d,alg=a,order=o) +@deprecate sort(v::AbstractVector,d::Integer,o::Ordering,a::Algorithm) sort(v,d,alg=a,order=o) + +@deprecate sort!(v::AbstractVector,d::Integer,o::Ordering) sort!(v,d,order=o) +@deprecate sort!(v::AbstractVector,d::Integer,a::Algorithm) sort!(v,d,alg=a) +@deprecate sort!(v::AbstractVector,d::Integer,a::Algorithm,o::Ordering) sort!(v,d,alg=a,order=o) +@deprecate sort!(v::AbstractVector,d::Integer,o::Ordering,a::Algorithm) sort!(v,d,alg=a,order=o) + +@deprecate sortby(v::AbstractVector,f::Function) sort(v,by=f) +@deprecate sortby(v::AbstractVector,a::Algorithm,f::Function) sort(v,alg=a,by=f) +@deprecate sortby(v::AbstractVector,f::Function,a::Algorithm) sort(v,alg=a,by=f) +@deprecate sortby(f::Function,v::AbstractVector,a::Algorithm) sort(v,alg=a,by=f) + +@deprecate sortby!(v::AbstractVector,f::Function) sortby!(v,by=f) +@deprecate sortby!(v::AbstractVector,a::Algorithm,f::Function) sort!(v,alg=a,by=f) +@deprecate sortby!(v::AbstractVector,f::Function,a::Algorithm) sort!(v,alg=a,by=f) +@deprecate sortby!(f::Function,v::AbstractVector,a::Algorithm) sort!(v,alg=a,by=f) + +@deprecate sortrows(v::AbstractMatrix,o::Ordering) sortrows(v,order=o) +@deprecate sortrows(v::AbstractMatrix,a::Algorithm) sortrows(v,alg=a) +@deprecate sortrows(v::AbstractMatrix,a::Algorithm,o::Ordering) sortrows(v,alg=a,order=o) +@deprecate sortrows(v::AbstractMatrix,o::Ordering,a::Algorithm) sortrows(v,alg=a,order=o) + +@deprecate sortcols(v::AbstractMatrix,o::Ordering) sortcols(v,order=o) +@deprecate sortcols(v::AbstractMatrix,a::Algorithm) sortcols(v,alg=a) +@deprecate sortcols(v::AbstractMatrix,a::Algorithm,o::Ordering) sortcols(v,alg=a,order=o) +@deprecate sortcols(v::AbstractMatrix,o::Ordering,a::Algorithm) sortcols(v,alg=a,order=o) + function amap(f::Function, A::AbstractArray, axis::Integer) warn_once("amap is deprecated, use mapslices(f, A, dims) instead") dimsA = size(A) diff --git a/base/sort.jl b/base/sort.jl index 4a70a5a8525fa..1f94a42ad953e 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -7,17 +7,20 @@ import Base.sortperm export # also exported by Base + # order-only: issorted, - sort, - sort!, - sortperm, - sortrows, - sortcols, select, select!, searchsorted, searchsortedfirst, searchsortedlast, + # order & algorithm: + sort, + sort!, + sortperm, + sortrows, + sortcols, + # algorithms: InsertionSort, QuickSort, MergeSort, @@ -33,11 +36,6 @@ export # not exported by Base SMALL_ALGORITHM, SMALL_THRESHOLD -# not exported - # selectby - # selectby! - # sortpermby - ## notions of element ordering ## abstract Ordering @@ -142,12 +140,12 @@ function select!(v::AbstractVector, r::Range1, lo::Int, hi::Int, o::Ordering) end end -select!(v::AbstractVector, k, o::Ordering) = select!(v,k,1,length(v),o) -select!(v::AbstractVector, k; +select!(v::AbstractVector, k::Union(Int,Range1), o::Ordering) = select!(v,k,1,length(v),o) +select!(v::AbstractVector, k::Union(Int,Range1); 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...) +select(v::AbstractVector, k::Union(Int,Range1); kws...) = select!(copy(v), k; kws...) # reference on sorted binary search: # http://www.tbray.org/ongoing/When/200x/2003/03/22/Binary