Scipy minimize variational plugin¶
In this notebook, we briefly introduce the particularization of the Optimizer abstract plugin for scipy.optimize.minimize.
We assume that you are already familiar with the Optimize class. If not, you can access a detailed notebook introducting this class here.
ScipyMinimizePlugin is an Optimizer wrapping the scipy.optimize.minimize method, thus inheriting from all the underlying minimization algorithms.
The plugin can be instantiated as follows:
In [1]:
import numpy
from qat.vsolve.optimize import ScipyMinimizePlugin
from scipy.optimize import minimize
## A cobyla minimizer over any number of variables, random initialization, 20 max steps
cobyla = ScipyMinimizePlugin(tol=1e-2,
method="COBYLA",
options={"maxiter": 20})
Lets try to use this plugin to solve a QAOA instance.
In [2]:
from qat.opt import MaxCut
import networkx as nx
import matplotlib.pyplot as plt
from qat.qpus import get_default_qpu
qpu = get_default_qpu()
stack = cobyla | qpu
graph = nx.cycle_graph(4)
problem = MaxCut(graph)
job = problem.to_job("qaoa", 2) # '2' is the depth
circuit = job.circuit
result = stack.submit(job)
print("The maxcut problem:")
print(problem)
print("Final energy:", result.value)
print("The optimization data:")
print(result.meta_data["optimizer_data"])
print("The best set of parameters:")
print(result.meta_data["parameters"])
The maxcut problem:
MaxCut(graph=<networkx.classes.graph.Graph object at 0x7f0005e6c4d0>, _J=[np.float64(-0.0), np.float64(-0.25), np.float64(-0.0), np.float64(-0.25), np.float64(-0.25), np.float64(-0.0), np.float64(-0.25), np.float64(-0.0), np.float64(-0.0), np.float64(-0.25), np.float64(-0.0), np.float64(-0.25), np.float64(-0.25), np.float64(-0.0), np.float64(-0.25), np.float64(-0.0)], _h=[np.float64(-0.0), np.float64(-0.0), np.float64(-0.0), np.float64(-0.0)], offset_i=0)
Final energy: -3.540311323849526
The optimization data:
message: Return from COBYLA because the objective function has been evaluated MAXFUN times.
success: False
status: 3
fun: -3.540311323849526
x: [ 1.208e+00 1.039e+00 1.718e+00 -6.839e-01]
nfev: 20
maxcv: 0.0
The best set of parameters:
[np.float64(1.2078575674799803), np.float64(1.0394079711245894), np.float64(1.7175560306787159), np.float64(-0.6839318971928736)]
Notice that the 'optimizer_data' entry of the result's meta_data contains the (stringified) output of scipy's minimize function.
As we can see, 20 iterations are not enough for the optimizer to converge. Lets try with 200:
In [3]:
cobyla = ScipyMinimizePlugin(method="COBYLA",
tol=1e-2,
options={"maxiter": 200})
stack = cobyla | qpu
result = stack.submit(job)
print("The maxcut problem:")
print(problem)
print("Final energy:", result.value)
print("The optimization data:")
print(result.meta_data["optimizer_data"])
The maxcut problem:
MaxCut(graph=<networkx.classes.graph.Graph object at 0x7f0005e6c4d0>, _J=[np.float64(-0.0), np.float64(-0.25), np.float64(-0.0), np.float64(-0.25), np.float64(-0.25), np.float64(-0.0), np.float64(-0.25), np.float64(-0.0), np.float64(-0.0), np.float64(-0.25), np.float64(-0.0), np.float64(-0.25), np.float64(-0.25), np.float64(-0.0), np.float64(-0.25), np.float64(-0.0)], _h=[np.float64(-0.0), np.float64(-0.0), np.float64(-0.0), np.float64(-0.0)], offset_i=0)
Final energy: -3.9972096801579386
The optimization data:
message: Return from COBYLA because the trust region radius reaches its lower bound.
success: True
status: 0
fun: -3.9972096801579386
x: [ 2.356e+00 1.571e+00 -3.038e+00 1.508e+00]
nfev: 160
maxcv: 0.0
In [ ]: