Skip to content

Commit 357c48e

Browse files
committed
Modernize code and tests
1 parent 16c414b commit 357c48e

File tree

8 files changed

+93
-85
lines changed

8 files changed

+93
-85
lines changed

LICENSE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The RandomMatrices Julia module is licensed under the MIT License:
22

3-
> Copyright (c) 2013-2014: Jiahao Chen, Alan Edelman, Jameson Nash, Sheehan
3+
> Copyright (c) 2013-2015: Jiahao Chen, Alan Edelman, Jameson Nash, Sheehan
44
> Olver and other contributors
55
>
66
> Permission is hereby granted, free of charge, to any person obtaining

REQUIRE

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
julia 0.3+
2-
Compat
3-
Combinatorics
1+
julia 0.4
2+
Combinatorics 0.2
43
Docile
54
Distributions
65
ODE

src/FormalPowerSeries.jl

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -193,12 +193,12 @@ end
193193
#TODO implement the FFT-based algorithm of one of the following
194194
# doi:10.1109/TAC.1984.1103499
195195
# https://cs.uwaterloo.ca/~glabahn/Papers/tamir-george-1.pdf
196-
function reciprocal{T}(P::FormalPowerSeries{T}, n :: Integer)
197-
n<0 ? error(sprintf("Invalid inverse truncation length %d requested", n)) : true
196+
function reciprocal{T}(P::FormalPowerSeries{T}, n::Integer)
197+
n<0 && error(sprintf("Invalid inverse truncation length %d requested", n))
198198

199199
a = tovector(P, 0:n-1) #Extract original coefficients in vector
200-
a[1]==0 ? (error("Inverse does not exist")) : true
201-
inv_a1 = T<:Number ? 1.0/a[1] : inv(a[1])
200+
a[1]==0 && error("Inverse does not exist")
201+
inv_a1 = inv(a[1])
202202

203203
b = zeros(n) #Inverse
204204
b[1] = inv_a1
@@ -210,13 +210,13 @@ end
210210

211211
#Derivative of fps [H. Sec.1.4, p.18]
212212
function derivative{T}(P::FormalPowerSeries{T})
213-
c = Dict{BigInt, T}()
214-
for (k,v) in P.c
215-
if k != 0 && v != 0
216-
c[k-1] = k*v
213+
c = Dict{BigInt, T}()
214+
for (k,v) in P.c
215+
if k != 0 && v != 0
216+
c[k-1] = k*v
217+
end
217218
end
218-
end
219-
FormalPowerSeries{T}(c)
219+
FormalPowerSeries{T}(c)
220220
end
221221

222222
#[H, Sec.1.4, p.18]
@@ -233,17 +233,17 @@ end
233233

234234
# Power of fps [H, Sec.1.5, p.35]
235235
function ^{T}(P::FormalPowerSeries{T}, n :: Integer)
236-
if n == 0
237-
return FormalPowerSeries{T}([convert(T, 1)])
238-
elseif n > 1
239-
#The straightforward recursive way
240-
return P^(n-1) * P
241-
#TODO implement the non-recursive formula
242-
elseif n==1
243-
return P
244-
else
245-
error(@sprintf("I don't know what to do for power n = %d", n))
246-
end
236+
if n == 0
237+
return FormalPowerSeries{T}([one(T)])
238+
elseif n > 1
239+
#The straightforward recursive way
240+
return P^(n-1) * P
241+
#TODO implement the non-recursive formula
242+
elseif n==1
243+
return P
244+
else
245+
error("I don't know what to do for power n = $n")
246+
end
247247
end
248248

249249

src/HaarMeasure.jl

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
export NeedPiecewiseCorrection
2-
3-
4-
# Computes samplex of real or complex Haar matrices of size nxn
1+
# Computes samples of real or complex Haar matrices of size nxn
52
#
63
# For beta=1,2,4, generates random orthogonal, unitary and symplectic matrices
7-
# of uniform Haar measure.
4+
# of uniform Haar measure.
85
# These matrices are distributed with uniform Haar measure over the
96
# classical orthogonal, unitary and symplectic groups O(N), U(N) and
107
# Sp(N)~USp(2N) respectively.
@@ -20,13 +17,16 @@ export NeedPiecewiseCorrection
2017
# Edelman and Rao, 2005
2118
# Mezzadri, 2006, math-ph/0609050
2219
#TODO implement O(n^2) method
23-
function rand(W::Haar, n::Integer, doCorrection::Integer)
20+
#By default, always do piecewise correction
21+
#For most applications where you use the HaarMatrix as a similarity transform
22+
#it doesn't matter, but better safe than sorry... let the user choose else
23+
function rand(W::Haar, n::Int, doCorrection::Int=1)
2424
beta = W.beta
2525
M=rand(Ginibre(beta,n))
2626
q,r=qr(M)
2727
if doCorrection==0
2828
q
29-
elseif doCorrection==1
29+
elseif doCorrection==1
3030
if beta==1
3131
L = sign(rand(n).-0.5)
3232
elseif beta==2
@@ -50,11 +50,6 @@ function rand(W::Haar, n::Integer, doCorrection::Integer)
5050
end
5151
end
5252

