Skip to content

optimizer_base⚓︎

Shared OptimizerBase for iterative optimization algorithms.

BoundTransformHandler ⚓︎

Transform states between the original parameter domain and the unit cube.

Notes

All bounds must be finite whenever bounds are supplied.

__init__(bounds=None, transform=False) ⚓︎

Initialize the BoundTransformHandler.

Parameters:

Name Type Description Default
bounds sequence of (lower, upper) pairs

Lower and upper bounds for each state variable.

None
transform bool

If True, transform the optimization problem to the unit cube [0, 1]^n.

False

hess_from_unit_cube(hess) ⚓︎

Transform a Hessian from unit-cube coordinates.

hess_to_unit_cube(hess) ⚓︎

Transform a Hessian to unit-cube coordinates.

jac_from_unit_cube(jac) ⚓︎

Transform a gradient from unit-cube coordinates.

jac_to_unit_cube(jac) ⚓︎

Transform a gradient to unit-cube coordinates.

project_gradient(x, g, tol=1e-08) ⚓︎

Project a gradient to respect active bound constraints.

project_to_bounds(x) ⚓︎

Project a vector onto the feasible domain.

state_to_unit_cube(x) ⚓︎

Transform original coordinates to unit-cube coordinates.

unit_cube_to_state(u) ⚓︎

Transform unit-cube coordinates to original coordinates.

OptimizerBase ⚓︎

Bases: OptimizerRestartMixin, ABC

The iteration every optimizer shares; a subclass supplies the step.

A subclass implements :meth:update_step, committing an improving point with :meth:_commit_step and returning a :class:StepReport, and names what its log row shows in :meth:log_columns. Everything else -- the starting evaluation, the callback, recording and saving the result, the log row, the function, state and projected-gradient convergence checks, restart checkpoints and the EPF outer loop -- happens here.

NAME = 'Optimizer' ⚓︎

Shown in the start-of-run banner.

__init__(x0, fun, jac=None, hess=None, args=(), bounds=None, callback=None, **options) ⚓︎

Parameters:

Name Type Description Default
x0 ndarray

Initial parameter vector.

required
fun callable

Objective function.

required
jac callable

Gradient function.

None
hess callable

Hessian function.

None
args tuple

Extra positional arguments passed to callables: fun, jac, hess.

()
bounds sequence

Lower and upper bounds for each state variable.

None
callback callable

Called with the optimizer after every accepted step.

None
**options

Optimizer configuration such as tolerances, logging, restart, and persistence options. - maxiter: Maximum number of iterations (default: 100) - ftol: Relative function tolerance for convergence (default: 1e-5) - xtol: Relative change in state for convergence (default: 1e-8) - gtol: Projected-gradient infinity-norm tolerance for convergence (default: 1e-5) - fun0, jac0, hess0: Initial objective, gradient and Hessian values to reuse instead of evaluating them - logit: Enable logging (default: True) - logger_name: Log file name (default: 'OPTIM.log') - restart: Enable restart from file (default: False) - restartsave: Save restart file after each iteration (default: False) - restart_file: Path for restart file (default: '{optimizer_name}_restart.pkl') - epf: Dictionary of EPF options (default: None) - r: Initial penalty factor - r_factor: Penalty factor update multiplier (default: 2) - tol_factor: Function tolerance update multiplier (default: 0.9) - conv_crit: EPF convergence criterion, compared against the mean penalty with the penalty factor divided out (default: 1e-5). The objective must write penalty into the epf dict it is handed. - transform: Enable [lb, ub] → [0, 1] transformation for optimization (default: False) - saveit: Save intermediate results after each iteration (default: False) - savefolder (or save_folder): Folder for those results (default: 'Iteration_Results')

{}

check_convergence() ⚓︎

Optimizer-specific criteria; by default the projected gradient against gtol.

Runs after the function and state checks. An optimizer with more criteria extends this; one without a gradient gets False.

check_epf_convergence() ⚓︎

Evaluate convergence of the outer EPF iteration.

The loop stops once the constraints are satisfied, measured as the mean of self.epf['penalty'] with the penalty factor r divided back out. The objective is responsible for writing penalty into the epf dict it is handed; without it there is nothing to converge on and this raises.

Returns:

Type Description
bool

True when the EPF loop should terminate, otherwise False.

check_function_convergence() ⚓︎

Check convergence based on relative change in objective value.

check_state_convergence() ⚓︎

Check convergence based on the norm of the state update.

log_columns() ⚓︎

One row of the iteration log. Optimizers override to show their own quantities.

minimize(x0, fun, *args, **kwargs) ⚓︎

Construct the optimizer with these arguments, run it, and return its result.

The arguments are the constructor's, in the constructor's order; see the class for what each optimizer takes.

run_optimization() ⚓︎

Run this optimizer to completion.

Named for the job rather than the mechanism; the counterpart in pipt is AssimilationScheme.run_assimilation.

The loop handles restart restoration, the starting evaluation, optional EPF outer iterations, repeated calls to update_step(), and the shared convergence checks. When enabled, restart files are updated after successful iterations and after EPF penalty updates.

update_step() ⚓︎

Take one step from the current iterate.

Find a better point and make it current with :meth:_commit_step, which also keeps the previous iterate for the convergence checks; then return StepReport(True). The loop runs the callback, records and saves the result, logs a row and checks convergence -- none of that is the step's job. Return StepReport(False, why) when no acceptable step exists: the run stops and why is its message.

OptimizerRestartMixin ⚓︎

Bases: RestartMixin

Checkpoint/restart behaviour for optimizers.

The implementation is shared with PIPT via :class:ensemble.checkpoint.RestartMixin; this subclass exists so the optimizer-facing name stays stable.

StepReport ⚓︎

What one call to :meth:OptimizerBase.update_step produced.

accepted says the optimizer committed a new iterate (through :meth:OptimizerBase._commit_step); the loop then does the bookkeeping every optimizer used to repeat. message is why it stopped when it did not, and becomes the result's message.