Skip to content

Commit fa4514e

Browse files
committed
add doctests for random matrix ensembles
1 parent f3901a3 commit fa4514e

4 files changed

Lines changed: 166 additions & 43 deletions

File tree

src/GaussianEnsembles.jl

Lines changed: 83 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,25 @@ export GaussianHermite, GaussianLaguerre, GaussianJacobi,
2424
#####################
2525

2626
"""
27-
GaussianHermite{β} represents a Gaussian Hermite ensemble with parameter β.
27+
GaussianHermite(β::Int) <: ContinuousMatrixDistribution
2828
29-
Wigner{β} is a synonym.
29+
Represents a Gaussian Hermite ensemble with Dyson index `β`.
3030
31-
Example of usage:
31+
`Wigner(β)` is a synonym.
3232
33-
β = 2 #β = 1, 2, 4 generates real, complex and quaternionic matrices respectively.
34-
d = Wigner{β} #same as GaussianHermite{β}
33+
## Examples
3534
36-
n = 20 #Generate square matrices of this size
35+
```jldoctest
36+
julia> d = Wigner(2); n = 3;
3737
38-
S = rand(d, n) #Generate a 20x20 symmetric Wigner matrix
39-
T = tridrand(d, n) #Generate the symmetric tridiagonal form
40-
v = eigvalrand(d, n) #Generate a sample of eigenvalues
38+
julia> Random.seed!(1234);
39+
40+
julia> rand(d, n)
41+
3×3 LinearAlgebra.Hermitian{ComplexF64, Matrix{ComplexF64}}:
42+
0.560409+0.0im -0.292145+0.125521im 1.04191+0.513798im
43+
-0.292145-0.125521im -0.346868+0.0im 0.0228835-0.00164725im
44+
1.04191-0.513798im 0.0228835+0.00164725im -0.118721+0.0im
45+
```
4146
"""
4247
struct GaussianHermite{β} <: ContinuousMatrixDistribution end
4348
GaussianHermite(β) = GaussianHermite{β}()
@@ -47,6 +52,13 @@ Synonym for GaussianHermite{β}
4752
"""
4853
const Wigner{β} = GaussianHermite{β}
4954

55+
"""
56+
rand(d::Wigner, n::Int)
57+
58+
Generates an `n × n` matrix randomly sampled from the Gaussian-Hermite ensemble (also known as the Wigner ensemble).
59+
60+
The Dyson index `β` is restricted to `β = 1,2` or `4`, for real, complex, and quaternionic fields, respectively.
61+
"""
5062
rand(d::Type{Wigner{β}}, dims...) where {β} = rand(d(), dims...)
5163

5264
function rand(d::Wigner{1}, n::Int)
@@ -82,12 +94,15 @@ function rand(d::Wigner{β}, dims::Int...) where {β}
8294
end
8395

8496
"""
85-
Generates a nxn symmetric tridiagonal Wigner matrix
97+
tridand(d::Wigner, n::Int)
98+
99+
Generates an `n × n` symmetric tridiagonal matrix from the Gaussian-Hermite ensemble (also known as the Wigner ensemble).
86100
87-
Unlike for `rand(Wigner{β}, n)`, which is restricted to β=1,2 or 4,
88-
`trirand(Wigner{β}, n)` will generate a
101+
Unlike for `rand(Wigner(β), n)`, which is restricted to `β = 1,2` or `4`,
102+
the call `trirand(Wigner(β), n)` will generate a tridiagonal Wigner matrix for any positive
103+
value of `β`, including infinity.
89104
90-
The β=∞ case is defined in Edelman, Persson and Sutton, 2012
105+
The `β == ∞` case is defined in Edelman, Persson and Sutton, 2012.
91106
"""
92107
function tridrand(d::Wigner{β}, n::Int) where {β}
93108
χ(df::Real) = rand(Distributions.Chi(df))
@@ -146,16 +161,37 @@ end
146161
# Laguerre ensemble #
147162
#####################
148163

164+
"""
165+
GaussianLaguerre(β::Real, a::Real)` <: ContinuousMatrixDistribution
166+
167+
Represents a Gaussian-Laguerre ensemble with Dyson index `β` and `a` parameter
168+
used to control the density of eigenvalues near `λ = 0`.
169+
170+
`Wishart(β, a)` is a synonym.
171+
172+
## Fields
173+
- `beta`: Dyson index
174+
- `a`: Parameter used for weighting the joint probability density function of the ensemble
175+
176+
## References:
177+
- Edelman and Rao, 2005
178+
"""
149179
mutable struct GaussianLaguerre <: ContinuousMatrixDistribution
150180
beta::Real
151181
a::Real
152182
end
153183
const Wishart = GaussianLaguerre
154184

155-
156-
#Generates a NxN Hermitian Wishart matrix
157185
#TODO Check - the eigenvalue distribution looks funky
158186
#TODO The appropriate matrix size should be calculated from a and one matrix dimension
187+
"""
188+
rand(d::GaussianLaguerre, dims::Tuple)
189+
190+
Generate a random matrix sampled from the Gaussian Laguerre ensemble (also known as the Wishart ensemble)
191+
with parameters defined in `d` and dimensions given by `dims`.
192+
193+
The Dyson index `β` is restricted to `β = 1,2` or `4`, for real, complex, and quaternionic fields, respectively.
194+
"""
159195
function rand(d::GaussianLaguerre, dims::Dim2)
160196
n = 2.0*a/d.beta
161197
if d.beta == 1 #real
@@ -172,15 +208,23 @@ function rand(d::GaussianLaguerre, dims::Dim2)
172208
return (A * A') / dims[1]
173209
end
174210

175-
#Generates a NxN bidiagonal Wishart matrix
211+
"""
212+
bidrand(d::GaussianLaguerre, n::Int)
213+
214+
Generate an `n × n` bidiagonal matrix sampled from the Gaussian Laguerre ensemble (also known as the Wishart ensemble).
215+
"""
176216
function bidrand(d::GaussianLaguerre, m::Integer)
177217
if d.a <= d.beta*(m-1)/2.0
178218
error("Given your choice of m and beta, a must be at least $(d.beta*(m-1)/2.0) (You said a = $(d.a))")
179219
end
180220
Bidiagonal([chi(2*d.a-i*d.beta) for i=0:m-1], [chi(d.beta*i) for i=m-1:-1:1], true)
181221
end
182222

183-
#Generates a NxN tridiagonal Wishart matrix
223+
"""
224+
tridrand(d::GaussianLaguerre, n::Int)
225+
226+
Generate an `n × n` tridiagonal matrix sampled from the Gaussian Laguerre ensemble (also known as the Wishart ensemble).
227+
"""
184228
function tridrand(d::GaussianLaguerre, m::Integer)
185229
B = bidrand(d, m)
186230
L = B * B'
@@ -218,14 +262,35 @@ end
218262
# Jacobi ensemble #
219263
###################
220264

221-
#Generates a NxN self-dual MANOVA matrix
265+
"""
266+
GaussianJacobi(β::Real, a::Real, a::Real)` <: ContinuousMatrixDistribution
267+
268+
Represents a Gaussian-Jacobi ensemble with Dyson index `β`, while
269+
`a`and `b` are parameters used to weight the joint probability density function of the ensemble.
270+
271+
`MANOVA(β, a, b)` is a synonym.
272+
273+
## Fields
274+
- `beta`: Dyson index
275+
- `a`: Parameter used for shaping the joint probability density function near `λ = 0`
276+
- `b`: Parameter used for shaping the joint probability density function near `λ = 1`
277+
278+
## References:
279+
- Edelman and Rao, 2005
280+
"""
222281
mutable struct GaussianJacobi <: ContinuousMatrixDistribution
223282
beta::Real
224283
a::Real
225284
b::Real
226285
end
227286
const MANOVA = GaussianJacobi
228287

288+
"""
289+
rand(d::GaussianJacobi, n::Int)
290+
291+
Generate an `n × n` random matrix sampled from the Gaussian-Jacobi ensemble (also known as the MANOVA ensemble)
292+
with parameters defined in `d`.
293+
"""
229294
function rand(d::GaussianJacobi, m::Integer)
230295
w1 = Wishart(m, int(2.0*d.a/d.beta), d.beta)
231296
w2 = Wishart(m, int(2.0*d.b/d.beta), d.beta)

src/Ginibre.jl

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,44 @@
11
export rand, Ginibre
22
import Base.rand
33

4-
#Samples a matrix from the Ginibre ensemble
5-
#This ensemble lives in GL(N, F), the set of all invertible N x N matrices
6-
#over the field F
7-
#For beta=1,2,4, F=R, C, H respectively
4+
"""
5+
Ginibre(β::Int, N::Int) <: ContinuousMatrixDistribution
6+
7+
Represents a Ginibre ensemble with Dyson index `β` living in `GL(N, F)`, the set
8+
of all invertible `N × N` matrices over the field `F`.
9+
10+
## Fields
11+
- `beta`: Dyson index
12+
- `N`: Matrix dimension over the field `F`.
13+
14+
## Examples
15+
16+
```jldoctest
17+
julia> Random.seed!(1234);
18+
19+
julia> rand(Ginibre(2, 3))
20+
3×3 Matrix{ComplexF64}:
21+
0.970656-0.763689im -0.0328031-0.0998909im 2.70742+0.942733im
22+
-0.979218-0.534709im -0.600792-0.726142im 1.52445-0.00991272im
23+
0.901861-0.837116im -1.44518-0.00420647im -0.20563-0.66748im
24+
```
25+
26+
## References:
27+
- Edelman and Rao, 2005
28+
"""
829
struct Ginibre <: ContinuousMatrixDistribution
930
beta::Float64
1031
N::Integer
1132
end
1233

34+
"""
35+
rand(W::Ginibre)
36+
37+
Samples a matrix from the Ginibre ensemble.
38+
39+
For `β = 1,2,4`, generates matrices randomly sampled from the real, complex, and quaternion
40+
Ginibre ensemble, respectively.
41+
"""
1342
function rand(W::Ginibre)
1443
beta, n = W.beta, W.N
1544
if beta==1

src/Haar.jl

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,32 @@ end
6464
data(P::Ptr{gsl_permutation}) = [convert(Int64, x)+1 for x in
6565
pointer_to_array(permutation_data(P), (convert(Int64, permutation_size(P)) ,))]
6666

67+
"""
68+
Haar(β::Int) <: ContinuousMatrixDistribution
6769
70+
Represents a Haar measure with Dyson index `β`, in which values of `β = 1,2` or `4`
71+
correspond to matrices are distributed with uniform Haar measure over the
72+
classical orthogonal, unitary and symplectic groups `O(n)`, `U(n)` and
73+
`Sp(n)~USp(2n)` respectively.
74+
75+
## Fields
76+
- `beta`: Dyson index
77+
78+
## Examples
79+
80+
```jldoctest
81+
julia> Random.seed!(1234);
82+
83+
julia> rand(Haar(2), 3)
84+
3×3 Matrix{ComplexF64}:
85+
-0.587093-0.106607im -0.109587-0.0619909im 0.666498+0.428819im
86+
0.120119+0.525468im 0.205226+0.641757im -0.0408499+0.503801im
87+
-0.591627-0.0582071im 0.725559+0.0611728im -0.28036-0.194448im
88+
```
89+
90+
## References:
91+
- Edelman and Rao, 2005
92+
"""
6893
mutable struct Haar <: ContinuousMatrixDistribution
6994
beta::Real
7095
end

src/HaarMeasure.jl

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,29 @@
1-
# Computes samples of real or complex Haar matrices of size nxn
2-
#
3-
# For beta=1,2,4, generates random orthogonal, unitary and symplectic matrices
4-
# of uniform Haar measure.
5-
# These matrices are distributed with uniform Haar measure over the
6-
# classical orthogonal, unitary and symplectic groups O(N), U(N) and
7-
# Sp(N)~USp(2N) respectively.
8-
#
9-
# The last parameter specifies whether or not the piecewise correction
10-
# is applied to ensure that it truly of Haar measure
11-
# This addresses an inconsistency in the Householder reflections as
12-
# implemented in most versions of LAPACK
13-
# Method 0: No correction
14-
# Method 1: Multiply rows by uniform random phases
15-
# Method 2: Multiply rows by phases of diag(R)
16-
# References:
17-
# Edelman and Rao, 2005
18-
# Mezzadri, 2006, math-ph/0609050
191
#TODO implement O(n^2) method
20-
#By default, always do piecewise correction
21-
#For most applications where you use the HaarMatrix as a similarity transform
22-
#it doesn't matter, but better safe than sorry... let the user choose else
2+
"""
3+
rand(W::Haar, n::Int)
4+
5+
Computes samples of real or complex Haar matrices of size `n`×`n`.
6+
7+
For `beta = 1,2,4`, generates random orthogonal, unitary and symplectic matrices
8+
of uniform Haar measure.
9+
These matrices are distributed with uniform Haar measure over the
10+
classical orthogonal, unitary and symplectic groups `O(n)`, `U(n)` and
11+
`Sp(n)~USp(2n)` respectively.
12+
13+
rand(W::Haar, n::Int, doCorrection::Int = 1)
14+
15+
The additional argument `doCorrection` specifies whether or not the piecewise correction
16+
is applied to ensure that it is truly of Haar measure.
17+
This addresses an inconsistency in the Householder reflections as
18+
implemented in most versions of LAPACK.
19+
- Method 0: No correction
20+
- Method 1: Multiply rows by uniform random phases
21+
- Method 2: Multiply rows by phases of diag(R)
22+
23+
## References:
24+
- Edelman and Rao, 2005
25+
- Mezzadri, 2006, math-ph/0609050
26+
"""
2327
function rand(W::Haar, n::Int, doCorrection::Int=1)
2428
beta = W.beta
2529
M=rand(Ginibre(beta,n))

0 commit comments

Comments
 (0)