Minimizers minimizer#

Available Minimizers minimizer#

The following minimizers are implemented in pyCIF so far:

Documentation#

Minimizer plugins: iterative solvers for the variational cost function.

Description#

A minimizer plugin drives the iterative loop of a variational inversion. It receives the cost function value \(J(\boldsymbol{\chi})\) and its gradient \(\nabla J\) from a simulator plugin, then proposes a new candidate \(\boldsymbol{\chi}\) until a convergence criterion is met.

All minimizers in pyCIF operate in the pre-conditioned chi-space defined by \(\mathbf{x} = \mathbf{x}_b + \mathbf{B}^{1/2}\boldsymbol{\chi}\), so they minimise an isotropic-looking cost function regardless of the original background error covariance structure.

Minimizers are called by the variational mode plugin via:

chiopt = minimizer.minimize(costinit, gradinit, controlvect.chi, **kwargs)

Available minimizers#

Plugin name / version

Description

M1QN3 / std

Quasi-Newton L-BFGS algorithm (Gilbert & Lemaréchal, 1989)

congrad / std

Conjugate-gradient / Lanczos algorithm (Fisher, ECMWF, 2002)

scipy / std

Wrapper around scipy.optimize.minimize() (multiple methods)

scipy / conjugate

Sparse conjugate-gradient via scipy.sparse.linalg.cg() or LOBPCG

Required plugin interface#

Every minimizer plugin is a Python package whose __init__.py must expose at minimum a minimize function and the standard plugin identification variables. The optional ini_data function is called during initialisation.

Plugin identification#

_name (str):

short name used to select this minimizer in the YAML (minimizer.plugin.name).

_version (str):

version string, typically "std".

requirements#

Minimizers require a simulator sub-plugin that evaluates the cost function and its gradient:

requirements = {
    "simulator": {
        "any": True, "empty": True,
        "name": "gausscost", "version": "std",
    },
}

input_arguments#

Convergence parameters are declared as input_arguments and applied to the plugin instance before ini_data is called. Common keys across minimizers:

maxiter (int):

maximum number of iterations.

epsg (float):

relative convergence tolerance on the gradient norm, \(\|\nabla J\|_k < \epsilon_g \cdot \|\nabla J\|_0\).

Functions#

minimize (mandatory)#

The sole mandatory callable; called once per inversion by the variational mode after an initial cost/gradient evaluation:

def minimize(self, finit, gradinit, chi0, **kwargs) -> np.ndarray:
    ...
self:

minimizer plugin instance carrying all input_arguments attributes and a reference to the simulator sub-plugin.

finit (float):

initial cost function value \(J(\boldsymbol{\chi}_0)\).

gradinit (np.ndarray):

initial gradient vector \(\nabla J(\boldsymbol{\chi}_0)\), shape (n,).

chi0 (np.ndarray):

initial iterate \(\boldsymbol{\chi}_0\), shape (n,).

**kwargs:

forwarded to the simulator.

Returns chiopt (np.ndarray): the minimiser solution \(\boldsymbol{\chi}_\mathrm{opt}\), same shape as chi0.

The minimizer calls self.simulator.simul(chi, run_id=k) internally at each iteration to obtain updated \((J, \nabla J)\) pairs.

ini_data (optional)#

Called after input_arguments are applied, before minimize. Used to validate parameters, build derived attributes (e.g. variable bounds, internal working arrays), and attach helper methods via MethodType:

def ini_data(plugin, **kwargs) -> None:
    ...
plugin:

partially initialised minimizer plugin instance.

**kwargs:

unused; accepted for interface consistency.