# qml.RotoselectOptimizer¶

class RotoselectOptimizer(possible_generators=None)[source]

Bases: object

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(params, wires=0)
...     generators(params, wires=1)
...     qml.CNOT(wires=[0, 1])
...     return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliX(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 plotting cost_rotosel.

 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 values x and a list of the gates generators 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 values x and a list of the gates generators 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