qml.RotoselectOptimizer¶
- class RotoselectOptimizer(possible_generators=None)[source]¶
Bases:
object
Rotoselect gradient-free optimizer.
The Rotoselect optimizer minimizes an objective function with respect to the rotation gates and parameters of a quantum circuit without the need for calculating the gradient of the function. The algorithm works by updating the parameters \(\theta = \theta_1, \dots, \theta_D\) and rotation gate choices \(R = R_1,\dots,R_D\) one at a time according to a closed-form expression for the optimal value of the \(d^{th}\) parameter \(\theta^*_d\) when the other parameters and gate choices are fixed:
\[\theta^*_d = \underset{\theta_d}{\text{argmin}}\left<H\right>_{\theta_d} = -\frac{\pi}{2} - \text{arctan2}\left(2\left<H\right>_{\theta_d=0} - \left<H\right>_{\theta_d=\pi/2} - \left<H\right>_{\theta_d=-\pi/2}, \left<H\right>_{\theta_d=\pi/2} - \left<H\right>_{\theta_d=-\pi/2}\right),\]where \(\left<H\right>_{\theta_d}\) is the expectation value of the objective function optimized over the parameter \(\theta_d\). \(\text{arctan2}(x, y)\) computes the element-wise arc tangent of \(x/y\) choosing the quadrant correctly, avoiding, in particular, division-by-zero when \(y = 0\).
Which parameters and gates that should be optimized over is decided in the user-defined cost function, where \(R\) is a list of parametrized rotation gates in a quantum circuit, along with their respective parameters \(\theta\) for the circuit and its gates. Note that the number of generators should match the number of parameters.
The algorithm is described in further detail in Ostaszewski et al. (2021).
- Parameters
possible_generators (list[Operation]) – List containing the possible
pennylane.ops.qubit
operators that are allowed in the circuit. Default is the set of Pauli rotations \(\{R_x, R_y, R_z\}\).
Example:
Initialize the Rotoselect optimizer, set the initial values of the weights
x
, choose the initial generators, and set the number of steps to optimize over.>>> opt = qml.optimize.RotoselectOptimizer() >>> x = [0.3, 0.7] >>> generators = [qml.RX, qml.RY] >>> n_steps = 10
Set up the PennyLane circuit using the
default.qubit
simulator device.>>> dev = qml.device("default.qubit", shots=None, wires=2) >>> @qml.qnode(dev) ... def circuit(params, generators=None): # generators will be passed as a keyword arg ... generators[0](params[0], wires=0) ... generators[1](params[1], wires=1) ... qml.CNOT(wires=[0, 1]) ... return qml.expval(qml.Z(0)), qml.expval(qml.X(1))
Define a cost function based on the above circuit.
>>> def cost(x, generators): ... Z_1, X_2 = circuit(x, generators=generators) ... return 0.2 * Z_1 + 0.5 * X_2
Run the optimization step-by-step for
n_steps
steps.>>> cost_rotosel = [] >>> for _ in range(n_steps): ... cost_rotosel.append(cost(x, generators)) ... x, generators = opt.step(cost, x, generators)
The optimized values for x should now be stored in
x
together with the optimal gates for the circuit, while steps-vs-cost can be seen by plottingcost_rotosel
.Methods
step
(objective_fn, x, generators, **kwargs)Update trainable arguments with one step of the optimizer.
step_and_cost
(objective_fn, x, generators, ...)Update trainable arguments with one step of the optimizer and return the corresponding objective function value prior to the step.
- step(objective_fn, x, generators, **kwargs)[source]¶
Update trainable arguments with one step of the optimizer.
- Parameters
objective_fn (function) – The objective function for optimization. It must have the signature
objective_fn(x, generators=None)
with a sequence of the valuesx
and a list of the gatesgenerators
as inputs, returning a single value.x (Union[Sequence[float], float]) – sequence containing the initial values of the variables to be optimized over or a single float with the initial value
generators (list[Operation]) – list containing the initial
pennylane.ops.qubit
operators to be used in the circuit and optimized over**kwargs – variable length of keyword arguments for the objective function.
- Returns
The new variable values \(x^{(t+1)}\) as well as the new generators.
- Return type
array
- step_and_cost(objective_fn, x, generators, **kwargs)[source]¶
Update trainable arguments with one step of the optimizer and return the corresponding objective function value prior to the step.
- Parameters
objective_fn (function) – The objective function for optimization. It must have the signature
objective_fn(x, generators=None)
with a sequence of the valuesx
and a list of the gatesgenerators
as inputs, returning a single value.x (Union[Sequence[float], float]) – sequence containing the initial values of the variables to be optimized over or a single float with the initial value
generators (list[Operation]) – list containing the initial
pennylane.ops.qubit
operators to be used in the circuit and optimized over**kwargs – variable length of keyword arguments for the objective function.
- Returns
the new variable values \(x^{(t+1)}\), the new generators, and the objective function output prior to the step
- Return type
tuple