53-
#By default, always do piecewise correction
54-
#For most applications where you use the HaarMatrix as a similarity transform
55-
#it doesn't matter, but better safe than sorry... let the user choose else
56-
rand(W::Haar,n::Integer) = rand(W,n, 1)
57-
5853
#A utility method to check if the piecewise correction is needed
5954
#This checks the R part of the QR factorization; if correctly done,
6055
#the diagonals are all chi variables so are non-negative
@@ -94,8 +89,9 @@ function Stewart(::Type{Float64}, n)
9489
for i = 0:n-2
9590
larfg!(n - i, pβ + (n + 1)*8i, pH + (n + 1)*8i, 1, pτ + 8i)
9691
end
97-
LinAlg.QRPackedQ(H,τ)
92+
Base.LinAlg.QRPackedQ(H,τ)
9893
end
94+
9995
function Stewart(::Type{Complex128}, n)
10096
τ = Array(Complex128, n)
10197
H = complex(randn(n, n), randn(n,n))
@@ -107,7 +103,17 @@ function Stewart(::Type{Complex128}, n)
107103
for i = 0:n-2
108104
larfg!(n - i, pβ + (n + 1)*16i, pH + (n + 1)*16i, 1, pτ + 16i)
109105
end
110-
LinAlg.QRPackedQ(H,τ)
106+
Base.LinAlg.QRPackedQ(H,τ)
111107
end
112108

109+
export randfast
110+
function randfast(W::Haar, n::Int)
111+
if W.beta==1
112+
Stewart(Float64, n)
113+
elseif W.beta==2
114+
Stewart(Complex128, n)
115+
else
116+
error("beta = $beta not implemented")
117+
end
118+
end
113119

src/InvariantEnsembles.jl

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ function adaptiveie(w,μ0,α,β,d)
139139
end
140140

141141
#Reads in recurrence relationship and constructs OPs
142-
function InvariantEnsemble(str::@compat(AbstractString),V::Function,d,n::Integer)
142+
function InvariantEnsemble(str::AbstractString,V::Function,d,n::Integer)
143143
file = Pkg.dir("RandomMatrices/data/CoefficientDatabase/" * str * "/" * string(n))
144144
μ0=readdlm(file * "norm.csv")[1]
145145
A=readdlm(file * "rc.csv",',')
@@ -151,7 +151,7 @@ end
151151

152152

153153
# For constructing InvariantEnsembles that do not scale with n
154-
function InvariantEnsembleUnscaled(str::@compat(AbstractString),V::Function,d,n::Integer)
154+
function InvariantEnsembleUnscaled(str::AbstractString,V::Function,d,n::Integer)
155155
file = Pkg.dir("RandomMatrices/data/CoefficientDatabaseUnscaled/" * str * "/")
156156
μ0=readdlm(file * "norm.csv")[1]
157157
A=readdlm(file * "rc.csv",',')
@@ -166,7 +166,7 @@ end
166166

167167
#Decides whether to use built in recurrence or read it in
168168
# Also contains ensemble data
169-
function InvariantEnsemble(str::@compat(AbstractString),n::Integer)
169+
function InvariantEnsemble(str::AbstractString,n::Integer)
170170
if(str == "GUE")
171171
InvariantEnsemble(str,x->x.^2,[-3.,3.],n)
172172
elseif(str == "Quartic")
@@ -204,7 +204,8 @@ function iekernel(q::Array{Float64,2},d,plan::Function)
204204
end
205205

206206

207-
samplespectra(str::@compat(AbstractString),n::Integer,m::Integer)=samplespectra(InvariantEnsemble(str,n),m)
207+
<<<<<<< 16c414b28d81a04c589c8ec5e66aa724f4e110f0
208+
samplespectra(str::AbstractString,n::Integer,m::Integer)=samplespectra(InvariantEnsemble(str,n),m)
208209

