diff --git a/base/darray.jl b/base/darray.jl index 2fefdad809abb..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))), 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/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/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 5149d696a209d..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, 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 f08e8f042ef82..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, 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 a213b9134fa97..1f94a42ad953e 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -7,19 +7,20 @@ import Base.sortperm export # also exported by Base - sort, - sort!, - sortby, - sortby!, - sortperm, - sortrows, - sortcols, + # order-only: + issorted, select, select!, - issorted, searchsorted, searchsortedfirst, searchsortedlast, + # order & algorithm: + sort, + sort!, + sortperm, + sortrows, + sortcols, + # algorithms: InsertionSort, QuickSort, MergeSort, @@ -35,41 +36,50 @@ export # not exported by Base SMALL_ALGORITHM, SMALL_THRESHOLD -# not exported - # selectby - # selectby! - # sortpermby - ## notions of element ordering ## 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) +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 ## -function issorted(itr, o::Ordering = Forward) +function issorted(itr, order::Ordering) 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 end +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") @@ -130,22 +140,12 @@ 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::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)) -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) - 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) - end -end +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 @@ -195,38 +195,33 @@ 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 -end - -function searchsortedlast{T<:Real}(a::Ranges{T},x::Real,o::Ordering) +function searchsortedlast{T<:Real}(a::Ranges{T}, x::Real, o::Ordering=Forward) if step(a) == 0 lt(o, 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(o, 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, o::Ordering=Forward) if step(a) == 0 - lt(o, 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(o,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,o::Ordering) +function searchsortedlast{T<:Integer}(a::Ranges{T}, x::Real, o::Ordering=Forward) if step(a) == 0 lt(o, x, first(a)) ? 0 : length(a) else @@ -234,24 +229,34 @@ function searchsortedlast{T<:Integer}(a::Ranges{T},x::Real,o::Ordering) end end -function searchsortedfirst{T<:Integer}(a::Ranges{T},x::Real,o::Ordering) +function searchsortedfirst{T<:Integer}(a::Ranges{T}, x::Real, o::Ordering=Forward) if step(a) == 0 - lt(o, 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) = searchsortedfirst(a,x):searchsortedlast(a,x) +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 ## 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() @@ -263,15 +268,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 +303,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,54 +338,51 @@ 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]) +lt(p::Perm, a, b) = lt(p.order, p.data[a], p.data[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) +## generic sorting methods ## -############## +defalg(v::AbstractArray) = DEFAULT_STABLE +defalg{T<:Number}(v::AbstractArray{T}) = DEFAULT_UNSTABLE -# generic sorting methods +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, rev::Bool=false) = + sort!(v, alg, ord(lt,by,order,rev)) -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) +sortperm(v::AbstractVector; alg::Algorithm=defalg(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)) - # also allow ordering before algorithm - $s(v::AbstractVector, o::Ordering, a::Algorithm) = $s(v, a, o) - end -end +sort(v::AbstractVector; kws...) = sort!(copy(v); kws...) -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...) - end +## sorting multi-dimensional arrays ## + +sort(A::AbstractArray, dim::Integer; kws...) = mapslices(a->sort(a; kws...), A, [dim]) + +function sortrows(A::AbstractMatrix; kws...) + c = 1:size(A,2) + rows = [ sub(A,i,c) for i=1:size(A,1) ] + p = sortperm(rows; kws...) + A[p,:] 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...) - end +function sortcols(A::AbstractMatrix; kws...) + r = 1:size(A,1) + cols = [ sub(A,r,i) for i=1:size(A,2) ] + p = sortperm(cols; kws...) + A[:,p] end ## fast clever sorting for floats ## @@ -397,28 +390,28 @@ 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) +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.vec) -right{O<:Direct}(o::Perm{O}) = Perm(right(O()),o.vec) +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.vec[i]) +isnan(o::Perm, i::Int) = isnan(o.order,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]) @@ -439,7 +432,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]) @@ -460,22 +453,20 @@ 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) -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.vec[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) 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 @@ -488,49 +479,10 @@ 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) - -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) - -sort(A::AbstractArray, dim::Integer, alg::Base.Sort.Algorithm, o::Base.Sort.Ordering) = - sort(A, dim, o, alg) - -function sortrows(A::AbstractMatrix, o::Base.Sort.Ordering=Base.Sort.Forward, - alg::Base.Sort.Algorithm = DEFAULT_STABLE) - c = 1:size(A,2) - rows = [ sub(A,i,c) for i=1:size(A,1) ] - p = sortperm(rows, o, alg) - 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) +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) -function sortcols(A::AbstractMatrix, o::Base.Sort.Ordering=Base.Sort.Forward, - alg::Base.Sort.Algorithm = DEFAULT_STABLE) - r = 1:size(A,1) - cols = [ sub(A,r,i) for i=1:size(A,2) ] - p = sortperm(cols, o, alg) - 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.Float end # module Sort diff --git a/examples/bubblesort.jl b/examples/bubblesort.jl index 05e1a17f554b0..4fd8a9811e0e2 100644 --- a/examples/bubblesort.jl +++ b/examples/bubblesort.jl @@ -1,8 +1,7 @@ -importall Base +immutable BubbleSortAlg <: Sort.Algorithm end +const BubbleSort = BubbleSortAlg() -type BubbleSort <: Sort.Algorithm end - -function sort!(v::AbstractVector, lo::Int, hi::Int, ::BubbleSort, 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 diff --git a/test/arrayops.jl b/test/arrayops.jl index 17e4e9898eecd..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, Sort.Reverse) + asr = sortrows(a, rev=true) @test isless(asr[2,:],asr[1,:]) @test isless(asr[3,:],asr[2,:]) - asc = sortcols(a, 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 fc0813e9e74f3..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],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, 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, 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, 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, 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, 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, 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,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, 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 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], 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],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], 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) 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, rev=true) + @test issorted(b, rev=true) + ix = sortperm(a, alg=alg, rev=true) b = a[ix] - @test issorted(b, Sort.Reverse) + @test issorted(b, rev=true) @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 = 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, Sort.By(x -> -10x)) + @test issorted(b, by=x->1/x) @test a[ix] == b c = copy(a) @@ -120,26 +120,22 @@ for alg in [InsertionSort, MergeSort, TimSort] ipermute!(c, ix) @test c == a - c = sort(a, alg) do x,y - x > y - end + c = sort(a, alg=alg, lt=(>)) @test b == c - c = sortby(a, alg) do x - -10x - end + c = sort(a, alg=alg, by=x->1/x) @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, 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, Sort.Reverse) == 9 -@test select([3,6,30,1,9], 2, Sort.By(x -> -x)) == 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 ## @@ -161,12 +157,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 +170,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 +179,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 +188,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,15 +203,15 @@ 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) - @test reinterpret(Uint64,s) == reinterpret(Uint64,vp) + @test isequal(vp,s) + @test reinterpret(Uint64,vp) == reinterpret(Uint64,s) end end