Skip to content

Commit b380f46

Browse files
committed
Merge pull request #3 from jiahao/master
merge back master
2 parents caec3f9 + b07d8c4 commit b380f46

File tree

9 files changed

+183
-48
lines changed

9 files changed

+183
-48
lines changed

.travis.yml

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,13 @@
1-
language: cpp
2-
compiler:
3-
- clang
1+
language: julia
2+
os:
3+
- osx
4+
- linux
5+
julia:
6+
- release
7+
- nightly
48
notifications:
59
email: false
6-
env:
7-
- JULIAVERSION="juliareleases"
8-
- JULIAVERSION="julianightlies"
9-
before_install:
10-
- sudo add-apt-repository ppa:staticfloat/julia-deps -y
11-
- sudo add-apt-repository ppa:staticfloat/${JULIAVERSION} -y
12-
- sudo apt-get update -qq -y
13-
- sudo apt-get install libpcre3-dev julia -y
14-
- git config --global user.name "Travis User"
15-
- git config --global user.email "[email protected]"
16-
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
1710
script:
18-
- julia -e 'Pkg.init(); Pkg.clone(pwd())'
19-
- julia -e 'Pkg.test("RandomMatrices", coverage=true)'
20-
after_success:
21-
- julia -e 'cd(Pkg.dir("RandomMatrices")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())'
11+
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
12+
- julia -e 'Pkg.clone(pwd()); Pkg.build("RandomMatrices"); Pkg.test("RandomMatrices"; coverage=true)';
13+
- julia -e 'cd(Pkg.dir("RandomMatrices")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())';

README.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ RandomMatrices.jl
33

