Variational Quantum Simulation with analog QPUs¶

Here is a very basic example of Variational Quantum Simulation (VQS, as introduced in http://dx.doi.org/10.1038/s41586-019-1177-4) with QutipQPU.

Let us recall that Variational Quantum Simulation consists in finding the approximate ground state of a "target" Hamiltonian H_target using a variational state preparation parameterized by a time-dependent Hamiltonian (called drive below, also called a "resource" Hamiltonian in the literature).

A basic example¶

In this example, the parameters we are going to optimize are the durations (parameterized by times $t_1$ and $t_2$) of the pulses of our resource Hamiltonian to prepare a trial state that minimizes the target energy (encoded in H_target).

The optimization of the parameters is carried out by a so-called 'variational plugin', ScipyMinimizePlugin (the same we also use for digital variational algorithms such as VQE or QAOA).

In this example, we use a basic noise model described in terms of Lindblad jump operators (jump_operators below).

Here is the full code of VQS:

In [1]:
%matplotlib inline
from qat.core import Observable, Term, Schedule
from qat.core.variables import Variable, heaviside
from qat.qpus import QutipQPU
from qat.plugins import ScipyMinimizePlugin
from qat.hardware import HardwareModel

# Resource Hamiltonian
t = Variable("t", float)
t1 = Variable("t_1", float)
t2 = Variable("t_2", float)
tf = 3.0
drive = [(heaviside(t, 0., t1), Observable(2, pauli_terms=[Term(1, "X", [0]), Term(1, "X", [1])])), 
         (heaviside(t, t1, t2), Observable(2, pauli_terms=[Term(1, "ZZ", [0, 1])])),
         (heaviside(t, t2, tf), Observable(2, pauli_terms=[Term(1, "X", [0]), Term(1, "X", [1])]))] 
schedule = Schedule(drive=drive, tmax=tf)

# Target Hamiltonian
H_target = Observable(2, pauli_terms=[Term(1, 'XZ', [0, 1])])

# Parametric job
job = schedule.to_job(job_type="OBS", observable=H_target)

# Description of the stack
hardware_model = HardwareModel(jump_operators=[Observable(2, pauli_terms=[(Term(.1, 'Z', [0]))])])
qpu = QutipQPU(hardware_model=hardware_model)
optimizer_scipy = ScipyMinimizePlugin(method="COBYLA", x0=[0.4, 1.2])
stack = optimizer_scipy | qpu

# Simulation
res = stack.submit(job)
print("<H_target> =", res.value)
[1/1] Cythonizing qtcoeff_c5167fdf90774f0f16aac1e722cb2d.pyx
running build_ext
building 'qtcoeff_c5167fdf90774f0f16aac1e722cb2d' extension
g++ -fno-strict-overflow -Wsign-compare -DNDEBUG -g -O3 -Wall -I/usr/local/lib64/openmpi/../../include/openmpi-x86_64 -fPIC -I/usr/local/qaptiva/python_references/112/rhel9/ref312/lib/python3.12/site-packages/qutip/core/data -I/usr/local/qaptiva/python_references/112/rhel9/ref312/lib/python3.12/site-packages/numpy/_core/include -I/usr/local/qaptiva/python_references/112/rhel9/ref312/include -I/usr/local/include/python3.12 -c qtcoeff_c5167fdf90774f0f16aac1e722cb2d.cpp -o build/temp.linux-x86_64-cpython-312/qtcoeff_c5167fdf90774f0f16aac1e722cb2d.o -w -O3 -funroll-loops
g++ -fno-strict-overflow -Wsign-compare -DNDEBUG -g -O3 -Wall -I/usr/local/lib64/openmpi/../../include/openmpi-x86_64 -shared -L/usr/local/lib64/openmpi/lib -I/usr/local/lib64/openmpi/../../include/openmpi-x86_64 build/temp.linux-x86_64-cpython-312/qtcoeff_c5167fdf90774f0f16aac1e722cb2d.o -L/usr/local/lib -o build/lib.linux-x86_64-cpython-312/qtcoeff_c5167fdf90774f0f16aac1e722cb2d.cpython-312-x86_64-linux-gnu.so
copying build/lib.linux-x86_64-cpython-312/qtcoeff_c5167fdf90774f0f16aac1e722cb2d.cpython-312-x86_64-linux-gnu.so -> 
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
[1/1] Cythonizing qtcoeff_ed08ece29e29ac89c73c53898812a1.pyx
running build_ext
building 'qtcoeff_ed08ece29e29ac89c73c53898812a1' extension
g++ -fno-strict-overflow -Wsign-compare -DNDEBUG -g -O3 -Wall -I/usr/local/lib64/openmpi/../../include/openmpi-x86_64 -fPIC -I/usr/local/qaptiva/python_references/112/rhel9/ref312/lib/python3.12/site-packages/qutip/core/data -I/usr/local/qaptiva/python_references/112/rhel9/ref312/lib/python3.12/site-packages/numpy/_core/include -I/usr/local/qaptiva/python_references/112/rhel9/ref312/include -I/usr/local/include/python3.12 -c qtcoeff_ed08ece29e29ac89c73c53898812a1.cpp -o build/temp.linux-x86_64-cpython-312/qtcoeff_ed08ece29e29ac89c73c53898812a1.o -w -O3 -funroll-loops
g++ -fno-strict-overflow -Wsign-compare -DNDEBUG -g -O3 -Wall -I/usr/local/lib64/openmpi/../../include/openmpi-x86_64 -shared -L/usr/local/lib64/openmpi/lib -I/usr/local/lib64/openmpi/../../include/openmpi-x86_64 build/temp.linux-x86_64-cpython-312/qtcoeff_ed08ece29e29ac89c73c53898812a1.o -L/usr/local/lib -o build/lib.linux-x86_64-cpython-312/qtcoeff_ed08ece29e29ac89c73c53898812a1.cpython-312-x86_64-linux-gnu.so
copying build/lib.linux-x86_64-cpython-312/qtcoeff_ed08ece29e29ac89c73c53898812a1.cpython-312-x86_64-linux-gnu.so -> 
[1/1] Cythonizing qtcoeff_ea216e735daa39cd8bab6e858fefde.pyx
running build_ext
building 'qtcoeff_ea216e735daa39cd8bab6e858fefde' extension
g++ -fno-strict-overflow -Wsign-compare -DNDEBUG -g -O3 -Wall -I/usr/local/lib64/openmpi/../../include/openmpi-x86_64 -fPIC -I/usr/local/qaptiva/python_references/112/rhel9/ref312/lib/python3.12/site-packages/qutip/core/data -I/usr/local/qaptiva/python_references/112/rhel9/ref312/lib/python3.12/site-packages/numpy/_core/include -I/usr/local/qaptiva/python_references/112/rhel9/ref312/include -I/usr/local/include/python3.12 -c qtcoeff_ea216e735daa39cd8bab6e858fefde.cpp -o build/temp.linux-x86_64-cpython-312/qtcoeff_ea216e735daa39cd8bab6e858fefde.o -w -O3 -funroll-loops
g++ -fno-strict-overflow -Wsign-compare -DNDEBUG -g -O3 -Wall -I/usr/local/lib64/openmpi/../../include/openmpi-x86_64 -shared -L/usr/local/lib64/openmpi/lib -I/usr/local/lib64/openmpi/../../include/openmpi-x86_64 build/temp.linux-x86_64-cpython-312/qtcoeff_ea216e735daa39cd8bab6e858fefde.o -L/usr/local/lib -o build/lib.linux-x86_64-cpython-312/qtcoeff_ea216e735daa39cd8bab6e858fefde.cpython-312-x86_64-linux-gnu.so
copying build/lib.linux-x86_64-cpython-312/qtcoeff_ea216e735daa39cd8bab6e858fefde.cpython-312-x86_64-linux-gnu.so -> 
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
<H_target> = -0.9361456052290016

Checking the exact result¶

We compare the variational energy we got with the target Hamiltonian's exact ground state energy.

In [2]:
import numpy as np
from qat.fermion import SpinHamiltonian
H_target_mat = SpinHamiltonian(H_target.nbqbits, H_target.terms).get_matrix()
eigvals, eigvecs = np.linalg.eigh(H_target_mat)
print("E0 =", min(eigvals))
E0 = -1.0

Plot of the variational energy vs. the optimization step¶

We now plot the results, i.e. the convergence to the optimized energy.

In [3]:
import matplotlib.pyplot as plt
plt.figure(figsize=(6, 4), dpi=90)
plt.plot(eval(res.meta_data["optimization_trace"]), lw=3, label ="VQS energies")
plt.plot([min(eigvals) for _ in range(len(eval(res.meta_data["optimization_trace"])))],
         '--k', lw=3, label = "exact energy")
plt.grid()
plt.xlabel("VQS steps")
plt.ylabel("Energy")
plt.legend()

# Show the optimized parameters
params = eval(res.meta_data["parameters"])
print("Optimized parameters:\n" + str(params))
Optimized parameters:
[np.float64(0.7393274104604622), np.float64(1.4766960354598346)]
No description has been provided for this image

Playing with the optimized schedule¶

In [4]:
params_dic = {"t_1": params[0],   "t_2": params[1]}

# Let us check that the final energy is the expected one
job2= job(**params_dic)
res = qpu.submit(job2)
print("<H_target> =", res.value)

# let us check the probabilities of the final distribution
job3 = schedule.to_job(job_type="SAMPLE")(**params_dic)
res = qpu.submit(job3)
for sample in res:
    print(sample.state, sample.probability)
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Did not find any quantum register info: wrapping results with a dummy BITSTRING register of length 0
Post processing a list of results of length 1
<H_target> = -0.9361456052290016
New batch of length 1 submitted
Compiling a batch of length 1
Starting compilation...
Returning compiled batch.
Resource management is not available, passing through.
Running jobs...
Done
Wrapping results using 1 quantum registers
Post processing a list of results of length 1
|00> 0.20388533086688498
|01> 0.24467687013375594
|10> 0.24589941311403704
|11> 0.305538385885322
In [5]:
sched = job2.schedule
sched.display()
No description has been provided for this image