Plugins for variational algorithms

The following plugins inherit from the Optimizer class and provide an easy way to include your favorite classical optimizer inside a QLM stack.

These plugins require the input job to have abstract parameters (i.e the circuit and/or the observable should be parametrized).

We can, for instance, build a very simple variational job as follows:

from qat.plugins import ScipyMinimizePlugin
from qat.qpus import get_default_qpu
from qat.lang.AQASM import Program, RY
from qat.core import Observable

prog = Program()
qbits = prog.qalloc(1)
RY(prog.new_var(float, "a"))(qbits)
job = prog.to_circ().to_job(observable=Observable.sigma_z(0, 1))

stack = ScipyMinimizePlugin(method="COBYLA") | get_default_qpu()

result = stack.submit(job)

print("Final energy:", result.value)
print("Minimization trace:", result.meta_data["optimization_trace"])
print("Best parameters:", result.meta_data["parameters"])
Final energy: -0.9999999957096648
Minimization trace: [0.6781401351902188, -0.2520237974059332, -0.95047821293436, -0.7750673428457935, -0.9831243410666745, -0.9073016531299735, -0.9982614985175263, -0.9978211191612134, -0.9999937860065149, -0.9978211191612134, -0.9993953989073746, -0.9999267999687756, -0.9999357274163913, -0.9999999274525834, -0.999990810130099, -0.9999972761341723, -0.9999998226009366, -0.9999996222505634, -0.999999990646637, -0.9999999942360466, -0.9999999784992375, -0.9999999999728556, -0.9999999957096648]
Best parameters: [3.1416852854989563]

Below is the detailed documentation of the available plugins:

Scipy Minimizers

class qat.plugins.ScipyMinimizePlugin(collective=False, binding_args=None, **kwargs)

A variational plugin for hybrid quantum classical optimization based on the scipy.optimize.minimize method.

It is a particularization of the Optimizer class.

Parameters
  • x0 (np.array, optional) – initial value of the parameters. Defaults to None, in which case we assume random initilization.

  • binding_args (dict) – arguments passed to the variable binding method

  • kwargs – minimize parameters (see scipy.optimize.minimize documentation), e.g ‘method’, ‘tol’, ‘options’…

Note

Parameters can be changed dynamically using the qat.plugins.ScipyMinimizePlugin.set_options() method.

Example:

import numpy as np
form qat.plugins import ScipyMinimizePlugin
from qat.linalg import LinAlg

plugin = ScipyMinimizePlugin(x0=np.random.random(10),
                             method="COBYLA",
                             tol=1e-3,
                             options={"maxiter": 300})

stack = plugin | LinAlg()
# Any job will run, as long as it contains 10 variables!
result = stack.submit(my_job)
set_options(**kwargs)

Sets new options for the minimize function.

Parameters

kwargs – a new set of options

Simultaneous Perturbation Stochastic Approximation

class qat.plugins.SPSAMinimizePlugin(x0=None, collective=False, binding_args=None, **kwargs)

A variational minimizer based on the Simultaneous Perturbation Stochastic Approximation (SPSA) algorithm.

This is a particularization of the Optimizer class.

Parameters
  • x0 (np.array, optional) – Initial parameters values. If set to None, the initial parameters will be randomly chosen.

  • binding_args (dict, optional) – arguments to bind job variables (see Optimizer documentation). Defaults to None.

  • maxiter (int, optional) – maximal number of iterations. Defaults to 100.

  • a (int, optional) – \(a\) parameter. Defaults to 1.

  • A (int, optional) – \(A\) parameter. Defaults to 10.

  • alpha (float, optional) – \(\alpha\) parameter. Defaults to 0.602.

  • c (float, optional) – \(c\) parameter. Defaults to 0.01.

  • gamma (float, optional) – \(\gamma\) parameter. Defaults to 0.101.

  • precision (float, optional) – stop after ‘stop_condition’ consecutive times when difference between two successive function evalutions are lower than precision. Defaults to 1e-4.

  • stop_condition (int, optional) – see ‘precision’. Defaults to 5.

  • a_calibration (bool, optional) – whether to calibrate a param. Defaults to False

  • n_calibrations (int, optional) – Defaults to 25.

  • seed (int, optional) – seed for random number generator. Defaults to None.

References

https://en.wikipedia.org/wiki/Simultaneous_perturbation_stochastic_approximation

Particle Swarm Optimization

class qat.plugins.PSOMinimizePlugin(x0=None, collective=False, binding_args=None, **kwargs)

A variational minimizer based on the Particle Swarm Optimization (PSO) algorithm.

It is a particularization of the Optimizer class.

Parameters
  • x0 (optional, numpy.ndarray) – Initial position of one Particle. By default defined as an integer equal to the number of parameters to optimize.

  • binding_args (optional, dict) – arguments passed to the variable binding method

  • choose_inertia_function (str, optional) – method for picking the inertia weights. It may be ‘constant’, ‘random’, ‘linearly_decreasing’ (default), ‘chaotic_random’.

  • name_method_used (str, optional) – Kind of PSO to be used. It may be ‘PSO’ (default), ‘CLPSO’, ‘FDR_PSO’, ‘LIPS’, ‘HPSO_TVAC’.

  • max_iter (int, optional) – maximum number of iterations. Defaults to 10.

  • swarm_number (int, optional) – size of the swarm. Defaults to 10.

  • size_initial_vector_space (float, optional) – size of the hypercube. Defaults to 1.

  • inertia_kwargs (float, optional) – depending on the inertia_function used. See class Inertia_weight for more details.

Sequential Optimization

class qat.plugins.SeqOptim(ncycles: Optional[int] = 10, coeff: Optional[float] = 1, x0: Optional[ndarray] = None, verbose: Optional[bool] = False, collective: bool = False)

This plugin implements the sequential parameter optimization technique (also known as rotosolve) described in:

It is a particularization of the Optimizer class.

It consists in tuning the parameters of a variational ansatz one after the other, cycling several times through all of them, leveraging the parameter shift rule to find a local minimum with three measurements of the cost function.

Such a method can be used only if all parametrized gates are of the form \(\exp(-i c \theta P/2)\) where \(P\) is a tensor product of Pauli matrices and \(c\) a number that must be entered in the ‘coeff’ field of the plugin (e.g. for rotation matrices \(RX\), \(RY\), \(RZ\), \(c=1\)).

In the current implementation of the plugin, all parameterized gates are assumed to be of the same type (i.e. have the same coefficient \(c\)).

Note

The applicability of the method is not checked for when the batch is received. It belongs to the user to provide a circuit matching the requirements mentioned above.

Parameters
  • ncycles (int, optional) – Number of times the plugin cycles through each angle, defaults to 10. The value to which it should be set so that the cost function converges is however strongly problem-dependent.

  • coeff (Optional[float]) – Rescaling parameter \(c\) for all the circuit’s angles. Defaults to 1.

  • x0 (Optional[np.ndarray]) – Initial value of the parameters. Defaults to None, in which case we assume random initialization.

  • verbose (bool) – whether we want to print intermediary cost function values, defaults to False.