Skip to content

Commit

Permalink
Merge pull request #23051 from JuliaLang/nl/select
Browse files Browse the repository at this point in the history
Rename select* functions to partialsort* and various related fixes
  • Loading branch information
nalimilan authored Aug 27, 2017
2 parents e545c65 + 7a54a2f commit c5d5e9a
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 64 deletions.
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,9 @@ Deprecated or removed
respectively. Similarly, `MPFR.get_version()`, has been renamed to `MPFR.version()` ([#23323]). Also,
`LinAlg.LAPACK.laver()` has been renamed to `LinAlg.LAPACK.version()` and now returns a `VersionNumber`.

* `select`, `select!`, `selectperm` and `selectperm!` have been renamed respectively to
`partialsort`, `partialsort!`, `partialsortperm` and `partialsortperm!` ([#23051]).

Command-line option changes
---------------------------

Expand Down
6 changes: 6 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1739,6 +1739,12 @@ end

@deprecate IOContext(io::IO, key, value) IOContext(io, key=>value)

# issue #22791
@deprecate select partialsort
@deprecate select! partialsort!
@deprecate selectperm partialsortperm
@deprecate selectperm! partialsortperm!

# END 0.7 deprecations

# BEGIN 1.0 deprecations
Expand Down
8 changes: 4 additions & 4 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,10 @@ export
ones,
parent,
parentindexes,
partialsort,
partialsort!,
partialsortperm,
partialsortperm!,
permute,
permute!,
permutedims,
Expand All @@ -517,17 +521,13 @@ export
searchsorted,
searchsortedfirst,
searchsortedlast,
select!,
select,
shuffle,
shuffle!,
size,
slicedim,
sort!,
sort,
sortcols,
selectperm,
selectperm!,
sortperm,
sortperm!,
sortrows,
Expand Down
87 changes: 49 additions & 38 deletions base/sort.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,18 @@ import
export # also exported by Base
# order-only:
issorted,
select,
select!,
searchsorted,
searchsortedfirst,
searchsortedlast,
# order & algorithm:
sort,
sort!,
selectperm,
selectperm!,
sortperm,
sortperm!,
partialsort,
partialsort!,
partialsortperm,
partialsortperm!,
sortrows,
sortcols,
# algorithms:
Expand Down Expand Up @@ -82,20 +82,25 @@ issorted(itr;
lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward) =
issorted(itr, ord(lt,by,rev,order))

function select!(v::AbstractVector, k::Union{Int,OrdinalRange}, o::Ordering)
function partialsort!(v::AbstractVector, k::Union{Int,OrdinalRange}, o::Ordering)
inds = indices(v, 1)
sort!(v, first(inds), last(inds), PartialQuickSort(k), o)
v[k]

if k isa Integer
return v[k]
else
return view(v, k)
end
end

"""
select!(v, k, [by=<transform>,] [lt=<comparison>,] [rev=false])
partialsort!(v, k, [by=<transform>,] [lt=<comparison>,] [rev=false])
Partially sort the vector `v` in place, according to the order specified by `by`, `lt` and
`rev` so that the value at index `k` (or range of adjacent values if `k` is a range) occurs
at the position where it would appear if the array were fully sorted via a non-stable
algorithm. If `k` is a single index, that value is returned; if `k` is a range, an array of
values at those indices is returned. Note that `select!` does not fully sort the input
values at those indices is returned. Note that `partialsort!` does not fully sort the input
array.
# Examples
Expand All @@ -108,7 +113,7 @@ julia> a = [1, 2, 4, 3, 4]
3
4
julia> select!(a, 4)
julia> partialsort!(a, 4)
4
julia> a
Expand All @@ -127,7 +132,7 @@ julia> a = [1, 2, 4, 3, 4]
3
4
julia> select!(a, 4, rev=true)
julia> partialsort!(a, 4, rev=true)
2
julia> a
Expand All @@ -139,17 +144,18 @@ julia> a
1
```
"""
select!(v::AbstractVector, k::Union{Int,OrdinalRange};
lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward) =
select!(v, k, ord(lt,by,rev,order))
partialsort!(v::AbstractVector, k::Union{Int,OrdinalRange};
lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward) =
partialsort!(v, k, ord(lt,by,rev,order))

"""
select(v, k, [by=<transform>,] [lt=<comparison>,] [rev=false])
partialsort(v, k, [by=<transform>,] [lt=<comparison>,] [rev=false])
Variant of [`select!`](@ref) which copies `v` before partially sorting it, thereby returning the
same thing as `select!` but leaving `v` unmodified.
Variant of [`partialsort!`](@ref) which copies `v` before partially sorting it, thereby returning the
same thing as `partialsort!` but leaving `v` unmodified.
"""
select(v::AbstractVector, k::Union{Int,OrdinalRange}; kws...) = select!(copymutable(v), k; kws...)
partialsort(v::AbstractVector, k::Union{Int,OrdinalRange}; kws...) =
partialsort!(copymutable(v), k; kws...)


# reference on sorted binary search:
Expand Down Expand Up @@ -667,36 +673,36 @@ julia> v
"""
sort(v::AbstractVector; kws...) = sort!(copymutable(v); kws...)

## selectperm: the permutation to sort the first k elements of an array ##
## partialsortperm: the permutation to sort the first k elements of an array ##

"""
selectperm(v, k, [alg=<algorithm>,] [by=<transform>,] [lt=<comparison>,] [rev=false])
partialsortperm(v, k, [alg=<algorithm>,] [by=<transform>,] [lt=<comparison>,] [rev=false])
Return a partial permutation of the vector `v`, according to the order specified by
`by`, `lt` and `rev`, so that `v[output]` returns the first `k` (or range of adjacent values
if `k` is a range) values of a fully sorted version of `v`. If `k` is a single index
(Integer), an array of the first `k` indices is returned; if `k` is a range, an array of
those indices is returned. Note that the handling of integer values for `k` is different
from [`select`](@ref) in that it returns a vector of `k` elements instead of just the `k` th
element. Also note that this is equivalent to, but more efficient than, calling
`sortperm(...)[k]`.
if `k` is a range) values of a fully sorted version of `v`. If `k` is a single index,
the index in `v` of the value which would be sorted at position `k` is returned;
if `k` is a range, an array with the indices in `v` of the values which would be sorted in
these positions is returned.
Note that this is equivalent to, but more efficient than, calling `sortperm(...)[k]`.
"""
selectperm(v::AbstractVector, k::Union{Integer,OrdinalRange}; kwargs...) =
selectperm!(similar(Vector{eltype(k)}, indices(v,1)), v, k; kwargs..., initialized=false)
partialsortperm(v::AbstractVector, k::Union{Integer,OrdinalRange}; kwargs...) =
partialsortperm!(similar(Vector{eltype(k)}, indices(v,1)), v, k; kwargs..., initialized=false)

"""
selectperm!(ix, v, k, [alg=<algorithm>,] [by=<transform>,] [lt=<comparison>,] [rev=false,] [initialized=false])
partialsortperm!(ix, v, k, [alg=<algorithm>,] [by=<transform>,] [lt=<comparison>,] [rev=false,] [initialized=false])
Like [`selectperm`](@ref), but accepts a preallocated index vector `ix`. If `initialized` is `false`
(the default), ix is initialized to contain the values `1:length(ix)`.
Like [`partialsortperm`](@ref), but accepts a preallocated index vector `ix`. If `initialized` is `false`
(the default), `ix` is initialized to contain the values `1:length(ix)`.
"""
function selectperm!(ix::AbstractVector{<:Integer}, v::AbstractVector,
k::Union{Int, OrdinalRange};
lt::Function=isless,
by::Function=identity,
rev::Bool=false,
order::Ordering=Forward,
initialized::Bool=false)
function partialsortperm!(ix::AbstractVector{<:Integer}, v::AbstractVector,
k::Union{Int, OrdinalRange};
lt::Function=isless,
by::Function=identity,
rev::Bool=false,
order::Ordering=Forward,
initialized::Bool=false)
if !initialized
@inbounds for i = indices(ix,1)
ix[i] = i
Expand All @@ -705,7 +711,12 @@ function selectperm!(ix::AbstractVector{<:Integer}, v::AbstractVector,

# do partial quicksort
sort!(ix, PartialQuickSort(k), Perm(ord(lt, by, rev, order), v))
return ix[k]

if k isa Integer
return ix[k]
else
return view(ix, k)
end
end

## sortperm: the permutation to sort an array ##
Expand Down
4 changes: 2 additions & 2 deletions base/statistics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -599,9 +599,9 @@ function median!(v::AbstractVector)
n = length(inds)
mid = div(first(inds)+last(inds),2)
if isodd(n)
return middle(select!(v,mid))
return middle(partialsort!(v,mid))
else
m = select!(v, mid:mid+1)
m = partialsort!(v, mid:mid+1)
return middle(m[1], m[2])
end
end
Expand Down
8 changes: 4 additions & 4 deletions doc/src/stdlib/sort.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,10 @@ Base.issorted
Base.Sort.searchsorted
Base.Sort.searchsortedfirst
Base.Sort.searchsortedlast
Base.Sort.select!
Base.Sort.select
Base.Sort.selectperm
Base.Sort.selectperm!
Base.Sort.partialsort!
Base.Sort.partialsort
Base.Sort.partialsortperm
Base.Sort.partialsortperm!
```

## Sorting Algorithms
Expand Down
6 changes: 3 additions & 3 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3796,11 +3796,11 @@ end

module M15455
function rpm_provides(r::T) where T
push!([], select(r,T))
push!([], partialsort(r,T))
end
select(a,b) = 0
partialsort(a,b) = 0
end
@test M15455.select(1,2)==0
@test M15455.partialsort(1,2)==0

# check that medium-sized array is 64-byte aligned (#15139)
@test Int(pointer(Vector{Float64}(1024))) % 64 == 0
Expand Down
2 changes: 1 addition & 1 deletion test/ranges.jl
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ end
@test sort!(UnitRange(1,2)) == UnitRange(1,2)
@test sort(1:10, rev=true) == collect(10:-1:1)
@test sort(-3:3, by=abs) == [0,-1,1,-2,2,-3,3]
@test select(1:10, 4) == 4
@test partialsort(1:10, 4) == 4

@test 0 in UInt(0):100:typemax(UInt)
@test last(UInt(0):100:typemax(UInt)) in UInt(0):100:typemax(UInt)
Expand Down
24 changes: 12 additions & 12 deletions test/sorting.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ end
@test !issorted([2,3,1])
@test issorted([1,2,3])
@test reverse([2,3,1]) == [1,3,2]
@test select([3,6,30,1,9],3) == 6
@test select([3,6,30,1,9],3:4) == [6,9]
@test selectperm([3,6,30,1,9], 3:4) == [2,5]
@test selectperm!(collect(1:5), [3,6,30,1,9], 3:4) == [2,5]
@test partialsort([3,6,30,1,9],3) == 6
@test partialsort([3,6,30,1,9],3:4) == [6,9]
@test partialsortperm([3,6,30,1,9], 3:4) == [2,5]
@test partialsortperm!(collect(1:5), [3,6,30,1,9], 3:4) == [2,5]
let a=[1:10;]
for r in Any[2:4, 1:2, 10:10, 4:2, 2:1, 4:-1:2, 2:-1:1, 10:-1:10, 4:1:3, 1:2:8, 10:-3:1]
@test select(a, r) == [r;]
@test selectperm(a, r) == [r;]
@test select(a, r, rev=true) == (11 .- [r;])
@test selectperm(a, r, rev=true) == (11 .- [r;])
@test partialsort(a, r) == [r;]
@test partialsortperm(a, r) == [r;]
@test partialsort(a, r, rev=true) == (11 .- [r;])
@test partialsortperm(a, r, rev=true) == (11 .- [r;])
end
end
@test sum(randperm(6)) == 21
Expand Down Expand Up @@ -204,10 +204,10 @@ let alg = PartialQuickSort(div(length(a), 10))
@test !issorted(d, rev=true)
end

@test select([3,6,30,1,9], 2, rev=true) == 9
@test select([3,6,30,1,9], 2, by=x->1/x) == 9
@test selectperm([3,6,30,1,9], 2, rev=true) == 5
@test selectperm([3,6,30,1,9], 2, by=x->1/x) == 5
@test partialsort([3,6,30,1,9], 2, rev=true) == 9
@test partialsort([3,6,30,1,9], 2, by=x->1/x) == 9
@test partialsortperm([3,6,30,1,9], 2, rev=true) == 5
@test partialsortperm([3,6,30,1,9], 2, by=x->1/x) == 5

## more advanced sorting tests ##

Expand Down

0 comments on commit c5d5e9a

Please sign in to comment.