Skip to content

Commit c6d97cf

Browse files
committed
implement sortperm
fixes JuliaArrays#772
1 parent 93ec354 commit c6d97cf

File tree

3 files changed

+29
-3
lines changed

3 files changed

+29
-3
lines changed

src/SOneTo.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ function SOneTo{n}(r::AbstractUnitRange) where n
1515
errmsg(r)
1616
end
1717

18+
Base.Tuple(::SOneTo{N}) where N = ntuple(identity, Val(N))
19+
1820
Base.axes(s::SOneTo) = (s,)
1921
Base.size(s::SOneTo) = (length(s),)
2022
Base.length(s::SOneTo{n}) where {n} = n

src/sort.jl

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import Base.Order: Ordering, Forward, ReverseOrdering, ord
2-
import Base.Sort: Algorithm, lt, sort
1+
import Base.Order: Forward, Ordering, Perm, ReverseOrdering, ord
2+
import Base.Sort: Algorithm, lt, sort, sortperm
33

44

55
struct BitonicSortAlg <: Algorithm end
@@ -23,20 +23,36 @@ defalg(a::StaticVector) =
2323
return _sort(a, alg, ordr)
2424
end
2525

26+
@inline function sortperm(a::StaticVector;
27+
alg::Algorithm = defalg(a),
28+
lt = isless,
29+
by = identity,
30+
rev::Union{Bool,Nothing} = nothing,
31+
order::Ordering = Forward)
32+
p = Tuple(axes(a, 1))
33+
length(a) <= 1 && return similar_type(a, eltype(p))(p)
34+
35+
ordr = Perm(ord(lt, by, rev, order), a)
36+
return similar_type(a, eltype(p))(_sort(p, alg, ordr))
37+
end
38+
39+
2640
@inline _sort(a::StaticVector, alg, order) =
2741
similar_type(a)(sort!(Base.copymutable(a); alg=alg, order=order))
2842

2943
@inline _sort(a::StaticVector, alg::BitonicSortAlg, order) =
3044
similar_type(a)(_sort(Tuple(a), alg, order))
3145

46+
_sort(a::NTuple, alg, order) = sort!(Base.copymutable(a); alg=alg, order=order)
47+
3248
# Implementation loosely following
3349
# https://www.inf.hs-flensburg.de/lang/algorithmen/sortieren/bitonic/oddn.htm
3450
@generated function _sort(a::NTuple{N}, ::BitonicSortAlg, order) where N
3551
function swap_expr(i, j, rev)
3652
ai = Symbol('a', i)
3753
aj = Symbol('a', j)
3854
order = rev ? :revorder : :order
39-
return :( ($ai, $aj) = lt($order, $ai, $aj) ? ($ai, $aj) : ($aj, $ai) )
55+
return :( ($ai, $aj) = @inbounds lt($order, $ai, $aj) ? ($ai, $aj) : ($aj, $ai) )
4056
end
4157

4258
function merge_exprs(idx, rev)

test/sort.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,12 @@ using StaticArrays, Test
1919
end
2020
end
2121

22+
@testset "sortperm" for T in (Int, Float64)
23+
for N in (0, 1, 2, 3, 10, 20, 30)
24+
v = rand(SVector{N,T})
25+
vp = sortperm(v)
26+
@test v[vp] == sort(v)
27+
end
28+
end
29+
2230
end

0 commit comments

Comments
 (0)