import tequila as tq
= tq.QCircuit QCircuit
Basic VQE
We will showcase some basic circuit constructions within tequila via the UpCCGSD circuit class.
Note that you can create the circuits also via mol.make_ansatz(name="2-UpCCGSD")
and similar for the other names.
We will use canonical Hartree-Fock (HF) orbitals in a closed-shell formulation, the terms occupied refer to those orbitals occupied in the HF reference, while virtual refers to the rest. The HF reference can be prepared via a simple circuit obtained from mol.prepare_reference
.
Dependencies for the code in this tutorial
pip install tequila-basic
pip install pyscf
pip install qulacs
Essential imports in the next cell:
The following figure illustrates the different circuits using a high-level representation: - each line is a spatial orbital - circles indicate single excitations (one operation includes spin-up and spin-down excitations) - squared indicate paired double excitations (two spin-paired electrons from one spatial orbital into the other)
The color code indicates what is created by the individual code blocks below.
The UpCCD circuit includes all paired double excitations from occupied to virtual orbitals
def UpCCD(m):
= QCircuit()
U # occupied HF reference orbitals
for i in reversed(range(0, m.n_electrons//2)):
# unoccupied HF reference orbitals
for a in range(m.n_electrons//2, m.n_orbitals):
+= m.UC(i,a)
U
return U
The next stage is the inclusion of the missing paired double excitations
def UpCCGD(m):
= UpCCD(m)
U for i in range(0,m.n_electrons//2):
for j in range(i+1,m.n_electrons//2):
+= m.UC(i,j)
U for a in range(m.n_electrons//2, m.n_orbitals):
for b in range(a+1, m.n_orbitals):
+= m.UC(a,b)
U
return U
Finally we add all possible single excitations
def UpCCGSD(m):
= UpCCGD(m)
U for k in range(0, m.n_orbitals):
for l in range(k+1, m.n_orbitals):
+= m.UR(k,l)
U return U
As an example we compute the VQE energies of a \(H_4\) molecule with different bond distances. We illustrate UpCCD and UpCCGSD and use either random or fixed initial values. Initial values fixed to zero essentially start from the HF reference. You will see that this is not sufficient to find the best paramters for the UpCCGSD – however, random initialization is also not the practiable solution, as you usually need a few tries.
Our example looks like this
with a variable \(R\) and fixed \(d=0.75\) Angstroms.
= 0.75
d = 0.5
R = {"exact":{}}
data for _ in range(15):
+= 0.2
R = "H 0.0 0.0 0.0\nH 0.0 0.0 0.75\nH 0.0 0.0 {}\nH 0.0 0.0 {}".format(d+R, d+R+d)
geom = tq.Molecule(geometry=geom, basis_set="sto-3g")
mol = mol.prepare_reference()
U0 = mol.make_hamiltonian()
H
"exact"][R]=mol.compute_energy("fci")
data[for circDesign in [UpCCD, UpCCGSD]:
= str(circDesign.__name__)
name = U0 + circDesign(mol)
U = tq.ExpectationValue(U=U, H=H)
E for iv in ["zero", "random"]:
= name+"("+str(iv)+")"
xname if xname not in data: data[xname]={}
= tq.minimize(E, silent=True, initial_values=iv)
result =result.energy data[xname][R]
Code
from matplotlib import pyplot as plt
= {"exact":"black", "UpCCD(zero)":"tab:blue", "UpCCGSD(zero)":"forestgreen", "UpCCGSD(random)":"tab:red"}
color for name,d in data.items():
= list(d.keys())
x = list(d.values())
y if name in color:
=name, color=color[name])
plt.plot(x,y,label
plt.legend() plt.show()