Skip to content

Commit d51a7a6

Browse files
committed
Merge branch 'master' into dw/mixture_inference
2 parents 39b7191 + 5604316 commit d51a7a6

File tree

8 files changed

+243
-143
lines changed

8 files changed

+243
-143
lines changed

Project.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,10 @@ Calculus = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9"
3030
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
3131
FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000"
3232
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
33-
HypothesisTests = "09f84164-cd44-5f33-b23f-e6b0d136a0d5"
3433
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
3534
StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3"
3635
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
3736
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
3837

3938
[targets]
40-
test = ["StableRNGs", "Calculus", "Distributed", "FiniteDifferences", "ForwardDiff", "JSON", "StaticArrays", "HypothesisTests", "Test"]
39+
test = ["StableRNGs", "Calculus", "Distributed", "FiniteDifferences", "ForwardDiff", "JSON", "StaticArrays", "Test"]

src/univariate/continuous/locationscale.jl

Lines changed: 0 additions & 96 deletions
This file was deleted.

src/univariate/discrete/discretenonparametric.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,16 @@ end
133133
ccdf(d::DiscreteNonParametric{T}, x::Integer) where T = _ccdf(d, convert(T, x))
134134
ccdf(d::DiscreteNonParametric{T}, x::Real) where T = _ccdf(d, convert(T, x))
135135

136+
# fix incorrect defaults
137+
for f in (:cdf, :ccdf)
138+
_f = Symbol(:_, f)
139+
logf = Symbol(:log, f)
140+
@eval begin
141+
$logf(d::DiscreteNonParametric{T}, x::Integer) where T = log($_f(d, convert(T, x)))
142+
$logf(d::DiscreteNonParametric{T}, x::Real) where T = log($_f(d, convert(T, x)))
143+
end
144+
end
145+
136146
function quantile(d::DiscreteNonParametric, q::Real)
137147
0 <= q <= 1 || throw(DomainError())
138148
x = support(d)

