Skip to content

Commit

Permalink
fix a stopping criterions summary and further test coverage.
Browse files Browse the repository at this point in the history
  • Loading branch information
kellertuer committed Jun 13, 2024
1 parent 1110082 commit 956db4b
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 9 deletions.
17 changes: 10 additions & 7 deletions src/solvers/cma_es.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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])
Expand Down Expand Up @@ -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
Expand All @@ -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 ""
Expand Down
6 changes: 4 additions & 2 deletions test/solvers/test_cma_es.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 956db4b

Please sign in to comment.