ScipyOptimizer#

class lumopt2.optimizer.scipy_optimizer.ScipyOptimizer(method: str = 'L-BFGS-B', max_iter: int | None = None, max_feval: int | None = None, ftol: float = 1e-06, gtol: float = 1e-05, bounds: list | None = None, options: Dict[str, Any] | None = None, max_eval: int | None = None)#

Wrapper for scipy.optimize.minimize optimizers, particularly L-BFGS-B.

This class provides a clean interface to scipy’s optimization methods with proper handling of gradients, bounds, and optimization parameters commonly used in photonic inverse design.

Parameters:
methodstr, optional

Optimization method to use. Supported methods include ‘L-BFGS-B’, ‘BFGS’, ‘CG’, ‘Nelder-Mead’, ‘Powell’, ‘SLSQP’, etc. See scipy.optimize.minimize documentation for full list (default: ‘L-BFGS-B’).

max_iterint, optional

Maximum number of iterations (default: 100).

max_fevalint, optional

Hard upper bound on the number of objective-function evaluations. A single SciPy iteration may request many evaluations (line search, finite-difference gradients, simplex updates, …), so this knob is independent of max_iter. Translates to maxfun for L-BFGS-B and maxfev for Nelder-Mead / Powell. If the chosen method does not expose a function-evaluation budget, the value is ignored with a warning (default: None).

ftolfloat, optional

Tolerance for termination by the change of the objective function. For L-BFGS-B, this is the factr parameter multiplied by machine precision (default: 1e-6).

gtolfloat, optional

Tolerance for termination by the gradient norm (default: 1e-5).

boundslist of tuple, optional

Bounds for each parameter as (min, max) pairs. If None, uses unbounded optimization (default: None). When bounds are provided, LumOpt2 requires every lower/upper bound to be finite.

optionsdict, optional

Additional options to pass to scipy.optimize.minimize (default: None).

max_evalint, optional

Backward-compatible alias for max_iter (default: None).

Deprecated since version Use: max_iter to cap iterations or max_feval to cap function evaluations.

Attributes:
methodstr

The optimization method being used.

max_iterint

Maximum number of iterations.

max_fevalint or None

Maximum number of objective-function evaluations (None for no cap).

ftolfloat

Function tolerance.

gtolfloat

Gradient tolerance.

boundslist or None

Parameter bounds.

optionsdict

Additional scipy options.

resultscipy.optimize.OptimizeResult or None

Result object from the last optimization run.

historydict

Dictionary storing optimization history with keys: - ‘params’: list of parameter arrays at each iteration - ‘fom’: list of FOM values at each iteration - ‘gradient’: list of gradient arrays at each iteration

Notes

The L-BFGS-B method is particularly well-suited for inverse design because: - It handles box constraints (bounds) naturally - It’s memory-efficient for high-dimensional problems - It uses gradient information efficiently - It converges quickly for smooth objective functions

The optimizer expects the objective function to be maximized. If you need to minimize, negate your FOM.

Examples

Basic L-BFGS-B optimization:

>>> optimizer = ScipyOptimizer(method='L-BFGS-B', max_iter=50)
>>> result = optimizer.optimize(objective_func, gradient_func, initial_params)

With bounds:

>>> bounds = [(0, 1) for _ in range(n_params)]
>>> optimizer = ScipyOptimizer(method='L-BFGS-B', bounds=bounds)
>>> result = optimizer.optimize(objective_func, gradient_func, initial_params)

Using different method:

>>> optimizer = ScipyOptimizer(method='SLSQP', max_iter=100, ftol=1e-8)
>>> result = optimizer.optimize(objective_func, gradient_func, initial_params)

Methods

ScipyOptimizer.get_history()

Get the optimization history.

ScipyOptimizer.get_result()

Get the full scipy optimization result object.

ScipyOptimizer.optimize(objective_func, ...)

Run the optimization.

Attributes

ScipyOptimizer.is_gradient_free

Return True if the optimizer uses a gradient-free method.