diff --git a/src/univariate/continuous/exponential.jl b/src/univariate/continuous/exponential.jl index 36ccd90..c239a35 100644 --- a/src/univariate/continuous/exponential.jl +++ b/src/univariate/continuous/exponential.jl @@ -6,21 +6,46 @@ function fit(::Type{Exponential}, m::AbstractMoments) return Exponential(mean(m)) end -function fit(::Type{Exponential}, lower::QuantilePoint, upper::QuantilePoint) +function fit(::Type{Exponential}, lower::QuantilePoint, upper::Missing) + θ_lower = -lower.q/log(1-lower.p) + Exponential(θ_lower) +end + +function fit(::Type{Exponential}, lower::Missing, upper::QuantilePoint) + θ_upper = -upper.q/log(1-upper.p) + Exponential(θ_upper) +end + +function fit(dt::Type{Exponential}, lower::QuantilePoint, upper::QuantilePoint) # return average for the two quantiles + ismissing(lower.q) && return(fit(dt, missing, upper)) + ismissing(upper.q) && return(fit(dt, lower, missing)) θ_lower = -lower.q/log(1-lower.p) θ_upper = -upper.q/log(1-upper.p) + θ_lower ≈ θ_upper || @warn("Averaging scale for lower and upper quantile " * + "for fitting expoenential distribution.") θ = (θ_lower + θ_upper)/2 Exponential(θ) end -function fit_mean_quantile(::Type{Exponential}, mean::Real, qp::QuantilePoint) +function fit_mean_quantile(dt::Type{Exponential}, mean::Real, qp::QuantilePoint) # only fit to mean + warning("ignoring upper quantile when fitting Exponential to mean.") + fit_mean_quantile(dt, mean, missing) +end + +function fit_mean_quantile(::Type{Exponential}, mean::Real, qp::Missing) fit(Type{Exponential}, AbstractMoments(mean)) end -function fit_mode_quantile(::Type{Exponential}, mode::Real, qp::QuantilePoint) +function fit_mode_quantile(dt::Type{Exponential}, mode::Real, qp::QuantilePoint) # ignore mode (its always at 0) + mode != zero(mode) && @warn("ignoring mode when fitting Exponential.") + fit_mode_quantile(dt, missing, qp) +end + + +function fit_mode_quantile(::Type{Exponential}, mode::Missing, qp::QuantilePoint) θ = -qp.q/log(1-qp.p) Exponential(θ) end diff --git a/test/exponential.jl b/test/exponential.jl index ca4db47..31823c7 100644 --- a/test/exponential.jl +++ b/test/exponential.jl @@ -30,12 +30,17 @@ end; @testset "fit two quantiles" begin qpl = @qp_m(3) qpu = @qp_u(5) - d = fit(Exponential, qpl, qpu); + d = @test_logs (:warn,) fit(Exponential, qpl, qpu); #plot(d); #plot!(fit_mode_quantile(Exponential, NaN, qpl)) #plot!(fit_mode_quantile(Exponential, NaN, qpu)) #vline!([3,5]) @test quantile(d, qpl.p) < qpl.q @test quantile(d, qpu.p) > qpu.q + # + d = fit(Exponential, missing, qpu); + @test quantile.(d, [qpu.p]) ≈ [qpu.q] + d = fit(Exponential, qpl, missing); + @test quantile.(d, [qpl.p]) ≈ [qpl.q] end;