Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kdm/univariateboundaryfix #457

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 48 additions & 2 deletions src/testutils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -268,15 +268,61 @@ function test_support(d::UnivariateDistribution, vs::AbstractVector)
end
@test all(insupport(d, vs))

@test lowerboundary(d) == :closed || lowerboundary(d) == :open
@test upperboundary(d) == :closed || upperboundary(d) == :open

sp = support(d)
if isa(d,ContinuousUnivariateDistribution)
@test minimum(sp) == minimum(d)
@test maximum(sp) == maximum(d)
@test lowerboundary(sp) == lowerboundary(d)
@test upperboundary(sp) == upperboundary(d)
@test lowercomparator(sp) == lowercomparator(d)
@test uppercomparator(sp) == uppercomparator(d)
end

if isa(d,DiscreteUnivariateDistribution)
@test (isfinite(minimum(d)) && minimum(d) == minimum(sp)) || (minimum(sp) == typemin(Int))
@test (isfinite(minimum(d)) && maximum(d) == maximum(sp)) || (maximum(sp) == typemax(Int))
end

if islowerbounded(d)
@test isfinite(minimum(d))
@test insupport(d, minimum(d))
@test (lowerboundary(d) == :closed && insupport(d, minimum(d))) || (lowerboundary(d) == :open && !insupport(d, minimum(d)))
@test !insupport(d, minimum(d)-1)
if lowerboundary(d) == :open
@test pdf(d,minimum(d)) == 0.0
@test logpdf(d,minimum(d)) == -Inf
@test cdf(d,minimum(d)) == 0.0
@test logcdf(d,minimum(d)) == -Inf
@test ccdf(d,minimum(d)) == 1.0
@test logccdf(d,minimum(d)) == 0.0
end
@test pdf(d,minimum(d)-1) == 0.0
@test logpdf(d,minimum(d)-1) == -Inf
@test cdf(d,minimum(d)-1) == 0.0
@test logcdf(d,minimum(d)-1) == -Inf
@test ccdf(d,minimum(d)-1) == 1.0
@test logccdf(d,minimum(d)-1) == 0.0
end
if isupperbounded(d)
@test isfinite(maximum(d))
@test insupport(d, maximum(d))
@test (upperboundary(d) == :closed && insupport(d, maximum(d))) || (upperboundary(d) == :open && !insupport(d, maximum(d)))
@test !insupport(d, maximum(d)+1)
if upperboundary(d) == :open
@test pdf(d,maximum(d)) == 0.0
@test logpdf(d,maximum(d)) == -Inf
end
@test cdf(d,maximum(d)) == 1.0
@test ccdf(d,maximum(d)) == 0.0
@test logcdf(d,maximum(d)) == 0.0
@test logccdf(d,maximum(d)) == -Inf
@test pdf(d,maximum(d)+1) == 0.0
@test logpdf(d,maximum(d)+1) == -Inf
@test cdf(d,maximum(d)+1) == 1.0
@test logcdf(d,maximum(d)+1) == 0.0
@test ccdf(d,maximum(d)+1) == 0.0
@test logccdf(d,maximum(d)+1) == -Inf
end

@test isbounded(d) == (isupperbounded(d) && islowerbounded(d))
Expand Down
9 changes: 7 additions & 2 deletions src/univariate/continuous/betaprime.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ immutable BetaPrime <: ContinuousUnivariateDistribution
end

@distr_support BetaPrime 0.0 Inf
@distr_boundaries BetaPrime :open :closed

#### Parameters

Expand Down Expand Up @@ -42,8 +43,12 @@ end
#### Evaluation

function logpdf(d::BetaPrime, x::Float64)
(α, β) = params(d)
(α - 1.0) * log(x) - (α + β) * log1p(x) - lbeta(α, β)
if insupport(d, x)
(α, β) = params(d)
(α - 1.0) * log(x) - (α + β) * log1p(x) - lbeta(α, β)
else
return -Inf
end
end

pdf(d::BetaPrime, x::Float64) = exp(logpdf(d, x))
Expand Down
4 changes: 2 additions & 2 deletions src/univariate/continuous/biweight.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ end

