Skip to content

Commit

Permalink
Fix support of Dirac and LocationScale (#1346)
Browse files Browse the repository at this point in the history
* Fix support of `Dirac` and `LocationScale`

* Fix method ambiguity error

* Remove unstable Dirac test

* Fix test errors
  • Loading branch information
devmotion authored Jun 16, 2021
1 parent 0ac7c42 commit 239a9fa
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 16 deletions.
3 changes: 2 additions & 1 deletion src/univariate/discrete/dirac.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ Base.eltype(::Type{Dirac{T}}) where {T} = T
insupport(d::Dirac, x::Real) = x == d.value
minimum(d::Dirac) = d.value
maximum(d::Dirac) = d.value
support(d::Dirac) = (d.value,)

#### Properties

mean(d::Dirac) = d.value
var(d::Dirac{T}) where {T} = zero(T)

Expand All @@ -43,6 +43,7 @@ pdf(d::Dirac, x::Real) = insupport(d, x) ? 1.0 : 0.0
logpdf(d::Dirac, x::Real) = insupport(d, x) ? 0.0 : -Inf

cdf(d::Dirac, x::Real) = x < d.value ? 0.0 : 1.0
cdf(d::Dirac, x::Integer) = x < d.value ? 0.0 : 1.0

quantile(d::Dirac{T}, p::Real) where {T} = 0 <= p <= 1 ? d.value : T(NaN)

Expand Down
5 changes: 5 additions & 0 deletions src/univariate/locationscale.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ Base.eltype(::Type{<:LocationScale{T}}) where T = T

minimum(d::LocationScale) = d.μ + d.σ * minimum(d.ρ)
maximum(d::LocationScale) = d.μ + d.σ * maximum(d.ρ)
support(d::LocationScale) = locationscale_support(d.μ, d.σ, support(d.ρ))
function locationscale_support::Real, σ::Real, support::RealInterval)
return RealInterval+ σ * support.lb, μ + σ * support.ub)
end
locationscale_support::Real, σ::Real, support) = μ .+ σ .* support

LocationScale::Real, σ::Real, d::LocationScale) = LocationScale+ d.μ * σ, σ * d.σ, d.ρ)

Expand Down
12 changes: 6 additions & 6 deletions src/univariates.jl
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
#### Domain && Support

struct RealInterval
lb::Float64
ub::Float64

RealInterval(lb::Real, ub::Real) = new(Float64(lb), Float64(ub))
struct RealInterval{T<:Real}
lb::T
ub::T
end

RealInterval(lb::Real, ub::Real) = RealInterval(promote(lb, ub)...)

minimum(r::RealInterval) = r.lb
maximum(r::RealInterval) = r.ub
extrema(r::RealInterval) = (r.lb, r.ub)
in(x::Real, r::RealInterval) = (r.lb <= Float64(x) <= r.ub)
in(x::Real, r::RealInterval) = r.lb <= x <= r.ub

isbounded(d::Union{D,Type{D}}) where {D<:UnivariateDistribution} = isupperbounded(d) && islowerbounded(d)

Expand Down
19 changes: 10 additions & 9 deletions test/dirac.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,27 @@ using Distributions
using Test

@testset "Dirac tests" begin
for val in [3, 3.0, -3.5]
for val in (3, 3.0, -3.5)
d = Dirac(val)

@test minimum(d) == val
@test maximum(d) == val
@test !insupport(d, prevfloat(val))
@test !insupport(d, prevfloat(float(val)))
@test insupport(d, val)
@test !insupport(d, nextfloat(val))
@test !insupport(d, nextfloat(float(val)))
@test support(d) == (val,)

@test iszero(pdf(d, prevfloat(val)))
@test iszero(pdf(d, prevfloat(float(val))))
@test isone(pdf(d, val))
@test iszero(pdf(d, nextfloat(val)))
@test iszero(pdf(d, nextfloat(float(val))))

@test logpdf(d, prevfloat(val)) == -Inf
@test logpdf(d, prevfloat(float(val))) == -Inf
@test iszero(logpdf(d, val))
@test logpdf(d, nextfloat(val)) == -Inf
@test logpdf(d, nextfloat(float(val))) == -Inf

@test iszero(cdf(d, prevfloat(val)))
@test iszero(cdf(d, prevfloat(float(val))))
@test isone(cdf(d, val))
@test isone(cdf(d, nextfloat(val)))
@test isone(cdf(d, nextfloat(float(val))))

@test quantile(d, 0) == val
@test quantile(d, 0.5) == val
Expand Down
7 changes: 7 additions & 0 deletions test/locationscale.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ function test_location_scale(
@test minimum(d) == minimum(dref)
@test maximum(d) == maximum(dref)
@test extrema(d) == (minimum(d), maximum(d))
@test extrema(support(d)) == extrema(d)
if support(d.ρ) isa RealInterval
@test support(d) isa RealInterval
elseif hasfinitesupport(d.ρ)
@test support(d) == d.μ .+ d.σ .* support(d.ρ)
end
end
@testset "$k" for (k,dtest) in d_dict
test_support(dtest, dref)
Expand Down Expand Up @@ -61,6 +67,7 @@ function test_location_scale(

@test var(d) var(dref)
@test std(d) std(dref)

@test skewness(d) skewness(dref)
@test kurtosis(d) kurtosis(dref)

Expand Down

2 comments on commit 239a9fa

@devmotion
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/38931

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.25.4 -m "<description of version>" 239a9fa86a2bafe793eb16889d6ab544c119cf88
git push origin v0.25.4

Please sign in to comment.