From dd5c913714bfde181516d3a5fb94f7ca8de33d0f Mon Sep 17 00:00:00 2001 From: tmigot Date: Sun, 21 Feb 2021 23:48:20 +0100 Subject: [PATCH] add exception status --- src/Stopping.jl | 2 +- src/Stopping/GenericStoppingmod.jl | 51 ++++---- src/Stopping/StoppingMetamod.jl | 116 +++++++++--------- .../test-unitaire-linearalgebrastopping.jl | 8 +- test/test-stopping/unit-test-stopping-meta.jl | 1 + 5 files changed, 94 insertions(+), 84 deletions(-) diff --git a/src/Stopping.jl b/src/Stopping.jl index 6d3d6f1c..d75b426e 100644 --- a/src/Stopping.jl +++ b/src/Stopping.jl @@ -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 diff --git a/src/Stopping/GenericStoppingmod.jl b/src/Stopping/GenericStoppingmod.jl index 34aec394..3aa164b0 100644 --- a/src/Stopping/GenericStoppingmod.jl +++ b/src/Stopping/GenericStoppingmod.jl @@ -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. @@ -685,6 +687,8 @@ 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. @@ -692,27 +696,28 @@ Note: """ 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 diff --git a/src/Stopping/StoppingMetamod.jl b/src/Stopping/StoppingMetamod.jl index 2fff8ffa..ea838c10 100644 --- a/src/Stopping/StoppingMetamod.jl +++ b/src/Stopping/StoppingMetamod.jl @@ -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. @@ -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 @@ -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 @@ -153,6 +155,7 @@ function StoppingMeta(;atol :: Number = 1.0e-6, domainerror = false suboptimal = false stopbyuser = false + exception = false nb_of_stop = 0 @@ -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 @@ -181,7 +184,8 @@ const meta_statuses = [:fail_sub_pb, :main_pb, :domainerror, :infeasible, - :stopbyuser] + :stopbyuser, + :exception] """ `OK_check(meta :: StoppingMeta)` diff --git a/test/test-stopping/test-unitaire-linearalgebrastopping.jl b/test/test-stopping/test-unitaire-linearalgebrastopping.jl index c7665188..f57668f8 100644 --- a/test/test-stopping/test-unitaire-linearalgebrastopping.jl +++ b/test/test-stopping/test-unitaire-linearalgebrastopping.jl @@ -126,16 +126,16 @@ 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) @@ -143,4 +143,4 @@ update!(la_stop.current_state, x = xref) update!(op_stop.current_state, x = xref) @test normal_equation_check(op_stop.pb, op_stop.current_state) <= la_stop.meta.atol -end \ No newline at end of file +end diff --git a/test/test-stopping/unit-test-stopping-meta.jl b/test/test-stopping/unit-test-stopping-meta.jl index 1f8cc19d..e9d75bf7 100644 --- a/test/test-stopping/unit-test-stopping-meta.jl +++ b/test/test-stopping/unit-test-stopping-meta.jl @@ -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