src/univariate/locationscale.jl

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
"""
2+
LocationScale(μ,σ,ρ)
3+
4+
A location-scale transformed distribution with location parameter `μ`,
5+
scale parameter `σ`, and given univariate distribution `ρ`.
6+
7+
If ``Z`` is a random variable with distribution `ρ`, then the distribution of the random
8+
variable
9+
```math
10+
X = μ + σ Z
11+
```
12+
is the location-scale transformed distribution with location parameter `μ` and scale
13+
parameter `σ`.
14+
15+
If `ρ` is a discrete distribution, the probability mass function of
16+
the transformed distribution is given by
17+
```math
18+
P(X = x) = P\\left(Z = \\frac{x-μ}{σ} \\right).
19+
```
20+
If `ρ` is a continuous distribution, the probability density function of
21+
the transformed distribution is given by
22+
```math
23+
f(x) = \\frac{1}{σ} ρ \\! \\left( \\frac{x-μ}{σ} \\right).
24+
```
25+
26+
```julia
27+
LocationScale(μ,σ,ρ) # location-scale transformed distribution
28+
params(d) # Get the parameters, i.e. (μ, σ, and the base distribution)
29+
location(d) # Get the location parameter
30+
scale(d) # Get the scale parameter
31+
```
32+
33+
External links
34+
[Location-Scale family on Wikipedia](https://en.wikipedia.org/wiki/Location%E2%80%93scale_family)
35+
"""
36+
struct LocationScale{T<:Real, S<:ValueSupport, D<:UnivariateDistribution{S}} <: UnivariateDistribution{S}
37+
μ::T
38+
σ::T
39+
ρ::D
40+
function LocationScale{T,S,D}::T, σ::T, ρ::D; check_args=true) where {T<:Real, S<:ValueSupport, D<:UnivariateDistribution{S}}
41+
check_args && @check_args(LocationScale, σ > zero(σ))
42+
new{T, S, D}(μ, σ, ρ)
43+
end
44+
end
45+
46+
function LocationScale::T, σ::T, ρ::UnivariateDistribution; check_args=true) where {T<:Real}
47+
_T = promote_type(eltype(ρ), T)
48+
D = typeof(ρ)
49+
S = value_support(D)
50+
return LocationScale{_T,S,D}(_T(μ), _T(σ), ρ; check_args=check_args)
51+
end
52+
53+
LocationScale::Real, σ::Real, ρ::UnivariateDistribution) = LocationScale(promote(μ, σ)..., ρ)
54+
55+
# aliases
56+
const ContinuousLocationScale{T<:Real,D<:ContinuousUnivariateDistribution} = LocationScale{T,Continuous,D}
57+
const DiscreteLocationScale{T<:Real,D<:DiscreteUnivariateDistribution} = LocationScale{T,Discrete,D}
58+
59+
Base.eltype(::Type{<:LocationScale{T}}) where T = T
60+
61+
minimum(d::LocationScale) = d.μ + d.σ * minimum(d.ρ)
62+
maximum(d::LocationScale) = d.μ + d.σ * maximum(d.ρ)
63+
64+
LocationScale::Real, σ::Real, d::LocationScale) = LocationScale+ d.μ * σ, σ * d.σ, d.ρ)
65+
66+
#### Conversions
67+
68+
convert(::Type{LocationScale{T}}, μ::Real, σ::Real, ρ::D) where {T<:Real, D<:UnivariateDistribution} = LocationScale(T(μ),T(σ),ρ)
69+
convert(::Type{LocationScale{T}}, d::LocationScale{S}) where {T<:Real, S<:Real} = LocationScale(T(d.μ),T(d.σ),d.ρ, check_args=false)
70+
71+
#### Parameters
72+
73+
location(d::LocationScale) = d.μ
74+
scale(d::LocationScale) = d.σ
75+
params(d::LocationScale) = (d.μ,d.σ,d.ρ)
76+
partype(::LocationScale{T}) where {T} = T
77+
78+
#### Statistics
79+
80+
mean(d::LocationScale) = d.μ + d.σ * mean(d.ρ)
81+
median(d::LocationScale) = d.μ + d.σ * median(d.ρ)
82+
mode(d::LocationScale) = d.μ + d.σ * mode(d.ρ)
83+
modes(d::LocationScale) = d.μ .+ d.σ .* modes(d.ρ)
84+
85+
var(d::LocationScale) = d.σ^2 * var(d.ρ)
86+
std(d::LocationScale) = d.σ * std(d.ρ)
87+
skewness(d::LocationScale) = skewness(d.ρ)
88+
kurtosis(d::LocationScale) = kurtosis(d.ρ)
89+
90+
isplatykurtic(d::LocationScale) = isplatykurtic(d.ρ)
91+
isleptokurtic(d::LocationScale) = isleptokurtic(d.ρ)
92+
ismesokurtic(d::LocationScale) = ismesokurtic(d.ρ)
93+
94+
entropy(d::ContinuousLocationScale) = entropy(d.ρ) + log(d.σ)
95+
entropy(d::DiscreteLocationScale) = entropy(d.ρ)
96+
97+
mgf(d::LocationScale,t::Real) = exp(d.μ*t) * mgf(d.ρ,d.σ*t)
98+
99+
#### Evaluation & Sampling
100+
101+
pdf(d::ContinuousLocationScale,x::Real) = pdf(d.ρ,(x-d.μ)/d.σ) / d.σ
102+
pdf(d::DiscreteLocationScale, x::Real) = pdf(d.ρ,(x-d.μ)/d.σ)
103+
104+
logpdf(d::ContinuousLocationScale,x::Real) = logpdf(d.ρ,(x-d.μ)/d.σ) - log(d.σ)
105+
logpdf(d::DiscreteLocationScale, x::Real) = logpdf(d.ρ,(x-d.μ)/d.σ)
106+
107+
# additional definitions are required to fix ambiguity errors and incorrect defaults
108+
for f in (:cdf, :ccdf, :logcdf, :logccdf)
109+
_f = Symbol(:_, f)
110+
@eval begin
111+
$f(d::LocationScale, x::Real) = $_f(d, x)
112+
$f(d::DiscreteLocationScale, x::Real) = $_f(d, x)
113+
$f(d::DiscreteLocationScale, x::Integer) = $_f(d, x)
114+
$_f(d::LocationScale, x::Real) = $f(d.ρ, (x - d.μ) / d.σ)
115+
end
116+
end
117+
118+
quantile(d::LocationScale,q::Real) = d.μ + d.σ * quantile(d.ρ,q)
119+
120+
rand(rng::AbstractRNG, d::LocationScale) = d.μ + d.σ * rand(rng, d.ρ)
121+
cf(d::LocationScale, t::Real) = cf(d.ρ,t*d.σ) * exp(1im*t*d.μ)
122+
gradlogpdf(d::ContinuousLocationScale, x::Real) = gradlogpdf(d.ρ,(x-d.μ)/d.σ) / d.σ
123+
124+
#### Syntactic sugar for simple transforms of distributions, e.g., d + x, d - x, and so on
125+
126+
Base.:+(d::UnivariateDistribution, x::Real) = LocationScale(x, one(x), d)
127+
Base.:+(x::Real, d::UnivariateDistribution) = d + x
128+
Base.:*(x::Real, d::UnivariateDistribution) = LocationScale(zero(x), x, d)
129+
Base.:*(d::UnivariateDistribution, x::Real) = x * d
130+
Base.:-(d::UnivariateDistribution, x::Real) = d + -x
131+
Base.:/(d::UnivariateDistribution, x::Real) = inv(x) * d
132+

src/univariates.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,6 @@ const continuous_distributions = [
606606
"ksonesided",
607607
"laplace",
608608
"levy",
609-
"locationscale",
610609
"logistic",
611610
"noncentralbeta",
612611
"noncentralchisq",
@@ -631,6 +630,8 @@ const continuous_distributions = [
631630
"weibull"
632631
]
633632

633+
include(joinpath("univariate", "locationscale.jl"))
634+
634635
for dname in discrete_distributions
635636
include(joinpath("univariate", "discrete", "$(dname).jl"))
636637
end

0 commit comments

Comments
 (0)