Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
review arguments and documentation
  • Loading branch information
Evgeny Metelkin committed May 8, 2022
1 parent f63e109 commit ead9521
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 81 deletions.
7 changes: 2 additions & 5 deletions TODO.md
@@ -1,8 +1,5 @@
# TODO

- set modified abstol for log transformation
- `loss_grad`, `scan_grad` for :LIN_EXTRAPOL, :QUADR_EXTRAPOL
- remove bound for scanned parameter
- use fitting reset as an option
- review kwargs
- update documentation
- review `plot_interval`, `profile`, `update_profile_endpoint!`
- ? use fitting reset as an option
4 changes: 1 addition & 3 deletions src/cico_one_pass.jl
Expand Up @@ -155,7 +155,7 @@ function get_right_endpoint(
end

return res
end # get_right_endpoint
end

function get_right_endpoint(
theta_init::Vector{Float64}, # initial point of parameters
Expand Down Expand Up @@ -205,5 +205,3 @@ function get_right_endpoint(
#kwargs...
)
end

# struct OutOfBoundException <: Exception end
50 changes: 41 additions & 9 deletions src/get_endpoint.jl
Expand Up @@ -89,10 +89,11 @@ unscaling(::Nothing, ::Symbol) = nothing
scale[theta_num]
),
scan_tol::Float64 = 1e-3,
loss_tol::Float64 = 1e-3,
loss_tol::Float64 = 0.,
local_alg::Symbol = :LN_NELDERMEAD,
silent::Bool = false,
kwargs...
max_iter::Int = 10^5,
loss_grad::Union{Function, Symbol} = :EMPTY,
silent::Bool = false
)
Calculates confidence interval's right or left endpoints for a given parameter `theta_num`.
Expand All @@ -108,9 +109,23 @@ Calculates confidence interval's right or left endpoints for a given parameter `
- `direction`: `:right` or `:left` endpoint to estimate.
## Keyword arguments
- `loss_crit` : critical level of loss function. Confidence interval's endpoint value is the intersection point of profile likelihood and `loss_crit` level.
- `scale` : vector of scale transformations for each parameters' component. Possible values: `:direct` (`:lin`), `:log`, `:logit`. This option can speed up the optimization, especially for wide `theta_bounds`. The default value is `:direct` (no transformation) for all parameters.
- `theta_bounds` : vector of tuple `(lower_bound, upper_bound)` for each parameter. Bounds define the ranges for possible parameter values. Default bounds are `(-Inf,Inf)`.
- `scan_bound` : value which states the area of confidence point analysis.
- `scan_tol` : Absolute tolerance for `theta_num` parameter used as termination criterion.
- `loss_tol` : Absolute tolerance controlling `loss_func` closenes to `loss_crit` (termination criterion). Currently doesn't work for `:CICO_ONE_PASS` method because of limitation in `LN_AUGLAG` interface.
- `local_alg` : algorithm of optimization. Derivative-free and gradient-based algorithms form NLopt package.
- `max_iter` : maximal number of fitter iterations. If reaches the result status will be `:MAX_ITER_STOP`.
- `loss_grad` : For gradient optimization methods it is necessary to set how the gradient of `loss_func` should be calculated.
There are options:
- `:EMPTY` (default) no gradient is set. It works only for gradient-free methods.
- `:AUTODIFF` means autodifferentiation from `ForwardDiff` package is used.
- `:FINITE` means finite difference method from `Calculus` is used.
- It is also possible to set gradient function here `function(x::Vector{Float64})` which returns gradient vector.
- `silent` : Boolean argument declaring whether we display the optimization progress. Default is `false`
see also [`get_interval`](@ref)
See also [`get_interval`](@ref)
"""
function get_endpoint(
theta_init::Vector{Float64},
Expand Down Expand Up @@ -246,8 +261,7 @@ function get_endpoint(
Val(method);
theta_bounds = theta_bounds_gd,
scan_bound = scan_bound_gd,
scan_tol = scan_tol,
#scan_rtol
scan_tol,
loss_tol,
local_alg,
max_iter,
Expand Down Expand Up @@ -299,7 +313,7 @@ end
scale[theta_num]
),
scan_tol::Float64 = 1e-3,
loss_tol::Float64 = 1e-3,
loss_tol::Float64 = 0.,
local_alg::Symbol = :LN_NELDERMEAD,
kwargs...
)
Expand All @@ -317,8 +331,27 @@ Calculates confidence interval's right or left endpoints for a function of param
- `direction`: `:right` or `:left` endpoint to estimate.
## Keyword arguments
see [`get_interval`](@ref)
- `loss_crit`: critical level of loss function. Confidence interval's endpoint value is the intersection point of profile likelihood and `loss_crit` level.
- `scale`: vector of scale transformations for each parameters' component. Possible values: `:direct` (`:lin`), `:log`, `:logit`. This option can speed up the optimization, especially for wide `theta_bounds`. The default value is `:direct` (no transformation) for all parameters.
- `theta_bounds`: vector of tuple `(lower_bound, upper_bound)` for each parameter. Bounds define the ranges for possible parameter values. Default bounds are `(-Inf,Inf)`.
- `scan_bound`: value which states the area of confidence point analysis.
- `scan_tol`: Absolute tolerance for `theta_num` parameter used as termination criterion.
- `loss_tol`: Absolute tolerance controlling `loss_func` closenes to `loss_crit` (termination criterion). Currently doesn't work for `:CICO_ONE_PASS` method because of limitation in `LN_AUGLAG` interface.
- `local_alg`: algorithm of optimization. Derivative-free and gradient-based algorithms form NLopt package.
- `max_iter` : maximal number of fitter iterations. If reaches the result status will be `:MAX_ITER_STOP`.
- `scan_grad` : For gradient optimization methods it is necessary to set how the gradient of `scan_func` should be calculated.
- `:EMPTY` (default) no gradient is set. It works only for gradient-free methods.
- `:AUTODIFF` means autodifferentiation from `ForwardDiff` package is used.
- `:FINITE` means finite difference method from `Calculus` is used.
- `function(x::Vector{Float64})` which returns gradient vector.
- `loss_grad` : For gradient optimization methods it is necessary to set how the gradient of `loss_func` should be calculated.
- `:EMPTY` (default) no gradient is set. It works only for gradient-free methods.
- `:AUTODIFF` means autodifferentiation from `ForwardDiff` package is used.
- `:FINITE` means finite difference method from `Calculus` is used.
- `function(x::Vector{Float64})` which returns gradient vector.
- `silent` : Boolean argument declaring whether we display the optimization progress. Default is `false`
See also [`get_interval`](@ref)
"""
function get_endpoint(
theta_init::Vector{Float64},
Expand Down Expand Up @@ -473,7 +506,6 @@ function get_endpoint(
theta_bounds = theta_bounds_gd,
scan_bound = scan_bound_gd,
scan_tol,
# scan_rtol, # not required
loss_tol,
local_alg,
max_iter,
Expand Down
88 changes: 27 additions & 61 deletions src/get_interval.jl
@@ -1,36 +1,30 @@
abstract type AbstractIntervalInput end

"""
struct ParamIntervalInput
struct ParamIntervalInput <: AbstractIntervalInput
theta_init::Vector{Float64} # initial parameters vector
theta_num::Int # number of the parameter for identifiability analysis
scan_func::Function # scan function
loss_func::Function # loss function
loss_crit::Float64 # loss function maximum value, "identifiability level"
scale::Vector{Symbol}
theta_bounds::Vector{Tuple{Float64, Float64}} # search bounds for id parameter
scan_bounds::Tuple{Float64,Float64}
scan_tol::Float64 # fitting tolerance for local optimizer (default - `1e-3`)
loss_tol::Float64 # constraints tolerance
local_alg::Symbol # local fitting algorithm (default - `:LN_NELDERMEAD`)
theta_num::Int # number of the parameter for identifiability analysis
loss_func::Function # loss function
method::Symbol
options::Any
end
Structure storing input data for parameter identification
"""
struct ParamIntervalInput
struct ParamIntervalInput <: AbstractIntervalInput
theta_init::Vector{Float64} # initial parameters vector
theta_num::Int # number of the parameter for analysis
scan_func::Function
loss_func::Function # loss function
method::Symbol
scale::Vector{Symbol}
#loss_crit::Float64 # loss function maximum value, "identifiability level"
#scale::Vector{Symbol}
#theta_bounds::Vector{Tuple{Float64, Float64}} # search bounds for id parameter
scan_bounds::Tuple{Float64,Float64}
#scan_tol::Float64 # fitting tolerance for local optimizer (default - 1e-3)
#loss_tol::Float64 # constraints tolerance
#local_alg::Symbol # local fitting algorithm (default - :LN_NELDERMEAD)
options::Any
options::Dict{Symbol, Any}
end

struct PredictionIntervalInput <: AbstractIntervalInput
theta_init::Vector{Float64}
scan_func::Function
loss_func::Function
method::Symbol
options::Dict{Symbol, Any}
end

"""
Expand All @@ -44,35 +38,26 @@ end
Structure storing result of parameter identification
"""
struct ParamInterval
input::ParamIntervalInput
input::AbstractIntervalInput
loss_init::Float64
method::Symbol
result::Tuple{EndPoint, EndPoint}
end

"""
get_interval(
function get_interval(
theta_init::Vector{Float64},
theta_num::Int,
loss_func::Function,
method::Symbol;
loss_crit::Float64 = 0.0,
scale::Vector{Symbol} = fill(:direct, length(theta_init)),
theta_bounds::Vector{Tuple{Float64,Float64}} = unscaling.(
fill((-Inf, Inf), length(theta_init)),
scale
),
scan_bounds::Tuple{Float64,Float64} = unscaling.(
(-9.0, 9.0),
scale[theta_num]
),
scan_tol::Float64 = 1e-3,
loss_tol::Float64 = 1e-3,
local_alg::Symbol = :LN_NELDERMEAD,
autodiff::Bool = true,
kwargs...
)
)
Computes confidence interval for single component `theta_num` of parameter vector.
## Return
Expand All @@ -85,16 +70,9 @@ Computes confidence interval for single component `theta_num` of parameter vecto
- `method`: computational method to estimate confidence interval's endpoint. Currently the following methods are implemented: `:CICO_ONE_PASS`, `:LIN_EXTRAPOL`, `:QUADR_EXTRAPOL`.
## Keyword arguments
- `loss_crit`: critical level of loss function. Confidence interval's endpoint value is the intersection point of profile likelihood and `loss_crit` level.
- `scale`: vector of scale transformations for each parameters' component. Possible values: `:direct` (`:lin`), `:log`, `:logit`. This option can speed up the optimization, especially for wide `theta_bounds`. The default value is `:direct` (no transformation) for all parameters.
- `theta_bounds`: vector of tuple `(lower_bound, upper_bound)` for each parameter. Bounds define the ranges for possible parameter values. Default bounds are `(-Inf,Inf)`.
- `scan_bounds`: scan bounds tuple for `theta_num` parameter. Should be within the `theta_bounds` for `theta_num` parameter. Default is `(1e-9,1e9)`.
- `scan_tol`: Absolute tolerance for `theta_num` parameter used as termination criterion.
- `loss_tol`: Absolute tolerance controlling `loss_func` closenes to `loss_crit` (termination criterion). Currently doesn't work for `:CICO_ONE_PASS` method because of limitation in `LN_AUGLAG` interface.
- `local_alg`: algorithm of optimization. Derivative-free and gradient-based algorithms form NLopt package.
- `autodiff` : whether to use automatic differentiation with gradient-based algorithms. Default is `true`.
- `kwargs...`: the additional `method` specific keyword arguments.
- `scan_bounds`: scan bounds tuple for `theta_num` parameter. Should be within the `theta_bounds` for `theta_num` parameter. Default is `(-9.,9.)` for `:direct` scales and `(1e-9, 1e+9)` for `:log`.
- `kwargs...`: the additional arguments passed to [`get_endpoint`](@ref)
"""
function get_interval(
theta_init::Vector{Float64},
Expand Down Expand Up @@ -125,12 +103,9 @@ function get_interval(
input = ParamIntervalInput(
theta_init,
theta_num,
(x) -> x[theta_num],
loss_func,
method,
scale,
scan_bounds,
kwargs
Dict(:scale=>scale, :scan_bounds=>scan_bounds, kwargs...) # ? NamedTuple
)

ParamInterval(
Expand Down Expand Up @@ -160,7 +135,7 @@ end
:direct
),
scan_tol::Float64 = 1e-3,
loss_tol::Float64 = 1e-3,
loss_tol::Float64 = 0.,
local_alg::Symbol = :LN_NELDERMEAD,
autodiff::Bool = true,
kwargs...
Expand All @@ -177,15 +152,9 @@ Computes confidence interval for function of parameters `scan_func`.
- `method`: computational method to estimate confidence interval's endpoint. Currently supports only `:CICO_ONE_PASS` method.
## Keyword arguments
- `loss_crit`: critical level of loss function. Confidence interval's endpoint value is the intersection point of profile likelihood and `loss_crit` level.
- `scale`: vector of scale transformations for each parameters' component. Possible values: `:direct` (`:lin`), `:log`, `:logit`. This option can speed up the optimization, especially for wide `theta_bounds`. The default value is `:direct` (no transformation) for all parameters.
- `theta_bounds`: vector of tuple `(lower_bound, upper_bound)` for each parameter. Bounds define the ranges for possible parameter values. Default bounds are `(-Inf,Inf)`.
- `scan_bounds`: scan bounds tuple for `scan_func` values. Default is `(1e-9, 1e9)` .
- `scan_tol`: Absolute tolerance for `theta_num` parameter used as termination criterion.
- `loss_tol`: Absolute tolerance controlling `loss_func` closenes to `loss_crit` (termination criterion). Currently doesn't work for `:CICO_ONE_PASS` method because of limitation in `LN_AUGLAG` interface.
- `local_alg`: algorithm of optimization. Derivative-free and gradient-based algorithms form NLopt package.
- `autodiff` : whether to use automatic differentiation with gradient-based algorithms. Default is `true`.
- `kwargs...`: the additional `method` specific keyword arguments.
- `kwargs...`: the additional arguments passed to [`get_endpoint`](@ref)
"""
function get_interval(
theta_init::Vector{Float64},
Expand Down Expand Up @@ -213,15 +182,12 @@ function get_interval(
kwargs...
) for i in 1:2]

input = ParamIntervalInput(
input = PredictionIntervalInput(
theta_init,
0,
scan_func,
loss_func,
method,
scale,
scan_bounds,
kwargs
Dict(:scale=>scale, :scan_bounds=>scan_bounds, kwargs...) # ? NamedTuple
)

ParamInterval(
Expand All @@ -230,4 +196,4 @@ function get_interval(
method,
Tuple(endpoints)
)
end
end
2 changes: 1 addition & 1 deletion src/get_optimal.jl
Expand Up @@ -33,7 +33,7 @@ Currently it uses standard NLopt optimization but allows to use parameter scalin
- `scan_tol`: Absolute tolerance for all component of theta used as termination criterion.
- `loss_tol`: Absolute tolerance controlling `loss_func`.
- `local_alg`: algorithm of optimization. Derivative-free and gradient-based algorithms form NLopt package.
- `max_iter` : maximal number of optimizator iterations.
- `max_iter` : maximal number of optimizer iterations.
- `loss_grad` : This option declares the method for calcuting loss function gradient.
This is required for gradient-based methods. The possible values
- `:EMPTY` (default) not gradient is set. IT works only for gradient-free methods.
Expand Down
4 changes: 2 additions & 2 deletions src/show.jl
Expand Up @@ -14,15 +14,15 @@ function Base.show(io::IO, mime::MIME"text/plain", pe::ParamInterval)
left_interval_point = if pe.result[1].status === :BORDER_FOUND_BY_SCAN_TOL || pe.result[1].status === :BORDER_FOUND_BY_LOSS_TOL
round(pe.result[1].value, sigdigits=4)
elseif pe.result[1].status === :SCAN_BOUND_REACHED
bound_1 = pe.input.scan_bounds[1]
bound_1 = pe.input.options[:scan_bounds][1]
"<$(round(bound_1, sigdigits=4))"
else
pe.result[1].value
end
right_interval_point = if pe.result[2].status === :BORDER_FOUND_BY_SCAN_TOL || pe.result[2].status === :BORDER_FOUND_BY_LOSS_TOL
round(pe.result[2].value, sigdigits=4)
elseif pe.result[2].status === :SCAN_BOUND_REACHED
bound_2 = pe.input.scan_bounds[2]
bound_2 = pe.input.options[:scan_bounds][2]
">$(round(bound_2, sigdigits=4))"
else
pe.result[2].value
Expand Down

0 comments on commit ead9521

Please sign in to comment.