|
1 |
| - |
2 | 1 | # Computes samplex of real or complex Haar matrices of size nxn
|
3 |
| -function HaarMatrix(n::Integer, beta::Integer) |
| 2 | +# |
| 3 | +# For beta=1,2,4, generates random matrices from the circular |
| 4 | +# orthogonal, unitary and symplectic ensembles (COE, CUE, CSE) respectively |
| 5 | +# These are collectively known as the Dyson circular ensembles. |
| 6 | +# These matrices are distributed with uniform Haar measure over the |
| 7 | +# classical orthogonal, unitary and symplectic groups O(N), U(N) and |
| 8 | +# Sp(N)~USp(2N) respectively. |
| 9 | +# |
| 10 | +# The last parameter specifies whether or not the piecewise correction |
| 11 | +# is applied to ensure that it truly of Haar measure |
| 12 | +# This addresses an inconsistency in the Householder reflections as |
| 13 | +# implemented in most versions of LAPACK |
| 14 | +# Method 0: No correction |
| 15 | +# Method 1: Edelman correction - multiply rows by uniform random phases |
| 16 | +# Method 2: Mezzadri correction - multiply rows by phases of diag(R) |
| 17 | +# References: |
| 18 | +# Edelman and Rao, 2005 |
| 19 | +# Mezzadri, 2006, math-ph/0609050 |
| 20 | +#TODO implement O(n^2) method |
| 21 | +function HaarMatrix(n::Integer, beta::Integer, doCorrection::Integer) |
| 22 | + M=GinibreMatrix(n, beta) |
| 23 | + q,r=qr(M) |
| 24 | + if doCorrection==0 |
| 25 | + q |
| 26 | + elseif doCorrection==1 |
| 27 | + if beta==1 |
| 28 | + L = sign(rand(n)-0.5) |
| 29 | + elseif beta==2 |
| 30 | + L = exp(im*rand(n)*2pi) |
| 31 | + elseif beta==4 |
| 32 | + L = exp(im*rand(2n)*2pi) |
| 33 | + else |
| 34 | + error(string("beta = ",beta, " not implemented.")) |
| 35 | + end |
| 36 | + q*diagm(L) |
| 37 | + elseif doCorrection==2 |
| 38 | + if beta==1 |
| 39 | + L=sign(diag(r)) |
| 40 | + elseif (beta==2 || beta==4) |
| 41 | + L=diag(r) |
| 42 | + L=L./abs(L) |
| 43 | + else |
| 44 | + error(string("beta = ",beta, " not implemented.")) |
| 45 | + end |
| 46 | + q*diagm(L) |
| 47 | + end |
| 48 | +end |
| 49 | + |
| 50 | +#By default, always do piecewise correction |
| 51 | +#For most applications where you use the HaarMatrix as a similarity transform |
| 52 | +#it doesn't matter, but better safe than sorry... let the user choose |
| 53 | +HaarMatrix(n::Integer, beta::Integer) = HaarMatrix(n, beta, 1) |
| 54 | + |
| 55 | + |
| 56 | +#A utility method to check if the piecewise correction is needed |
| 57 | +#This checks the R part of the QR factorization; if correctly done, |
| 58 | +#the diagonals are all chi variables so are non-negative |
| 59 | +function NeedPiecewiseCorrection() |
| 60 | + n=20 |
| 61 | + R=qr(randn(n,n))[2] |
| 62 | + return any([x<0 for x in diag(R)]) |
| 63 | +end |
| 64 | + |
| 65 | + |
| 66 | +#Samples a matrix from the Ginibre ensemble |
| 67 | +#This ensemble lives in GL(N, F), the set of all invertible N x N matrices |
| 68 | +#over the field F |
| 69 | +#For beta=1,2,4, F=R, C, H respectively |
| 70 | +function GinibreMatrix(n::Integer, beta::Integer) |
4 | 71 | if beta==1
|
5 |
| - M=randn(n,n) |
| 72 | + randn(n,n) |
6 | 73 | elseif beta==2
|
7 |
| - M=randn(n,n)+im*randn(n,n) |
8 |
| - else |
9 |
| - error(string("beta = ",beta, " not implemented.")) |
| 74 | + randn(n,n)+im*randn(n,n) |
| 75 | + elseif beta==4 |
| 76 | + Q0=randn(n,n) |
| 77 | + Q1=randn(n,n) |
| 78 | + Q2=randn(n,n) |
| 79 | + Q3=randn(n,n) |
| 80 | + [Q0+im*Q1 Q2+im*Q3;-Q2+im*Q3 Q0-im*Q1] |
| 81 | + else |
| 82 | + error(string("beta = ", beta, " not implemented")) |
10 | 83 | end
|
11 |
| - qr(M)[1] |
12 | 84 | end
|
13 | 85 |
|
| 86 | +function jpdfGinibre{z<:Complex}(Z::AbstractMatrix{z}) |
| 87 | + pi^(size(Z,1)^2)*exp(-trace(Z'*Z)) |
| 88 | +end |
14 | 89 |
|
| 90 | +#TODO maybe, someday |
| 91 | +#Haar measure on U(N) in terms of local coordinates |
| 92 | +#Zyczkowski and Kus, Random unitary matrices, J. Phys. A: Math. Gen. 27, |
| 93 | +#4235–4245 (1994). |
15 | 94 |
|
0 commit comments