Skip to content

Commit e9a4fe9

Browse files
committed
Added beta-Jacobi sparse matrix sample and samples of beta-Gaussian ensemble eigenvalues
1 parent 5309722 commit e9a4fe9

File tree

2 files changed

+98
-1
lines changed

2 files changed

+98
-1
lines changed

src/GaussianEnsembleSamples.jl

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ function GaussianHermiteTridiagonalMatrix(n :: Integer, beta :: FloatingPoint)
7070
end
7171

7272

73-
#TODO Check normalization - I guessed this
73+
#Generates a NxN tridiagonal Wishart matrix
74+
#Laguerre ensemble
7475
function GaussianLaguerreTridiagonalMatrix(m :: Integer, a :: FloatingPoint, beta :: FloatingPoint)
7576
if a <= beta*(m-1)/2.0
7677
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))
@@ -83,3 +84,94 @@ function GaussianLaguerreTridiagonalMatrix(m :: Integer, a :: FloatingPoint, bet
8384
return SymTridiagonal(diag(L)/sqrt(m), diag(L,1)/sqrt(m))
8485
end
8586

87+
88+
# A helper function for Jacobi samples
89+
function SampleCSValues(n :: Integer, a :: FloatingPoint, b :: FloatingPoint, beta :: FloatingPoint)
90+
if beta == Inf
91+
c=sqrt((a+[1:n])./(a+b+2*[1:n]))
92+
s=sqrt((b+[1:n])./(a+b+2*[1:n]))
93+
cp=sqrt([1:n-1]./(a+b+1+2*[1:n-1]))
94+
sp=sqrt((a+b+1+[1:n-1])./(a+b+1+2*[1:n-1]))
95+
else
96+
#Generate cosine-squared values
97+
csq = [rand(Beta(beta*(a+i)/2,beta*(b+i)/2)) for i=1:n]
98+
cpsq = [rand(Beta(beta*i/2,beta*(a+b+1+i)/2)) for i=1:n]
99+
#Cosine-sine pairs
100+
c, s = sqrt(csq), sqrt(1-csq)
101+
cp, sp = sqrt(cpsq), sqrt(1-cpsq)
102+
end
103+
return c, s, cp, sp
104+
end
105+
#Generates a 2Mx2M sparse MANOVA matrix
106+
#Jacobi ensemble
107+
#
108+
# Reference:
109+
# A. Edelman and B. D. Sutton, "The beta-Jacobi matrix model, the CS decomposition,
110+
# and generalized singular value problems", Foundations of Computational Mathematics,
111+
# vol. 8 iss. 2 (2008), pp 259-285.
112+
#TODO check normalization
113+
function GaussianJacobiSparseMatrix(n :: Integer, a :: FloatingPoint, b :: FloatingPoint, beta :: FloatingPoint)
114+
CoordI = zeros(8n-4)
115+
CoordJ = zeros(8n-4)
116+
Values = zeros(8n-4)
117+
118+
c, s, cp, sp = SampleCSValues(n, a, b, beta)
119+
120+
#Diagonals of each block
121+
for i=1:n
122+
CoordI[i], CoordJ[i] = i, i
123+
Values[i] = i==1 ? c[n] : c[n+1-i] * sp[n+1-i]
124+
end
125+
for i=1:n
126+
CoordI[n+i], CoordJ[n+i] = i, n+i
127+
Values[n+i] = i==n ? s[1] : s[n+1-i] * sp[n-i]
128+
end
129+
for i=1:n
130+
CoordI[2n+i], CoordJ[2n+i] = n+i, i
131+
Values[2n+i] = i==1 ? -s[n] : -s[n+1-i] * sp[n+1-i]
132+
end
133+
for i=1:n
134+
CoordI[3n+i], CoordJ[3n+i] = n+i, n+i
135+
Values[3n+i] = i==n ? c[1] : c[n+1-i] * sp[n-i]
136+
end
137+
#Off-diagonals of each block
138+
for i=1:n+1
139+
CoordI[4n+i], CoordJ[4n+i] = i,i+1
140+
Values[4n+i] = -s[n+1-i]*cp[n-i]
141+
end
142+
for i=1:n+1
143+
CoordI[5n-1+i], CoordJ[5n-1+i] = i+1,n+i
144+
Values[5n-1+i] = c[n-i]*cp[n-i]
145+
end
146+
for i=1:n+1
147+
CoordI[6n-2+i], CoordJ[6n-2+i] = n+i,i+1
148+
Values[6n-2+i] = -c[n+1-i]*cp[n-i]
149+
end
150+
for i=1:n+1
151+
CoordI[7n-3+i], CoordJ[7n-3+i] = n+i,i+1
152+
Values[7n-3+i] = -s[n-i]*cp[n-i]
153+
end
154+
155+
return sparse(CoordI, CoordJ, Values)
156+
end
157+
158+
#Return n eigenvalues distributed according to the Hermite ensemble
159+
function GaussianHermiteSamples(n :: Integer, beta :: FloatingPoint)
160+
eigvals(GaussianHermiteTridiagonalMatrix(n, beta))
161+
end
162+
163+
#Return n eigenvalues distributed according to the Laguerre ensemble
164+
function GaussianLaguerreSamples(m :: Integer, a :: FloatingPoint, beta :: FloatingPoint)
165+
eigvals(GaussianLaguerreTridiagonalMatrix(m, a, beta))
166+
end
167+
168+
#Return n eigenvalues distributed according to the Jacobi ensemble
169+
function GaussianJacobiSamples(n :: Integer, a :: FloatingPoint, b :: FloatingPoint, beta :: FloatingPoint)
170+
#Generate just the upper left quadrant of the matrix
171+
c, s, cp, sp = SampleCSValues(n, a, b, beta)
172+
dv = [i==1 ? c[n] : c[n+1-i] * sp[n+1-i] for i=1:n]
173+
ev = [-s[n+1-i]*cp[n-i] for i=1:n-1]
174+
M = Tridiagonal(zeros(n-1), dv, ev)
175+
return svdvals(full(M)) #No SVD for tridiagonal matrices... yet
176+
end
177+

src/RandomMatrices.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,9 @@ module RandomMatrices
55

66
#Classical Gaussian matrix ensembles
77
include("GaussianEnsembleSamples.jl")
8+
#Classical univariate distributions
9+
include("GaussianDensities.jl")
10+
11+
#Fast histogrammer for matrix eigenvalues
12+
include("FastHistogram.jl")
813
end

0 commit comments

Comments
 (0)