From 956db4b5de2316de853c12d3ffe41df2f4341f3c Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Thu, 13 Jun 2024 14:50:12 +0200 Subject: [PATCH] fix a stopping criterions summary and further test coverage. --- src/solvers/cma_es.jl | 17 ++++++++++------- test/solvers/test_cma_es.jl | 6 ++++-- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/solvers/cma_es.jl b/src/solvers/cma_es.jl index bc34ab5c93..16e49edbf3 100644 --- a/src/solvers/cma_es.jl +++ b/src/solvers/cma_es.jl @@ -531,7 +531,7 @@ mutable struct StopWhenCovarianceIllConditioned{T<:Real} <: StoppingCriterion at_iteration::Int end function StopWhenCovarianceIllConditioned(threshold::Real=1e14) - return StopWhenCovarianceIllConditioned{typeof(threshold)}(threshold, 1, 0) + return StopWhenCovarianceIllConditioned{typeof(threshold)}(threshold, 1, -1) end indicates_convergence(c::StopWhenCovarianceIllConditioned) = false @@ -696,6 +696,9 @@ function status_summary(c::StopWhenEvolutionStagnates) has_stopped = is_active_stopping_criterion(c) s = has_stopped ? "reached" : "not reached" N = length(c.best_history) + if N == 0 + return "best and median fitness not yet filled, stopping criterion:\t$s" + end thr_low = Int(ceil(N * c.fraction)) thr_high = Int(floor(N * (1 - c.fraction))) median_best_old = median(c.best_history[1:thr_low]) @@ -788,24 +791,24 @@ far too small `σ`, or divergent behavior. This corresponds to `TolXUp` conditio mutable struct StopWhenPopulationDiverges{TParam<:Real} <: StoppingCriterion tol::TParam last_σ_times_maxstddev::TParam - is_active::Bool + at_iteration::Int end function StopWhenPopulationDiverges(tol::Real) - return StopWhenPopulationDiverges{typeof(tol)}(tol, 1.0, false) + return StopWhenPopulationDiverges{typeof(tol)}(tol, 1.0, -1) end indicates_convergence(c::StopWhenPopulationDiverges) = false function is_active_stopping_criterion(c::StopWhenPopulationDiverges) - return c.is_active + return c.at_iteration >= 0 end function (c::StopWhenPopulationDiverges)(::AbstractManoptProblem, s::CMAESState, i::Int) if i == 0 # reset on init - c.is_active = false + c.at_iteration = -1 return false end cur_σ_times_maxstddev = s.σ * maximum(s.deviations) if cur_σ_times_maxstddev / c.last_σ_times_maxstddev > c.tol - c.is_active = true + c.at_iteration = i return true end return false @@ -816,7 +819,7 @@ function status_summary(c::StopWhenPopulationDiverges) return "cur_σ_times_maxstddev / c.last_σ_times_maxstddev > $(c.tol) :\t$s" end function get_reason(c::StopWhenPopulationDiverges) - if c.is_active + if c.at_iteration >= 0 return "σ times maximum standard deviation exceeded $(c.tol). This indicates either much too small σ or divergent behavior.\n" end return "" diff --git a/test/solvers/test_cma_es.jl b/test/solvers/test_cma_es.jl index a88757a8b7..61c036d79e 100644 --- a/test/solvers/test_cma_es.jl +++ b/test/solvers/test_cma_es.jl @@ -141,10 +141,12 @@ flat_example(::AbstractManifold, p) = 0.0 @testset "Special Stopping Criteria" begin sc1 = StopWhenBestCostInGenerationConstant{Float64}(10) sc2 = StopWhenEvolutionStagnates(1, 2, 0.5) + @test contains(Manopt.status_summary(sc2), "not yet filled") sc3 = StopWhenPopulationStronglyConcentrated(0.1) sc4 = StopWhenPopulationCostConcentrated(0.1, 5) - - for sc in [sc1, sc2, sc3, sc4] + sc5 = StopWhenCovarianceIllConditioned(1e-5) + sc6 = StopWhenPopulationDiverges(0.1) + for sc in [sc1, sc2, sc3, sc4, sc5, sc6] @test get_reason(sc) == "" # Manually set is active sc.at_iteration = 10