Skip to content

Commit 8f927ce

Browse files
committed
add loglogistic distribution
1 parent 2cd6c67 commit 8f927ce

File tree

7 files changed

+182
-3
lines changed

7 files changed

+182
-3
lines changed

docs/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
[deps]
2+
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
23
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
34
GR = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71"
45

docs/src/univariate.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,10 +320,17 @@ plotdensity((0, 20), Lindley, (1.5,)) # hide
320320
```
321321

322322
```@docs
323-
Logistic
323+
logistic
324324
```
325325
```@example plotdensity
326-
plotdensity((-4, 8), Logistic, (2, 1)) # hide
326+
plotdensity((-4, 8), logistic, (2, 1)) # hide
327+
```
328+
329+
```@docs
330+
loglogistic
331+
```
332+
```@example plotdensity
333+
plotdensity((0, 2), logistic, (1, 1)) # hide
327334
```
328335

329336
```@docs

src/Distributions.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ export
120120
LKJCholesky,
121121
LocationScale,
122122
Logistic,
123+
LogLogistic,
123124
LogNormal,
124125
LogUniform,
125126
LogitNormal,
@@ -356,7 +357,7 @@ Supported distributions:
356357
InverseWishart, InverseGamma, InverseGaussian, IsoNormal,
357358
IsoNormalCanon, JohnsonSU, Kolmogorov, KSDist, KSOneSided, Kumaraswamy,
358359
Laplace, Levy, Lindley, LKJ, LKJCholesky,
359-
Logistic, LogNormal, MatrixBeta, MatrixFDist, MatrixNormal,
360+
Logistic, LogLogistic, LogNormal, MatrixBeta, MatrixFDist, MatrixNormal,
360361
MatrixTDist, MixtureModel, Multinomial,
361362
MultivariateNormal, MvLogNormal, MvNormal, MvNormalCanon,
362363
MvNormalKnownCov, MvTDist, NegativeBinomial, NoncentralBeta, NoncentralChisq,
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
"""
2+
LogLogistic(θ, ϕ)
3+
4+
The *log logistic distribution* with scale `θ` and shape `ϕ` is the distribution of a random variable whose logarithm has a [`Logistic`](@ref) distribution.
5+
If ``X \\sim \\operatorname{Logistic}(\\theta, \\phi)`` then ``exp(X) \\sim \\operatorname{LogLogistic}(\\theta, \\phi)``. The probability density function is
6+
7+
```math
8+
f(x; \\theta, \\phi) = \\frac{(\\phi / \\theta)x/\\theta()^(\\phi - 1)}{(1 + (x/\\theta)^\\phi)^2}, \\theta > 0, \\phi > 0
9+
```
10+
11+
```julia
12+
LogLogistic() # Log-logistic distribution with unit scale and unit shape
13+
LogLogistic(θ) # Log-logistic distribution with scale θ and unit shape
14+
LogLogistic(θ,ϕ) # Log-logistic distribution with scale θ and shape ϕ
15+
16+
params(d) # Get the parameters, i.e. (θ, ϕ)
17+
scale(d) # Get the scale parameter, i.e. θ
18+
shape(d) # Get the shape parameter, i.e. ϕ
19+
```
20+
21+
External links
22+
23+
* [Log logistic distribution on Wikipedia](https://en.wikipedia.org/wiki/Log-logistic_distribution)
24+
25+
"""
26+
27+
28+
struct LogLogistic{T<:Real} <: ContinuousUnivariateDistribution
29+
θ::T
30+
ϕ::T
31+
LogLogistic{T}::T::T) where {T} = new{T}(θ,ϕ)
32+
end
33+
34+
function LogLogistic::T, ϕ::T; check_args=true) where {T <: Real}
35+
check_args && @check_args(LogLogistic, θ > zero(θ) && ϕ > zero(ϕ))
36+
return LogLogistic{T}(θ, ϕ)
37+
end
38+
39+
LogLogistic::Real, ϕ::Real) = LogLogistic(promote(θ,ϕ)...)
40+
LogLogistic::Integer, ϕ::Integer) = LogLogistic(float(θ), float(ϕ))
41+
LogLogistic::T) where {T<:Real} = LogLogistic(θ, 1.0)
42+
LogLogistic() = LogLogistic(1.0, 1.0, check_args=false)
43+
44+
@distr_support LogLogistic 0.0 Inf
45+
46+
#### Coversions
47+
convert(::Type{LogLogistic{T}}, θ::S, ϕ::S) where {T <: Real, S <: Real} = LogLogistic(T(θ), T(ϕ))
48+
convert(::Type{LogLogistic{T}}, d::LogLogistic{S}) where {T <: Real, S <: Real} = LogLogistic(T(d.θ), T(d.ϕ), check_args=false)
49+
50+
#### Parameters
51+
52+
params(d::LogLogistic) = (d.θ, d.ϕ)
53+
partype(::LogLogistic{T}) where {T} = T
54+
55+
#### Statistics
56+
57+
median(d::LogLogistic) = d.θ
58+
function mean(d::LogLogistic)
59+
if d.ϕ 1
60+
error("mean is defined only when ϕ > 1")
61+
end
62+
return d.θ*π/d.ϕ/sin/d.ϕ)
63+
end
64+
65+
function mode(d::LogLogistic)
66+
if d.ϕ 1
67+
error("mode is defined only when ϕ > 1")
68+
end
69+
return d.θ*((d.ϕ-1)/(d.ϕ+1))^(1/d.ϕ)
70+
end
71+
72+
function var(d::LogLogistic)
73+
if d.ϕ 2
74+
erros("var is defined only when ϕ > 2")
75+
end
76+
b = π/d.ϕ
77+
return d.θ^2 * (2*b/sin(2*b)-b^2/(sin(b))^2)
78+
end
79+
80+
81+
#### Evaluation
82+
function pdf(d::LogLogistic, x::Real)
83+
if x zero(0)
84+
z = zero(x)
85+
else
86+
# use built-in impletation to evaluate the density
87+
# of loglogistic at x
88+
# Y = log(X)
89+
# Y ~ logistic(log(θ), 1/ϕ)
90+
z = pdf(Logistic(log(d.θ), 1/d.ϕ), log(x)) / x
91+
end
92+
return z
93+
end
94+
95+
function logpdf(d::LogLogistic, x::Real)
96+
if x zero(0)
97+
z = log(zero(x))
98+
else
99+
z = logpdf(Logistic(log(d.θ), 1/d.ϕ), log(x)) + log(x)
100+
end
101+
return z
102+
end
103+
104+
function cdf(d::LogLogistic, x::Real)
105+
if x <= 0
106+
return 0.0
107+
end
108+
z = cdf(Logistic(log(d.θ), 1/d.ϕ), log(x))
109+
return z
110+
end
111+
112+
function logcdf(d::LogLogistic, x::Real)
113+
if x <= 0
114+
-Inf
115+
end
116+
z = logcdf(Logistic(log(d.θ), 1/d.ϕ), log(x))
117+
return z
118+
end
119+
120+
function ccdf(d::LogLogistic, x::Real)
121+
if x <= 0
122+
return 1
123+
end
124+
z = ccdf(Logistic(log(d.θ), 1/d.ϕ), log(x))
125+
return z
126+
end
127+
128+
function logccdf(d::LogLogistic, x::Real)
129+
if x <= 0
130+
return 0.0
131+
end
132+
z = logccdf(Logistic(log(d.θ), 1/d.ϕ), log(x))
133+
return z
134+
end
135+
136+
137+
#### Sampling
138+
function rand(rng::AbstractRNG, d::LogLogistic)
139+
u = rand(rng)
140+
r = u / (1 - u)
141+
return r^(1/d.ϕ)*d.θ
142+
end

