Skip to content

Commit 44010cf

Browse files
committed
Fixes exports and abstracts Haar random matrix types
1 parent bad41f5 commit 44010cf

File tree

3 files changed

+78
-54
lines changed

3 files changed

+78
-54
lines changed

src/HaarMeasure.jl

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
export rand, Ginibre, NeedPiecewiseCorrection, jpdfGinibre,
2+
CircularOrthogonal, CircularUnitary, CircularSymplectic
3+
import Base.rand
4+
15
# Computes samplex of real or complex Haar matrices of size nxn
26
#
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.
7+
# For beta=1,2,4, generates random orthogonal, unitary and symplectic matrices
8+
# of uniform Haar measure.
69
# These matrices are distributed with uniform Haar measure over the
710
# classical orthogonal, unitary and symplectic groups O(N), U(N) and
811
# Sp(N)~USp(2N) respectively.
@@ -12,14 +15,15 @@
1215
# This addresses an inconsistency in the Householder reflections as
1316
# implemented in most versions of LAPACK
1417
# 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)
18+
# Method 1: Multiply rows by uniform random phases
19+
# Method 2: Multiply rows by phases of diag(R)
1720
# References:
1821
# Edelman and Rao, 2005
1922
# Mezzadri, 2006, math-ph/0609050
2023
#TODO implement O(n^2) method
21-
function HaarMatrix(n::Integer, beta::Integer, doCorrection::Integer)
22-
M=GinibreMatrix(n, beta)
24+
function rand(W::UniformHaar, doCorrection::Integer)
25+
n, beta = W.N, W.beta
26+
M=rand(Ginibre(n, beta))
2327
q,r=qr(M)
2428
if doCorrection==0
2529
q
@@ -49,16 +53,15 @@ end
4953

5054
#By default, always do piecewise correction
5155
#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-
56+
#it doesn't matter, but better safe than sorry... let the user choose else
57+
rand(W::UniformHaar) = rand(W, 1)
5558

5659
#A utility method to check if the piecewise correction is needed
5760
#This checks the R part of the QR factorization; if correctly done,
5861
#the diagonals are all chi variables so are non-negative
5962
function NeedPiecewiseCorrection()
6063
n=20
61-
R=qr(randn(n,n))[2]
64+
R=qr(randn(Ginibre(2,n)))[2]
6265
return any([x<0 for x in diag(R)])
6366
end
6467