209210

210211
# Sample eigenvalues of invariant ensemble, m times

src/RandomMatrices.jl

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@ using Combinatorics,Compat
44

55
import Distributions: ContinuousMatrixDistribution
66

7-
if VERSION < v"0.4-"
8-
using Docile
9-
end
10-
117
import Base.rand
128

139
#If the GNU Scientific Library is present, turn on additional functionality.
@@ -24,17 +20,15 @@ export bidrand, #Generate random bidiagonal matrix
2420
eigvalrand, #Generate random set of eigenvalues
2521
eigvaljpdf #Eigenvalue joint probability density
2622

27-
typealias Dim2 @compat(Tuple{Int,Int}) #Dimensions of a rectangular matrix
23+
typealias Dim2 Tuple{Int, Int} #Dimensions of a rectangular matrix
2824

2925
#Classical Gaussian matrix ensembles
3026
include("GaussianEnsembles.jl")
3127

32-
3328
# Classical univariate distributions
3429
include("densities/Semicircle.jl")
3530
include("densities/TracyWidom.jl")
3631

37-
3832
# Ginibre
3933
include("Ginibre.jl")
4034

@@ -58,7 +52,7 @@ include("StatisticalTests.jl")
5852
include("StochasticProcess.jl")
5953

6054
#Invariant ensembles
61-
if filemode(Pkg.dir("ApproxFun")) != 0
55+
if Pkg.installed("ApproxFun")!== nothing
6256
include("InvariantEnsembles.jl")
6357
end
6458

test/FormalPowerSeries.jl

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,74 @@
1+
using RandomMatrices
2+
using Base.Test
3+
14
# Excursions in formal power series (fps)
2-
MaxSeriesSize=10
3-
MaxRange = 50
4-
MatrixSize=15
5+
MaxSeriesSize=8
6+
MaxRange = 20
7+
MatrixSize=10
58
TT=Int64
69

7-
(n1, n2, n3) = round(Int,rand(3)*MaxSeriesSize)
10+
(n1, n2, n3) = rand(1:MaxSeriesSize, 3)
811

9-
X = FormalPowerSeries{TT}(round(Int,rand(n1)*MaxRange))
10-
Y = FormalPowerSeries{TT}(round(Int,rand(n2)*MaxRange))
11-
Z = FormalPowerSeries{TT}(round(Int,rand(n3)*MaxRange))
12+
X = FormalPowerSeries{TT}(rand(1:MaxRange, n1))
13+
Y = FormalPowerSeries{TT}(rand(1:MaxRange, n2))
14+
Z = FormalPowerSeries{TT}(rand(1:MaxRange, n3))
1215

13-
c = round(Int,rand()*MatrixSize) #Size of matrix representation to generate
16+
c = rand(1:MatrixSize) #Size of matrix representation to generate
1417

15-
nzeros = round(Int,rand()*MaxSeriesSize)
16-
@assert X == trim(X)
18+
nzeros = rand(1:MaxSeriesSize)
19+
@test X == trim(X)
1720
XX = deepcopy(X)
1821
for i=1:nzeros
19-
idx = round(Int,rand()*MaxRange)
22+
idx = rand(1:MaxRange)
2023
if !haskey(XX.c, idx)
2124
XX.c[idx] = convert(TT, 0)
2225
end
2326
end
24-
@assert trim(XX) == X
27+
@test trim(XX) == X
2528

2629
#Test addition, p.15, (1.3-4)
27-
@assert X+X == 2X
28-
@assert X+Y == Y+X
29-
@assert MatrixForm(X+Y,c) == MatrixForm(X,c)+MatrixForm(Y,c)
30+
@test X+X == 2X
31+
@test X+Y == Y+X
32+
@test MatrixForm(X+Y,c) == MatrixForm(X,c)+MatrixForm(Y,c)
3033

3134
#Test subtraction, p.15, (1.3-4)
32-
@assert X-X == 0X
33-
@assert X-Y == -(Y-X)
34-
@assert MatrixForm(X-Y,c) == MatrixForm(X,c)-MatrixForm(Y,c)
35+
@test X-X == 0X
36+
@test X-Y == -(Y-X)
37+
@test MatrixForm(X-Y,c) == MatrixForm(X,c)-MatrixForm(Y,c)
3538

