qml.RotosolveOptimizer¶
-
class
RotosolveOptimizer
[source]¶ Bases:
object
Rotosolve gradient free optimizer.
The Rotosolve optimizer minimizes an objective function with respect to the 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\) 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 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\).
The algorithm is described in further detail in Ostaszewski et al. (2019)
Example:
Initialize the optimizer, set the initial values of
x
to be used and set the number of steps to optimize over.>>> opt = qml.optimize.RotosolveOptimizer() >>> x = [0.3, 0.7] >>> n_steps = 10
Set up the PennyLane circuit using the
default.qubit
as simulator device.>>> dev = qml.device("default.qubit", analytic=True, wires=2) ... @qml.qnode(dev) ... def circuit(params): ... qml.RX(params[0], wires=0) ... qml.RY(params[1], wires=1) ... qml.CNOT(wires=[0, 1]) ... return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliX(1))
Define a cost function (that takes a list of values as input and return a single value) based on the above circuit.
>>> def cost(x): ... Z_1, X_2 = circuit(x) ... return 0.2 * Z_1 + 0.5 * X_2
Run the optimization step-by-step for
n_steps
steps.>>> cost_rotosolve = [] >>> for _ in range(n_steps): ... cost_rotosolve.append(cost(x)) ... x = opt.step(cost, x)
The optimized values for x should now be stored in
x
and steps-vs-cost can be seen by plottingcost_rotosel
.Methods
step
(objective_fn, x)Update x with one step of the optimizer.
step_and_cost
(objective_fn, x)Update x with one step of the optimizer and return the corresponding objective function value prior to the step.
-
step
(objective_fn, x)[source]¶ Update x with one step of the optimizer.
- Parameters
objective_fn (function) – The objective function for optimization. It should take a sequence of the values
x
and a list of the gatesgenerators
as inputs, and return 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
- Returns
the new variable values \(x^{(t+1)}\)
- Return type
array
-
step_and_cost
(objective_fn, x)[source]¶ Update x 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 should take a sequence of the values
x
and a list of the gatesgenerators
as inputs, and return 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
- Returns
- the new variable values \(x^{(t+1)}\) and the objective function output
prior to the step
- Return type
tuple
-
Contents
Using PennyLane
Development
API
Downloads