@@ -67,7 +70,12 @@ end
6770
#This ensemble lives in GL(N, F), the set of all invertible N x N matrices
6871
#over the field F
6972
#For beta=1,2,4, F=R, C, H respectively
70-
function GinibreMatrix(n::Integer, beta::Integer)
73+
immutable Ginibre <: ContinuousMatrixDistribution
74+
beta::Float64
75+
N::Integer
76+
end
77+
78+
function rand(W::Ginibre)
7179
if beta==1
7280
randn(n,n)
7381
elseif beta==2
@@ -87,6 +95,28 @@ function jpdfGinibre{z<:Complex}(Z::AbstractMatrix{z})
8795
pi^(size(Z,1)^2)*exp(-trace(Z'*Z))
8896
end
8997

98+
#Dyson Circular orthogonal, unitary and symplectic ensembles
99+
immutable CircularOrthogonal
100+
N :: Int64
101+
end
102+
103+
function rand(M::CircularOrthogonal)
104+
U = rand(Ginibre(2, M.N))
105+
U * U'
106+
end
107+
108+
immutable CircularUnitary
109+
N :: Int64
110+
end
111+
112+
rand(M::CircularUnitary) = rand(Ginibre(2, M.N))
113+
114+
immutable CircularSymplectic
115+
N :: Int64
116+
end
117+
118+
rand(M::CircularSymplectic) = error("Not implemented")
119+
90120
#TODO maybe, someday
91121
#Haar measure on U(N) in terms of local coordinates
92122
#Zyczkowski and Kus, Random unitary matrices, J. Phys. A: Math. Gen. 27,

src/Haar.jl renamed to src/HaarSymbolic.jl

Lines changed: 30 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,28 @@
11
using GSL
22
using Catalan
33

4+
export permutations_in_Sn, compose, cycle_structure, data, part #Functions working with partitions and permutations
5+
UniformHaar, expectation, expectationtrace, WeingartenUnitary
6+
7+
#Functions working with partitions and permutations
8+
# TODO Migrate these functions to Catalan
9+
10+
#Iterate over partitions of n in lexicographic order
11+
function part(n::Integer)
12+
if n==0 produce([]) end
13+
if n<=0 return end
14+
for p in @task part(n-1)
15+
p = [p; 1]
16+
produce(p)
17+
p = p[1:end-1]
18+
if length(p) == 1 || (length(p)>1 && p[end]<p[end-1])
19+
p[end] += 1
20+
produce(p)
21+
p[end] -= 1
22+
end
23+
end
24+
end
25+
426
function permutations_in_Sn(n::Integer)
527
P = permutation_calloc(n)
628
while true
@@ -42,7 +64,11 @@ end
4264
data(P::Ptr{gsl_permutation}) = [convert(Int64, x)+1 for x in
4365
pointer_to_array(permutation_data(P), (convert(Int64, permutation_size(P)) ,))]
4466

45-
67+
immutable UniformHaar <: ContinuousMatrixDistribution
68+
beta::Float64
69+
N::Integer
70+
end
71+
4672
# In random matrix theory one often encounters expressions of the form
4773
#
4874
#X = Q * A * Q' * B
@@ -58,7 +84,7 @@ data(P::Ptr{gsl_permutation}) = [convert(Int64, x)+1 for x in
5884
#of matrices over the symmetric group that Q is uniform Haar over.
5985
#It takes an expression consisting of a product of matrices and replaces it
6086
#with an evaluated symbolic expression which is the expectation.
61-
function Expectation(X::Expr)
87+
function expectation(X::Expr)
6288
if X.head != :call
6389
error(string("Unexpected type of expression: ", X.head))
6490
end
@@ -238,6 +264,8 @@ function Expectation(X::Expr)
238264
eval(X)
239265
end
240266

267+
expectationtrace(X::Expr)=trace(expectation(X))
268+
241269
#Computes the Weingarten function for permutations
242270
function WeingartenUnitary(P::Ptr{gsl_permutation})
243271
C = cycle_structure(P)
@@ -262,43 +290,3 @@ function WeingartenUnitary(P::partition)
262290
thesum
263291
end
264292

265-
#Iterate over partitions of n in lexicographic order
266-
function part(n::Integer)
267-
if n==0 produce([]) end
268-
if n<=0 return end
269-
for p in @task part(n-1)
270-
p = [p; 1]
271-
produce(p)
272-
p = p[1:end-1]
273-
if length(p) == 1 || (length(p)>1 && p[end]<p[end-1])
274-
p[end] += 1
275-
produce(p)
276-
p[end] -= 1
277-
end
278-
end
279-
end
280-
281-
###############
282-
# SANDBOX
283-
N=5
284-
A=randn(N,N)
285-
B=randn(N,N)
286-
type HaarMatrix
287-
beta::Real
288-
end
289-
Q = HaarMatrix(2)
290-
291-
println("Case 1")
292-
println("E(A*B) = ", Expectation(:(A*B)))
293-
println("A*B/N = ", A*B)
294-
295-
println("Case 2")
296-
println("tr(A)*tr(B)/N = ", trace(A)*trace(B)/N)
297-
println(trace(B)*A)
298-
println("E(A*Q*B*Q') = ", Expectation(:(A*Q*B*Q')))
299-
println("E.tr(A*Q*B*Q') = ", trace(Expectation(:(A*Q*B*Q'))))
300-
301-
println("Case 3")
302-
println(Expectation(:(A*B)) == A*B)
303-
println("E(A*Q*B*Q'*A*Q*B*Q') = ", Expectation(:(A*Q*B*Q'*A*Q*B*Q')))
304-

src/RandomMatrices.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
require("Distributions")
2+
require("Catalan")
3+
require("GSL")
24

35
module RandomMatrices
46
importall Distributions
@@ -18,4 +20,8 @@ module RandomMatrices
1820

1921
#Formal power series
2022
include("FormalPowerSeries.jl")
23+
24+
#Symbolic integrator of uniform Haar matrices
25+
include("HaarSymbolic.jl")
26+
include("HaarMeasure.jl")
2127
end #module

0 commit comments

Comments
 (0)