@@ -17,7 +17,8 @@ using Distributions
17
17
export GaussianHermiteMatrix, GaussianLaguerreMatrix, GaussianJacobiMatrix,
18
18
GaussianHermiteTridiagonalMatrix, GaussianLaguerreTridiagonalMatrix,
19
19
GaussianJacobiSparseMatrix,
20
- GaussianHermiteSamples, GaussianLaguerreSamples, GaussianJacobiSamples
20
+ GaussianHermiteSamples, GaussianLaguerreSamples, GaussianJacobiSamples,
21
+ chi, GaussianLaguerreBidiagonalMatrix, GaussianJacobiBidiagonalMatrix
21
22
22
23
23
24
# ########################
@@ -36,49 +37,56 @@ chi(df) = df==0? 0.0 : sqrt(rand(Chisq(df)))
36
37
function GaussianHermiteMatrix (n:: Integer , beta:: Integer )
37
38
if beta == 1 # real
38
39
A = randn (n, n)
39
- normalization = sqrt (2 * n)
40
40
elseif beta == 2 # complex
41
41
A = randn (n, n) + im* randn (n, n)
42
- normalization = sqrt (4 * n)
43
42
elseif beta == 4 # quaternion
44
43
# Employs 2x2 matrix representation of quaternions
45
44
X = randn (n, n) + im* randn (n, n)
46
45
Y = randn (n, n) + im* randn (n, n)
47
- A = [X Y; - conj (Y) conj (X)]
48
- normalization = sqrt (8 * n) # TODO check normalization
46
+ A = [X Y - conj (Y) conj (X)]
49
47
else
50
- error ( @sprintf (" beta = %d is not implemented" , beta ))
48
+ throw ( string (" beta = " , beta, " is not implemented" ))
51
49
end
52
- return (A + A' ) / normalization
50
+ return (A + A' ) / sqrt ( 2 * beta * n)
53
51
end
54
52
53
+
55
54
# Generates a NxN tridiagonal Wigner matrix
56
55
# The beta=infinity case is defined in Edelman, Persson and Sutton, 2012
57
56
function GaussianHermiteTridiagonalMatrix (n:: Integer , beta:: Real )
58
- if beta<= 0 error (" beta must be positive" ) end
59
- if beta== Inf return SymTridiagonal (zeros (n), [sqrt (x/ 2 ) for x= n- 1 : - 1 : 1 ]) end
60
- Hdiag = randn (n)/ sqrt (n)
61
- Hsup = [chi (beta* i)/ sqrt (2 * n) for i= n- 1 : - 1 : 1 ]
57
+ if beta< 0 error (" beta must be non-negative" ) end
58
+ if beta== Inf return SymTridiagonal (zeros (n), Float64[sqrt (x/ n) for x= n- 1 : - 1 : 1 ]) end
59
+ nrm = 1 / sqrt (beta* n) # normalization
60
+ Hdiag = randn (n)* nrm
61
+ Hsup = [chi (beta* i)* nrm for i= n- 1 : - 1 : 1 ]
62
62
return SymTridiagonal (Hdiag, Hsup)
63
63
end
64
64
65
+
66
+ # Return n eigenvalues distributed according to the Hermite ensemble
67
+ function GaussianHermiteSamples (n:: Integer , beta:: Real )
68
+ eigvals (GaussianHermiteTridiagonalMatrix (n, beta))
69
+ end
70
+
71
+
65
72
# #############################
66
73
# Gaussian Wishart ensemble #
67
74
# Gaussian Laguerre ensemble #
68
75
# #############################
69
76
70
77
# Generates a NxN Hermitian Wishart matrix
71
- # TODO Check - the eigenvalue distribution looks funky
72
- function GaussianLaguerreMatrix (m:: Integer , n:: Integer , beta:: Integer )
78
+ # n: exterior dimension of matrix
79
+ # m: "interior" dimension of the matrix
80
+ function GaussianLaguerreMatrix (n:: Integer , m:: Integer , beta:: Integer )
73
81
if beta == 1 # real
74
- A = randn (m, n )
82
+ A = randn (n, m )
75
83
elseif beta == 2 # complex
76
- A = randn (m, n ) + im* randn (m, n )
84
+ A = randn (n, m ) + im* randn (n, m )
77
85
elseif beta == 4 # quaternion
78
86
# Employs 2x2 matrix representation of quaternions
79
- X = randn (m, n ) + im* randn (m, n )
80
- Y = randn (m, n ) + im* randn (m, n )
81
- A = [X Y; - conj (Y) conj (X)]
87
+ X = randn (n, m ) + im* randn (n, m )
88
+ Y = randn (n, m ) + im* randn (n, m )
89
+ A = [X Y - conj (Y) conj (X)]
82
90
error (@sprintf (" beta = %d is not implemented" , beta))
83
91
end
84
92
return (A * A' ) / m
87
95
88
96
# Generates a NxN bidiagonal Wishart matrix
89
97
# Laguerre ensemble
90
- function GaussianLaguerreBidiagonalMatrix (m :: Integer , a:: Real , beta:: Real )
91
- min_a = beta* (m - 1 )/ 2
92
- a< min_a ? error (@sprintf (" Given your choice of m and beta, a must be at least %f (You said a = %f)" , min_a, a)) : nothing
93
- Hdiag = [chi (2 * a- i* beta) for i= 0 : m - 1 ]
94
- Hsub = [chi (beta* i) for i= m - 1 : - 1 : 1 ]
95
- Bidiagonal (Hsub, Hdiag , false )/ (m ^ 0.25 )
98
+ function GaussianLaguerreBidiagonalMatrix (n :: Integer , a:: Real , beta:: Real )
99
+ min_a = beta* (n - 1 )/ 2
100
+ a< min_a ? error (@sprintf (" Given your choice of n and beta, a must be at least %f (You said a = %f)" , min_a, a)) : nothing
101
+ Hdiag = [chi (2 * a- i* beta) for i= 0 : n - 1 ]
102
+ Hsub = [chi (beta* i) for i= n - 1 : - 1 : 1 ]
103
+ Bidiagonal (Hdiag, Hsub , false )/ sqrt (n )
96
104
end
97
105
98
106
@@ -104,21 +112,35 @@ function GaussianLaguerreTridiagonalMatrix(m::Integer, a::Real, beta::Real)
104
112
end
105
113
106
114
107
- # Return n eigenvalues distributed according to the Hermite ensemble
108
- function GaussianHermiteSamples (n:: Integer , beta:: Real )
109
- eigvals (GaussianHermiteTridiagonalMatrix (n, beta))
115
+ # Return n eigenvalues distributed according to the Laguerre ensemble
116
+ # Compute the singular values of the bidiagonal matrix
117
+ function GaussianLaguerreSamples (m:: Integer , a:: Real , beta:: Real )
118
+ svdvals (GaussianLaguerreBidiagonalMatrix (m, a, beta))
110
119
end
111
120
121
+ # The limiting density of states for an infinite matrix
122
+ # This is the Marčenko-Pastur law
123
+ # Marčenko, V.A. and Pastur, L.A. (1967). Distribution of eigenvalues for some sets of random
124
+ # matrices. Sbornik: Mathematics 1, 457–483.
125
+ function GaussianLaguerreDensity (n:: Integer , m:: Integer , beta:: Real , x:: Real )
126
+ GaussianLaguerreDensity (n/ m, beta, x)
127
+ end
128
+ function GaussianLaguerreDensity (c:: Real , beta:: Real , x:: Real )
129
+ # There is also a finite mass at 0 for c>1 of weight (1 - 1/c)
130
+ if c> 1 && x== 0 return Inf
131
+ am, ap = beta* (1 - sqrt (c))^ 2 , beta* (1 - sqrt (c))^ 2
132
+ sqrt ((x- am)* (ap- x))/ (2 * pi * beta* x* c)
133
+ end
112
134
113
135
# ###########################
114
136
# Gaussian MANOVA ensemble #
115
137
# Jacobi ensemble #
116
138
# ###########################
117
139
118
140
# Generates a NxN self-dual MANOVA Matrix
119
- function GaussianJacobiMatrix (m :: Integer , n1 :: Integer , n2 :: Integer , beta:: Integer )
120
- w1 = Wishart (m, n1 , beta)
121
- w2 = Wishart (m, n2 , beta)
141
+ function GaussianJacobiMatrix (n :: Integer , m1 :: Integer , m2 :: Integer , beta:: Integer )
142
+ w1 = Wishart (n, m1 , beta)
143
+ w2 = Wishart (n, m2 , beta)
122
144
return (w1 + w2) \ w1
123
145
end
124
146
@@ -142,13 +164,6 @@ function SampleCSValues(n::Integer, a::Real, b::Real, beta::Real)
142
164
end
143
165
144
166
145
- # Return n eigenvalues distributed according to the Laguerre ensemble
146
- # Compute the singular values of the bidiagonal matrix
147
- function GaussianLaguerreSamples (m:: Integer , a:: Real , beta:: Real )
148
- svdvals (GaussianLaguerreBidiagonalMatrix (m, a, beta))
149
- end
150
-
151
-
152
167
# Generates a 2Mx2M sparse MANOVA matrix
153
168
# Jacobi ensemble
154
169
#
@@ -218,4 +233,18 @@ function GaussianJacobiSamples(n::Integer, a::Real, b::Real, beta::Real)
218
233
svdvals (GaussianJacobiBidiagonalMatrix (n, a, b))
219
234
end
220
235
221
-
236
+ # Returns limiting density of states for an infinite-dimensional matrix
237
+ # A generalization of Marcenko-Pastur
238
+ function GaussianJacobiDensity (n:: Integer , m1:: Integer , m2:: Integer , beta:: Real , x:: Real )
239
+ GaussianJacobiDensity (n/ m1, n/ m2, beta, x)
240
+ end
241
+ function GaussianJacobiDensity (c1:: Real , c2:: Real , beta:: Real , x:: Real )
242
+ if ! (0 <= c1<= 1 ) error (string (" Need 0<=c1<=1 but you have c1=" , c1)) end
243
+ if ! (beta== 1 ) error (string (" beta!=1 not implemented" )) end
244
+ # Finite mass at 0 of weight (1-1/c2)
245
+ if c2> 1 && x== 0 return Inf
246
+ b0= c1* x- c2* x- c1+ 2
247
+ b1= - 2 c2* x^ 2 + 2 x- 3 c1* x+ c1+ c2* x- 1 + 2 c1* x^ 2
248
+ b2= c1* x- 2 c1* x^ 2 + c2* x^ 2 - x^ 3 * c2+ x^ 3 * c1
249
+ sqrt (4 b2* b0- b1^ 2 )/ (2 * pi * b2)
250
+ end
0 commit comments