From 46c927d1b6c5439f304701486fc130a5714237be Mon Sep 17 00:00:00 2001 From: Gregor Robinson Date: Sat, 30 Jul 2016 16:53:02 -0400 Subject: [PATCH] Add complex random normals. --- base/random.jl | 13 ++++++++++++- doc/stdlib/numbers.rst | 2 +- test/random.jl | 12 +++++++++--- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/base/random.jl b/base/random.jl index c6cf2bfdeb2c0..5acc673ddaee2 100644 --- a/base/random.jl +++ b/base/random.jl @@ -1123,7 +1123,10 @@ 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`, `Float64` (the default), `Complex32`, `Complex64`, and `Complex128`. +When the type argument is complex, the values returned are drawn from the circularly symmetric +complex normal distribution. +. """ @inline function randn(rng::AbstractRNG=GLOBAL_RNG) @inbounds begin @@ -1224,6 +1227,14 @@ let Floats = Union{Float16,Float32,Float64} $randfun( dims::Integer... ) = $randfun(GLOBAL_RNG, Float64, dims...) end end + + for (T,SQRT_HALF) in ((Float64, 0.7071067811865475), + (Float32, 0.70710677f0), + (Float16, 0.70710677f0)) + @inline function randn(rng::AbstractRNG, ::Type{Complex{T}}) + Complex{T}(SQRT_HALF*randn(rng, T), SQRT_HALF*randn(rng, T)) + end + end end ## random UUID generation diff --git a/doc/stdlib/numbers.rst b/doc/stdlib/numbers.rst index ae1d47fa34c5f..9dc71baa520cb 100644 --- a/doc/stdlib/numbers.rst +++ b/doc/stdlib/numbers.rst @@ -602,7 +602,7 @@ As ``BigInt`` represents unbounded integers, the interval must be specified (e.g .. Docstring generated from Julia source - 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). + 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``\ , ``Float64`` (the default), ``Complex32``\ , ``Complex64``\ , and ``Complex128``\ . When the type argument is complex, the values returned are drawn from the circularly symmetric complex normal distribution. . .. function:: randn!([rng], A::AbstractArray) -> A diff --git a/test/random.jl b/test/random.jl index 75a2a871d8a58..c02e6ccbd6bcd 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.8236475079774124 @@ -59,6 +60,10 @@ A = zeros(2, 2) 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.7071067811865475 for T in (Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Int128, UInt128, BigInt, Float16, Float32, Float64, Rational{Int}) @@ -300,8 +305,9 @@ end # test all rand APIs for rng in ([], [MersenneTwister()], [RandomDevice()]) - types = [Base.BitInteger_types..., Bool, Float16, Float32, Float64, Char] ftypes = [Float16, Float32, Float64] + cftypes = [ftypes..., Complex32, Complex64, Complex128] + types = [Base.BitInteger_types..., ftypes..., Bool, Char] b2 = big(2) u3 = UInt(3) for f in [rand, randn, randexp] @@ -310,7 +316,7 @@ for rng in ([], [MersenneTwister()], [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} @@ -324,7 +330,7 @@ for rng in ([], [MersenneTwister()], [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)