3639
#Test multiplication, p.15, (1.3-5)
37-
@assert X*Y == Y*X
38-
@assert MatrixForm(X*X,c) == MatrixForm(X,c)*MatrixForm(X,c)
39-
@assert MatrixForm(X*Y,c) == MatrixForm(X,c)*MatrixForm(Y,c)
40-
@assert MatrixForm(Y*X,c) == MatrixForm(Y,c)*MatrixForm(X,c)
41-
@assert MatrixForm(Y*Y,c) == MatrixForm(Y,c)*MatrixForm(Y,c)
40+
@test X*Y == Y*X
41+
@test MatrixForm(X*X,c) == MatrixForm(X,c)*MatrixForm(X,c)
42+
@test MatrixForm(X*Y,c) == MatrixForm(X,c)*MatrixForm(Y,c)
43+
@test MatrixForm(Y*X,c) == MatrixForm(Y,c)*MatrixForm(X,c)
44+
@test MatrixForm(Y*Y,c) == MatrixForm(Y,c)*MatrixForm(Y,c)
4245

43-
@assert X.*Y == Y.*X
46+
@test X.*Y == Y.*X
4447

4548
#The reciprocal series has associated matrix that is the matrix inverse
4649
#of the original series
4750
#Force reciprocal to exist
4851
X.c[0] = 1
49-
discrepancy = (norm(inv(float(MatrixForm(X,c)))[1, :]'[:, 1] - tovector(reciprocal(X, c),0:c-1)))
50-
if discrepancy > c*sqrt(eps())
51-
error(@sprintf("Error %f exceeds tolerance %f", discrepancy, c*sqrt(eps())))
52+
discrepancy = (norm(inv(float(MatrixForm(X,c)))[1, :]'[:, 1] - tovector(reciprocal(X, c), 0:c-1)))
53+
tol = c*√eps()
54+
if discrepancy > tol
55+
error(string("Error ", discrepancy, " exceeds tolerance ", tol))
5256
end
53-
#@assert norm(inv(float(MatrixForm(X,c)))[1, :]'[:, 1] - tovector(reciprocal(X, c),c)) < c*sqrt(eps())
57+
#@test norm(inv(float(MatrixForm(X,c)))[1, :]'[:, 1] - tovector(reciprocal(X, c),c)) < c*sqrt(eps())
5458

5559
#Test differentiation
5660
XX = derivative(X)
5761
for (k, v) in XX.c
58-
k==0 ? continue : true
59-
@assert X.c[k+1] == v/(k+1)
62+
k==0 && continue
63+
@test X.c[k+1] == v/(k+1)
6064
end
6165

6266
#Test product rule [H, Sec.1.4, p.19]
63-
@assert derivative(X*Y) == derivative(X)*Y + X*derivative(Y)
67+
@test derivative(X*Y) == derivative(X)*Y + X*derivative(Y)
6468

6569
#Test right distributive law of composition [H, Sec.1.6, p.38]
66-
@assert compose(X,Z)*compose(Y,Z) == compose(X*Y, Z)
70+
@test compose(X,Z)*compose(Y,Z) == compose(X*Y, Z)
6771

6872
#Test chain rule [H, Sec.1.6, p.40]
69-
@assert derivative(compose(X,Y)) == compose(derivative(X),Y)*derivative(Y)
73+
@test derivative(compose(X,Y)) == compose(derivative(X),Y)*derivative(Y)
74+

test/Haar.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
using RandomMatrices
2+
using Base.Test
3+
14
if isdefined(:_HAVE_GSL)
25
N=5
36
A=randn(N,N)
@@ -7,7 +10,7 @@ Q=UniformHaar(2, N)
710
#Test case where there are no symbolic Haar matrices
811
@test_approx_eq eval(expectation(N, :Q, :(A*B))) A*B
912
#Test case where there is one pair of symbolic Haar matrices
10-
@test_approx_eq eval(expectedtrace(N, :Q, :(A*Q*B*Q'))) trace(A)*trace(B)/N
13+
@test_approx_eq eval(expectedtrace(N, :Q, :(A*Q*B*Q'))) trace(A)*trace(B)/N
1114

1215
println("Case 3")
1316
println("E(A*Q*B*Q'*A*Q*B*Q') = ", eval(expectation(N, :Q, :(A*Q*B*Q'*A*Q*B*Q'))))

0 commit comments

Comments
 (0)