|
| 1 | +# Generates samples of dense random matrices that are distributed according |
| 2 | +# to the classical Gaussian random matrix ensembles |
| 3 | +# |
| 4 | +# The notation follows closely that in: |
| 5 | +# |
| 6 | +# Ioana Dumitriu and Alan Edelman, "Matrix Models for Beta Ensembles" |
| 7 | +# Journal of Mathematical Physics, vol. 43 no. 11 (2002), pp. 5830--5547 |
| 8 | +# doi: 10.1063/1.1507823 |
| 9 | +# arXiv: math-ph/0206043 |
| 10 | + |
| 11 | +#Generates a NxN symmetric Wigner matrix |
| 12 | +#Hermite ensemble |
| 13 | +function GaussianHermiteMatrix(n :: Integer, beta :: Integer) |
| 14 | + if beta == 1 #real |
| 15 | + A = randn(n, n) |
| 16 | + normalization = sqrt(2*n) |
| 17 | + elseif beta == 2 #complex |
| 18 | + A = randn(n, n) + im*randn(n, n) |
| 19 | + normalization = sqrt(4*n) |
| 20 | + elseif beta == 4 #quaternion |
| 21 | + #Employs 2x2 matrix representation of quaternions |
| 22 | + X = randn(n, n) + im*randn(n, n) |
| 23 | + Y = randn(n, n) + im*randn(n, n) |
| 24 | + A = [X Y; -conj(Y) conj(X)] |
| 25 | + normalization = sqrt(8*n) #TODO check normalization |
| 26 | + else |
| 27 | + error(@sprintf("beta = %d is not implemented", beta)) |
| 28 | + end |
| 29 | + return (A + A') / normalization |
| 30 | +end |
| 31 | + |
| 32 | +#Generates a NxN Hermitian Wishart matrix |
| 33 | +#Laguerre ensemble |
| 34 | +#TODO Check - the eigenvalue distribution looks funky |
| 35 | +function GaussianLaguerreMatrix(m :: Integer, n :: Integer, beta :: Integer) |
| 36 | + if beta == 1 #real |
| 37 | + A = randn(m, n) |
| 38 | + elseif beta == 2 #complex |
| 39 | + A = randn(m, n) + im*randn(m, n) |
| 40 | + elseif beta == 4 #quaternion |
| 41 | + #Employs 2x2 matrix representation of quaternions |
| 42 | + X = randn(m, n) + im*randn(m, n) |
| 43 | + Y = randn(m, n) + im*randn(m, n) |
| 44 | + A = [X Y; -conj(Y) conj(X)] |
| 45 | + error(@sprintf("beta = %d is not implemented", beta)) |
| 46 | + end |
| 47 | + return (A * A') / m |
| 48 | +end |
| 49 | + |
| 50 | +#Generates a NxN self-dual MANOVA Matrix |
| 51 | +#Jacobi ensemble |
| 52 | +function GaussianJacobiMatrix(m :: Integer, n1 :: Integer, n2 :: Integer, beta :: Integer) |
| 53 | + w1 = Wishart(m, n1, beta) |
| 54 | + w2 = Wishart(m, n2, beta) |
| 55 | + return (w1 + w2) \ w1 |
| 56 | +end |
| 57 | + |
| 58 | + |
| 59 | +#A convenience function |
| 60 | +using Distributions |
| 61 | +chi(df) = sqrt(rand(Chisq(df))) |
| 62 | + |
| 63 | +#Generates a NxN tridiagonal Wigner matrix |
| 64 | +#Hermite ensemble |
| 65 | +function GaussianHermiteTridiagonalMatrix(n :: Integer, beta :: FloatingPoint) |
| 66 | + @assert beta > 0 |
| 67 | + Hdiag = randn(n)/sqrt(n) |
| 68 | + Hsup = [chi(beta*i)/sqrt(2*n) for i=n-1:-1:1] |
| 69 | + return SymTridiagonal(Hdiag, Hsup) |
| 70 | +end |
| 71 | + |
| 72 | + |
| 73 | +#TODO Check normalization - I guessed this |
| 74 | +function GaussianLaguerreTridiagonalMatrix(m :: Integer, a :: FloatingPoint, beta :: FloatingPoint) |
| 75 | + if a <= beta*(m-1)/2.0 |
| 76 | + error(@sprintf("Given your choice of m and beta, a must be at least %f (You said a = %f)", beta*(m-1)/2.0, a)) |
| 77 | + end |
| 78 | + Hdiag = [chi(2*a-i*beta) for i=0:m-1] |
| 79 | + Hsub = [chi(beta*i) for i=m-1:-1:1] |
| 80 | + #Julia has no bidiagonal type... yet |
| 81 | + B = Tridiagonal(Hsub, Hdiag, zeros(m-1)) |
| 82 | + L = B * B' #Currently returns a dense matrix |
| 83 | + return SymTridiagonal(diag(L)/sqrt(m), diag(L,1)/sqrt(m)) |
| 84 | +end |
| 85 | + |
0 commit comments