src/univariates.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,7 @@ const continuous_distributions = [
697697
"levy",
698698
"lindley",
699699
"logistic",
700+
"loglogistic",
700701
"noncentralbeta",
701702
"noncentralchisq",
702703
"noncentralf",

test/runtests.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import JSON
1111
import ForwardDiff
1212

1313
const tests = [
14+
"univariate/continuous/loglogistic",
1415
"univariate/continuous/loguniform",
1516
"univariate/continuous/arcsine",
1617
"univariate/discrete/dirac",
@@ -77,6 +78,7 @@ const tests = [
7778
"univariate/continuous/gumbel",
7879
"univariate/continuous/lindley",
7980
"univariate/continuous/logistic",
81+
# "univariate/continuous/loglogistic",
8082
"univariate/continuous/johnsonsu",
8183
"univariate/continuous/noncentralchisq",
8284
"univariate/continuous/weibull",
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using Distributions
2+
using Test
3+
4+
@testset "LogLogistic" begin
5+
6+
@test round(pdf(LogLogistic(), -1), digits=6) == 0.0
7+
@test round(pdf(LogLogistic(), 1), digits=6) == 0.25
8+
@test round(pdf(LogLogistic(2), 2), digits=6) == 0.125
9+
@test round(pdf(LogLogistic(2,2), 1), digits=6) == 0.32
10+
11+
@test round(cdf(LogLogistic(), -1), digits=6) == 0.0
12+
@test round(cdf(LogLogistic(), 1), digits=6) == 0.5
13+
@test round(cdf(LogLogistic(2), 3), digits=6) == 0.6
14+
@test round(cdf(LogLogistic(2,2), 4), digits=6) == 0.8
15+
16+
@test round(ccdf(LogLogistic(2), 3), digits=6) == 0.4
17+
@test round(ccdf(LogLogistic(2,2), 4), digits=6) == 0.2
18+
19+
@test round(logpdf(LogLogistic(), -1), digits=6) == -Inf
20+
@test round(logpdf(LogLogistic(), 1), digits=6) == -1.386294
21+
22+
@test round(logcdf(LogLogistic(2,2), 4), digits=6) == -0.223144
23+
@test round(logccdf(LogLogistic(2,2), 4), digits=6) == -1.609438
24+
25+
end

0 commit comments

Comments
 (0)