Skip to content

Commit

Permalink
Added sortperm!
Browse files Browse the repository at this point in the history
* Allows preallocation (and therefore, reuse) of an index array
* Useful for JuliaLang#8316
  • Loading branch information
kmsquire committed Oct 23, 2014
1 parent 45a1463 commit 1a3a702
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 2 deletions.
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,7 @@ export
sort,
sortcols,
sortperm,
sortperm!,
sortrows,
squeeze,
step,
Expand Down
4 changes: 2 additions & 2 deletions base/ordering.jl
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ lt(o::By, a, b) = isless(o.by(a),o.by(b))
lt(o::Lt, a, b) = o.lt(a,b)
lt(o::LexicographicOrdering, a, b) = lexcmp(a,b) < 0

function lt(p::Perm, a::Int, b::Int)
function lt(p::Perm, a::Integer, b::Integer)
da = p.data[a]
db = p.data[b]
lt(p.order, da, db) | (!lt(p.order, db, da) & (a < b))
end
function lt(p::Perm{LexicographicOrdering}, a::Int, b::Int)
function lt(p::Perm{LexicographicOrdering}, a::Integer, b::Integer)
c = lexcmp(p.data[a], p.data[b])
c != 0 ? c < 0 : a < b
end
Expand Down
9 changes: 9 additions & 0 deletions base/sort.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export # also exported by Base
sort,
sort!,
sortperm,
sortperm!,
sortrows,
sortcols,
# algorithms:
Expand Down Expand Up @@ -341,6 +342,14 @@ sortperm(v::AbstractVector; alg::Algorithm=DEFAULT_UNSTABLE,
lt::Function=isless, by::Function=identity, rev::Bool=false, order::Ordering=Forward) =
sort!([1:length(v)], alg, Perm(ord(lt,by,rev,order),v))

function sortperm!{I<:Integer}(x::Vector{I}, v::AbstractVector; alg::Algorithm=DEFAULT_UNSTABLE,
lt::Function=isless, by::Function=identity, rev::Bool=false, order::Ordering=Forward,
initialized::Bool=false)
length(x) != length(v) && throw(ArgumentError("Index vector must be the same length as the source vector."))
!initialized && @inbounds for i = 1:length(v); x[i] = i; end
sort!(x, alg, Perm(ord(lt,by,rev,order),v))
end

## sorting multi-dimensional arrays ##

sort(A::AbstractArray, dim::Integer; kws...) = mapslices(a->sort(a; kws...), A, [dim])
Expand Down
9 changes: 9 additions & 0 deletions doc/stdlib/sort.rst
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,15 @@ Sorting Functions
sorting algorithm such as ``QuickSort``, a different permutation that puts the array
into order may be returned. The order is specified using the same keywords as ``sort!``.

See also :func:`sortperm!`

.. function:: sortperm!(ix, v, [alg=<algorithm>,] [by=<transform>,] [lt=<comparison>,] [rev=false,] [initialized=false])

Like ``sortperm``, but accepts a preallocated index vector ``ix``. If ``initialized`` is ``false``
(the default), ix is initialized to contain the values ``1:length(v)``.

See also :func:`sortperm`

.. function:: sortrows(A, [alg=<algorithm>,] [by=<transform>,] [lt=<comparison>,] [rev=false])

Sort the rows of matrix ``A`` lexicographically.
Expand Down
15 changes: 15 additions & 0 deletions test/sorting.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@test sort([2,3,1]) == [1,2,3]
@test sort([2,3,1], rev=true) == [3,2,1]
@test sortperm([2,3,1]) == [3,1,2]
@test sortperm!([1,2,3], [2,3,1]) == [3,1,2]
@test !issorted([2,3,1])
@test issorted([1,2,3])
@test reverse([2,3,1]) == [1,3,2]
Expand Down Expand Up @@ -66,20 +67,34 @@ for alg in [InsertionSort, MergeSort]
@test issorted(b)
@test a[ix] == b

sortperm!(ix, a, alg=alg)
b = a[ix]
@test issorted(b)
@test a[ix] == b

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, rev=true)
@test a[ix] == b

sortperm!(ix, a, alg=alg, rev=true)
b = a[ix]
@test issorted(b, rev=true)
@test a[ix] == b

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, by=x->1/x)
@test a[ix] == b

sortperm!(ix, a, alg=alg, by=x->1/x)
@test issorted(b, by=x->1/x)
@test a[ix] == b

c = copy(a)
permute!(c, ix)
@test c == b
Expand Down

0 comments on commit 1a3a702

Please sign in to comment.