Skip to content

Commit 44a233c

Browse files
Merge pull request #471 from SciML/evoup
Update OptimizationEvolutionary to support constraints and pass additional kwargs
2 parents c74294b + a3e8990 commit 44a233c

File tree

3 files changed

+46
-7
lines changed

3 files changed

+46
-7
lines changed

lib/OptimizationEvolutionary/Project.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ Optimization = "3.9"
1515
Reexport = "1.2"
1616

1717
[extras]
18+
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
1819
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
1920

2021
[targets]
21-
test = ["Test"]
22+
test = ["Random", "Test"]

lib/OptimizationEvolutionary/src/OptimizationEvolutionary.jl

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ using Reexport
55
using Optimization.SciMLBase
66

77
SciMLBase.allowsbounds(opt::Evolutionary.AbstractOptimizer) = true
8+
SciMLBase.allowsconstraints(opt::Evolutionary.AbstractOptimizer) = true
89

910
decompose_trace(trace::Evolutionary.OptimizationTrace) = last(trace)
1011
decompose_trace(trace::Evolutionary.OptimizationTraceRecord) = trace
@@ -20,8 +21,9 @@ function __map_optimizer_args(prob::OptimizationProblem,
2021
maxiters::Union{Number, Nothing} = nothing,
2122
maxtime::Union{Number, Nothing} = nothing,
2223
abstol::Union{Number, Nothing} = nothing,
23-
reltol::Union{Number, Nothing} = nothing)
24-
mapped_args = (;)
24+
reltol::Union{Number, Nothing} = nothing,
25+
kwargs...)
26+
mapped_args = (;kwargs...)
2527

2628
if !isnothing(callback)
2729
mapped_args = (; mapped_args..., callback = callback)
@@ -74,6 +76,8 @@ function SciMLBase.__solve(prob::OptimizationProblem, opt::Evolutionary.Abstract
7476
maxiters = Optimization._check_and_convert_maxiters(maxiters)
7577
maxtime = Optimization._check_and_convert_maxtime(maxtime)
7678

79+
f = Optimization.instantiate_function(prob.f, prob.u0, prob.f.adtype, prob.p,
80+
prob.ucons === nothing ? 0 : length(prob.ucons))
7781
_loss = function (θ)
7882
x = prob.f(θ, prob.p, cur...)
7983
return first(x)
@@ -84,10 +88,21 @@ function SciMLBase.__solve(prob::OptimizationProblem, opt::Evolutionary.Abstract
8488
kwargs...)
8589

8690
t0 = time()
87-
if isnothing(prob.ub) || isnothing(prob.ub)
88-
opt_res = Evolutionary.optimize(_loss, prob.u0, opt, opt_args)
91+
if isnothing(prob.lb) || isnothing(prob.ub)
92+
if !isnothing(f.cons)
93+
c = x -> (res = zeros(length(prob.lcons)); f.cons(res, x); res)
94+
cons = WorstFitnessConstraints(Float64[], Float64[], prob.lcons, prob.ucons, c)
95+
opt_res = Evolutionary.optimize(_loss, cons, prob.u0, opt, opt_args)
96+
else
97+
opt_res = Evolutionary.optimize(_loss, prob.u0, opt, opt_args)
98+
end
8999
else
90-
cons = Evolutionary.BoxConstraints(prob.lb, prob.ub)
100+
if !isnothing(f.cons)
101+
c = x -> (res = zeros(length(prob.lcons)); f.cons(res, x); res)
102+
cons = WorstFitnessConstraints(prob.lb, prob.ub, prob.lcons, prob.ucons, c)
103+
else
104+
cons = BoxConstraints(prob.lb, prob.ub)
105+
end
91106
opt_res = Evolutionary.optimize(_loss, cons, prob.u0, opt, opt_args)
92107
end
93108
t1 = time()

lib/OptimizationEvolutionary/test/runtests.jl

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
using OptimizationEvolutionary, Optimization
1+
using OptimizationEvolutionary, Optimization, Random
22
using Test
33

4+
Random.seed!(1234)
45
@testset "OptimizationEvolutionary.jl" begin
56
rosenbrock(x, p) = (p[1] - x[1])^2 + p[2] * (x[2] - x[1]^2)^2
67
x0 = zeros(2)
@@ -10,4 +11,26 @@ using Test
1011
prob = Optimization.OptimizationProblem(optprob, x0, _p)
1112
sol = solve(prob, CMAES= 40, λ = 100), abstol = 1e-15)
1213
@test 10 * sol.objective < l1
14+
15+
x0 = [-0.7, 0.3]
16+
prob = Optimization.OptimizationProblem(optprob, x0, _p, lb = [0.0, 0.0],
17+
ub = [0.5, 0.5])
18+
sol = solve(prob, CMAES= 50, λ = 60))
19+
@test sol.u == zeros(2)
20+
21+
x0 = zeros(2)
22+
cons_circ = (res, x, p) -> res .= [x[1]^2 + x[2]^2]
23+
optprob = OptimizationFunction(rosenbrock; cons = cons_circ)
24+
prob = OptimizationProblem(optprob, x0, _p, lcons = [-Inf], ucons = [0.25^2])
25+
sol = solve(prob, CMAES= 40, λ = 100))
26+
res = zeros(1)
27+
cons_circ(res, sol.u, nothing)
28+
@test res[1]0.0625 atol=1e-5
29+
@test sol.objective < l1
30+
31+
prob = OptimizationProblem(optprob, x0, _p, lcons = [-Inf], ucons = [5.0], lb = [0.0, 1.0], ub = [Inf, Inf])
32+
sol = solve(prob, CMAES= 40, λ = 100))
33+
res = zeros(1)
34+
cons_circ(res, sol.u, nothing)
35+
@test sol.objective < l1
1336
end

0 commit comments

Comments
 (0)