-
Notifications
You must be signed in to change notification settings - Fork 52
/
transformdistribution.jl
93 lines (71 loc) · 2.35 KB
/
transformdistribution.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
#################### TransformDistribution ####################
const TransformDistribution{T<:ContinuousUnivariateDistribution} =
Union{T, Truncated{T}}
function link(d::TransformDistribution, x::Real)
a, b = minimum(d), maximum(d)
lowerbounded, upperbounded = isfinite(a), isfinite(b)
if lowerbounded && upperbounded
logit((x - a) / (b - a))
elseif lowerbounded
log(x - a)
elseif upperbounded
log(b - x)
else
x
end
end
function invlink(d::TransformDistribution, x::Real)
a, b = minimum(d), maximum(d)
lowerbounded, upperbounded = isfinite(a), isfinite(b)
if lowerbounded && upperbounded
(b - a) * invlogit(x) + a
elseif lowerbounded
exp(x) + a
elseif upperbounded
b - exp(x)
else
x
end
end
function logpdf(d::TransformDistribution, x::Real, transform::Bool)
lp = logpdf(d, x)
if transform
a, b = minimum(d), maximum(d)
lowerbounded, upperbounded = isfinite(a), isfinite(b)
if lowerbounded && upperbounded
lp += log((x - a) * (b - x) / (b - a))
elseif lowerbounded
lp += log(x - a)
elseif upperbounded
lp += log(b - x)
end
end
lp
end
#################### RealDistribution ####################
const RealDistribution =
Union{Cauchy, Gumbel, Laplace, Logistic, NoncentralT, Normal,
NormalCanon, TDist}
link(d::RealDistribution, x::Real) = x
invlink(d::RealDistribution, x::Real) = x
logpdf(d::RealDistribution, x::Real, transform::Bool) = logpdf(d, x)
#################### PositiveDistribution ####################
const PositiveDistribution =
Union{BetaPrime, Chi, Chisq, Erlang, Exponential, FDist, Frechet,
Gamma, InverseGamma, InverseGaussian, Kolmogorov, LogNormal,
NoncentralChisq, NoncentralF, Rayleigh, Weibull}
link(d::PositiveDistribution, x::Real) = log(x)
invlink(d::PositiveDistribution, x::Real) = exp(x)
function logpdf(d::PositiveDistribution, x::Real, transform::Bool)
lp = logpdf(d, x)
transform ? lp + log(x) : lp
end
#################### UnitDistribution ####################
const UnitDistribution =
Union{Beta, KSOneSided, NoncentralBeta}
link(d::UnitDistribution, x::Real) = logit(x)
invlink(d::UnitDistribution, x::Real) = invlogit(x)
function logpdf(d::UnitDistribution, x::Real, transform::Bool)
lp = logpdf(d, x)
transform ? lp + log(x * (1.0 - x)) : lp
end