quri_parts.algo.optimizer.spsa module#
- class quri_parts.algo.optimizer.spsa.OptimizerStateSPSA(params: 'npt.NDArray[np.float_]', cost: float = 0.0, status: quri_parts.algo.optimizer.interface.OptimizerStatus = <OptimizerStatus.SUCCESS: 1>, niter: int = 0, funcalls: int = 0, gradcalls: int = 0, rng: numpy.random._generator.Generator = Generator(PCG64) at 0x7FAF1730DC80)#
Bases:
OptimizerState
- rng: Generator = Generator(PCG64) at 0x7FAF1730DC80#
- class quri_parts.algo.optimizer.spsa.SPSA(a: float = 0.6283185307179586, c: float = 0.1, alpha: float = 0.602, gamma: float = 0.101, A: float = 0.0, ftol: float | None = 1e-05, rng_seed: int | None = None)#
Bases:
Optimizer
Simultaneous perturbation stochastic approximation (SPSA) optimizer. The implementation is heavily inspired by [1]. Given the parameters \(\theta_k\) at an iteration \(k\), the updated parameters \(\theta_{k+1}\) is given by
\[\theta_{k+1} = \theta_k - \alpha_k g_k(\theta_k), g_k(\theta_k) = \frac{f(\theta_k+c_k \Delta_k)-f(\theta_k-c_k \Delta_k)}{2 c_k} \Delta_k^{-1}, a_k = a / (A + k + 1)^\alpha, c_k = c / (k + 1)^\gamma,\]where \(f\) is the cost function to be minimized, and \(\Delta_k\) is a vector generated randomly. \(\Delta_k^{-1}\) is defined as the element-wise inverse of \(\Delta_k\). The dimension of \(\Delta_k\) is the same as that of \(\theta_k\). In this optimizer, \(\Delta_k\) is generated from a Bernoulli distribution. Note that \(g_k(\theta_k)\) works as an estimate of the first order gradient of the cost function \(f(\theta_k)\).
The main advantage of the SPSA optimizer is that it requires only 2 function evaluations to estimate the gradient in each iteration. Whereas the standard gradient-based optimizers require \(2p\) or more function evaluations (\(p\): the parameter length/size) in each iteration to compute the gradient. Hence the SPSA could be useful when performing VQE with sampling.
- Parameters:
a – \(a\) in the parameter update rule that is defined above.
c – \(c\) in the parameter update rule that is defined above.
alpha – \(\alpha\) in the parameter update rule that is defined above.
gamma – \(\gamma\) in the parameter update rule that is defined above.
A – \(A\) in the parameter update rule that is defined above. A recommended choice is A = (10 or 100) multiplied by the maximum number of iterations that the optimizer runs.
ftol – If not None, judge convergence by cost function tolerance. See
ftol()
for details.
- Ref:
- [1]: J. C. Spall, “Implementation of the simultaneous perturbation algorithm
for stochastic optimization,” in IEEE Transactions on Aerospace and Electronic Systems, vol. 34, no. 3, pp. 817-823, July 1998, doi: 10.1109/7.705889.
- get_init_state(init_params: npt.NDArray[np.float_]) OptimizerStateSPSA #
Returns an initial state for optimization.
- step(state: OptimizerState, cost_function: Callable[[npt.NDArray[np.float_]], float], grad_function: Callable[[npt.NDArray[np.float_]], npt.NDArray[np.float_]] | None = None) OptimizerStateSPSA #
Run a single optimization step and returns a new state.