Skip to content

Commit

Permalink
Merge pull request #22 from rafaelbailo/main
Browse files Browse the repository at this point in the history
Additional unit tests
  • Loading branch information
rafaelbailo committed Mar 8, 2024
2 parents 049048b + ef0fc91 commit 6966fb3
Show file tree
Hide file tree
Showing 10 changed files with 108 additions and 43 deletions.
2 changes: 2 additions & 0 deletions docs/src/function_minimisation.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
12 changes: 10 additions & 2 deletions docs/src/low_level_examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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).

Expand All @@ -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)
Expand All @@ -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).
2 changes: 2 additions & 0 deletions src/ConsensusBasedXLowLevel.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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!,
Expand Down
17 changes: 6 additions & 11 deletions src/interface/maximise.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
24 changes: 24 additions & 0 deletions test/CBO/corrections.jl
Original file line number Diff line number Diff line change
@@ -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()
20 changes: 20 additions & 0 deletions test/interface/maximise.jl
Original file line number Diff line number Diff line change
@@ -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()
45 changes: 15 additions & 30 deletions test/interface/parse_config.jl
Original file line number Diff line number Diff line change
@@ -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()
3 changes: 3 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
16 changes: 16 additions & 0 deletions test/tuples/tuples.jl
Original file line number Diff line number Diff line change
@@ -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()
10 changes: 10 additions & 0 deletions test/tuples/types.jl
Original file line number Diff line number Diff line change
@@ -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()

0 comments on commit 6966fb3

Please sign in to comment.