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 θ=θ1,…,θD and rotation gate choices R=R1,…,RD one at a time according to a closed-form expression for the optimal value of the dth parameter θ∗d when the other parameters and gate choices are fixed:
θ∗d=argminθd⟨H⟩θd=−π2−arctan2(2⟨H⟩θd=0−⟨H⟩θd=π/2−⟨H⟩θd=−π/2,⟨H⟩θd=π/2−⟨H⟩θd=−π/2),where ⟨H⟩θd is the expectation value of the objective function optimized over the parameter θd. 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 θ 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 {Rx,Ry,Rz}.
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