Skip to content

optimizers

eigenkit.core.optimizers

Optimisers that need no gradient, for objectives that are noisy and expensive.

spsa implements Simultaneous Perturbation Stochastic Approximation (SPSA) (Spall 1992). It estimates the gradient from two evaluations of the objective per iteration, whatever the number of parameters. This is why it is the usual choice when every evaluation is a whole kernel matrix or a paid job on hardware. It uses only NumPy.

Example
import numpy as np
from eigenkit.core.optimizers import spsa

result = spsa(lambda x: float(np.sum((x - 1.0) ** 2)), np.zeros(3), maxiter=200)
print(np.round(result.x, 1))   # [0.9 0.9 0.9]

SPSAResult dataclass

Outcome of spsa().

Attributes:

Name Type Description
x ndarray

The final parameters.

fun float

The value of the objective at x.

n_iterations int

The number of iterations run.

n_evaluations int

The number of evaluations of the objective, including the one at the final x.

history tuple[float, ...]

The value of the objective after every iteration, in order.

success bool

Whether the final value of the objective is lower than the starting value.

initial_fun float

The value of the objective at x0.

best_x ndarray | None

The point with the lowest value of the objective seen, including x0. The last point of Simultaneous Perturbation Stochastic Approximation (SPSA) can move past a minimum that it already reached, so on a deterministic objective this is the point to keep.

best_fun float

The value of the objective at best_x.

spsa(fun, x0, *, maxiter=100, learning_rate=0.05, perturbation=0.05, alpha=0.602, gamma=0.101, random_state=0, callback=None)

Minimise fun with Simultaneous Perturbation Stochastic Approximation (SPSA).

Each iteration draws a random direction delta with entries ±1, evaluates fun at x ± c_k * delta, and takes a step against the resulting estimate of the gradient. The step size and the perturbation size decrease as a / (k + 1) ** alpha and c / (k + 1) ** gamma, with the standard exponents of Spall.

Parameters:

Name Type Description Default
fun Callable[[ndarray], float]

The objective to minimise. It maps a 1-D parameter vector to a float.

required
x0 ndarray

The starting parameters.

required
maxiter int

The number of iterations to run.

100
learning_rate float | None

The initial step size a. None calibrates it from a few gradient estimates at x0, so that the first step moves the parameters by about 2π / 10, as the SPSA of qiskit-algorithms does. These evaluations are counted in n_evaluations.

0.05
perturbation float

The initial perturbation size c.

0.05
alpha float

The exponent with which the step size decreases.

0.602
gamma float

The exponent with which the perturbation size decreases.

0.101
random_state int | None

The seed for the perturbation directions.

0
callback Callable[[int, ndarray, float], None] | None

A function called after every iteration as callback(iteration, x, fun(x)).

None

Returns:

Type Description
SPSAResult

An SPSAResult. The evaluations for the history are extra calls to fun, made so that the run can be plotted, and n_evaluations counts them.