From 32d8b0670b19cb200541476bc6b529aacf18f9d0 Mon Sep 17 00:00:00 2001 From: Dr Rafael Bailo Date: Fri, 8 Mar 2024 10:54:22 +0000 Subject: [PATCH 1/2] Improve low-level documentation --- docs/src/function_minimisation.md | 2 ++ docs/src/low_level_examples.md | 12 ++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/src/function_minimisation.md b/docs/src/function_minimisation.md index b94191c..8aeb025 100644 --- a/docs/src/function_minimisation.md +++ b/docs/src/function_minimisation.md @@ -41,6 +41,8 @@ or config = (; D = 2) maximise(f, config) ``` +`maximise` will attempt to define `g(x) = -f(x)` and call `minimise(g, config)`. + Full-code examples are provided for the [keyword](https://github.com/PdIPS/ConsensusBasedX.jl/blob/main/examples/basic_usage/maximise_with_keywords.jl) and [config](https://github.com/PdIPS/ConsensusBasedX.jl/blob/main/examples/basic_usage/maximise_with_config.jl) approaches. diff --git a/docs/src/low_level_examples.md b/docs/src/low_level_examples.md index 72148c8..c802112 100644 --- a/docs/src/low_level_examples.md +++ b/docs/src/low_level_examples.md @@ -14,7 +14,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) @@ -30,6 +32,8 @@ compute_dynamic!(particle_dynamic, particle_dynamic_cache) finalise_dynamic!(particle_dynamic, particle_dynamic_cache) out = wrap_output(X₀, particle_dynamic, particle_dynamic_cache) + +@show out.minimiser ``` [Full-code example](https://github.com/PdIPS/ConsensusBasedX.jl/blob/main/examples/low_level/low_level.jl). @@ -45,7 +49,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) @@ -67,5 +73,7 @@ end finalise_dynamic!(particle_dynamic, particle_dynamic_cache) out = wrap_output(X₀, particle_dynamic, particle_dynamic_cache) + +@show out.minimiser ``` [Full-code example](https://github.com/PdIPS/ConsensusBasedX.jl/blob/main/examples/low_level/manual_stepping.jl). From ef0fc91e8c8edb447fa4c625f0c8b3e1017c8005 Mon Sep 17 00:00:00 2001 From: Dr Rafael Bailo Date: Fri, 8 Mar 2024 12:01:20 +0000 Subject: [PATCH 2/2] Additional unit tests --- src/ConsensusBasedXLowLevel.jl | 2 ++ src/interface/maximise.jl | 17 +++++-------- test/CBO/corrections.jl | 24 ++++++++++++++++++ test/interface/maximise.jl | 20 +++++++++++++++ test/interface/parse_config.jl | 45 ++++++++++++---------------------- test/runtests.jl | 3 +++ test/tuples/tuples.jl | 16 ++++++++++++ test/tuples/types.jl | 10 ++++++++ 8 files changed, 96 insertions(+), 41 deletions(-) create mode 100644 test/CBO/corrections.jl create mode 100644 test/interface/maximise.jl create mode 100644 test/tuples/tuples.jl create mode 100644 test/tuples/types.jl diff --git a/src/ConsensusBasedXLowLevel.jl b/src/ConsensusBasedXLowLevel.jl index c8d5e33..bc9e665 100644 --- a/src/ConsensusBasedXLowLevel.jl +++ b/src/ConsensusBasedXLowLevel.jl @@ -29,6 +29,8 @@ using Reexport ..construct_particle_dynamic, ..construct_particle_dynamic_cache, ..finalise_dynamic!, + ..forced_convert_2_NamedTuple, + ..get_val, ..initialise_particles, ..initialise_particle_dynamic_cache!, ..initialise_dynamic!, diff --git a/src/interface/maximise.jl b/src/interface/maximise.jl index e8efa67..fa81a99 100644 --- a/src/interface/maximise.jl +++ b/src/interface/maximise.jl @@ -16,19 +16,14 @@ Attempts to define `x -> -f(x)` and calls the `minimise` routine. This might be See also [`minimise`](@ref). """ function maximise(f, config::NamedTuple) - if haskey(config, :mode) - if !(config.mode isa TParticleMode) - explanation = - "ConsensusBasedX.jl cannot define the function `x -> -f(x)` in mode `" * - string(get_val(config.mode)) * - "`. You should define the function yourself and call `minimise` instead." - throw(ArgumentError(explanation)) - end - end - g(x) = -f(x) - return minimise(g, config) + return maximise_with_parsed_config(parse_config(config), f) end export maximise +function maximise_with_parsed_config(config::NamedTuple, f) + g(x) = -f(x) + return minimise_with_parsed_config(config, g) +end + const maximize = maximise export maximize diff --git a/test/CBO/corrections.jl b/test/CBO/corrections.jl new file mode 100644 index 0000000..7fd88f8 --- /dev/null +++ b/test/CBO/corrections.jl @@ -0,0 +1,24 @@ +using ConsensusBasedX, ConsensusBasedX.ConsensusBasedXLowLevel, Test + +function tests() + x = 1 + rand() + + noCorrection = NoCorrection() + @test noCorrection(x) == 1 + @test noCorrection(-x) == 1 + + heavisideCorrection = HeavisideCorrection() + @test heavisideCorrection(x) == 1 + @test heavisideCorrection(-x) == 0 + + regularCorrection = RegularisedHeavisideCorrection(1e-1) + sharpCorrection = RegularisedHeavisideCorrection(1e-2) + @test regularCorrection(x) <= 1 + @test regularCorrection(x) >= 0 + @test regularCorrection(-x) <= 1 + @test regularCorrection(-x) >= 0 + @test regularCorrection(x) <= sharpCorrection(x) + @test regularCorrection(-x) >= sharpCorrection(-x) +end + +tests() diff --git a/test/interface/maximise.jl b/test/interface/maximise.jl new file mode 100644 index 0000000..7455a7f --- /dev/null +++ b/test/interface/maximise.jl @@ -0,0 +1,20 @@ +using ConsensusBasedX, Test + +function tests() + alloc(x) = Base.gc_alloc_count(x.gcstats) + + config = (; D = 2, benchmark = true) + + f(x) = -ConsensusBasedX.Quadratic(x, shift = 1) + @test alloc(maximise(f, config)) == 0 + + g(x) = -ConsensusBasedX.Ackley(x, shift = 1) + @test alloc(maximise(g, config)) == 0 + + h(x) = -ConsensusBasedX.Rastrigin(x, shift = 1) + @test alloc(maximise(h, config)) == 0 + + return config = (; D = 2,) +end + +tests() diff --git a/test/interface/parse_config.jl b/test/interface/parse_config.jl index c70d40a..42a5aeb 100644 --- a/test/interface/parse_config.jl +++ b/test/interface/parse_config.jl @@ -1,40 +1,25 @@ -using ConsensusBasedX, Test +using ConsensusBasedX, ConsensusBasedX.ConsensusBasedXLowLevel, Test function tests() - out = @test_nowarn ConsensusBasedX.parse_config((; D = 2)) - @test haskey(out, :D) - @test haskey(out, :N) - @test haskey(out, :M) - @test haskey(out, :mode) + @test_throws ArgumentError parse_config(NamedTuple()) - @test_nowarn ConsensusBasedX.check_config_has_D((; D = 2, N = 20)) - @test_throws ArgumentError ConsensusBasedX.check_config_has_D((; N = 20)) + @test_throws ArgumentError parse_config((; D = 2, mode = "wrongMode")) + @test_throws ArgumentError parse_config((; D = 2, mode = :wrongMode)) + @test_throws ArgumentError parse_config((; D = 2, mode = 1.0)) - @test_nowarn ConsensusBasedX.parse_config_mode(NamedTuple()) + @test_throws ArgumentError parse_config((; D = 2, noise = "wrongNoise")) + @test_throws ArgumentError parse_config((; D = 2, noise = :wrongNoise)) + @test_throws ArgumentError parse_config((; D = 2, noise = 1.0)) - out = @test_nowarn ConsensusBasedX.parse_config_mode((; - mode = ConsensusBasedX.ParticleMode + @test_throws ArgumentError parse_config((; + D = 2, + parallelisation = "wrongParallelisation", )) - @test out.mode isa ConsensusBasedX.TParticleMode - out = @test_nowarn ConsensusBasedX.parse_config_mode((; - mode = Val(:ParticleMode) - )) - @test out.mode isa ConsensusBasedX.TParticleMode - out = @test_nowarn ConsensusBasedX.parse_config_mode((; mode = :ParticleMode)) - @test out.mode isa ConsensusBasedX.TParticleMode - out = - @test_nowarn ConsensusBasedX.parse_config_mode((; mode = "ParticleMode")) - @test out.mode isa ConsensusBasedX.TParticleMode - - @test_throws ArgumentError ConsensusBasedX.parse_config_mode((; - mode = Val(:WrongMode) - )) - @test_throws ArgumentError ConsensusBasedX.parse_config_mode((; - mode = :WrongMode - )) - @test_throws ArgumentError ConsensusBasedX.parse_config_mode((; - mode = "WrongMode" + @test_throws ArgumentError parse_config((; + D = 2, + parallelisation = :wrongParallelisation, )) + @test_throws ArgumentError parse_config((; D = 2, parallelisation = 1.0)) end tests() diff --git a/test/runtests.jl b/test/runtests.jl index 8e89477..6571f9d 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,11 +4,14 @@ using SafeTestsets, Test @testset "ConsensusBasedX.jl" begin for test ∈ [ + "CBO/corrections", "CBO/is_method_pending", "dynamics/is_dynamic_pending", "interface/initialise_particles", + "interface/maximise", "interface/minimise", "interface/parse_config", + "tuples/types", "aqua", "examples", "format", diff --git a/test/tuples/tuples.jl b/test/tuples/tuples.jl new file mode 100644 index 0000000..26072d4 --- /dev/null +++ b/test/tuples/tuples.jl @@ -0,0 +1,16 @@ +using ConsensusBasedX, ConsensusBasedX.ConsensusBasedXLowLevel, Test + +function tests() + tuple = (; a = 1, b = 2.0, c = "three") + @test forced_convert_2_NamedTuple(tuple) == tuple + + dict = Dict(:a => 1, :b => 2.0, :c => "three") + @test forced_convert_2_NamedTuple(dict) == tuple + + string_dict = Dict("a" => 1, "b" => 2.0, "c" => "three") + @test forced_convert_2_NamedTuple(string_dict) == tuple + + @test_throws ArgumentError forced_convert_2_NamedTuple(values(tuple)) +end + +tests() diff --git a/test/tuples/types.jl b/test/tuples/types.jl new file mode 100644 index 0000000..3f0cf89 --- /dev/null +++ b/test/tuples/types.jl @@ -0,0 +1,10 @@ +using ConsensusBasedX, ConsensusBasedX.ConsensusBasedXLowLevel, Test + +function tests() + @test get_val("string") isa String + @test get_val(:symbol) isa Symbol + @test get_val(Val(:val)) isa Symbol + @test get_val(Val(:val)) == :val +end + +tests()