From 24816cae357d551fd937fdd04371ea7e47545220 Mon Sep 17 00:00:00 2001 From: Dr Rafael Bailo Date: Thu, 7 Mar 2024 16:46:10 +0000 Subject: [PATCH] Unit tests for stopping criteria and examples --- docs/src/low_level.md | 6 +- docs/src/noise_types.md | 4 +- examples/advanced_usage/anisotropic_noise.jl | 6 ++ examples/advanced_usage/isotropic_noise.jl | 6 ++ examples/low_level/low_level.jl | 6 +- examples/low_level/manual_stepping.jl | 6 +- .../{ConsensusBasedOptimisation.jl => CBO.jl} | 14 ++--- src/CBO/CBO_method.jl | 4 +- src/CBO/corrections.jl | 6 +- src/CBO/is_method_pending.jl | 18 +++--- src/ConsensusBasedX.jl | 2 +- src/ConsensusBasedXLowLevel.jl | 9 ++- src/dynamics/ParticleDynamics.jl | 25 +++++--- src/dynamics/is_dynamic_pending.jl | 22 +++---- src/dynamics/run_dynamic.jl | 26 ++++----- src/interface/maximise.jl | 2 +- src/types/abstract.jl | 6 +- test/CBO/is_method_pending.jl | 57 +++++++++++++++++++ test/dynamics/is_dynamic_pending.jl | 50 ++++++++++++++++ test/examples.jl | 16 ++++++ test/runtests.jl | 3 + 21 files changed, 226 insertions(+), 68 deletions(-) create mode 100644 examples/advanced_usage/anisotropic_noise.jl create mode 100644 examples/advanced_usage/isotropic_noise.jl rename src/CBO/{ConsensusBasedOptimisation.jl => CBO.jl} (94%) create mode 100644 test/CBO/is_method_pending.jl create mode 100644 test/dynamics/is_dynamic_pending.jl create mode 100644 test/examples.jl diff --git a/docs/src/low_level.md b/docs/src/low_level.md index c043cff..4b9090a 100644 --- a/docs/src/low_level.md +++ b/docs/src/low_level.md @@ -1,6 +1,6 @@ # Low-level interface -Internally, the `minimise` routine relies on two constructs: the `ParticleDynamic` and a `ConsensusBasedXMethod`. +Internally, the `minimise` routine relies on two constructs: the `ParticleDynamic` and a `CBXMethod`. ## ConsensusBasedXLowLevel @@ -31,7 +31,7 @@ ConsensusBasedX.ParticleDynamicCache ## `ConsensusBasedOptimisation` -The `ConsensusBasedOptimisation` struct (of type `ConsensusBasedXMethod`) defines the details of the *consensus-based optimisation method* (function evaluations, consensus point...). +The `ConsensusBasedOptimisation` struct (of type `CBXMethod`) defines the details of the *consensus-based optimisation method* (function evaluations, consensus point...). ```@docs ConsensusBasedX.ConsensusBasedOptimisation @@ -39,7 +39,7 @@ ConsensusBasedX.ConsensusBasedOptimisation ### `ConsensusBasedOptimisationCache` -`ConsensusBasedOptimisation` requires a cache, `ConsensusBasedOptimisationCache` (of type `ConsensusBasedXMethodCache`). This can be constructed with: +`ConsensusBasedOptimisation` requires a cache, `ConsensusBasedOptimisationCache` (of type `CBXMethodCache`). This can be constructed with: ```@docs ConsensusBasedX.construct_method_cache ``` diff --git a/docs/src/noise_types.md b/docs/src/noise_types.md index 05858c7..9fad46c 100644 --- a/docs/src/noise_types.md +++ b/docs/src/noise_types.md @@ -4,7 +4,7 @@ By default, ConsensusBasedX.jl uses so-called *isotropic noise* (option `noise = ```math \mathrm{d}X_i(t) = \cdots + \sqrt{2} \sigma \left| X_i(t) - V(t) \right| \mathrm{d}W_i(t), ``` -where ``W_i`` are independent Brownian processes. The intensity of the noise depends on the distance of each particle to the consensus point, ``\left| X_i(t) - V(t) \right|``. +where ``W_i`` are independent Brownian processes. The intensity of the noise depends on the distance of each particle to the consensus point, ``\left| X_i(t) - V(t) \right|``. [Full-code example](https://github.com/PdIPS/ConsensusBasedX.jl/blob/main/examples/advanced_usage/isotropic_noise.jl). ## Anisotropic noise @@ -12,4 +12,4 @@ ConsensusBasedX.jl also offers *anisotropic noise*, given by ```math \mathrm{d}X_i(t) = \cdots + \sqrt{2} \sigma \,\mathrm{diag} \left( X_i(t) - V(t) \right) \mathrm{d}W_i(t). ``` -The intensity of the noise now varies along each dimension. This can be selected with the option `noise = :AnisotropicNoise`. +The intensity of the noise now varies along each dimension. This can be selected with the option `noise = :AnisotropicNoise`. [Full-code example](https://github.com/PdIPS/ConsensusBasedX.jl/blob/main/examples/advanced_usage/anisotropic_noise.jl). diff --git a/examples/advanced_usage/anisotropic_noise.jl b/examples/advanced_usage/anisotropic_noise.jl new file mode 100644 index 0000000..920a6c5 --- /dev/null +++ b/examples/advanced_usage/anisotropic_noise.jl @@ -0,0 +1,6 @@ +using ConsensusBasedX + +f(x) = ConsensusBasedX.Ackley(x, shift = 1) + +config = (; D = 2, noise = :AnisotropicNoise) +minimise(f, config) diff --git a/examples/advanced_usage/isotropic_noise.jl b/examples/advanced_usage/isotropic_noise.jl new file mode 100644 index 0000000..35ebe0a --- /dev/null +++ b/examples/advanced_usage/isotropic_noise.jl @@ -0,0 +1,6 @@ +using ConsensusBasedX + +f(x) = ConsensusBasedX.Ackley(x, shift = 1) + +config = (; D = 2, noise = :IsotropicNoise) +minimise(f, config) diff --git a/examples/low_level/low_level.jl b/examples/low_level/low_level.jl index 1db60f9..d980ab1 100644 --- a/examples/low_level/low_level.jl +++ b/examples/low_level/low_level.jl @@ -8,7 +8,9 @@ f(x) = ConsensusBasedX.Ackley(x, shift = 1) X₀ = [[rand(config.D) for n ∈ 1:(config.N)] for m ∈ 1:(config.M)] correction = HeavisideCorrection() -method = ConsensusBasedOptimisation(f, correction, config.α, config.λ, config.σ) +noise = IsotropicNoise +method = + ConsensusBasedOptimisation(f, correction, noise, config.α, config.λ, config.σ) Δt = 0.1 particle_dynamic = ParticleDynamic(method, Δt) @@ -25,4 +27,4 @@ finalise_dynamic!(particle_dynamic, particle_dynamic_cache) out = wrap_output(X₀, particle_dynamic, particle_dynamic_cache) -@show out.minimiser # should be close to [1, 1] +out.minimiser # should be close to [1, 1] diff --git a/examples/low_level/manual_stepping.jl b/examples/low_level/manual_stepping.jl index 19b450a..8a20647 100644 --- a/examples/low_level/manual_stepping.jl +++ b/examples/low_level/manual_stepping.jl @@ -8,7 +8,9 @@ f(x) = ConsensusBasedX.Ackley(x, shift = 1) X₀ = [[rand(config.D) for n ∈ 1:(config.N)] for m ∈ 1:(config.M)] correction = HeavisideCorrection() -method = ConsensusBasedOptimisation(f, correction, config.α, config.λ, config.σ) +noise = IsotropicNoise +method = + ConsensusBasedOptimisation(f, correction, noise, config.α, config.λ, config.σ) Δt = 0.1 particle_dynamic = ParticleDynamic(method, Δt) @@ -31,4 +33,4 @@ finalise_dynamic!(particle_dynamic, particle_dynamic_cache) out = wrap_output(X₀, particle_dynamic, particle_dynamic_cache) -@show out.minimiser # should be close to [1, 1] +out.minimiser # should be close to [1, 1] diff --git a/src/CBO/ConsensusBasedOptimisation.jl b/src/CBO/CBO.jl similarity index 94% rename from src/CBO/ConsensusBasedOptimisation.jl rename to src/CBO/CBO.jl index 37b1ef0..a4a4312 100644 --- a/src/CBO/ConsensusBasedOptimisation.jl +++ b/src/CBO/CBO.jl @@ -6,16 +6,16 @@ ConsensusBasedOptimisation Fields: - `f`, the objective function. - - `correction<:ConsensusBasedXCorrection`, a correction term. + - `correction<:CBXCorrection`, a correction term. - `α::Float64`, the the exponential weight parameter. - `λ::Float64`, the drift strengh. - `σ::Float64`, the noise strengh. """ mutable struct ConsensusBasedOptimisation{ TF, - TCorrection <: ConsensusBasedXCorrection, + TCorrection <: CBXCorrection, TNoise <: Noises, -} <: ConsensusBasedXMethod +} <: CBXMethod f::TF correction::TCorrection noise::TNoise @@ -26,7 +26,7 @@ end @config function construct_CBO( f, - correction::ConsensusBasedXCorrection, + correction::CBXCorrection, noise::Noises; α::Real = 10, λ::Real = 1, @@ -67,7 +67,7 @@ Fields: - `max_evaluations::Float64`, the maximum number of `f` evaluations. - `evaluations::Vector{Int}`, the current number of `f` evaluations. """ -mutable struct ConsensusBasedOptimisationCache{T} <: ConsensusBasedXMethodCache +mutable struct ConsensusBasedOptimisationCache{T} <: CBXMethodCache consensus::Vector{Vector{T}} consensus_energy::Vector{T} consensus_energy_previous::Vector{T} @@ -133,12 +133,12 @@ end construct_method_cache( config::NamedTuple, X₀::AbstractArray, - method::ConsensusBasedXMethod, + method::CBXMethod, particle_dynamic::ParticleDynamic, ) ``` -A constructor helper for `ConsensusBasedXMethodCache`. +A constructor helper for `CBXMethodCache`. """ construct_method_cache diff --git a/src/CBO/CBO_method.jl b/src/CBO/CBO_method.jl index b2f1458..eaa068b 100644 --- a/src/CBO/CBO_method.jl +++ b/src/CBO/CBO_method.jl @@ -1,6 +1,6 @@ function compute_CBO_consensus!( - method::ConsensusBasedOptimisation, - method_cache::ConsensusBasedOptimisationCache, + method::CBXMethod, + method_cache::CBXMethodCache, particle_dynamic::ParticleDynamic, particle_dynamic_cache::ParticleDynamicCache, m::Int, diff --git a/src/CBO/corrections.jl b/src/CBO/corrections.jl index 066f5dc..0dbd7a0 100644 --- a/src/CBO/corrections.jl +++ b/src/CBO/corrections.jl @@ -1,10 +1,10 @@ -struct NoCorrection <: ConsensusBasedXCorrection end +struct NoCorrection <: CBXCorrection end (c::NoCorrection)(s::Real) = 1.0 -struct HeavisideCorrection <: ConsensusBasedXCorrection end +struct HeavisideCorrection <: CBXCorrection end (c::HeavisideCorrection)(s::Real) = 1.0 * (s > 0) -struct RegularisedHeavisideCorrection <: ConsensusBasedXCorrection +struct RegularisedHeavisideCorrection <: CBXCorrection ε::Float64 end (c::RegularisedHeavisideCorrection)(s::Real) = (1 + tanh(s / c.ε)) / 2 diff --git a/src/CBO/is_method_pending.jl b/src/CBO/is_method_pending.jl index faa2143..212dc17 100644 --- a/src/CBO/is_method_pending.jl +++ b/src/CBO/is_method_pending.jl @@ -5,35 +5,37 @@ function is_method_pending( particle_dynamic_cache::ParticleDynamicCache, m::Int, ) - pending_energy_threshold = is_method_pending_energy_threshold( + if !is_method_pending_energy_threshold( particle_dynamic.method, particle_dynamic_cache.method_cache, particle_dynamic, particle_dynamic_cache, m, ) + return false, "energy_threshold" + end - pending_energy_tolerance = is_method_pending_energy_tolerance( + if !is_method_pending_energy_tolerance( particle_dynamic.method, particle_dynamic_cache.method_cache, particle_dynamic, particle_dynamic_cache, m, ) + return false, "energy_tolerance" + end - pending_max_evaluations = is_method_pending_max_evaluations( + if !is_method_pending_max_evaluations( particle_dynamic.method, particle_dynamic_cache.method_cache, particle_dynamic, particle_dynamic_cache, m, ) + return false, "max_evaluations" + end - pending = - pending_energy_threshold && - pending_energy_tolerance && - pending_max_evaluations - return pending + return true, "method_pending" end function is_method_pending_energy_threshold( diff --git a/src/ConsensusBasedX.jl b/src/ConsensusBasedX.jl index ec9ed7f..8fa57de 100644 --- a/src/ConsensusBasedX.jl +++ b/src/ConsensusBasedX.jl @@ -28,7 +28,7 @@ include("./dynamics/benchmark_dynamic.jl") include("./dynamics/is_dynamic_pending.jl") include("./dynamics/run_dynamic.jl") -include("./CBO/ConsensusBasedOptimisation.jl") +include("./CBO/CBO.jl") include("./CBO/CBO_method.jl") include("./CBO/corrections.jl") include("./CBO/is_method_pending.jl") diff --git a/src/ConsensusBasedXLowLevel.jl b/src/ConsensusBasedXLowLevel.jl index 07efcdb..c8d5e33 100644 --- a/src/ConsensusBasedXLowLevel.jl +++ b/src/ConsensusBasedXLowLevel.jl @@ -3,8 +3,8 @@ module ConsensusBasedXLowLevel using Reexport @reexport import ..AnisotropicNoise, - ..ConsensusBasedXMethod, - ..ConsensusBasedXMethodCache, + ..CBXMethod, + ..CBXMethodCache, ..ConsensusBasedOptimisation, ..ConsensusBasedOptimisationCache, ..HeavisideCorrection, @@ -24,11 +24,16 @@ using Reexport ..Quadratic, ..compute_dynamic!, ..compute_dynamic_step!, + ..construct_CBO, ..construct_method_cache, + ..construct_particle_dynamic, ..construct_particle_dynamic_cache, ..finalise_dynamic!, + ..initialise_particles, ..initialise_particle_dynamic_cache!, ..initialise_dynamic!, + ..is_dynamic_pending, + ..parse_config, ..wrap_output end diff --git a/src/dynamics/ParticleDynamics.jl b/src/dynamics/ParticleDynamics.jl index 9a6f934..76db73b 100644 --- a/src/dynamics/ParticleDynamics.jl +++ b/src/dynamics/ParticleDynamics.jl @@ -5,10 +5,10 @@ ParticleDynamic Fields: - - `method<:ConsensusBasedXMethod`, the optimisation method. + - `method<:CBXMethod`, the optimisation method. - `Δt::Float64`, the time step. """ -mutable struct ParticleDynamic{TM <: ConsensusBasedXMethod} +mutable struct ParticleDynamic{TM <: CBXMethod} method::TM Δt::Float64 end @@ -29,7 +29,7 @@ Fields: - `mode` should be set to `ParticleMode`. - `parallelisation<:Parallelisations`, the parallelisation mode. - - `method_cache<:ConsensusBasedXMethodCache`, a cache for the `method` field of `ParticleDynamic`. + - `method_cache<:CBXMethodCache`, a cache for the `method` field of `ParticleDynamic`. - `D::Int`, the dimension of the problem. - `N::Int`, the number of particles per ensemble. - `M::Int`, the number of ensembles. @@ -45,7 +45,7 @@ Fields: mutable struct ParticleDynamicCache{ TMode <: Modes, TParallelisation <: Parallelisations, - TMC <: ConsensusBasedXMethodCache, + TMC <: CBXMethodCache, TX, TdX, } @@ -130,13 +130,13 @@ construct_particle_dynamic_cache( ) ``` -A constructor helper for `ParticleDynamicCache`. Calls [`ConsensusBasedX.construct_method_cache`](@ref) to construct the corresponding `ConsensusBasedXMethodCache`. +A constructor helper for `ParticleDynamicCache`. Calls [`ConsensusBasedX.construct_method_cache`](@ref) to construct the corresponding `CBXMethodCache`. """ construct_particle_dynamic_cache @config construct_method_cache( X₀::AbstractArray, - method::ConsensusBasedXMethod, + method::CBXMethod, particle_dynamic::ParticleDynamic, ) = nothing @@ -167,13 +167,22 @@ function set_Δt!(particle_dynamic_cache::ParticleDynamicCache, Δt::Real) particle_dynamic_cache.Δt = Δt particle_dynamic_cache.rootΔt = sqrt(Δt) particle_dynamic_cache.root2Δt = sqrt(2) * particle_dynamic_cache.rootΔt + set_Δt!(particle_dynamic_cache.method_cache, particle_dynamic_cache, Δt) + return nothing +end + +function set_Δt!( + method_cache::CBXMethodCache, + particle_dynamic_cache::ParticleDynamicCache, + Δt::Real, +) return nothing end function initialise_method_cache!( X₀::AbstractArray, - method::ConsensusBasedXMethod, - method_cache::ConsensusBasedXMethodCache, + method::CBXMethod, + method_cache::CBXMethodCache, particle_dynamic::ParticleDynamic, particle_dynamic_cache::ParticleDynamicCache, ) diff --git a/src/dynamics/is_dynamic_pending.jl b/src/dynamics/is_dynamic_pending.jl index c672b16..ba1e1e3 100644 --- a/src/dynamics/is_dynamic_pending.jl +++ b/src/dynamics/is_dynamic_pending.jl @@ -3,25 +3,25 @@ function is_dynamic_pending( particle_dynamic_cache::ParticleDynamicCache, m::Int, ) - pending_max_iterations = is_dynamic_pending_max_iterations( + if !is_dynamic_pending_max_iterations( particle_dynamic, particle_dynamic_cache, m, ) + return false, "max_iterations" + end - pending_max_time = - is_dynamic_pending_max_time(particle_dynamic, particle_dynamic_cache, m) + if !is_dynamic_pending_max_time(particle_dynamic, particle_dynamic_cache, m) + return false, "max_time" + end - pending_method = is_method_pending( + return is_method_pending( particle_dynamic.method, particle_dynamic_cache.method_cache, particle_dynamic, particle_dynamic_cache, m, ) - - pending = pending_max_iterations && pending_max_time && pending_method - return pending end function is_dynamic_pending_max_iterations( @@ -40,15 +40,15 @@ function is_dynamic_pending_max_time( ) @expand particle_dynamic Δt @expand particle_dynamic_cache iteration max_time - return iteration[m] * Δt <= max_time + return iteration[m] * Δt < max_time end function is_method_pending( - method::ConsensusBasedXMethod, - method_cache::ConsensusBasedXMethodCache, + method::CBXMethod, + method_cache::CBXMethodCache, particle_dynamic::ParticleDynamic, particle_dynamic_cache::ParticleDynamicCache, m::Int, ) - return true + return true, "method_pending" end diff --git a/src/dynamics/run_dynamic.jl b/src/dynamics/run_dynamic.jl index 9e50bce..d642e8e 100644 --- a/src/dynamics/run_dynamic.jl +++ b/src/dynamics/run_dynamic.jl @@ -54,8 +54,8 @@ function initialise_dynamic!( end function initialise_method!( - method::ConsensusBasedXMethod, - method_cache::ConsensusBasedXMethodCache, + method::CBXMethod, + method_cache::CBXMethodCache, particle_dynamic::ParticleDynamic, particle_dynamic_cache::ParticleDynamicCache, ) @@ -90,7 +90,7 @@ function compute_dynamic!( particle_dynamic_cache::ParticleDynamicCache, m::Int, ) - while is_dynamic_pending(particle_dynamic, particle_dynamic_cache, m) + while is_dynamic_pending(particle_dynamic, particle_dynamic_cache, m)[1] compute_dynamic_step!(particle_dynamic, particle_dynamic_cache, m) end return nothing @@ -128,8 +128,8 @@ function compute_dynamic_step!( end function prepare_method_step!( - method::ConsensusBasedXMethod, - method_cache::ConsensusBasedXMethodCache, + method::CBXMethod, + method_cache::CBXMethodCache, particle_dynamic::ParticleDynamic, particle_dynamic_cache::ParticleDynamicCache, m::Int, @@ -138,8 +138,8 @@ function prepare_method_step!( end function compute_method_step!( - method::ConsensusBasedXMethod, - method_cache::ConsensusBasedXMethodCache, + method::CBXMethod, + method_cache::CBXMethodCache, particle_dynamic::ParticleDynamic, particle_dynamic_cache::ParticleDynamicCache, m::Int, @@ -157,8 +157,8 @@ function update_dynamic!( end function finalise_method_step!( - method::ConsensusBasedXMethod, - method_cache::ConsensusBasedXMethodCache, + method::CBXMethod, + method_cache::CBXMethodCache, particle_dynamic::ParticleDynamic, particle_dynamic_cache::ParticleDynamicCache, m::Int, @@ -180,8 +180,8 @@ function finalise_dynamic!( end function finalise_method!( - method::ConsensusBasedXMethod, - method_cache::ConsensusBasedXMethodCache, + method::CBXMethod, + method_cache::CBXMethodCache, particle_dynamic::ParticleDynamic, particle_dynamic_cache::ParticleDynamicCache, ) @@ -204,8 +204,8 @@ end function wrap_output( X₀::AbstractArray, - method::ConsensusBasedXMethod, - method_cache::ConsensusBasedXMethodCache, + method::CBXMethod, + method_cache::CBXMethodCache, particle_dynamic::ParticleDynamic, particle_dynamic_cache::ParticleDynamicCache, ) diff --git a/src/interface/maximise.jl b/src/interface/maximise.jl index bed9c54..e8efa67 100644 --- a/src/interface/maximise.jl +++ b/src/interface/maximise.jl @@ -26,7 +26,7 @@ function maximise(f, config::NamedTuple) end end g(x) = -f(x) - return minimise(config, g) + return minimise(g, config) end export maximise diff --git a/src/types/abstract.jl b/src/types/abstract.jl index 6859fa6..57c200b 100644 --- a/src/types/abstract.jl +++ b/src/types/abstract.jl @@ -1,3 +1,3 @@ -abstract type ConsensusBasedXCorrection end -abstract type ConsensusBasedXMethod end -abstract type ConsensusBasedXMethodCache end +abstract type CBXCorrection end +abstract type CBXMethod end +abstract type CBXMethodCache end diff --git a/test/CBO/is_method_pending.jl b/test/CBO/is_method_pending.jl new file mode 100644 index 0000000..cf9e70e --- /dev/null +++ b/test/CBO/is_method_pending.jl @@ -0,0 +1,57 @@ +using ConsensusBasedX, ConsensusBasedX.ConsensusBasedXLowLevel, Test + +function get_objects() + config = parse_config((; D = 2,)) + f(x) = ConsensusBasedX.Ackley(x, shift = 1) + X₀ = reshape(initialise_particles(config), config.mode) + correction = HeavisideCorrection() + method = construct_CBO(config, f, correction, config.noise) + particle_dynamic = construct_particle_dynamic(config, method) + particle_dynamic_cache = + construct_particle_dynamic_cache(config, X₀, particle_dynamic) + initialise_particle_dynamic_cache!( + X₀, + particle_dynamic, + particle_dynamic_cache, + ) + initialise_dynamic!(particle_dynamic, particle_dynamic_cache) + method_cache = particle_dynamic_cache.method_cache + return method, method_cache, particle_dynamic, particle_dynamic_cache +end + +function tests() + m = 1 + + method, method_cache, particle_dynamic, particle_dynamic_cache = get_objects() + method_cache.energy_threshold = eps() + method_cache.consensus_energy[m] = 2 * eps() + @test is_dynamic_pending(particle_dynamic, particle_dynamic_cache, m)[1] + method_cache.consensus_energy[m] = 0 + pending, label = + is_dynamic_pending(particle_dynamic, particle_dynamic_cache, m) + @test !pending + @test label == "energy_threshold" + + method, method_cache, particle_dynamic, particle_dynamic_cache = get_objects() + method_cache.energy_tolerance = 1e-8 + method_cache.consensus_energy[m] = 0 + method_cache.consensus_energy_previous[m] = 1e-7 + @test is_dynamic_pending(particle_dynamic, particle_dynamic_cache, m)[1] + method_cache.consensus_energy_previous[m] = 1e-9 + pending, label = + is_dynamic_pending(particle_dynamic, particle_dynamic_cache, m) + @test !pending + @test label == "energy_tolerance" + + method, method_cache, particle_dynamic, particle_dynamic_cache = get_objects() + method_cache.max_evaluations = 10 + method_cache.evaluations[m] = 9 + @test is_dynamic_pending(particle_dynamic, particle_dynamic_cache, m)[1] + method_cache.evaluations[m] = 10 + pending, label = + is_dynamic_pending(particle_dynamic, particle_dynamic_cache, m) + @test !pending + @test label == "max_evaluations" +end + +tests() diff --git a/test/dynamics/is_dynamic_pending.jl b/test/dynamics/is_dynamic_pending.jl new file mode 100644 index 0000000..7d21b67 --- /dev/null +++ b/test/dynamics/is_dynamic_pending.jl @@ -0,0 +1,50 @@ +using ConsensusBasedX, ConsensusBasedX.ConsensusBasedXLowLevel, Test + +function get_objects() + config = parse_config((; D = 2,)) + f(x) = ConsensusBasedX.Ackley(x, shift = 1) + X₀ = reshape(initialise_particles(config), config.mode) + correction = HeavisideCorrection() + method = construct_CBO(config, f, correction, config.noise) + particle_dynamic = construct_particle_dynamic(config, method) + particle_dynamic_cache = + construct_particle_dynamic_cache(config, X₀, particle_dynamic) + initialise_particle_dynamic_cache!( + X₀, + particle_dynamic, + particle_dynamic_cache, + ) + initialise_dynamic!(particle_dynamic, particle_dynamic_cache) + return particle_dynamic, particle_dynamic_cache +end + +function tests() + m = 1 + + particle_dynamic, particle_dynamic_cache = get_objects() + @test is_dynamic_pending(particle_dynamic, particle_dynamic_cache, m)[1] + + particle_dynamic, particle_dynamic_cache = get_objects() + particle_dynamic_cache.iteration[m] = + particle_dynamic_cache.max_iterations - 1 + @test is_dynamic_pending(particle_dynamic, particle_dynamic_cache, m)[1] + particle_dynamic_cache.iteration[m] = particle_dynamic_cache.max_iterations + pending, label = + is_dynamic_pending(particle_dynamic, particle_dynamic_cache, m) + @test !pending + @test label == "max_iterations" + + particle_dynamic, particle_dynamic_cache = get_objects() + particle_dynamic_cache.max_time = 1.0 + particle_dynamic_cache.iteration[m] = + ceil(Int, particle_dynamic_cache.max_time / particle_dynamic.Δt) - 1 + @test is_dynamic_pending(particle_dynamic, particle_dynamic_cache, m)[1] + particle_dynamic_cache.iteration[m] = + ceil(Int, particle_dynamic_cache.max_time / particle_dynamic.Δt) + pending, label = + is_dynamic_pending(particle_dynamic, particle_dynamic_cache, m) + @test !pending + @test label == "max_time" +end + +tests() diff --git a/test/examples.jl b/test/examples.jl new file mode 100644 index 0000000..2a22a22 --- /dev/null +++ b/test/examples.jl @@ -0,0 +1,16 @@ +tests() = + for (root, dirs, files) ∈ walkdir("../examples") + for file ∈ files + if !contains(file, "visualisation") + path = joinpath(root, file) + test_name = "Example: " * file + @eval begin + @safetestset $test_name begin + @test_nowarn include($path) + end + end + end + end + end + +tests() diff --git a/test/runtests.jl b/test/runtests.jl index de550d2..8e89477 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,10 +4,13 @@ using SafeTestsets, Test @testset "ConsensusBasedX.jl" begin for test ∈ [ + "CBO/is_method_pending", + "dynamics/is_dynamic_pending", "interface/initialise_particles", "interface/minimise", "interface/parse_config", "aqua", + "examples", "format", ] @eval begin