44
Random matrix package for [Julia](http://julialang.org).
55

6+
[![RandomMatrices on Julia release](http://pkg.julialang.org/badges/RandomMatrices_release.svg)](http://pkg.julialang.org/?pkg=RandomMatrices&ver=release)
7+
[![RandomMatrices on Julia nightly](http://pkg.julialang.org/badges/RandomMatrices_nightly.svg)](http://pkg.julialang.org/?pkg=RandomMatrices&ver=nightly)
8+
[![Build Status](https://travis-ci.org/jiahao/RandomMatrices.jl.png?branch=master)](https://travis-ci.org/jiahao/RandomMatrices.jl)
9+
[![Coverage Status](https://coveralls.io/repos/jiahao/RandomMatrices.jl/badge.svg?branch=master)](https://coveralls.io/r/jiahao/RandomMatrices.jl?branch=master)
10+
611
This extends the [Distributions](https://github.com/JuliaStats/Distributions.jl)
712
package to provide methods for working with matrix-valued random variables,
813
a.k.a. random matrices. State of the art methods for computing random matrix
@@ -11,11 +16,6 @@ samples and their associated distributions are provided.
1116
The names of the various ensembles can vary widely across disciplines. Where possible,
1217
synonyms are listed.
1318

14-
[![Build Status](https://travis-ci.org/jiahao/RandomMatrices.jl.png?branch=master)](https://travis-ci.org/jiahao/RandomMatrices.jl)
15-
[![RandomMatrices](http://pkg.julialang.org/badges/RandomMatrices_release.svg)](http://pkg.julialang.org/?pkg=RandomMatrices&ver=release)
16-
[![RandomMatrices](http://pkg.julialang.org/badges/RandomMatrices_nightly.svg)](http://pkg.julialang.org/?pkg=RandomMatrices&ver=nightly)
17-
[![Coverage Status](https://img.shields.io/coveralls/jiahao/RandomMatrices.jl.svg)](https://img.shields.io/coveralls/jiahao/RandomMatrices.jl.svg)
18-
1919
Additional functionality is provided when these optional packages are installed:
2020
- Symbolic manipulation of Haar matrices with [GSL.jl](https://github.com/jiahao/GSL.jl)
2121
- Invariant ensembles with [ApproxFun.jl](https://github.com/dlfivefifty/ApproxFun.jl)
@@ -71,7 +71,7 @@ Hermite, Laguerre(m) and Jacobi(m1, m2) ensembles.
7171
`GaussianLaguerreTridiagonalMatrix(n, m, beta)`,
7272
`GaussianJacobiSparseMatrix(n, m1, m2, beta)`
7373
each construct a sparse `n`x`n` matrix for the corresponding matrix ensemble
74-
for arbitrary positive finite `beta`.
74+
for arbitrary positive finite `beta`.
7575
`GaussianHermiteTridiagonalMatrix(n, Inf)` is also allowed.
7676
These sampled matrices have the same eigenvalues as above but are much faster
7777
to diagonalize oweing to their sparsity. They also extend Dyson's threefold
@@ -87,7 +87,7 @@ Hermite, Laguerre(m) and Jacobi(m1, m2) ensembles.
8787
is applied to the raw QR decomposition. By default, `correction=1` (Edelman's correction) is
8888
used. Other valid values are `0` (no correction) and `2` (Mezzadri's correction).
8989
- `NeedsPiecewiseCorrection()` implements a simple test to see if a correction is necessary.
90-
90+
9191
- `InvariantEnsemble(str,n)`
9292
Generates a unitary invariant ensemble, where str determines the
9393
potential of the ensemble, see below.
@@ -151,15 +151,15 @@ Provides finite-dimensional matrix representations of stochastic operators.
151151
In the following, `dt` is the time interval being discretized over and `t_end` is the final time.
152152

153153
- `BrownianProcess(dt, t_end)` generates a vector corresponding to a Brownian random walk starting
154-
from time `t=0` and position `x=0`
155-
- `WhiteNoiceProcess(dt, t_end)` generates a vector corresponding to white noise.
154+
from time `t=0` and position `x=0`
155+
- `WhiteNoiseProcess(dt, t_end)` generates a vector corresponding to white noise.
156156
- `StochasticAiryProcess(dt, t_end, beta)` generates the largest eigenvalue corresponding to the
157157
stochastic Airy process with real positive `beta`. This is known to be distributed in the `t_end -> Inf`
158158
limit to the `beta`-Tracy-Widom law.
159-
159+
160160
# Invariant ensembles
161161

162-
`InvariantEnsemble(str,n)` supports n x n unitary invariant ensemble
162+
`InvariantEnsemble(str,n)` supports n x n unitary invariant ensemble
163163
with distribution
164164

165165
`exp(- Tr Q(M)) dM`

REQUIRE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
julia 0.3
22
Combinatorics
3+
Docile
34
Distributions
45
ODE

demos/book/8/randomgrowth.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ function random_growth(M, N, q)
77

88
G[1,1] = true
99
# update the possible sets
10-
imagesc((0,N), (M,0), G)
10+
display(imagesc((0,N), (M,0), G))
1111
for t = 1:T
1212
sets = next_possible_squares(G)
1313
## Highlights all the possible squares
1414
for i = 1:length(sets)
1515
idx = sets[i]::(Int,Int)
1616
G[idx[1], idx[2]] = 0.25
1717
end
18-
imagesc((0,N), (M,0), G)
18+
display(imagesc((0,N), (M,0), G))
1919
sleep(.01)
2020

2121
## Actual growth
@@ -26,12 +26,12 @@ function random_growth(M, N, q)
2626
G[idx[1], idx[2]] = ison
2727
end
2828
end
29-
imagesc((0,N), (M,0), G)
29+
display(imagesc((0,N), (M,0), G))
3030
G[G .== 0.5] = 1
3131
G[G .== 0.25] = 0
3232
sleep(.01)
3333
end
34-
G
34+
return G
3535
end
3636

3737
function next_possible_squares(G)

demos/book/8/randomgrowth2.jl

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
#randomgrowth2.jl
2-
using Winston
2+
using PyPlot
33
using ODE
4-
include("../1/gradient.jl")
54

65
function randomgrowth2()
76
num_trials = 2000
87
g = 1
98
q = 0.7
10-
Ns = 80 # [50, 100, 200]
9+
Ns = 80
10+
# Ns = [50, 100, 200]
11+
clf()
1112
# [-1.771086807411 08131947928329]
1213
# Gap = c d^N
1314
for jj = 1:length(Ns)
@@ -23,24 +24,25 @@ function randomgrowth2()
2324
end
2425
C = (B - N*om(g,q)) / (sigma_growth(g,q)*N^(1/3))
2526
d = 0.2
26-
x, n = hist(C - exp(-N*0.0025 - 3), -6:d:4)
27-
p = FramedPlot()
28-
h = Histogram(n/(d*num_trials), step(x))
29-
h.x0 = first(x)
30-
add(p, h)
27+
subplot(1,length(Ns),jj)
28+
plt.hist(C - exp(-N*0.0025 - 3), normed = true)
29+
xlim(-6, 4)
3130

3231
## Theory
3332
t0 = 4
3433
tn = -6
3534
dx = 0.005
3635
deq = (t, y) -> [y[2]; t*y[1]+2*y[1]^3; y[4]; y[1]^2]
3736
y0 = [airy(t0); airy(1,t0); 0; airy(t0)^2] # boundary conditions
38-
t, y = ode23(deq, t0:-dx:tn, y0) # solve
39-
F2 = exp(-y[:,3]) # the distribution
37+
t, y = ode23(deq, y0, t0:-dx:tn) # solve
38+
F2 = Float64[exp(-y[i][3]) for i = 1:length(y)] # the distribution
4039
f2 = gradient(F2, t) # the density
41-
42-
add(p, Curve(t, f2, "color", "red", "linewidth", 3))
43-
Winston.display(p)
40+
41+
# add(p, Curve(t, f2, "color", "red", "linewidth", 3))
42+
# Winston.display(p)
43+
subplot(1,length(Ns),jj)
44+
plot(t, f2, "r", linewidth = 3)
45+
ylim(0, 0.6)
4446
println(mean(C))
4547
end
4648
end
@@ -49,7 +51,7 @@ function G(N, M, q)
4951
# computes matrix G[N,M] for a given q
5052
GG = floor(log(rand(N,M))/log(q))
5153
#float(rand(N,M) < q)
52-
54+
5355
# Compute the edges: the boundary
5456
for ii = 2:N
5557
GG[ii, 1] = GG[ii, 1] + GG[ii-1, 1]
@@ -64,7 +66,7 @@ function G(N, M, q)
6466
## Plot
6567
# imagesc((0,N),(M,0),GG)
6668
# sleep(.01)
67-
69+
6870
return GG[N, M]
6971
end
7072

src/HaarMeasure.jl

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,44 @@ end
7070
#Zyczkowski and Kus, Random unitary matrices, J. Phys. A: Math. Gen. 27,
7171
#4235–4245 (1994).
7272

73+
### Stewarts algorithm for n^2 orthogonal random matrix
74+
using Base.LinAlg: BlasInt
75+
for (s, elty) in (("dlarfg_", Float64),
76+
("zlarfg_", Complex128))
77+
@eval begin
78+
function larfg!(n::Int, α::Ptr{$elty}, x::Ptr{$elty}, incx::Int, τ::Ptr{$elty})
79+
ccall(($(Base.blasfunc(s)), Base.liblapack_name), Void,
80+
(Ptr{BlasInt}, Ptr{$elty}, Ptr{$elty}, Ptr{BlasInt}, Ptr{$elty}),
81+
&n, α, x, &incx, τ)
82+
end
83+
end
84+
end
85+
86+
function Stewart(::Type{Float64}, n)
87+
τ = Array(Float64, n)
88+
H = randn(n, n)
89+
90+
= pointer(τ)
91+
= pointer(H)
92+
pH = pointer(H, 2)
93+
94+
for i = 0:n-2
95+
larfg!(n - i, pβ + (n + 1)*8i, pH + (n + 1)*8i, 1, pτ + 8i)
96+
end
97+
LinAlg.QRPackedQ(H,τ)
98+
end
99+
function Stewart(::Type{Complex128}, n)
100+
τ = Array(Complex128, n)
101+
H = complex(randn(n, n), randn(n,n))
102+
103+
= pointer(τ)
104+
= pointer(H)
105+
pH = pointer(H, 2)
106+
107+
for i = 0:n-2
108+
larfg!(n - i, pβ + (n + 1)*16i, pH + (n + 1)*16i, 1, pτ + 16i)
109+
end
110+
LinAlg.QRPackedQ(H,τ)
111+
end
112+
113+

src/RandomMatrices.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ module RandomMatrices
22
importall Distributions
33
using Combinatorics
44

5+
if VERSION < v"0.4-"
6+
using Docile
7+
end
8+
59
import Base.rand
610

711
#If the GNU Scientific Library is present, turn on additional functionality.
@@ -32,6 +36,9 @@ include("densities/TracyWidom.jl")
3236
# Ginibre
3337
include("Ginibre.jl")
3438

39+
# determinantal point processes
40+
include("dpp.jl")
41+
3542
#Generating matrices of Haar measure
3643
include("Haar.jl")
3744
include("HaarMeasure.jl")

src/dpp.jl

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Random samples from determinantal point processes
2+
3+
@doc doc"""
4+
Computes a random sample from the determinantal point process defined by the
5+
spectral factorization object `L`.
6+
7+
Inputs:
8+
9+
`L`: `Eigen` factorization object of an N x N matrix
10+
11+
Output:
12+
13+
`Y`: A `Vector{Int}` with entries in [1:N].
14+
15+
References:
16+
17+
Algorithm 18 of \cite{HKPV05}, as described in Algorithm 1 of \cite{KT12}.
18+
19+
@article{HKPV05,
20+
author = {Hough, J Ben and Krishnapur, Manjunath and Peres, Yuval and Vir\'{a}g, B\'{a}lint},
21+
doi = {10.1214/154957806000000078},
22+
journal = {Probability Surveys},
23+
pages = {206--229},
24+
title = {Determinantal Processes and Independence},
25+
volume = {3},
26+
year = {2005}
27+
archivePrefix = {arXiv},
28+
eprint = {0503110},
29+
}
30+
31+
@article{KT12,
32+
author = {Kulesza, Alex and Taskar, Ben},
33+
doi = {10.1561/2200000044},
34+
journal = {Foundations and Trends in Machine Learning},
35+
number = {2-3},
36+
pages = {123--286},
37+
title = {Determinantal Point Processes for Machine Learning},
38+
volume = {5},
39+
year = {2012},
40+
archivePrefix = {arXiv},
41+
eprint = {1207.6083},
42+
}
43+
""" ->
44+
function rand{S<:Real,T}(L::Base.LinAlg.Eigen{S,T})
45+
N = length(L.values)
46+
J = Int[]
47+
for n=1:N
48+
λ = L.values[n]
49+
rand() < λ/+1) && push!(J, n)
50+
end
51+
52+
V = L.vectors[:, J]
53+
Y = Int[]
54+
nV = size(V, 2)
55+
while true
56+
# Select i from 𝒴=[1:N] (ground set) with probabilities
57+
# Pr(i) = 1/|V| Σ_{v∈V} (v⋅eᵢ)²
58+
59+
#Compute selection probabilities
60+
Pr = zeros(N)
61+
for i=1:N
62+
for j=1:nV #TODO this loop is a bottleneck - why?
63+
Pr[i] += (V[i,j])^2 #ith entry of jth eigenvector
64+
end
65+
Pr[i] /= nV
66+
end
67+
@assert abs(1-sum(Pr)) < N*eps() #Check normalization
68+
69+
#Simple discrete sampler
70+
i, ρ = N, rand()
71+
for j=1:N
72+
if ρ < Pr[j]
73+
i = j
74+
break
75+
else
76+
ρ -= Pr[j]
77+
end
78+
end
79+
push!(Y, i)
80+
nV == 1 && break #Done
81+
#V = V⊥ #an orthonormal basis for the subspace of V ⊥ eᵢ
82+
V[i, :] = 0 #Project out eᵢ
83+
V = full(qrfact!(V)[:Q])[:, 1:nV-1]
84+
nV = size(V, 2)
85+
end
86+
Y
87+
end

test/Haar.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,9 @@ Q=UniformHaar(2, N)
1212
println("Case 3")
1313
println("E(A*Q*B*Q'*A*Q*B*Q') = ", eval(expectation(N, :Q, :(A*Q*B*Q'*A*Q*B*Q'))))
1414

15+
for elty in (Float64, Complex128)
16+
A = Stewart(elty, N)
17+
@test_approx_eq A'A eye(N)
18+
end
19+
1520
end #_HAVE_GSL

0 commit comments

Comments
 (0)