/
inv_gamma.jl
39 lines (28 loc) · 1021 Bytes
/
inv_gamma.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
import SpecialFunctions
struct InverseGamma <: Distribution{Float64} end
"""
inv_gamma(shape::Real, scale::Real)
Sample a `Float64` from a inverse gamma distribution.
"""
const inv_gamma = InverseGamma()
function logpdf(::InverseGamma, x::Real, shape::Real, scale::Real)
if x > 0.
shape * log(scale) - (shape + 1) * log(x) - loggamma(shape) - (scale / x)
else
-Inf
end
end
function logpdf_grad(::InverseGamma, x::Real, shape::Real, scale::Real)
deriv_x = -(shape + 1) / x + scale / (x^2)
deriv_shape = log(scale) - SpecialFunctions.digamma(shape) - log(x)
deriv_scale = shape / scale - 1/x
return (deriv_x, deriv_shape, deriv_scale)
end
function random(::InverseGamma, shape::Real, scale::Real)
rand(Distributions.InverseGamma(shape, scale))
end
is_discrete(::InverseGamma) = false
(::InverseGamma)(shape, scale) = random(InverseGamma(), shape, scale)
has_output_grad(::InverseGamma) = true
has_argument_grads(::InverseGamma) = (true, true)
export inv_gamma