JuliaStats / StatsFuns.jl

Mathematical functions related to statistics.
Other
235 stars 40 forks source link

Rational param breaks Binomial CDF #98

Closed ron-wolf closed 3 years ago

ron-wolf commented 4 years ago

StatsFuns.binomccdf() maps to the eponymous R function, as shown below.

https://github.com/JuliaStats/StatsFuns.jl/blob/d99fdf43d40a70ca7a688e11afba1a84963eb396/src/distrs/binom.jl#L3-L13

However, when called on a binomial distribution with 𝑝::Rational, an error occurs; currently, the only option is to convert the parameter using float(). Note that although the code below uses Distributions, I believe the error is on the part of StatsFuns: see this code in Distributions for the call to StatsFuns.

using Distributions; ccdf(Binomial(7, 1//5), 1)
ERROR: MethodError: no method matching binomccdf(::Int64, ::Rational{Int64}, ::Int64)
Closest candidates are:
  binomccdf(::Union{Float64, Int64}, ::Union{Float64, Int64}, ::Union{Float64, Int64}) at /Users/USER/.julia/packages/StatsFuns/CXyCV/src/rmath.jl:80
Stacktrace:
 [1] ccdf(::Binomial{Rational{Int64}}, ::Int64) at /Users/USER/.julia/packages/Distributions/RAeyY/src/univariates.jl:557
 [2] top-level scope at REPL[1]:1

Is this intended behavior? Such distributions work just fine with StatsPlots.plot().

using Distributions, StatsPlots; plot(Binomial(7, 1//5))

A plot of the binomial distribution with n=7 and p=⅕

andreasnoack commented 4 years ago

The cdf of the Binomial distribution is based on the incomplete Beta function which is very complicated function to implement reliably. However, I guess we could have a naive fallback that sums up the probabilities.

ron-wolf commented 4 years ago

Certainly! I’d be happy to get involved in implementing this. I’m relatively new to Julia though, as well as to statistics generally. I have a few questions:

ron-wolf commented 4 years ago

Related: #33

devmotion commented 3 years ago

The issue was fixed by https://github.com/JuliaStats/StatsFuns.jl/pull/125. With StatsFuns 0.9.11:

julia> using Distributions; ccdf(Binomial(7, 1//5), 1)
0.4232832000000002