From d891aefa4905177d7cec3e17b94eb52899a0d0b9 Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Fri, 19 May 2017 16:59:29 -0400 Subject: [PATCH 1/4] Add complex randn --- base/random.jl | 7 ++++++- base/sysimg.jl | 6 +++--- test/random.jl | 13 ++++++++++--- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/base/random.jl b/base/random.jl index f4b86f3d353ab..cebde6fa12f23 100644 --- a/base/random.jl +++ b/base/random.jl @@ -1181,7 +1181,9 @@ const ziggurat_exp_r = 7.6971174701310497140446280481 Generate a normally-distributed random number of type `T` with mean 0 and standard deviation 1. Optionally generate an array of normally-distributed random numbers. The `Base` module currently provides an implementation for the types -`Float16`, `Float32`, and `Float64` (the default). +`Float16`, `Float32`, and `Float64` (the default), and their `Complex` counterparts. +When the type argument is complex, the values are drawn from the circularly symmetric +complex normal distribution. """ @inline function randn(rng::AbstractRNG=GLOBAL_RNG) @inbounds begin @@ -1194,6 +1196,9 @@ The `Base` module currently provides an implementation for the types end end +Base.@irrational SQRT_HALF 0.7071067811865475244008 sqrt(big(0.5)) +randn{T}(rng::AbstractRNG, ::Type{Complex{T}}) = Complex{T}(SQRT_HALF * randn(rng, T), SQRT_HALF*randn(rng, T)) + # this unlikely branch is put in a separate function for better efficiency function randn_unlikely(rng, idx, rabs, x) @inbounds if idx == 0 diff --git a/base/sysimg.jl b/base/sysimg.jl index acfb4c7b68ee4..838b1c982b1e8 100644 --- a/base/sysimg.jl +++ b/base/sysimg.jl @@ -274,6 +274,9 @@ include("combinatorics.jl") # more hashing definitions include("hashing2.jl") +# irrational mathematical constants +include("irrationals.jl") + # random number generation include("dSFMT.jl") include("random.jl") @@ -334,9 +337,6 @@ const × = cross # statistics include("statistics.jl") -# irrational mathematical constants -include("irrationals.jl") - # signal processing include("dft.jl") importall .DFT diff --git a/test/random.jl b/test/random.jl index 1be9333d7ecd7..0d54f0a426cc4 100644 --- a/test/random.jl +++ b/test/random.jl @@ -13,6 +13,7 @@ srand(0); rand(); x = rand(384) @test typeof(rand(false:true)) === Bool @test typeof(rand(Char)) === Char @test length(randn(4, 5)) == 20 +@test length(randn(Complex128, 4, 5)) == 20 @test length(bitrand(4, 5)) == 20 @test rand(MersenneTwister(0)) == 0.8236475079774124 @@ -65,6 +66,11 @@ randn!(MersenneTwister(42), A) @test A == [-0.5560268761463861 0.027155338009193845; -0.444383357109696 -0.29948409035891055] +B = zeros(Complex128, 2) +randn!(MersenneTwister(42), B) +@test B == [Complex128(-0.5560268761463861,-0.444383357109696), + Complex128(0.027155338009193845,-0.29948409035891055)] * 0.7071067811865475244008 + for T in (Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Int128, UInt128, BigInt, Float16, Float32, Float64, Rational{Int}) r = rand(convert(T, 97):convert(T, 122)) @@ -306,8 +312,9 @@ end # test all rand APIs for rng in ([], [MersenneTwister(0)], [RandomDevice()]) - types = [Base.BitInteger_types..., Bool, Float16, Float32, Float64, Char] ftypes = [Float16, Float32, Float64] + cftypes = [Complex32, Complex64, Complex128, ftypes...] + types = [Bool, Char, Base.BitInteger_types..., ftypes...] b2 = big(2) u3 = UInt(3) for f in [rand, randn, randexp] @@ -316,7 +323,7 @@ for rng in ([], [MersenneTwister(0)], [RandomDevice()]) f(rng..., 2, 3) ::Array{Float64, 2} f(rng..., b2, u3) ::Array{Float64, 2} f(rng..., (2, 3)) ::Array{Float64, 2} - for T in (f === rand ? types : ftypes) + for T in (f === rand ? types : f === randn ? cftypes : ftypes) a0 = f(rng..., T) ::T a1 = f(rng..., T, 5) ::Vector{T} a2 = f(rng..., T, 2, 3) ::Array{T, 2} @@ -330,7 +337,7 @@ for rng in ([], [MersenneTwister(0)], [RandomDevice()]) end end for f! in [rand!, randn!, randexp!] - for T in (f! === rand! ? types : ftypes) + for T in (f! === rand! ? types : f! === randn! ? cftypes : ftypes) X = T == Bool ? T[0,1] : T[0,1,2] for A in (Array{T}(5), Array{T}(2, 3)) f!(rng..., A) ::typeof(A) From 2da70cccce9026b3347889abd0f69470459a5ad4 Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Sat, 20 May 2017 10:34:22 -0400 Subject: [PATCH 2/4] add where syntax and move to appropriate place in source --- base/random.jl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/base/random.jl b/base/random.jl index cebde6fa12f23..d9461963629e2 100644 --- a/base/random.jl +++ b/base/random.jl @@ -1196,9 +1196,6 @@ complex normal distribution. end end -Base.@irrational SQRT_HALF 0.7071067811865475244008 sqrt(big(0.5)) -randn{T}(rng::AbstractRNG, ::Type{Complex{T}}) = Complex{T}(SQRT_HALF * randn(rng, T), SQRT_HALF*randn(rng, T)) - # this unlikely branch is put in a separate function for better efficiency function randn_unlikely(rng, idx, rabs, x) @inbounds if idx == 0 @@ -1287,6 +1284,10 @@ let Floats = Union{Float16,Float32,Float64} $randfun( dims::Integer... ) = $randfun(GLOBAL_RNG, Float64, dims...) end end + + # complex randn + Base.@irrational SQRT_HALF 0.7071067811865475244008 sqrt(big(0.5)) + randn(rng::AbstractRNG, ::Type{Complex{T}}) where {T <: Floats} = Complex{T}(SQRT_HALF * randn(rng, T), SQRT_HALF*randn(rng, T)) end ## random UUID generation From e21065f9b3968be46d48807d7fa93861936ea55f Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Tue, 23 May 2017 08:07:05 -0400 Subject: [PATCH 3/4] update NEWS.md and adjust complex randn to accept AbstractFloat --- NEWS.md | 6 +++++- base/random.jl | 7 ++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/NEWS.md b/NEWS.md index 6d2e626aeb680..d2d246aaffa5d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -28,9 +28,13 @@ This section lists changes that do not have deprecation warnings. Library improvements -------------------- - * the functions `base` and `digits` digits now accept a negative + * The functions `base` and `digits` digits now accept a negative base (like `ndigits` did) ([#21692]). + * The function `randn` now accepts complex arguments (`Complex{T <: AbstractFloat}`) + ([#21973]). + + Compiler/Runtime improvements ----------------------------- diff --git a/base/random.jl b/base/random.jl index d9461963629e2..448ca83b998bf 100644 --- a/base/random.jl +++ b/base/random.jl @@ -1285,11 +1285,12 @@ let Floats = Union{Float16,Float32,Float64} end end - # complex randn - Base.@irrational SQRT_HALF 0.7071067811865475244008 sqrt(big(0.5)) - randn(rng::AbstractRNG, ::Type{Complex{T}}) where {T <: Floats} = Complex{T}(SQRT_HALF * randn(rng, T), SQRT_HALF*randn(rng, T)) end +# complex randn +Base.@irrational SQRT_HALF 0.7071067811865475244008 sqrt(big(0.5)) +randn(rng::AbstractRNG, ::Type{Complex{T}}) where {T <: AbstractFloat} = Complex{T}(SQRT_HALF * randn(rng, T), SQRT_HALF*randn(rng, T)) + ## random UUID generation struct UUID From f3c46e2c5f9fd68c8b1217514916ea2e800cbe43 Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Wed, 24 May 2017 14:45:07 -0400 Subject: [PATCH 4/4] minor formatting of complex randn and delete stray empty line --- base/random.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/random.jl b/base/random.jl index 448ca83b998bf..3697302a05153 100644 --- a/base/random.jl +++ b/base/random.jl @@ -1284,12 +1284,12 @@ let Floats = Union{Float16,Float32,Float64} $randfun( dims::Integer... ) = $randfun(GLOBAL_RNG, Float64, dims...) end end - end # complex randn Base.@irrational SQRT_HALF 0.7071067811865475244008 sqrt(big(0.5)) -randn(rng::AbstractRNG, ::Type{Complex{T}}) where {T <: AbstractFloat} = Complex{T}(SQRT_HALF * randn(rng, T), SQRT_HALF*randn(rng, T)) +randn(rng::AbstractRNG, ::Type{Complex{T}}) where {T <: AbstractFloat} = + Complex{T}(SQRT_HALF * randn(rng, T), SQRT_HALF * randn(rng, T)) ## random UUID generation