function ccdf(d::Biweight, x::Float64)
u = (d.μ - x) / d.σ
u <= -1.0 ? 1.0 :
u >= 1.0 ? 0.0 :
u <= -1.0 ? 0.0 :
u >= 1.0 ? 1.0 :
0.0625 * (u + 1.0)^3 * @horner(u,8.0,-9.0,3.0)
end

Expand Down
20 changes: 13 additions & 7 deletions src/univariate/continuous/chi.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ immutable Chi <: ContinuousUnivariateDistribution
end

@distr_support Chi 0.0 Inf
@distr_boundaries Chi :open :closed

#### Parameters

Expand Down Expand Up @@ -45,16 +46,21 @@ end

pdf(d::Chi, x::Float64) = exp(logpdf(d, x))

logpdf(d::Chi, x::Float64) = (ν = d.ν;
(1.0 - 0.5 * ν) * logtwo + (ν - 1.0) * log(x) - 0.5 * x^2 - lgamma(0.5 * ν)
)
function logpdf(d::Chi, x::Float64)
if insupport(d, x)
ν = d.ν
return (1.0 - 0.5 * ν) * logtwo + (ν - 1.0) * log(x) - 0.5 * x^2 - lgamma(0.5 * ν)
else
return -Inf
end
end

gradlogpdf(d::Chi, x::Float64) = x >= 0.0 ? (d.ν - 1.0) / x - x : 0.0

cdf(d::Chi, x::Float64) = chisqcdf(d.ν, x^2)
ccdf(d::Chi, x::Float64) = chisqccdf(d.ν, x^2)
logcdf(d::Chi, x::Float64) = chisqlogcdf(d.ν, x^2)
logccdf(d::Chi, x::Float64) = chisqlogccdf(d.ν, x^2)
cdf(d::Chi, x::Float64) = insupport(d,x)?chisqcdf(d.ν, x^2):0.0
ccdf(d::Chi, x::Float64) = insupport(d,x)?chisqccdf(d.ν, x^2):1.0
logcdf(d::Chi, x::Float64) = insupport(d,x)?chisqlogcdf(d.ν, x^2):-Inf
logccdf(d::Chi, x::Float64) = insupport(d,x)?chisqlogccdf(d.ν, x^2):0.0

quantile(d::Chi, p::Float64) = sqrt(chisqinvcdf(d.ν, p))
cquantile(d::Chi, p::Float64) = sqrt(chisqinvccdf(d.ν, p))
Expand Down
20 changes: 16 additions & 4 deletions src/univariate/continuous/cosine.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,25 @@ end
logpdf(d::Cosine, x::Float64) = insupport(d, x) ? log(pdf(d, x)) : -Inf

function cdf(d::Cosine, x::Float64)
z = (x - d.μ) / d.σ
0.5 * (1.0 + z + sinpi(z) * invπ)
if insupport(d, x)
z = (x - d.μ) / d.σ
return 0.5 * (1.0 + z + sinpi(z) * invπ)
elseif x < minimum(d)
return 0.0
else
return 1.0
end
end

function ccdf(d::Cosine, x::Float64)
nz = (d.μ - x) / d.σ
0.5 * (1.0 + nz + sinpi(nz) * invπ)
if insupport(d, x)
nz = (d.μ - x) / d.σ
return 0.5 * (1.0 + nz + sinpi(nz) * invπ)
elseif x < minimum(d)
return 1.0
else
return 0.0
end
end

quantile(d::Cosine, p::Float64) = quantile_bisect(d, p)
4 changes: 2 additions & 2 deletions src/univariate/continuous/epanechnikov.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ end

function ccdf(d::Epanechnikov, x::Float64)
u = (d.μ - x) / d.σ
u <= -1 ? 1.0 :
u >= 1 ? 0.0 :
u <= -1 ? 0.0 :
u >= 1 ? 1.0 :
0.5 + u * (0.75 - 0.25 * u^2)
end

