ScipyOptimizer#
- class braintools.optim.ScipyOptimizer(loss_fun, bounds, method=None, constraints=(), tol=None, callback=None, options=None)#
SciPy-based optimizer with dict/sequence bounds compatible with Nevergrad.
This optimizer accepts the same bounds structure as
braintools.optim.NevergradOptimizerand a loss function with matching signature:If
boundsis a sequence of(min, max)pairs,loss_funis called positionally asloss_fun(*params).If
boundsis a dict mapping names to(min, max)pairs,loss_funis called by keyword asloss_fun(**params).
Bounds can be scalars or arrays, and may optionally be provided as
brainunit.Quantity. Internally, SciPy works on the numeric mantissas while yourloss_funreceives values in the same structure as the bounds (without units).- Parameters:
loss_fun (
Callable) – Objective function returning a scalar (0-D array-like). Its signature must match the structure ofboundsas described above.bounds (
Sequence|Dict[str,Any]) – Search space bounds, as in Nevergrad: each value is(min, max)where elements are scalars or arrays, optionallyu.Quantity. All elements in a pair must share shape, and units (if any) must be compatible. For dict bounds, names define keyword arguments toloss_fun.method (
str|None) – SciPy method (e.g.,'L-BFGS-B','TNC','SLSQP','Powell'). If omitted, SciPy selects a default based on constraints/bounds.constraints – Passed through to
scipy.optimize.minimize.tol – Passed through to
scipy.optimize.minimize.callback – Passed through to
scipy.optimize.minimize.options – Passed through to
scipy.optimize.minimize.
Notes
This wrapper flattens parameters to a 1-D vector for SciPy and unflattens results back to the same structure found in
bounds.Gradients are computed via JAX auto-differentiation.
Examples
Minimize a simple quadratic with tuple bounds:
>>> import jax.numpy as jnp >>> def loss(x, y): ... return (x - 1.0)**2 + (y + 2.0)**2 >>> bounds = [(-5.0, 5.0), (-3.0, 3.0)] >>> opt = ScipyOptimizer(loss_fun=loss, bounds=bounds, method='L-BFGS-B') >>> res = opt.minimize(n_iter=3) >>> isinstance(res.x, (list, tuple)) # same structure as bounds True
With named parameters using dict bounds:
>>> def loss(**p): ... return (p['a'] - 1.0)**2 + (p['b'] + 2.0)**2 >>> bounds = {"a": (-5.0, 5.0), "b": (-3.0, 3.0)} >>> opt = ScipyOptimizer(loss_fun=loss, bounds=bounds, method='TNC') >>> res = opt.minimize(n_iter=2) >>> isinstance(res.x, dict) True