From 5039668467aab5a84833b92a35e0ad167c40993a Mon Sep 17 00:00:00 2001 From: Andy Dienes Date: Wed, 21 Jun 2023 14:41:38 -0400 Subject: [PATCH 01/15] add rand dispatch for tuple types --- stdlib/Random/src/generation.jl | 3 +++ stdlib/Random/test/runtests.jl | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/stdlib/Random/src/generation.jl b/stdlib/Random/src/generation.jl index cc9840f678413..ab3c08a676c20 100644 --- a/stdlib/Random/src/generation.jl +++ b/stdlib/Random/src/generation.jl @@ -167,6 +167,9 @@ function rand(r::AbstractRNG, ::SamplerType{T}) where {T<:AbstractChar} (c < 0xd800) ? T(c) : T(c+0x800) end +### random tuples + +rand(r::AbstractRNG, ::SamplerType{T}) where {T<:Tuple} = T(rand.(Ref(r), T.parameters)) ## Generate random integer within a range diff --git a/stdlib/Random/test/runtests.jl b/stdlib/Random/test/runtests.jl index eb5ae32965469..21bb91babe18d 100644 --- a/stdlib/Random/test/runtests.jl +++ b/stdlib/Random/test/runtests.jl @@ -333,7 +333,7 @@ end for rng in ([], [MersenneTwister(0)], [RandomDevice()], [Xoshiro()]) ftypes = [Float16, Float32, Float64, FakeFloat64, BigFloat] cftypes = [ComplexF16, ComplexF32, ComplexF64, ftypes...] - types = [Bool, Char, BigFloat, Base.BitInteger_types..., ftypes...] + types = [Bool, Char, BigFloat, Tuple{Bool, Tuple{Int, Char}}, Base.BitInteger_types..., ftypes...] randset = Set(rand(Int, 20)) randdict = Dict(zip(rand(Int,10), rand(Int, 10))) collections = [BitSet(rand(1:100, 20)) => Int, @@ -401,6 +401,7 @@ for rng in ([], [MersenneTwister(0)], [RandomDevice()], [Xoshiro()]) end for f! in [rand!, randn!, randexp!] for T in functypes[f!] + (T <: Tuple) && continue X = T == Bool ? T[0,1] : T[0,1,2] for A in (Vector{T}(undef, 5), Matrix{T}(undef, 2, 3), From c54a9694ae85be1209cff6a5cab14d949c6b2695 Mon Sep 17 00:00:00 2001 From: Andy Dienes Date: Thu, 22 Jun 2023 08:48:23 -0400 Subject: [PATCH 02/15] remove allocating broadcast --- stdlib/Random/src/generation.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stdlib/Random/src/generation.jl b/stdlib/Random/src/generation.jl index ab3c08a676c20..284752278b7a9 100644 --- a/stdlib/Random/src/generation.jl +++ b/stdlib/Random/src/generation.jl @@ -169,7 +169,9 @@ end ### random tuples -rand(r::AbstractRNG, ::SamplerType{T}) where {T<:Tuple} = T(rand.(Ref(r), T.parameters)) +function rand(r::AbstractRNG, ::SamplerType{T}) where {T<:Tuple} + ntuple(i -> rand(r, T.parameters[i]), length(T.parameters)) +end ## Generate random integer within a range From dd5bfe19f81ebe996565414f5e23d6de29b5b222 Mon Sep 17 00:00:00 2001 From: Andy Dienes Date: Tue, 27 Jun 2023 14:24:30 -0400 Subject: [PATCH 03/15] use opt. generated ntuple & add @inferred test --- stdlib/Random/src/generation.jl | 2 +- stdlib/Random/test/runtests.jl | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/stdlib/Random/src/generation.jl b/stdlib/Random/src/generation.jl index 284752278b7a9..6729c0438a042 100644 --- a/stdlib/Random/src/generation.jl +++ b/stdlib/Random/src/generation.jl @@ -170,7 +170,7 @@ end ### random tuples function rand(r::AbstractRNG, ::SamplerType{T}) where {T<:Tuple} - ntuple(i -> rand(r, T.parameters[i]), length(T.parameters)) + ntuple(i -> rand(r, T.parameters[i]), Val(length(T.parameters))) end ## Generate random integer within a range diff --git a/stdlib/Random/test/runtests.jl b/stdlib/Random/test/runtests.jl index 21bb91babe18d..9ef690e3078ef 100644 --- a/stdlib/Random/test/runtests.jl +++ b/stdlib/Random/test/runtests.jl @@ -336,6 +336,10 @@ for rng in ([], [MersenneTwister(0)], [RandomDevice()], [Xoshiro()]) types = [Bool, Char, BigFloat, Tuple{Bool, Tuple{Int, Char}}, Base.BitInteger_types..., ftypes...] randset = Set(rand(Int, 20)) randdict = Dict(zip(rand(Int,10), rand(Int, 10))) + + randwidetup = Tuple{Bool, Char, Vararg{Tuple{Int, Float64}, 14}} + @inferred rand(rng..., randwidetup) + collections = [BitSet(rand(1:100, 20)) => Int, randset => Int, GenericSet(randset) => Int, From 57f45e7bf3f8e109a2cf4fc6cc36cb7b1798f791 Mon Sep 17 00:00:00 2001 From: Andy Dienes Date: Tue, 27 Jun 2023 16:31:05 -0400 Subject: [PATCH 04/15] remove access to internal properties --- stdlib/Random/src/generation.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/Random/src/generation.jl b/stdlib/Random/src/generation.jl index 6729c0438a042..f3f3671ade876 100644 --- a/stdlib/Random/src/generation.jl +++ b/stdlib/Random/src/generation.jl @@ -170,7 +170,7 @@ end ### random tuples function rand(r::AbstractRNG, ::SamplerType{T}) where {T<:Tuple} - ntuple(i -> rand(r, T.parameters[i]), Val(length(T.parameters))) + ntuple(i -> rand(r, fieldtype(T, i)), Val(fieldcount(T))) end ## Generate random integer within a range From 59a07bb629a3eed969a6c3a0af58cb5e0f625498 Mon Sep 17 00:00:00 2001 From: Andy Dienes Date: Mon, 3 Jul 2023 16:45:02 -0400 Subject: [PATCH 05/15] add rational rand dispatch --- stdlib/Random/src/Random.jl | 27 ++++++++++++++++++++++----- stdlib/Random/src/generation.jl | 10 ++++++++++ stdlib/Random/test/runtests.jl | 3 ++- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/stdlib/Random/src/Random.jl b/stdlib/Random/src/Random.jl index 78d4f15e2beac..efc8756095f82 100644 --- a/stdlib/Random/src/Random.jl +++ b/stdlib/Random/src/Random.jl @@ -313,12 +313,26 @@ include("XoshiroSimd.jl") Pick a random element or array of random elements from the set of values specified by `S`; `S` can be -* an indexable collection (for example `1:9` or `('x', "y", :z)`), -* an `AbstractDict` or `AbstractSet` object, +* an indexable collection (for example `1:9` or `('x', "y", :z)`) + +* an `AbstractDict` or `AbstractSet` object + * a string (considered as a collection of characters), or -* a type: the set of values to pick from is then equivalent to `typemin(S):typemax(S)` for - integers (this is not applicable to [`BigInt`](@ref)), to ``[0, 1)`` for floating - point numbers and to ``[0, 1)+i[0, 1)`` for complex floating point numbers; + +* a supported type: the set of values to pick from is then equivalent to + + + `typemin(S):typemax(S)` for concrete integer types (excepting [`BigInt`](@ref) which is not supported) + + + ``[0, 1)`` for concrete floating point types + + + `rand(T) + rand(T) * im` for concrete complex types `Complex{T}` + + + `rand(T) // rand(T)` for concrete rational types `Rational{T}` + + + a valid Unicode scalar for any `<:AbstractChar` type + +* a Tuple type of supported types + `S` defaults to [`Float64`](@ref). When only one argument is passed besides the optional `rng` and is a `Tuple`, it is interpreted @@ -330,6 +344,9 @@ See also [`randn`](@ref) for normally distributed numbers, and [`rand!`](@ref) a !!! compat "Julia 1.1" Support for `S` as a tuple requires at least Julia 1.1. +!!! compat "Julia 1.11" + Support for `S` as a `Rational` or `Tuple` type requires at least Julia 1.11. + # Examples ```julia-repl julia> rand(Int, 2) diff --git a/stdlib/Random/src/generation.jl b/stdlib/Random/src/generation.jl index f3f3671ade876..a64cd61721d65 100644 --- a/stdlib/Random/src/generation.jl +++ b/stdlib/Random/src/generation.jl @@ -159,6 +159,16 @@ rand_generic(r::AbstractRNG, ::Type{Int64}) = rand(r, UInt64) % Int64 rand(r::AbstractRNG, ::SamplerType{Complex{T}}) where {T<:Real} = complex(rand(r, T), rand(r, T)) +### random rational numbers + +function rand(r::AbstractRNG, ::SamplerType{Rational{T}}) where {T<:Integer} + den = rand(r, T) + while iszero(den) || isequal(den, typemin(T)) + den = rand(r, T) + end + return Rational(rand(r, T), den) +end + ### random characters # returns a random valid Unicode scalar value (i.e. 0 - 0xd7ff, 0xe000 - # 0x10ffff) diff --git a/stdlib/Random/test/runtests.jl b/stdlib/Random/test/runtests.jl index 9ef690e3078ef..e0e4dde2e4ae7 100644 --- a/stdlib/Random/test/runtests.jl +++ b/stdlib/Random/test/runtests.jl @@ -333,7 +333,8 @@ end for rng in ([], [MersenneTwister(0)], [RandomDevice()], [Xoshiro()]) ftypes = [Float16, Float32, Float64, FakeFloat64, BigFloat] cftypes = [ComplexF16, ComplexF32, ComplexF64, ftypes...] - types = [Bool, Char, BigFloat, Tuple{Bool, Tuple{Int, Char}}, Base.BitInteger_types..., ftypes...] + ritypes = [Rational{T} for T in Base.BitInteger_types] + types = [Bool, Char, BigFloat, Tuple{Bool, Tuple{Int, Char}}, Base.BitInteger_types..., ritypes..., ftypes...] randset = Set(rand(Int, 20)) randdict = Dict(zip(rand(Int,10), rand(Int, 10))) From ef602c976c684d1ff8d4ac0611cfd732d5ec91b0 Mon Sep 17 00:00:00 2001 From: Andy Dienes Date: Mon, 3 Jul 2023 16:52:50 -0400 Subject: [PATCH 06/15] add to news --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index 18a8f89f6d382..8899083db845c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -46,6 +46,7 @@ Standard library changes #### Profile #### Random +* `rand` now supports sampling over `Rational` types and `Tuple` types ([#50251]). #### REPL From 030cc1683d59c56fa979534b9ec0a263e6fdc5f7 Mon Sep 17 00:00:00 2001 From: Andy Dienes Date: Tue, 4 Jul 2023 10:00:44 -0400 Subject: [PATCH 07/15] remove rational rand --- NEWS.md | 2 +- stdlib/Random/src/Random.jl | 4 +--- stdlib/Random/src/generation.jl | 10 ---------- stdlib/Random/test/runtests.jl | 3 +-- 4 files changed, 3 insertions(+), 16 deletions(-) diff --git a/NEWS.md b/NEWS.md index 8899083db845c..e42d008cd9285 100644 --- a/NEWS.md +++ b/NEWS.md @@ -46,7 +46,7 @@ Standard library changes #### Profile #### Random -* `rand` now supports sampling over `Rational` types and `Tuple` types ([#50251]). +* `rand` now supports sampling over `Tuple` types ([#50251]). #### REPL diff --git a/stdlib/Random/src/Random.jl b/stdlib/Random/src/Random.jl index efc8756095f82..a76ee3cebe7b7 100644 --- a/stdlib/Random/src/Random.jl +++ b/stdlib/Random/src/Random.jl @@ -327,8 +327,6 @@ Pick a random element or array of random elements from the set of values specifi + `rand(T) + rand(T) * im` for concrete complex types `Complex{T}` - + `rand(T) // rand(T)` for concrete rational types `Rational{T}` - + a valid Unicode scalar for any `<:AbstractChar` type * a Tuple type of supported types @@ -345,7 +343,7 @@ See also [`randn`](@ref) for normally distributed numbers, and [`rand!`](@ref) a Support for `S` as a tuple requires at least Julia 1.1. !!! compat "Julia 1.11" - Support for `S` as a `Rational` or `Tuple` type requires at least Julia 1.11. + Support for `S` as a `Tuple` type requires at least Julia 1.11. # Examples ```julia-repl diff --git a/stdlib/Random/src/generation.jl b/stdlib/Random/src/generation.jl index a64cd61721d65..f3f3671ade876 100644 --- a/stdlib/Random/src/generation.jl +++ b/stdlib/Random/src/generation.jl @@ -159,16 +159,6 @@ rand_generic(r::AbstractRNG, ::Type{Int64}) = rand(r, UInt64) % Int64 rand(r::AbstractRNG, ::SamplerType{Complex{T}}) where {T<:Real} = complex(rand(r, T), rand(r, T)) -### random rational numbers - -function rand(r::AbstractRNG, ::SamplerType{Rational{T}}) where {T<:Integer} - den = rand(r, T) - while iszero(den) || isequal(den, typemin(T)) - den = rand(r, T) - end - return Rational(rand(r, T), den) -end - ### random characters # returns a random valid Unicode scalar value (i.e. 0 - 0xd7ff, 0xe000 - # 0x10ffff) diff --git a/stdlib/Random/test/runtests.jl b/stdlib/Random/test/runtests.jl index e0e4dde2e4ae7..9ef690e3078ef 100644 --- a/stdlib/Random/test/runtests.jl +++ b/stdlib/Random/test/runtests.jl @@ -333,8 +333,7 @@ end for rng in ([], [MersenneTwister(0)], [RandomDevice()], [Xoshiro()]) ftypes = [Float16, Float32, Float64, FakeFloat64, BigFloat] cftypes = [ComplexF16, ComplexF32, ComplexF64, ftypes...] - ritypes = [Rational{T} for T in Base.BitInteger_types] - types = [Bool, Char, BigFloat, Tuple{Bool, Tuple{Int, Char}}, Base.BitInteger_types..., ritypes..., ftypes...] + types = [Bool, Char, BigFloat, Tuple{Bool, Tuple{Int, Char}}, Base.BitInteger_types..., ftypes...] randset = Set(rand(Int, 20)) randdict = Dict(zip(rand(Int,10), rand(Int, 10))) From 41da3823a0cd9053ed5b3635388d20f4973b845d Mon Sep 17 00:00:00 2001 From: Andy Dienes Date: Sun, 3 Sep 2023 19:24:01 -0400 Subject: [PATCH 08/15] faster sampler generation --- stdlib/Random/docs/src/index.md | 2 +- stdlib/Random/src/Random.jl | 6 ++++-- stdlib/Random/src/generation.jl | 13 +++++++++++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/stdlib/Random/docs/src/index.md b/stdlib/Random/docs/src/index.md index e344e47947440..7ef885775c58f 100644 --- a/stdlib/Random/docs/src/index.md +++ b/stdlib/Random/docs/src/index.md @@ -81,7 +81,7 @@ Random.MersenneTwister Random.RandomDevice ``` -## Hooking into the `Random` API +## [Hooking into the `Random` API](@id rand-api-hook) There are two mostly orthogonal ways to extend `Random` functionalities: 1) generating random values of custom types diff --git a/stdlib/Random/src/Random.jl b/stdlib/Random/src/Random.jl index a76ee3cebe7b7..b4f3231b3398f 100644 --- a/stdlib/Random/src/Random.jl +++ b/stdlib/Random/src/Random.jl @@ -319,7 +319,7 @@ Pick a random element or array of random elements from the set of values specifi * a string (considered as a collection of characters), or -* a supported type: the set of values to pick from is then equivalent to +* a type (and corresponding domain) from the list below + `typemin(S):typemax(S)` for concrete integer types (excepting [`BigInt`](@ref) which is not supported) @@ -329,7 +329,9 @@ Pick a random element or array of random elements from the set of values specifi + a valid Unicode scalar for any `<:AbstractChar` type -* a Tuple type of supported types +* a user-defined type and domain; for implementation guidance please see [Hooking into the `Random` API](@ref rand-api-hook) + +* a Tuple type `T` where each parameter of `T` is itself a sampleable type; return a value of type `T`` `S` defaults to [`Float64`](@ref). diff --git a/stdlib/Random/src/generation.jl b/stdlib/Random/src/generation.jl index f3f3671ade876..47507e139f987 100644 --- a/stdlib/Random/src/generation.jl +++ b/stdlib/Random/src/generation.jl @@ -169,8 +169,17 @@ end ### random tuples -function rand(r::AbstractRNG, ::SamplerType{T}) where {T<:Tuple} - ntuple(i -> rand(r, fieldtype(T, i)), Val(fieldcount(T))) +function Sampler(RNG::Type{<:AbstractRNG}, t::Type{T}, n::Repetition) where {T <: Tuple} + tail_sp_ = Sampler(RNG, Tuple{fieldtypes(t)[2:end]...}, n) + SamplerTag{t}((Sampler(RNG, fieldtype(t, 1), n), tail_sp_.data...)) +end + +function Sampler(RNG::Type{<:AbstractRNG}, t::Type{Tuple{Vararg{T, N}}}, n::Repetition) where {T, N} + SamplerTag{t}((Sampler(RNG, T, n),)) +end + +function rand(rng::AbstractRNG, sp::SamplerTag{T}) where T<:Tuple + ntuple(i -> rand(rng, sp.data[min(i, length(sp.data))]), Val{fieldcount(T)}()) end ## Generate random integer within a range From 07ffd9a6f563a2b90e431ba1c5628e5ac9776dab Mon Sep 17 00:00:00 2001 From: Andy Dienes Date: Sun, 3 Sep 2023 20:23:40 -0400 Subject: [PATCH 09/15] get rid of implicit `convert` --- stdlib/Random/src/generation.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/Random/src/generation.jl b/stdlib/Random/src/generation.jl index 47507e139f987..0ff6b9267fcc5 100644 --- a/stdlib/Random/src/generation.jl +++ b/stdlib/Random/src/generation.jl @@ -179,7 +179,7 @@ function Sampler(RNG::Type{<:AbstractRNG}, t::Type{Tuple{Vararg{T, N}}}, n::Repe end function rand(rng::AbstractRNG, sp::SamplerTag{T}) where T<:Tuple - ntuple(i -> rand(rng, sp.data[min(i, length(sp.data))]), Val{fieldcount(T)}()) + ntuple(i -> rand(rng, sp.data[min(i, length(sp.data))]), Val{fieldcount(T)}())::T end ## Generate random integer within a range From b2ba3b189ef4fcc6623718018ed3676835cc5483 Mon Sep 17 00:00:00 2001 From: Andy Dienes Date: Sun, 3 Sep 2023 20:50:56 -0400 Subject: [PATCH 10/15] fix double backticks --- stdlib/Random/src/Random.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/Random/src/Random.jl b/stdlib/Random/src/Random.jl index b4f3231b3398f..8bbaeb2f4958f 100644 --- a/stdlib/Random/src/Random.jl +++ b/stdlib/Random/src/Random.jl @@ -323,7 +323,7 @@ Pick a random element or array of random elements from the set of values specifi + `typemin(S):typemax(S)` for concrete integer types (excepting [`BigInt`](@ref) which is not supported) - + ``[0, 1)`` for concrete floating point types + + `[0, 1)` for concrete floating point types + `rand(T) + rand(T) * im` for concrete complex types `Complex{T}` From 73dc45e9abd58815e4f0a1a563f7b9a5a087f49a Mon Sep 17 00:00:00 2001 From: Andy Dienes Date: Thu, 7 Sep 2023 17:52:09 -0400 Subject: [PATCH 11/15] use Base.tail --- stdlib/Random/src/generation.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/Random/src/generation.jl b/stdlib/Random/src/generation.jl index 0ff6b9267fcc5..293ce2f27ce21 100644 --- a/stdlib/Random/src/generation.jl +++ b/stdlib/Random/src/generation.jl @@ -170,7 +170,7 @@ end ### random tuples function Sampler(RNG::Type{<:AbstractRNG}, t::Type{T}, n::Repetition) where {T <: Tuple} - tail_sp_ = Sampler(RNG, Tuple{fieldtypes(t)[2:end]...}, n) + tail_sp_ = Sampler(RNG, Tuple{Base.tail(fieldtypes(t))...}, n) SamplerTag{t}((Sampler(RNG, fieldtype(t, 1), n), tail_sp_.data...)) end From cf5e0265f9c3fd16db501448288b8b05f3d8972f Mon Sep 17 00:00:00 2001 From: Andy Dienes Date: Thu, 14 Sep 2023 17:08:16 -0400 Subject: [PATCH 12/15] update docs, apply code review, add tests --- stdlib/Random/src/Random.jl | 15 ++++++++------- stdlib/Random/src/generation.jl | 10 +++++----- stdlib/Random/test/runtests.jl | 4 ++++ 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/stdlib/Random/src/Random.jl b/stdlib/Random/src/Random.jl index 8bbaeb2f4958f..e5e2b4251bde6 100644 --- a/stdlib/Random/src/Random.jl +++ b/stdlib/Random/src/Random.jl @@ -319,19 +319,20 @@ Pick a random element or array of random elements from the set of values specifi * a string (considered as a collection of characters), or -* a type (and corresponding domain) from the list below +* a type from the list below, corresponding to the specified set of values - + `typemin(S):typemax(S)` for concrete integer types (excepting [`BigInt`](@ref) which is not supported) + + concrete integer types sample from `typemin(S):typemax(S)` (excepting [`BigInt`](@ref) which is not supported) - + `[0, 1)` for concrete floating point types + + concrete floating point types sample from `[0, 1)` - + `rand(T) + rand(T) * im` for concrete complex types `Complex{T}` + + concrete complex types `Complex{T}` sample from `rand(T) + rand(T) * im` - + a valid Unicode scalar for any `<:AbstractChar` type + + all `<:AbstractChar` types sample from the set of valid Unicode scalars -* a user-defined type and domain; for implementation guidance please see [Hooking into the `Random` API](@ref rand-api-hook) + + a user-defined type and set of values; for implementation guidance please see [Hooking into the `Random` API](@ref rand-api-hook) -* a Tuple type `T` where each parameter of `T` is itself a sampleable type; return a value of type `T`` + + `S` can also be a tuple type of known size and where each parameter of `S` is itself a sampleable type; return a value of type `S`. + Note that tuple types such as `Tuple{Vararg{T}}` (unknown size) and `Tuple{1:2}` (parameterized with a value) are not supported. `S` defaults to [`Float64`](@ref). diff --git a/stdlib/Random/src/generation.jl b/stdlib/Random/src/generation.jl index 293ce2f27ce21..1e3edea21c03b 100644 --- a/stdlib/Random/src/generation.jl +++ b/stdlib/Random/src/generation.jl @@ -169,13 +169,13 @@ end ### random tuples -function Sampler(RNG::Type{<:AbstractRNG}, t::Type{T}, n::Repetition) where {T <: Tuple} - tail_sp_ = Sampler(RNG, Tuple{Base.tail(fieldtypes(t))...}, n) - SamplerTag{t}((Sampler(RNG, fieldtype(t, 1), n), tail_sp_.data...)) +function Sampler(::Type{RNG}, ::Type{T}, n::Repetition) where {T<:Tuple, RNG<:AbstractRNG} + tail_sp_ = Sampler(RNG, Tuple{Base.tail(fieldtypes(T))...}, n) + SamplerTag{T}((Sampler(RNG, fieldtype(T, 1), n), tail_sp_.data...)) end -function Sampler(RNG::Type{<:AbstractRNG}, t::Type{Tuple{Vararg{T, N}}}, n::Repetition) where {T, N} - SamplerTag{t}((Sampler(RNG, T, n),)) +function Sampler(::Type{RNG}, ::Type{Tuple{Vararg{T, N}}}, n::Repetition) where {T, N, RNG<:AbstractRNG} + SamplerTag{Tuple{Vararg{T, N}}}((Sampler(RNG, T, n),)) end function rand(rng::AbstractRNG, sp::SamplerTag{T}) where T<:Tuple diff --git a/stdlib/Random/test/runtests.jl b/stdlib/Random/test/runtests.jl index 9ef690e3078ef..07ad0b1ff3726 100644 --- a/stdlib/Random/test/runtests.jl +++ b/stdlib/Random/test/runtests.jl @@ -446,6 +446,10 @@ for rng in ([], [MersenneTwister(0)], [RandomDevice()], [Xoshiro()]) @test_throws MethodError r(rng..., Number, (2,3)) @test_throws MethodError r(rng..., Any, 1) end + + # Test that you cannot call rand with a tuple type of unknown size or with isbits parameters + @test_throws ArgumentError rand(rng..., Tuple{Vararg{Int}}) + @test_throws TypeError rand(rng..., Tuple{1:2}) end function hist(X, n) From a19e2ca62c1c5bdc004bc3c2f8f9325339ea562a Mon Sep 17 00:00:00 2001 From: adienes <51664769+adienes@users.noreply.github.com> Date: Fri, 15 Sep 2023 10:50:26 -0400 Subject: [PATCH 13/15] Update Random.jl complex domain docstring --- stdlib/Random/src/Random.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stdlib/Random/src/Random.jl b/stdlib/Random/src/Random.jl index e5e2b4251bde6..1fd45e675c6fe 100644 --- a/stdlib/Random/src/Random.jl +++ b/stdlib/Random/src/Random.jl @@ -325,7 +325,8 @@ Pick a random element or array of random elements from the set of values specifi + concrete floating point types sample from `[0, 1)` - + concrete complex types `Complex{T}` sample from `rand(T) + rand(T) * im` + + concrete complex types `<:Complex{T}` if `T` is a sampleable type take their real and imaginary components + independently from the set of values corresponding to `T`, but are not supported if `T` is not sampleable. + all `<:AbstractChar` types sample from the set of valid Unicode scalars From e89dd567982b7cf677775521a9f65d74a145c705 Mon Sep 17 00:00:00 2001 From: adienes <51664769+adienes@users.noreply.github.com> Date: Fri, 15 Sep 2023 10:52:13 -0400 Subject: [PATCH 14/15] Update Random.jl complex docstring --- stdlib/Random/src/Random.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/Random/src/Random.jl b/stdlib/Random/src/Random.jl index 1fd45e675c6fe..54cae3adbf953 100644 --- a/stdlib/Random/src/Random.jl +++ b/stdlib/Random/src/Random.jl @@ -325,7 +325,7 @@ Pick a random element or array of random elements from the set of values specifi + concrete floating point types sample from `[0, 1)` - + concrete complex types `<:Complex{T}` if `T` is a sampleable type take their real and imaginary components + + concrete complex types `Complex{T}` if `T` is a sampleable type take their real and imaginary components independently from the set of values corresponding to `T`, but are not supported if `T` is not sampleable. + all `<:AbstractChar` types sample from the set of valid Unicode scalars From 6a192adfbacb99facdf126980aee94d75c9655d5 Mon Sep 17 00:00:00 2001 From: Rafael Fourquet Date: Fri, 29 Sep 2023 12:05:33 +0200 Subject: [PATCH 15/15] fix test caused by merge with master --- stdlib/Random/test/runtests.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stdlib/Random/test/runtests.jl b/stdlib/Random/test/runtests.jl index 0d479cbe051f5..3c760441d3746 100644 --- a/stdlib/Random/test/runtests.jl +++ b/stdlib/Random/test/runtests.jl @@ -323,7 +323,9 @@ for rng in ([], [MersenneTwister(0)], [RandomDevice()], [Xoshiro()]) a2 = f(rng..., T, 2, 3) ::Array{T, 2} a3 = f(rng..., T, b2, u3) ::Array{T, 2} a4 = f(rng..., T, (2, 3)) ::Array{T, 2} - @test size(a0) == () + if T <: Number + @test size(a0) == () + end @test size(a1) == (5,) @test size(a2) == size(a3) == size(a4) == (2, 3) if T <: AbstractFloat && f === rand