@@ -70,7 +70,8 @@ function GaussianHermiteTridiagonalMatrix(n :: Integer, beta :: FloatingPoint)
70
70
end
71
71
72
72
73
- # TODO Check normalization - I guessed this
73
+ # Generates a NxN tridiagonal Wishart matrix
74
+ # Laguerre ensemble
74
75
function GaussianLaguerreTridiagonalMatrix (m :: Integer , a :: FloatingPoint , beta :: FloatingPoint )
75
76
if a <= beta* (m- 1 )/ 2.0
76
77
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
83
84
return SymTridiagonal (diag (L)/ sqrt (m), diag (L,1 )/ sqrt (m))
84
85
end
85
86
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 (8 n- 4 )
115
+ CoordJ = zeros (8 n- 4 )
116
+ Values = zeros (8 n- 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[2 n+ i], CoordJ[2 n+ i] = n+ i, i
131
+ Values[2 n+ i] = i== 1 ? - s[n] : - s[n+ 1 - i] * sp[n+ 1 - i]
132
+ end
133
+ for i= 1 : n
134
+ CoordI[3 n+ i], CoordJ[3 n+ i] = n+ i, n+ i
135
+ Values[3 n+ 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[4 n+ i], CoordJ[4 n+ i] = i,i+ 1
140
+ Values[4 n+ i] = - s[n+ 1 - i]* cp[n- i]
141
+ end
142
+ for i= 1 : n+ 1
143
+ CoordI[5 n- 1 + i], CoordJ[5 n- 1 + i] = i+ 1 ,n+ i
144
+ Values[5 n- 1 + i] = c[n- i]* cp[n- i]
145
+ end
146
+ for i= 1 : n+ 1
147
+ CoordI[6 n- 2 + i], CoordJ[6 n- 2 + i] = n+ i,i+ 1
148
+ Values[6 n- 2 + i] = - c[n+ 1 - i]* cp[n- i]
149
+ end
150
+ for i= 1 : n+ 1
151
+ CoordI[7 n- 3 + i], CoordJ[7 n- 3 + i] = n+ i,i+ 1
152
+ Values[7 n- 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
+
0 commit comments