@@ -4,18 +4,21 @@ export TracyWidom
4
4
Tracy-Widom distribution
5
5
6
6
The probability distribution of the normalized largest eigenvalue of a random
7
- Hermitian matrix.
7
+ matrix with iid Gaussian matrix elements of variance 1/2 and mean 0 .
8
8
9
9
The cdf of Tracy-Widom is given by
10
10
11
11
``
12
- F_2 (s) = lim_{n→∞} Pr(√2 n^{1/6} (λₙ - √(2n) ≤ s)
12
+ F_beta (s) = lim_{n→∞} Pr(√2 n^{1/6} (λ_max - √(2n) ≤ s)
13
13
``
14
14
15
+ where beta = 1, 2, or 4 for the orthogonal, unitary, or symplectic ensembles.
16
+
15
17
References:
16
18
17
19
1. doi:10.1016/0370-2693(93)91114-3
18
20
2. doi:10.1007/BF02100489
21
+ 3. doi.org/10.1007/BF02099545
19
22
20
23
Numerical routines adapted from Alan Edelman's course notes for MIT 18.338,
21
24
Random Matrix Theory, 2016.
@@ -24,59 +27,82 @@ struct TracyWidom <: ContinuousUnivariateDistribution end
24
27
25
28
26
29
"""
27
- Probability density function of the Tracy-Widom distribution
30
+ Cumulative density function of the Tracy-Widom distribution.
31
+
32
+ Computes the Tracy-Widom distribution by Bornemann's method of evaluating
33
+ a finite dimensional approximation to the Fredholm determinant using quadrature.
28
34
29
- Computes the Tracy-Widom distribution by directly solving the
30
- Painlevé II equation using the Vern8 numerical integrator
35
+ doi.org/10.1090/S0025-5718-09-02280-7
31
36
32
37
# Arguments
33
38
* `d::TracyWidom` or `Type{TracyWidom}`: an instance of `TracyWidom` or the type itself
34
- * `t::Real`: The point at which to evaluate the pdf
35
- * `t0::Real = -8.0`: The point at which to start integrating
39
+ * `s::Real`: The point at which to evaluate the cdf
40
+ * `beta::Integer = 2`: The Dyson index defining the distribution. Takes values 1, 2, or 4
41
+ * `num_points::Integer = 25`: The number of points in the quadrature
36
42
"""
37
- function pdf (d:: TracyWidom , t:: S , t0:: S = convert (S, - 8.0 )) where {S<: Real }
38
- t≤ t0 && return 0.0
39
- t≥ 5 && return 0.0
43
+ function cdf {T<:Real} (d:: TracyWidom , s:: T ; beta:: Integer = 2 , num_points:: Integer = 25 )
44
+ beta ∈ (1 ,2 ,4 ) || throw (ArgumentError (" Beta must be 1, 2, or 4" ))
45
+ quad = gausslegendre (num_points)
46
+ _TWcdf (s, beta, quad)
47
+ end
40
48
41
- sol = _solve_painleve_ii (t0, t)
49
+ function cdf {T<: Real} (d:: Type{TracyWidom} , s:: T ; beta:: Integer = 2 , num_points:: Integer = 25 )
50
+ cdf (d (), s, beta= beta, num_points= num_points)
51
+ end
42
52
43
- ΔF2= exp (- sol[end - 1 ][3 ]) - exp (- sol[end ][3 ]) # the cumulative distribution
44
- f2= ΔF2/ (sol. t[end ]- sol. t[end - 1 ]) # the density at t
53
+ function cdf {T<:Real} (d:: TracyWidom , s_vals:: AbstractArray{T} ; beta:: Integer = 2 , num_points:: Integer = 25 )
54
+ beta ∈ (1 ,2 ,4 ) || throw (ArgumentError (" Beta must be 1, 2, or 4" ))
55
+ quad = gausslegendre (num_points)
56
+ [_TWcdf (s, beta, quad) for s in s_vals]
45
57
end
46
- pdf (d:: Type{TracyWidom} , t:: Real ) = pdf (d (), t)
47
58
48
- """
49
- Cumulative density function of the Tracy-Widom distribution
59
+ function cdf {T<:Real} (d:: Type{TracyWidom} , s_vals:: AbstractArray{T} ; beta:: Integer = 2 , num_points:: Integer = 25 )
60
+ cdf (d (), s_vals, beta= beta, num_points= num_points)
61
+ end
50
62
51
- Computes the Tracy-Widom distribution by directly solving the
52
- Painlevé II equation using the Vern8 numerical integrator
63
+ function _TWcdf {T<:Real} (s:: T , beta:: Integer , quad:: Tuple{Array{Float64,1},Array{Float64,1}} )
64
+ if beta == 2
65
+ kernel = ((ξ,η) -> _K2tilde (ξ,η,s))
66
+ return _fredholm_det (kernel, quad)
67
+ elseif beta == 1
68
+ kernel = ((ξ,η) -> _K1tilde (ξ,η,s))
69
+ return _fredholm_det (kernel, quad)
70
+ elseif beta == 4
71
+ kernel2 = ((ξ,η) -> _K2tilde (ξ,η,s* sqrt (2 )))
72
+ kernel1 = ((ξ,η) -> _K1tilde (ξ,η,s* sqrt (2 )))
73
+ F2 = _fredholm_det (kernel2, quad)
74
+ F1 = _fredholm_det (kernel1, quad)
75
+ return (F1 + F2/ F1) / 2
76
+ end
77
+ end
53
78
54
- See `pdf(::TracyWidom)` for a description of the arguments.
55
- """
56
- function cdf {S<:Real} (d :: TracyWidom , t :: S , t0 :: S = convert (S, - 8.0 ) )
57
- t ≤ t0 && return 0.0
58
- t ≥ 5 && return 1.0
59
- sol = _solve_painleve_ii (t0, t)
60
- F2 = exp ( - sol[ end ][ 3 ] )
79
+ function _fredholm_det {T<:Real} (kernel :: Function , quad :: Tuple{Array{T,1},Array{T,1}} )
80
+ nodes, weights = quad
81
+ N = length (nodes )
82
+ sqrt_weights = sqrt .(weights)
83
+ weights_matrix = kron ( transpose (sqrt_weights),sqrt_weights)
84
+ K_matrix = [ kernel (ξ,η) for ξ in nodes, η in nodes]
85
+ det ( eye (N) - weights_matrix .* K_matrix )
61
86
end
62
- cdf (d :: Type{TracyWidom} , t :: Real ) = cdf ( d (), t)
63
-
64
- # An internal function which sets up the Painleve II differential equation and
65
- # runs it through the Vern8 numerical integrator
66
- function _solve_painleve_ii {S<:Real} (t0 :: S , t :: S )
67
- function deq (dy , y, p, t )
68
- dy[ 1 ] = y[ 2 ]
69
- dy[ 2 ] = t * y[ 1 ] + 2 y[ 1 ] ^ 3
70
- dy[ 3 ] = y[ 4 ]
71
- dy[ 4 ] = y[ 1 ] ^ 2
87
+
88
+ _ϕ (ξ, s) = s + 10 * tan (π * (ξ + 1 ) / 4 )
89
+ _ϕprime (ξ) = ( 5 π / 2 ) * ( sec (π * (ξ + 1 ) / 4 )) ^ 2
90
+
91
+ # For beta = 2
92
+ function _airy_kernel (x , y)
93
+ if x == y
94
+ return ( airyaiprime (x)) ^ 2 - x * ( airyai (x)) ^ 2
95
+ else
96
+ return ( airyai (x) * airyaiprime (y) - airyai (y) * airyaiprime (x)) / (x - y)
72
97
end
73
- a0 = airyai (t0)
74
- T = typeof (big (a0))
75
- y0= T[a0, airyaiprime (t0), 0 , airyai (t0)^ 2 ] # Initial conditions
76
- prob = ODEProblem (deq,y0,(t0,t))
77
- solve (prob, Vern8 (), abstol= 1e-12 , reltol= 1e-12 ) # Solve the ODE
78
98
end
79
99
100
+ _K2tilde (ξ,η,s) = sqrt (_ϕprime (ξ) * _ϕprime (η)) * _airy_kernel (_ϕ (ξ,s), _ϕ (η,s))
101
+
102
+ # For beta = 1
103
+ _A_kernel (x,y) = airyai ((x+ y)/ 2 ) / 2
104
+ _K1tilde (ξ,η,s) = sqrt (_ϕprime (ξ) * _ϕprime (η)) * _A_kernel (_ϕ (ξ,s), _ϕ (η,s))
105
+
80
106
"""
81
107
Samples the largest eigenvalue of the n × n GUE matrix
82
108
"""
0 commit comments