Skip to content

Commit

Permalink
add exception status
Browse files Browse the repository at this point in the history
  • Loading branch information
tmigot committed Feb 21, 2021
1 parent 2c85236 commit dd5c913
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 84 deletions.
2 changes: 1 addition & 1 deletion src/Stopping.jl
Expand Up @@ -171,7 +171,7 @@ function show(io :: IO, stp :: AbstractStopping)
print("Problem is ")
show(io, stp.pb)
catch
print("Problem is $(typeof(stp.pb)).")
print("Problem is $(typeof(stp.pb)). ")
end
if !isnothing(stp.stopping_user_struct)
try
Expand Down
51 changes: 28 additions & 23 deletions src/Stopping/GenericStoppingmod.jl
Expand Up @@ -670,8 +670,10 @@ status: returns the status of the algorithm:
`status(:: AbstractStopping; list = false)`
The different status are:
The different statuses are:
- Optimal: reached an optimal solution.
- SubProblemFailure
- SubOptimal: reached an acceptable solution.
- Unbounded: current iterate too large in norm.
- UnboundedPb: unbouned problem.
- Stalled: stalled algorithm.
Expand All @@ -685,34 +687,37 @@ The different status are:
considered feasible.
- StopByUser: stopped by the user.
- DomainError: there is a NaN somewhere.
- Exception: unhandled exception
- Unknwon: if stopped for reasons unknown by Stopping.
Note:
- Set keyword argument *list* to true, to get an Array with all the status.
- The different status correspond to boolean values in the MetaData, see *StoppingMeta*.
"""
function status(stp :: AbstractStopping; list = false)

tt = Dict([(:Optimal, :optimal),
(:SubProblemFailure, :fail_sub_pb),
(:SubOptimal, :suboptimal),
(:Unbounded, :unbounded),
(:UnboundedPb, :unbounded_pb),
(:Stalled, :stalled),
(:IterationLimit, :iteration_limit),
(:TimeLimit, :tired),
(:EvaluationLimit, :resources),
(:ResourcesOfMainProblemExhausted, :main_pb),
(:Infeasible, :infeasible),
(:StopByUser, :stopbyuser),
(:DomainError, :domainerror)])

if list
list_status = findall(x -> getfield(stp.meta, x), tt)
if list_status == zeros(0) list_status = [:Unknown] end
else
list_status = findfirst(x -> getfield(stp.meta, x), tt)
if isnothing(list_status) list_status = :Unknown end
end
tt = Dict([(:Optimal, :optimal),
(:SubProblemFailure, :fail_sub_pb),
(:SubOptimal, :suboptimal),
(:Unbounded, :unbounded),
(:UnboundedPb, :unbounded_pb),
(:Stalled, :stalled),
(:IterationLimit, :iteration_limit),
(:TimeLimit, :tired),
(:EvaluationLimit, :resources),
(:ResourcesOfMainProblemExhausted, :main_pb),
(:Infeasible, :infeasible),
(:StopByUser, :stopbyuser),
(:Exception, :exception),
(:DomainError, :domainerror)])

if list
list_status = findall(x -> getfield(stp.meta, x), tt)
if list_status == zeros(0) list_status = [:Unknown] end
else
list_status = findfirst(x -> getfield(stp.meta, x), tt)
if isnothing(list_status) list_status = :Unknown end
end

return list_status
return list_status
end
116 changes: 60 additions & 56 deletions src/Stopping/StoppingMetamod.jl
Expand Up @@ -34,7 +34,8 @@ Attributes:
- main_pb : status.
- domainerror : status.
- suboptimal : status.
- stopbyuser : status
- stopbyuser : status.
- exception : status.
- meta_user_struct : Any
- user_check_func! : Function (AbstractStopping, Bool) -> callback.
Expand Down Expand Up @@ -62,55 +63,56 @@ mutable struct StoppingMeta{TolType <: Number,
IntType <: Int
} <: AbstractStoppingMeta

# problem tolerances
atol :: TolType # absolute tolerance
rtol :: TolType # relative tolerance
optimality0 :: TolType # value of the optimality residual at starting point
tol_check :: Function #function of atol, rtol and optimality0
#by default: tol_check = max(atol, rtol * optimality0)
#other example: atol + rtol * optimality0
tol_check_neg :: Function # function of atol, rtol and optimality0
check_pos :: CheckType #pre-allocation for positive tolerance
check_neg :: CheckType #pre-allocation for negative tolerance
optimality_check :: Function # stopping criterion
# Function of (pb, state; kwargs...)
#return type :: Union{Number, eltype(stp.meta)}
retol :: Bool #true if tolerances are updated

unbounded_threshold :: TolType # beyond this value, the problem is declared unbounded
unbounded_x :: TolType # beyond this value, ||x||_\infty is unbounded

# fine grain control on ressources
max_f :: IntType # max function evaluations allowed TODO: used?
max_cntrs :: Dict{Symbol,Int64} #contains the detailed max number of evaluations

# global control on ressources
max_eval :: IntType # max evaluations (f+g+H+Hv) allowed TODO: used?
max_iter :: IntType # max iterations allowed
max_time :: Float64 # max elapsed time allowed

#intern Counters
nb_of_stop :: IntType
#intern start_time
start_time :: Float64

# stopping properties status of the problem)
fail_sub_pb :: Bool
unbounded :: Bool
unbounded_pb :: Bool
tired :: Bool
stalled :: Bool
iteration_limit :: Bool
resources :: Bool
optimal :: Bool
infeasible :: Bool
main_pb :: Bool
domainerror :: Bool
suboptimal :: Bool
stopbyuser :: Bool

meta_user_struct :: MUS
user_check_func! :: Function #called dans Stopping._user_check!(stp, x)
# problem tolerances
atol :: TolType # absolute tolerance
rtol :: TolType # relative tolerance
optimality0 :: TolType # value of the optimality residual at starting point
tol_check :: Function #function of atol, rtol and optimality0
#by default: tol_check = max(atol, rtol * optimality0)
#other example: atol + rtol * optimality0
tol_check_neg :: Function # function of atol, rtol and optimality0
check_pos :: CheckType #pre-allocation for positive tolerance
check_neg :: CheckType #pre-allocation for negative tolerance
optimality_check :: Function # stopping criterion
# Function of (pb, state; kwargs...)
#return type :: Union{Number, eltype(stp.meta)}
retol :: Bool #true if tolerances are updated

unbounded_threshold :: TolType # beyond this value, the problem is declared unbounded
unbounded_x :: TolType # beyond this value, ||x||_\infty is unbounded

# fine grain control on ressources
max_f :: IntType # max function evaluations allowed TODO: used?
max_cntrs :: Dict{Symbol,Int64} #contains the detailed max number of evaluations

# global control on ressources
max_eval :: IntType # max evaluations (f+g+H+Hv) allowed TODO: used?
max_iter :: IntType # max iterations allowed
max_time :: Float64 # max elapsed time allowed

#intern Counters
nb_of_stop :: IntType
#intern start_time
start_time :: Float64

# stopping properties status of the problem)
fail_sub_pb :: Bool
unbounded :: Bool
unbounded_pb :: Bool
tired :: Bool
stalled :: Bool
iteration_limit :: Bool
resources :: Bool
optimal :: Bool
infeasible :: Bool
main_pb :: Bool
domainerror :: Bool
suboptimal :: Bool
stopbyuser :: Bool
exception :: Bool

meta_user_struct :: MUS
user_check_func! :: Function #called dans Stopping._user_check!(stp, x)

end

Expand All @@ -135,10 +137,10 @@ function StoppingMeta(;atol :: Number = 1.0e-6,
check_pos = tol_check(atol, rtol, optimality0)
check_neg = tol_check_neg(atol, rtol, optimality0)

# This might be an expansive step.
# if (true in (check_pos .< check_neg)) #any(x -> x, check_pos .< check_neg)
# throw(ErrorException("StoppingMeta: tol_check should be greater than tol_check_neg."))
# end
# This might be an expansive step.
# if (true in (check_pos .< check_neg)) #any(x -> x, check_pos .< check_neg)
# throw(ErrorException("StoppingMeta: tol_check should be greater than tol_check_neg."))
# end

fail_sub_pb = false
unbounded = false
Expand All @@ -153,6 +155,7 @@ function StoppingMeta(;atol :: Number = 1.0e-6,
domainerror = false
suboptimal = false
stopbyuser = false
exception = false

nb_of_stop = 0

Expand All @@ -165,7 +168,7 @@ function StoppingMeta(;atol :: Number = 1.0e-6,
max_time, nb_of_stop, start_time,
fail_sub_pb, unbounded, unbounded_pb, tired, stalled,
iteration_limit, resources, optimal, infeasible, main_pb,
domainerror, suboptimal, stopbyuser,
domainerror, suboptimal, stopbyuser, exception,
meta_user_struct, user_check_func!)
end

Expand All @@ -181,7 +184,8 @@ const meta_statuses = [:fail_sub_pb,
:main_pb,
:domainerror,
:infeasible,
:stopbyuser]
:stopbyuser,
:exception]

"""
`OK_check(meta :: StoppingMeta)`
Expand Down
8 changes: 4 additions & 4 deletions test/test-stopping/test-unitaire-linearalgebrastopping.jl
Expand Up @@ -126,21 +126,21 @@ op_stop = LAStopping(LinearSystem(LinearOperator(A), b),
opbis_stop = LAStopping(LinearOperator(A), b)

try
@time RandomizedBlockKaczmarz(la_stop)
@timed RandomizedBlockKaczmarz(la_stop)
@test status(la_stop) == :Optimal
@time RandomizedBlockKaczmarz(sa_stop)
@timed RandomizedBlockKaczmarz(sa_stop)
@test status(sa_stop) == :Optimal
catch
@warn "If LSSModel.A does not exist consider [la_stop.pb.Avals[i,j] for (i) in la_stop.pb.Arows, j in la_stop.pb.Acols]"
#https://github.com/JuliaSmoothOptimizers/NLPModels.jl/blob/master/src/lls_model.jl
end

@time RandomizedBlockKaczmarz(op_stop)
@timed RandomizedBlockKaczmarz(op_stop)
@test status(op_stop) == :Optimal

update!(la_stop.current_state, x = xref)
@test normal_equation_check(la_stop.pb, la_stop.current_state) <= la_stop.meta.atol
update!(op_stop.current_state, x = xref)
@test normal_equation_check(op_stop.pb, op_stop.current_state) <= la_stop.meta.atol

end
end
1 change: 1 addition & 0 deletions test/test-stopping/unit-test-stopping-meta.jl
Expand Up @@ -29,6 +29,7 @@
@test test_meta.suboptimal == false
@test test_meta.main_pb == false
@test test_meta.stopbyuser == false
@test test_meta.exception == false
@test test_meta.infeasible == false
@test test_meta.nb_of_stop == 0
@test test_meta.meta_user_struct == nothing
Expand Down

0 comments on commit dd5c913

Please sign in to comment.