Expand Down
2 changes: 1 addition & 1 deletion src/univariate/continuous/exponential.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pdf(d::Exponential, x::Float64) = (λ = rate(d); x < 0.0 ? 0.0 : λ * exp(-λ *
logpdf(d::Exponential, x::Float64) = (λ = rate(d); x < 0.0 ? -Inf : log(λ) - λ * x)

cdf(d::Exponential, x::Float64) = x > 0.0 ? -expm1(-zval(d, x)) : 0.0
ccdf(d::Exponential, x::Float64) = x > 0.0 ? exp(-zval(d, x)) : 0.0
ccdf(d::Exponential, x::Float64) = x > 0.0 ? exp(-zval(d, x)) : 1.0
logcdf(d::Exponential, x::Float64) = x > 0.0 ? log1mexp(-zval(d, x)) : -Inf
logccdf(d::Exponential, x::Float64) = x > 0.0 ? -zval(d, x) : 0.0

Expand Down
15 changes: 8 additions & 7 deletions src/univariate/continuous/generalizedpareto.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ immutable GeneralizedPareto <: ContinuousUnivariateDistribution
GeneralizedPareto() = new(1.0, 1.0, 0.0)
end

minimum(d::GeneralizedPareto) = d.μ
maximum(d::GeneralizedPareto) = d.ξ < 0.0 ? d.μ - d.σ / d.ξ : Inf
@distr_support GeneralizedPareto d.μ d.ξ<0.0?d.μ-d.σ/d.ξ:Inf


#### Parameters
Expand Down Expand Up @@ -74,9 +73,9 @@ function logpdf(d::GeneralizedPareto, x::Float64)
# The logpdf is log(0) outside the support range.
p = -Inf

if x >= μ
if insupport(d,x)
z = (x - μ) / σ
if abs(ξ) < eps()
if abs(ξ) < eps(x)
p = -z - log(σ)
elseif ξ > 0.0 || (ξ < 0.0 && x < maximum(d))
p = (-1.0 - 1.0 / ξ) * log1p(z * ξ) - log(σ)
Expand All @@ -91,17 +90,19 @@ pdf(d::GeneralizedPareto, x::Float64) = exp(logpdf(d, x))
function logccdf(d::GeneralizedPareto, x::Float64)
(ξ, σ, μ) = params(d)

# The logccdf is log(0) outside the support range.
p = -Inf
p = 0.0

if x >= μ
if insupport(d,x)
z = (x - μ) / σ
if abs(ξ) < eps()
p = -z
elseif ξ > 0.0 || (ξ < 0.0 && x < maximum(d))
p = (-1.0 / ξ) * log1p(z * ξ)
end
end
if x >= maximum(d)
p = -Inf
end

return p
end
Expand Down
17 changes: 11 additions & 6 deletions src/univariate/continuous/inversegamma.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ immutable InverseGamma <: ContinuousUnivariateDistribution
end

@distr_support InverseGamma 0.0 Inf
@distr_boundaries InverseGamma :open :closed


#### Parameters
Expand Down Expand Up @@ -55,14 +56,18 @@ end
pdf(d::InverseGamma, x::Float64) = exp(logpdf(d, x))

function logpdf(d::InverseGamma, x::Float64)
(α, θ) = params(d)
α * log(θ) - lgamma(α) - (α + 1.0) * log(x) - θ / x
if insupport(d, x)
(α, θ) = params(d)
return α * log(θ) - lgamma(α) - (α + 1.0) * log(x) - θ / x
else
return -Inf
end
end

cdf(d::InverseGamma, x::Float64) = ccdf(d.invd, 1.0 / x)
ccdf(d::InverseGamma, x::Float64) = cdf(d.invd, 1.0 / x)
logcdf(d::InverseGamma, x::Float64) = logccdf(d.invd, 1.0 / x)
logccdf(d::InverseGamma, x::Float64) = logcdf(d.invd, 1.0 / x)
cdf(d::InverseGamma, x::Float64) = insupport(d,x)?ccdf(d.invd, 1.0 / x):0.0
ccdf(d::InverseGamma, x::Float64) = insupport(d,x)?cdf(d.invd, 1.0 / x):1.0
logcdf(d::InverseGamma, x::Float64) = insupport(d,x)?logccdf(d.invd, 1.0 / x):-Inf
logccdf(d::InverseGamma, x::Float64) = insupport(d,x)?logcdf(d.invd, 1.0 / x):0.0

quantile(d::InverseGamma, p::Float64) = 1.0 / cquantile(d.invd, p)
cquantile(d::InverseGamma, p::Float64) = 1.0 / quantile(d.invd, p)
Expand Down
13 changes: 7 additions & 6 deletions src/univariate/continuous/inversegaussian.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ immutable InverseGaussian <: ContinuousUnivariateDistribution
end

@distr_support InverseGaussian 0.0 Inf
@distr_boundaries InverseGaussian :open :closed


#### Parameters
Expand Down Expand Up @@ -39,7 +40,7 @@ end
#### Evaluation

function pdf(d::InverseGaussian, x::Float64)
if x > 0.0
if insupport(d, x)
μ, λ = params(d)
return sqrt(λ / (twoπ * x^3)) * exp(-λ * (x - μ)^2 / (2.0 * μ^2 * x))
else
Expand All @@ -48,7 +49,7 @@ function pdf(d::InverseGaussian, x::Float64)
end

function logpdf(d::InverseGaussian, x::Float64)
if x > 0.0
if insupport(d, x)
μ, λ = params(d)
return 0.5 * (log(λ) - (log2π + 3.0 * log(x)) - λ * (x - μ)^2 / (μ^2 * x))
else
Expand All @@ -57,7 +58,7 @@ function logpdf(d::InverseGaussian, x::Float64)
end

function cdf(d::InverseGaussian, x::Float64)
if x > 0.0
if insupport(d, x)
μ, λ = params(d)
u = sqrt(λ / x)
v = x / μ
Expand All @@ -68,7 +69,7 @@ function cdf(d::InverseGaussian, x::Float64)
end

function ccdf(d::InverseGaussian, x::Float64)
if x > 0.0
if insupport(d, x)
μ, λ = params(d)
u = sqrt(λ / x)
v = x / μ
Expand All @@ -79,7 +80,7 @@ function ccdf(d::InverseGaussian, x::Float64)
end

function logcdf(d::InverseGaussian, x::Float64)
if x > 0.0
if insupport(d, x)
μ, λ = params(d)
u = sqrt(λ / x)
v = x / μ
Expand All @@ -92,7 +93,7 @@ function logcdf(d::InverseGaussian, x::Float64)
end

function logccdf(d::InverseGaussian, x::Float64)
if x > 0.0
if insupport(d, x)
μ, λ = params(d)
u = sqrt(λ / x)
v = x / μ
Expand Down
25 changes: 17 additions & 8 deletions src/univariate/continuous/levy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ immutable Levy <: ContinuousUnivariateDistribution
end

@distr_support Levy d.μ Inf
@distr_boundaries Levy :open :open


#### Parameters
Expand All @@ -33,19 +34,27 @@ median(d::Levy) = d.μ + d.σ / 0.4549364231195728 # 0.454... = (2.0 * erfcinv(
#### Evaluation

function pdf(d::Levy, x::Float64)
μ, σ = params(d)
z = x - μ
(sqrt(σ) / sqrt2π) * exp((-σ) / (2.0 * z)) / z^1.5
if (insupport(d,x))
μ, σ = params(d)
z = x - μ
return (sqrt(σ) / sqrt2π) * exp((-σ) / (2.0 * z)) / z^1.5
else
return zero(x)
end
end

function logpdf(d::Levy, x::Float64)
μ, σ = params(d)
z = x - μ
0.5 * (log(σ) - log2π - σ / z - 3.0 * log(z))
if (insupport(d,x))
μ, σ = params(d)
z = x - μ
return 0.5 * (log(σ) - log2π - σ / z - 3.0 * log(z))
else
return -Inf
end
end

cdf(d::Levy, x::Float64) = erfc(sqrt(d.σ / (2.0 * (x - d.μ))))
ccdf(d::Levy, x::Float64) = erf(sqrt(d.σ / (2.0 * (x - d.μ))))
cdf(d::Levy, x::Float64) = insupport(d,x)?erfc(sqrt(d.σ / (2.0 * (x - d.μ)))):0.0
ccdf(d::Levy, x::Float64) = insupport(d,x)?erf(sqrt(d.σ / (2.0 * (x - d.μ)))):1.0

quantile(d::Levy, p::Float64) = d.μ + d.σ / (2.0 * erfcinv(p)^2)
cquantile(d::Levy, p::Float64) = d.μ + d.σ / (2.0 * erfinv(p)^2)
Expand Down
Loading