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 0x7f5d98d05190>, _J=[-0.0, -0.25, -0.0, -0.25, -0.25, -0.0, -0.25, -0.0, -0.0, -0.25, -0.0, -0.25, -0.25, -0.0, -0.25, -0.0], _h=[-0.0, -0.0, -0.0, -0.0], offset_i=0)
Final energy: -3.3060960694503567
The optimization data:
 message: Maximum number of function evaluations has been exceeded.
 success: False
  status: 2
     fun: -3.3060960694503567
       x: [-7.095e-01  2.599e+00  9.630e-01  1.265e+00]
    nfev: 20
   maxcv: 0.0
The best set of parameters:
[-0.7095072676839483, 2.5990429914420425, 0.9629559468203422, 1.2654265679949046]

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 0x7f5d98d05190>, _J=[-0.0, -0.25, -0.0, -0.25, -0.25, -0.0, -0.25, -0.0, -0.0, -0.25, -0.0, -0.25, -0.25, -0.0, -0.25, -0.0], _h=[-0.0, -0.0, -0.0, -0.0], offset_i=0)
Final energy: -3.999564605098148
The optimization data:
 message: Optimization terminated successfully.
 success: True
  status: 1
     fun: -3.999564605098148
       x: [ 2.011e+00 -9.009e-01  1.802e+00  2.242e+00]
    nfev: 64
   maxcv: 0.0
In [ ]: