Optimization¶
Optimization problems can be solved with driver Optimizer.
Optimizer seeks a user-defined parameter set that minimizes a scalar objective.
Define an optimization problem¶
Optimization problems are defined using three driver methods:
set_minimumorset_maximum(as required)add_unknownadd_constraints
Add driver¶
from cosapp.drivers import Optimizer
s = SomeSystem('s')
optim = s.add_driver(Optimizer('optim'))
Set minimization or maximization objective¶
The argument passed to set_minimum (resp. set_maximum) must be a scalar expression evaluable in the context of owner system:
optim.set_minimum("a**2 + b.x * exp(c.p_out.y / 2)")
Define optimization parameters¶
Optimization parameters are declared with method add_unknown, akin to nonlinear problem unknowns:
optim.add_unknown(['u', 'v'])
optim.add_unknown('alpha', lower_bound=0, upper_bound=1)
When specified, lower and upper bounds are used as linear constraints during resolution.
Define constraints¶
General constraints are given as plain strings (or a list thereof) in add_constraints. Each constraint can either be an equality or an inequality. Inequalities are translated into non-negative constraints, whether the inequality is strict or not. For instance, x < y will translate into y - x >= 0.
Note that multiple constraints can be expressed in a single expression, as in: "a > b > c".
optim.add_constraints("0 <= b.y <= 2 * c.x") # yields two constraints
optim.add_constraints([
"0.1 <= h == sqrt(A)", # h >= 0.1 and h == sqrt(A)
"a + b < c", # interpreted as c - (a + b) >= 0
])
Options¶
Driver Optimizer encapsulates function scipy.optimize.minimize. All methods implemented in minimize (SLSQP, Conjugate Gradient, Nelder-Mead, etc.) are available, through optional argument method.
The list of available methods is given by:
[1]:
from cosapp.drivers import Optimizer
Optimizer.available_methods()
[1]:
['Nelder-Mead',
'Powell',
'CG',
'BFGS',
'Newton-CG',
'L-BFGS-B',
'TNC',
'COBYLA',
'SLSQP',
'dogleg',
'trust-constr',
'trust-ncg',
'trust-exact',
'trust-krylov']
Other options are:
tol[float]: Relative tolerance on objective value between two iterations (default: 1.5e-8).eps[float]: Relative step size used for numerical approximation of the Jacobian (default: 2^(-26) ~ 1.49e-8).max_iter[int]: Maximum number of iterations (default: 100).monitor[bool]: IfTrue, data are recorded into driver recorder (if any) at all iterations; ifFalse(default), only the final state is recorded.
Options may be set at driver construction (as keyword arguments), or by setting the desired key in dict attribute options, as in:
optim.options['tol'] = 1e-9
optim.options['max_iter'] = 50