Skip to content

Commit

Permalink
use finv(cdf) for functional inverse
Browse files Browse the repository at this point in the history
  • Loading branch information
jlapeyre committed May 18, 2018
1 parent a236734 commit 4825319
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 14 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ The exception is `print`, which does sort the cdf before printing.

`rand(cdf)` return a sample from the empirical probability distribution associated with `cdf`.

`getinverse(cdf::EmpiricalCDF,c)` return the functional inverse of `cdf` at the value `c`.
`finv(cdf::AbstractEmpiricalCDF)(c)` return the functional inverse of `cdf` at the value `c`.

Several existing methods on `AbstractEmpiricalCDF` simply call
the same funciton on the underlying data. These are:
Expand Down
1 change: 1 addition & 0 deletions src/EmpiricalCDFs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Compat.String

# cdfs.jl
export AbstractEmpiricalCDF, EmpiricalCDF, EmpiricalCDFHi, linprint, logprint, getinverse, getcdfindex, data, counts
export finv

# We probably do not want to import or use these in the package. Let the user do it.
#export mle, KSstatistic, mleKS, scanmle
Expand Down
27 changes: 16 additions & 11 deletions src/cdfs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -206,20 +206,25 @@ Pick a random sample from the distribution represented by `cdf`.
Base.rand(cdf::EmpiricalCDF) = _inverse(cdf,rand())

"""
getinverse(cdf::EmpiricalCDF,x)
return the value of the functional inverse of `cdf` at the point `x`.
finv(cdf::AbstractEmpiricalCDF) --> Function
Return the functional inverse of `cdf`. `cdf` is a callable object.
`finv(cdf)` returns a function that captures `cdf` in a closure.
"""
function getinverse(cdf::EmpiricalCDF,x::Real)
(x < 0 || x >= 1) && throw(DomainError())
_inverse(cdf,x)
function finv(cdf::EmpiricalCDF)
function (c::Real)
(c < 0 || c >= 1) && throw(DomainError())
_inverse(cdf,c)
end
end

function getinverse(cdf::EmpiricalCDFHi,x::Real)
(x < cdf.lowreject || x >= 1) && throw(DomainError())
_inverse(cdf,x)
function finv(cdf::EmpiricalCDFHi)
function (c::Real)
(c < cdf.lowreject || c >= 1) && throw(DomainError())
_inverse(cdf,c)
end
end


function Base.show(io::IO, cdf::EmpiricalCDF)
print(io, string(typeof(cdf)))
print(io, "(n=")
Expand Down Expand Up @@ -287,7 +292,7 @@ function _printfull(io, cdf::AbstractEmpiricalCDF, prpts; lastpt=false)
(p,state) = next(prpts,state)
ulim = lastpt ? n : n - 1 # usually don't print ordinate value of 1
# println("ulim is ", ulim)
for i in 1:ulim
for i in 1:ulim
@inbounds xp = cdf.xdata[i]
if done(prpts,state)
break
Expand Down Expand Up @@ -330,7 +335,7 @@ function _printcdf(io::IO, cdf::AbstractEmpiricalCDF, logprint::Bool, nprint_pts
_printcdf(io, cdf, prpts; lastpt=lastpt)
end

# FIXME We need to avoid resorting
# FIXME: We need to avoid resorting
function _printcdf(io::IO, cdf::AbstractEmpiricalCDF, prpts::AbstractArray; lastpt=false)
x = cdf.xdata
sort!(x)
Expand Down
4 changes: 2 additions & 2 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ sort!(cdf1)
@test cdf0(.4) != cdf1(.4)
@test cdf0(.6) == cdf1(.6)

@test getinverse(cdf0,1-eps(1.0)) == maximum(cdf0) # last point is as close to 1 as possible
@test getinverse(cdf1,1-eps(1.0)) == maximum(cdf1)
@test finv(cdf0)(1-eps(1.0)) == maximum(cdf0) # last point is as close to 1 as possible
@test finv(cdf1)(1-eps(1.0)) == maximum(cdf1)

infile = joinpath(@__DIR__, "paretocdf.bin")

Expand Down

0 comments on commit 4825319

Please sign in to comment.