-
Notifications
You must be signed in to change notification settings - Fork 414
/
chisq.jl
97 lines (65 loc) · 2.36 KB
/
chisq.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
97
"""
Chisq(ν)
The *Chi squared distribution* (typically written χ²) with `ν` degrees of freedom has the
probability density function
```math
f(x; \\nu) = \\frac{x^{\\nu/2 - 1} e^{-x/2}}{2^{\\nu/2} \\Gamma(k/2)}, \\quad x > 0.
```
If `ν` is an integer, then it is the distribution of the sum of squares of `ν` independent standard [`Normal`](@ref) variates.
```julia
Chisq(ν) # Chi-squared distribution with ν degrees of freedom
params(d) # Get the parameters, i.e. (ν,)
dof(d) # Get the degrees of freedom, i.e. ν
```
External links
* [Chi-squared distribution on Wikipedia](http://en.wikipedia.org/wiki/Chi-squared_distribution)
"""
struct Chisq{T<:Real} <: ContinuousUnivariateDistribution
ν::T
Chisq{T}(ν::T) where {T} = new{T}(ν)
end
function Chisq(ν::Real; check_args::Bool=true)
@check_args Chisq (ν, ν > zero(ν))
return Chisq{typeof(ν)}(ν)
end
Chisq(ν::Integer; check_args::Bool=true) = Chisq(float(ν); check_args=check_args)
@distr_support Chisq 0.0 Inf
#### Parameters
dof(d::Chisq) = d.ν
params(d::Chisq) = (d.ν,)
@inline partype(d::Chisq{T}) where {T<:Real} = T
### Conversions
convert(::Type{Chisq{T}}, ν::Real) where {T<:Real} = Chisq(T(ν))
Base.convert(::Type{Chisq{T}}, d::Chisq) where {T<:Real} = Chisq{T}(T(d.ν))
Base.convert(::Type{Chisq{T}}, d::Chisq{T}) where {T<:Real} = d
#### Statistics
mean(d::Chisq) = d.ν
var(d::Chisq) = 2d.ν
skewness(d::Chisq) = sqrt(8 / d.ν)
kurtosis(d::Chisq) = 12 / d.ν
mode(d::Chisq{T}) where {T<:Real} = d.ν > 2 ? d.ν - 2 : zero(T)
function median(d::Chisq; approx::Bool=false)
if approx
return d.ν * (1 - 2 / (9 * d.ν))^3
else
return quantile(d, 1//2)
end
end
function entropy(d::Chisq)
hν = d.ν/2
hν + logtwo + loggamma(hν) + (1 - hν) * digamma(hν)
end
function kldivergence(p::Chisq, q::Chisq)
pν = dof(p)
qν = dof(q)
return kldivergence(Chi{typeof(pν)}(pν), Chi{typeof(qν)}(qν))
end
#### Evaluation
@_delegate_statsfuns Chisq chisq ν
mgf(d::Chisq, t::Real) = (1 - 2 * t)^(-d.ν/2)
cf(d::Chisq, t::Real) = (1 - 2 * im * t)^(-d.ν/2)
gradlogpdf(d::Chisq{T}, x::Real) where {T<:Real} = x > 0 ? (d.ν/2 - 1) / x - 1//2 : zero(T)
#### Sampling
rand(rng::AbstractRNG, d::Chisq) =
(ν = d.ν; rand(rng, Gamma(ν / 2.0, 2.0one(ν))))
sampler(d::Chisq) = (ν = d.ν; sampler(Gamma(ν / 2.0, 2.0one(ν))))