Skip to content

Commit

Permalink
Merge pull request #16620 from stevengj/shufflin
Browse files Browse the repository at this point in the history
fix and consolidate uses of copy(a) and copy(similar(a),a) in to copymutable(a)
  • Loading branch information
tkelman committed May 29, 2016
2 parents b88be59 + 974994b commit 2fa728a
Show file tree
Hide file tree
Showing 12 changed files with 44 additions and 19 deletions.
14 changes: 13 additions & 1 deletion base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ function copy!(dest::AbstractArray, doffs::Integer,
return dest
end

copy(a::AbstractArray) = copy!(similar(a), a)
copy(a::AbstractArray) = copymutable(a)

function copy!{R,S}(B::AbstractVecOrMat{R}, ir_dest::Range{Int}, jr_dest::Range{Int},
A::AbstractVecOrMat{S}, ir_src::Range{Int}, jr_src::Range{Int})
Expand Down Expand Up @@ -340,6 +340,18 @@ function copy_transpose!{R,S}(B::AbstractVecOrMat{R}, ir_dest::Range{Int}, jr_de
return B
end

copymutable(a::AbstractArray) = copy!(similar(a), a)
copymutable(itr) = collect(itr)
"""
copymutable(a)
Make a mutable copy of an array or iterable `a`. For `a::Array`,
this is equivalent to `copy(a)`, but for other array types it may
differ depending on the type of `similar(a)`. For generic iterables
this is equivalent to `collect(a)`.
"""
copymutable

zero{T}(x::AbstractArray{T}) = fill!(similar(x), zero(T))

## iteration support for arrays by iterating over `eachindex` in the array ##
Expand Down
4 changes: 2 additions & 2 deletions base/collections.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module Collections

import Base: setindex!, done, get, hash, haskey, isempty, length, next, getindex, start
import Base: setindex!, done, get, hash, haskey, isempty, length, next, getindex, start, copymutable
import ..Order: Forward, Ordering, lt

export
Expand Down Expand Up @@ -106,7 +106,7 @@ end
Returns a new vector in binary heap order, optionally using the given ordering.
"""
heapify(xs::AbstractArray, o::Ordering=Forward) = heapify!(copy(xs), o)
heapify(xs::AbstractArray, o::Ordering=Forward) = heapify!(copymutable(xs), o)

"""
isheap(v, [ord])
Expand Down
4 changes: 2 additions & 2 deletions base/combinatorics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ to verify that `p` is a permutation.
To return a new permutation, use `v[p]`. Note that this is generally faster than
`permute!(v,p)` for large vectors.
"""
permute!(a, p::AbstractVector) = permute!!(a, copy!(similar(p), p))
permute!(a, p::AbstractVector) = permute!!(a, copymutable(p))

function ipermute!!{T<:Integer}(a, p::AbstractVector{T})
count = 0
Expand Down Expand Up @@ -130,7 +130,7 @@ end
Like `permute!`, but the inverse of the given permutation is applied.
"""
ipermute!(a, p::AbstractVector) = ipermute!!(a, copy!(similar(p), p))
ipermute!(a, p::AbstractVector) = ipermute!!(a, copymutable(p))

"""
invperm(v)
Expand Down
11 changes: 8 additions & 3 deletions base/docs/helpdb/Base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1417,7 +1417,8 @@ permutedims
"""
shuffle!([rng,] v)
In-place version of [`shuffle`](:func:`shuffle`).
In-place version of [`shuffle`](:func:`shuffle`): randomly permute the array `v` in-place,
optionally supplying the random-number generator `rng`.
"""
shuffle!

Expand Down Expand Up @@ -5916,7 +5917,9 @@ wait
shuffle([rng,] v)
Return a randomly permuted copy of `v`. The optional `rng` argument specifies a random
number generator, see [Random Numbers](:ref:`Random Numbers <random-numbers>`).
number generator (see [Random Numbers](:ref:`Random Numbers <random-numbers>`)).
To permute `v` in-place, see [`shuffle!`](:func:`shuffle!`). To obtain randomly permuted
indices, see [`randperm`](:func:`randperm`).
"""
shuffle

Expand Down Expand Up @@ -9986,7 +9989,9 @@ filter
randperm([rng,] n)
Construct a random permutation of length `n`. The optional `rng` argument specifies a random
number generator, see [Random Numbers](:ref:`Random Numbers <random-numbers>`).
number generator (see [Random Numbers](:ref:`Random Numbers <random-numbers>`)).
To randomly permute a arbitrary vector, see [`shuffle`](:func:`shuffle`)
or [`shuffle!`](:func:`shuffle!`).
"""
randperm

Expand Down
3 changes: 2 additions & 1 deletion base/random.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module Random

using Base.dSFMT
using Base.GMP: GMP_VERSION, Limb
import Base.copymutable

export srand,
rand, rand!,
Expand Down Expand Up @@ -1338,7 +1339,7 @@ end

shuffle!(a::AbstractVector) = shuffle!(GLOBAL_RNG, a)

shuffle(r::AbstractRNG, a::AbstractVector) = shuffle!(r, copy(a))
shuffle(r::AbstractRNG, a::AbstractVector) = shuffle!(r, copymutable(a))
shuffle(a::AbstractVector) = shuffle(GLOBAL_RNG, a)

function randperm(r::AbstractRNG, n::Integer)
Expand Down
6 changes: 3 additions & 3 deletions base/sort.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module Sort

using Base.Order
using Base.Order, Base.copymutable

import
Base.sort,
Expand Down Expand Up @@ -66,7 +66,7 @@ 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))

select(v::AbstractVector, k::Union{Int,OrdinalRange}; kws...) = select!(copy!(similar(v), v), k; kws...)
select(v::AbstractVector, k::Union{Int,OrdinalRange}; kws...) = select!(copymutable(v), k; kws...)


# reference on sorted binary search:
Expand Down Expand Up @@ -410,7 +410,7 @@ function sort!(v::AbstractVector;
sort!(v, alg, ord(lt,by,rev,order))
end

sort(v::AbstractVector; kws...) = sort!(copy!(similar(v), v); kws...)
sort(v::AbstractVector; kws...) = sort!(copymutable(v); kws...)


## selectperm: the permutation to sort the first k elements of 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 @@ -507,7 +507,7 @@ function median!{T}(v::AbstractVector{T})
end
median!{T}(v::AbstractArray{T}) = median!(vec(v))

median{T}(v::AbstractArray{T}) = median!(vec(copy(v)))
median{T}(v::AbstractArray{T}) = median!(copy!(Array(T, length(v)), v))
median{T}(v::AbstractArray{T}, region) = mapslices(median!, v, region)

# for now, use the R/S definition of quantile; may want variants later
Expand Down Expand Up @@ -612,4 +612,4 @@ for `k = 1:n` where `n = length(v)`. This corresponds to Definition 7 of Hyndman
*The American Statistician*, Vol. 50, No. 4, pp. 361-365
"""
quantile(v::AbstractVector, p; sorted::Bool=false) =
quantile!(sorted ? v : copy!(similar(v),v), p; sorted=sorted)
quantile!(sorted ? v : copymutable(v), p; sorted=sorted)
6 changes: 3 additions & 3 deletions doc/stdlib/arrays.rst
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,7 @@ Combinatorics

.. Docstring generated from Julia source
Construct a random permutation of length ``n``\ . The optional ``rng`` argument specifies a random number generator, see :ref:`Random Numbers <random-numbers>`\ .
Construct a random permutation of length ``n``\ . The optional ``rng`` argument specifies a random number generator (see :ref:`Random Numbers <random-numbers>`\ ). To randomly permute a arbitrary vector, see :func:`shuffle` or :func:`shuffle!`\ .

.. function:: invperm(v)

Expand Down Expand Up @@ -758,13 +758,13 @@ Combinatorics

.. Docstring generated from Julia source
Return a randomly permuted copy of ``v``\ . The optional ``rng`` argument specifies a random number generator, see :ref:`Random Numbers <random-numbers>`\ .
Return a randomly permuted copy of ``v``\ . The optional ``rng`` argument specifies a random number generator (see :ref:`Random Numbers <random-numbers>`\ ). To permute ``v`` in-place, see :func:`shuffle!`\ . To obtain randomly permuted indices, see :func:`randperm`\ .

.. function:: shuffle!([rng,] v)

.. Docstring generated from Julia source
In-place version of :func:`shuffle`\ .
In-place version of :func:`shuffle`\ : randomly permute the array ``v`` in-place, optionally supplying the random-number generator ``rng``\ .

.. function:: reverse(v [, start=1 [, stop=length(v) ]] )

Expand Down
4 changes: 2 additions & 2 deletions doc/stdlib/io-network.rst
Original file line number Diff line number Diff line change
Expand Up @@ -713,9 +713,9 @@ Julia environments (such as the IPython-based IJulia notebook).

For example, if you define a ``MyImage`` type and know how to write it to a PNG file, you could define a function ``show(stream, ::MIME"image/png", x::MyImage) = ...`` to allow your images to be displayed on any PNG-capable ``Display`` (such as IJulia). As usual, be sure to ``import Base.show`` in order to add new methods to the built-in Julia function ``show``\ .

Technically, the ``MIME"mime"`` macro defines a singleton type for the given ``mime`` string, which allows us to exploit Julia's dispatch mechanisms in determining how to display objects of any given type.
The default MIME type is ``MIME"text/plain"``\ . There is a fallback definition for ``text/plain`` output that calls ``show`` with 2 arguments. Therefore, this case should be handled by defining a 2-argument ``show(stream::IO, x::MyType)`` method.

The default MIME type is ``MIME"text/plain"``\ . There is a fallback definition for ``text/plain`` output that calls ``show`` with 2 arguments. Therefore, this case should be handled by defining a 2-argument ``show`` method.
Technically, the ``MIME"mime"`` macro defines a singleton type for the given ``mime`` string, which allows us to exploit Julia's dispatch mechanisms in determining how to display objects of any given type.

.. function:: mimewritable(mime, x)

Expand Down
3 changes: 3 additions & 0 deletions test/priorityqueue.jl
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ end
xs = heapify!([v for v in values(priorities)])
@test issorted([heappop!(xs) for _ in length(priorities)])

xs = heapify(10:-1:1)
@test issorted([heappop!(xs) for _ in 1:10])

xs = Array(Int, 0)
for priority in values(priorities)
heappush!(xs, priority)
Expand Down
2 changes: 2 additions & 0 deletions test/random.jl
Original file line number Diff line number Diff line change
Expand Up @@ -376,8 +376,10 @@ let mta = MersenneTwister(42), mtb = MersenneTwister(42)

@test shuffle(mta,collect(1:10)) == shuffle(mtb,collect(1:10))
@test shuffle!(mta,collect(1:10)) == shuffle!(mtb,collect(1:10))
@test shuffle(mta,collect(2:11)) == shuffle(mtb,2:11)

@test randperm(mta,10) == randperm(mtb,10)
@test sort!(randperm(10)) == sort!(shuffle(1:10)) == collect(1:10)
@test randperm(mta,big(10)) == randperm(mtb,big(10)) # cf. #16376
@test randperm(0) == []
@test_throws ErrorException randperm(-1)
Expand Down
2 changes: 2 additions & 0 deletions test/statistics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ end
@test median!([1 2 3 4]) == 2.5
@test median!([1 2; 3 4]) == 2.5

@test invoke(median, (AbstractVector,), 1:10) == median(1:10) == 5.5

# mean
@test_throws ArgumentError mean(())
@test mean((1,2,3)) === 2.
Expand Down

0 comments on commit 2fa728a

Please sign in to comment.