Skip to content

Commit

Permalink
Clean up cdf functions
Browse files Browse the repository at this point in the history
* For discrete functions with finite support, calculate
  cdf from right if we're in the right half of that support
* Remove cdf specialized on BetaBinomial (handled by
  DiscreteUnivariateDistribution version)
  • Loading branch information
kmsquire committed Jan 10, 2016
1 parent 88e815b commit 818c071
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 18 deletions.
16 changes: 0 additions & 16 deletions src/univariate/discrete/betabinomial.jl
Original file line number Diff line number Diff line change
Expand Up @@ -70,19 +70,3 @@ mode(d::BetaBinomial) = indmax(pdf(d)) - 1
modes(d::BetaBinomial) = [x - 1 for x in modes(Categorical(pdf(d)))]

quantile(d::BetaBinomial, p::Float64) = quantile(Categorical(pdf(d)), p) - 1

function cdf(d::BetaBinomial, x::Int)
c = 0.0
for y = minimum(d):min(floor(Int,x), maximum(d))
c += pdf(d, y)
end

# TODO: remove when https://github.com/JuliaLang/julia/issues/14620 is resolved
# this is needed due to the fact that pdf(d, y) can return values that are imprecise at higher decimal places (due to https://github.com/JuliaLang/julia/issues/14620)
# and so due to the impl above we can end up with cdf values that are basically 1 but are either slightly greater or smaller
if abs(c - 1.0) < 1.0e-10
c = 1.0
end

return c
end
24 changes: 22 additions & 2 deletions src/univariates.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ end
@compat support{D<:ContinuousUnivariateDistribution}(d::Union{D,Type{D}}) = RealInterval(minimum(d), maximum(d))
@compat support{D<:DiscreteUnivariateDistribution}(d::Union{D,Type{D}}) = round(Int, minimum(d)):round(Int, maximum(d))

# Type used for dispatch on finite support
# T = true or false
immutable FiniteSupport{T} end

## macros to declare support

macro distr_support(D, lb, ub)
Expand Down Expand Up @@ -108,15 +112,31 @@ logpdf(d::ContinuousUnivariateDistribution, x::Float64) = log(pdf(d, x))
@compat logpdf(d::ContinuousUnivariateDistribution, x::Real) = logpdf(d, Float64(x))

# cdf
cdf(d::DiscreteUnivariateDistribution, x::Int) = cdf(d, x, FiniteSupport{hasfinitesupport(d)})

function cdf(d::DiscreteUnivariateDistribution, x::Int)
# Discrete univariate with infinite support
function cdf(d::DiscreteUnivariateDistribution, x::Int, ::Type{FiniteSupport{false}})
c = 0.0
for y = minimum(d):floor(Int,x)
for y = minimum(d):x
c += pdf(d, y)
end
return c
end

# Discrete univariate with finite support
function cdf(d::DiscreteUnivariateDistribution, x::Int, ::Type{FiniteSupport{true}})
# calculate from left if x < (min + max)/2
# (same as infinite support version)
x <= div(minimum(d) + maximum(d),2) && return cdf(d, x, FiniteSupport{false})

# otherwise, calculate from the right
c = 1.0
for y = x+1:maximum(d)
c -= pdf(d, y)
end
return c
end

cdf(d::DiscreteUnivariateDistribution, x::Real) = cdf(d, floor(Int,x))

cdf(d::ContinuousUnivariateDistribution, x::Float64) = throw(MethodError(cdf, (d, x)))
Expand Down

0 comments on commit 818c071

Please sign in to comment.