Skip to content

Commit d62ff13

Browse files
Merge pull request #934 from mxpoch/master
added pycma docs and python kwargs
2 parents 582d6ee + 105d713 commit d62ff13

File tree

4 files changed

+87
-13
lines changed

4 files changed

+87
-13
lines changed

docs/pages.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pages = ["index.md",
2323
"API/modelingtoolkit.md",
2424
"API/FAQ.md"
2525
],
26-
"Optimizer Packages" => [
26+
"Optimizer Packages" => [
2727
"BlackBoxOptim.jl" => "optimization_packages/blackboxoptim.md",
2828
"CMAEvolutionStrategy.jl" => "optimization_packages/cmaevolutionstrategy.md",
2929
"Evolutionary.jl" => "optimization_packages/evolutionary.md",
@@ -40,6 +40,7 @@ pages = ["index.md",
4040
"Optimization.jl" => "optimization_packages/optimization.md",
4141
"Polyalgorithms.jl" => "optimization_packages/polyopt.md",
4242
"PRIMA.jl" => "optimization_packages/prima.md",
43+
"PyCMA.jl" => "optimization_packages/pycma.md",
4344
"QuadDIRECT.jl" => "optimization_packages/quaddirect.md",
4445
"SpeedMapping.jl" => "optimization_packages/speedmapping.md",
4546
"SciPy.jl" => "optimization_packages/scipy.md"
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# PyCMA.jl
2+
3+
[`PyCMA`](https://github.com/CMA-ES/pycma) is a Python implementation of CMA-ES and a few related numerical optimization tools. `OptimizationPyCMA.jl` gives access to the CMA-ES optimizer through the unified `Optimization.jl` interface just like any native Julia optimizer.
4+
5+
`OptimizationPyCMA.jl` relies on [`PythonCall`](https://github.com/cjdoris/PythonCall.jl). A minimal Python distribution containing PyCMA will be installed automatically on first use, so no manual Python set-up is required.
6+
7+
## Installation: OptimizationPyCMA.jl
8+
9+
```julia
10+
import Pkg
11+
Pkg.add("OptimizationPyCMA")
12+
```
13+
14+
## Methods
15+
16+
`PyCMAOpt` supports the usual keyword arguments `maxiters`, `maxtime`, `abstol`, `reltol` in addition to any PyCMA-specific options (passed verbatim via keyword arguments to `solve`).
17+
18+
## Example
19+
20+
```@example PyCMA
21+
using OptimizationPyCMA
22+
23+
rosenbrock(x, p) = (p[1] - x[1])^2 + p[2] * (x[2] - x[1]^2)^2
24+
x0 = zeros(2)
25+
_p = [1.0, 100.0]
26+
l1 = rosenbrock(x0, _p)
27+
f = OptimizationFunction(rosenbrock)
28+
prob = OptimizationProblem(f, x0, _p, lb = [-1.0, -1.0], ub = [0.8, 0.8])
29+
sol = solve(prob, PyCMAOpt())
30+
```
31+
32+
## Passing solver-specific options
33+
34+
Any keyword that `Optimization.jl` does not interpret is forwarded directly to PyCMA.
35+
36+
In the event an `Optimization.jl` keyword overlaps with a `PyCMA` keyword, the `Optimization.jl` keyword takes precedence.
37+
38+
An exhaustive list of keyword arguments can be found by running the following python script:
39+
40+
```python
41+
import cma
42+
options = cma.CMAOptions()
43+
print(options)
44+
```
45+
46+
An example passing the `PyCMA` keywords "verbose" and "seed":
47+
```julia
48+
sol = solve(prob, PyCMA(), verbose = -9, seed = 42)
49+
```
50+
51+
## Troubleshooting
52+
53+
The original Python result object is attached to the solution in the `original` field:
54+
55+
```julia
56+
sol = solve(prob, PyCMAOpt())
57+
println(sol.original)
58+
```
59+
60+
## Contributing
61+
62+
Bug reports and feature requests are welcome in the [Optimization.jl](https://github.com/SciML/Optimization.jl) issue tracker. Pull requests that improve either the Julia wrapper or the documentation are highly appreciated.
63+

lib/OptimizationPyCMA/src/OptimizationPyCMA.jl

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ function get_cma()
1818
end
1919

2020
# Defining the SciMLBase interface for PyCMAOpt
21-
2221
SciMLBase.allowsbounds(::PyCMAOpt) = true
2322
SciMLBase.supports_opt_cache_interface(opt::PyCMAOpt) = true
23+
SciMLBase.allowscallback(::PyCMAOpt) = false
2424
SciMLBase.requiresgradient(::PyCMAOpt) = false
2525
SciMLBase.requireshessian(::PyCMAOpt) = false
2626
SciMLBase.requiresconsjac(::PyCMAOpt) = false
@@ -31,15 +31,26 @@ function __map_optimizer_args(prob::OptimizationCache, opt::PyCMAOpt;
3131
maxiters::Union{Number, Nothing} = nothing,
3232
maxtime::Union{Number, Nothing} = nothing,
3333
abstol::Union{Number, Nothing} = nothing,
34-
reltol::Union{Number, Nothing} = nothing)
34+
reltol::Union{Number, Nothing} = nothing,
35+
PyCMAargs...)
3536
if !isnothing(reltol)
3637
@warn "common reltol is currently not used by $(opt)"
3738
end
39+
40+
# Converting Optimization.jl args to PyCMA opts
41+
# Optimization.jl kwargs will overwrite PyCMA kwargs supplied to solve()
3842

39-
mapped_args = Dict(
40-
"verbose" => -5,
41-
"bounds" => (prob.lb, prob.ub),
42-
)
43+
mapped_args = Dict{String, Any}()
44+
45+
# adding PyCMA args
46+
merge!(mapped_args, Dict(string(k) => v for (k, v) in PyCMAargs))
47+
48+
# mapping Optimization.jl args
49+
mapped_args["bounds"] = (prob.lb, prob.ub)
50+
51+
if !("verbose" keys(mapped_args))
52+
mapped_args["verbose"] = -1
53+
end
4354

4455
if !isnothing(abstol)
4556
mapped_args["tolfun"] = abstol
@@ -111,15 +122,15 @@ function SciMLBase.__solve(cache::OptimizationCache{
111122

112123
# wrapping the objective function
113124
_loss = function (θ)
114-
x = cache.f(θ, cache.p)
125+
x = cache.f(θ, cache.p)
115126
return first(x)
116127
end
117128

118129
# converting the Optimization.jl Args to PyCMA format
119130
opt_args = __map_optimizer_args(cache, cache.opt; cache.solver_args...,
120131
maxiters = maxiters,
121132
maxtime = maxtime)
122-
133+
123134
# init the CMAopt class
124135
es = get_cma().CMAEvolutionStrategy(cache.u0, 1, pydict(opt_args))
125136
logger = es.logger
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using OptimizationPyCMA
2-
using Test
1+
using OptimizationPyCMA, Test
32

43
@testset "OptimizationPyCMA.jl" begin
54
rosenbrock(x, p) = (p[1] - x[1])^2 + p[2] * (x[2] - x[1]^2)^2
@@ -9,6 +8,6 @@ using Test
98
f = OptimizationFunction(rosenbrock)
109
prob = OptimizationProblem(f, x0, _p, lb = [-1.0, -1.0], ub = [0.8, 0.8])
1110
sol = solve(prob, PyCMAOpt())
12-
@test 10 * sol.objective < l1
13-
sol = solve(prob, PyCMAOpt(), maxiters = 100)
11+
@test 10 * sol.objective < l1
12+
sol = solve(prob, PyCMAOpt(), maxiters = 100, verbose=-1, seed=42)
1413
end

0 commit comments

Comments
 (0)