-
Notifications
You must be signed in to change notification settings - Fork 415
/
tdist.jl
96 lines (70 loc) · 2.51 KB
/
tdist.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
"""
TDist(ν)
The *Students T distribution* with `ν` degrees of freedom has probability density function
```math
f(x; \\nu) = \\frac{1}{\\sqrt{\\nu} B(1/2, \\nu/2)}
\\left( 1 + \\frac{x^2}{\\nu} \\right)^{-\\frac{\\nu + 1}{2}}
```
```julia
TDist(d) # t-distribution with ν degrees of freedom
params(d) # Get the parameters, i.e. (ν,)
dof(d) # Get the degrees of freedom, i.e. ν
```
External links
[Student's T distribution on Wikipedia](https://en.wikipedia.org/wiki/Student%27s_t-distribution)
"""
struct TDist{T<:Real} <: ContinuousUnivariateDistribution
ν::T
TDist{T}(ν::T) where {T <: Real} = new{T}(ν)
end
function TDist(ν::Real; check_args::Bool=true)
@check_args TDist (ν, ν > zero(ν))
return TDist{typeof(ν)}(ν)
end
TDist(ν::Integer; check_args::Bool=true) = TDist(float(ν); check_args=check_args)
@distr_support TDist -Inf Inf
#### Conversions
convert(::Type{TDist{T}}, ν::Real) where {T<:Real} = TDist(T(ν))
Base.convert(::Type{TDist{T}}, d::TDist) where {T<:Real} = TDist{T}(T(d.ν))
Base.convert(::Type{TDist{T}}, d::TDist{T}) where {T<:Real} = d
#### Parameters
dof(d::TDist) = d.ν
params(d::TDist) = (d.ν,)
@inline partype(d::TDist{T}) where {T<:Real} = T
#### Statistics
mean(d::TDist{T}) where {T<:Real} = d.ν > 1 ? zero(T) : T(NaN)
median(d::TDist{T}) where {T<:Real} = zero(T)
mode(d::TDist{T}) where {T<:Real} = zero(T)
function var(d::TDist{T}) where T<:Real
ν = d.ν
isinf(ν) && return one(T)
ν > 2 ? ν / (ν - 2) :
ν > 1 ? T(Inf) : T(NaN)
end
skewness(d::TDist{T}) where {T<:Real} = d.ν > 3 ? zero(T) : T(NaN)
function kurtosis(d::TDist{T}) where T<:Real
ν = d.ν
ν > 4 ? 6 / (ν - 4) :
ν > 2 ? T(Inf) : T(NaN)
end
function entropy(d::TDist{T}) where T <: Real
isinf(d.ν) && return entropy( Normal(zero(T), one(T)) )
h = d.ν/2
h1 = h + 1//2
h1 * (digamma(h1) - digamma(h)) + log(d.ν)/2 + logbeta(h, 1//2)
end
#### Evaluation & Sampling
@_delegate_statsfuns TDist tdist ν
function rand(rng::AbstractRNG, d::TDist)
ν = d.ν
z = sqrt(rand(rng, Chisq{typeof(ν)}(ν)) / ν)
return randn(rng) / (isinf(ν) ? one(z) : z)
end
function cf(d::TDist{T}, t::Real) where T <: Real
isinf(d.ν) && return cf(Normal(zero(T), one(T)), t)
t == 0 && return complex(1)
h = d.ν/2
q = d.ν/4
complex(2(q*t^2)^q * besselk(h, sqrt(d.ν) * abs(t)) / gamma(h))
end
gradlogpdf(d::TDist{T}, x::Real) where {T<:Real} = isinf(d.ν) ? gradlogpdf(Normal(zero(T), one(T)), x) : -((d.ν + 1) * x) / (x^2 + d.ν)