Fermionic simulations
A fermionic Hamiltonian is described in a similar fashion to bosons and spins - with an Observable
(or many of them) in a Schedule
. The key difference lies within the operators used. The fermionic creation operator \(c^\dagger\) is encoded via the big letter C
, while the annihilation operator \(c\) - through the small letter c
.
Let us look at the following simple Hamiltonian:
Imagine we want to evolve \(H\) for time \(\frac{\pi}{2}\) starting from the state \(\left|01\right>\) (i.e. only site \(1\) is occupied). If at the end we measure the occupation of site \(0\) via the \(n_0 = c^\dagger_0 c_0\) operator, we would expect that the ocupation of the two sites has swapped such that the state of the system is \(\left|10\right>\) and \(\left<n_0\right> = 1\). One way to simulate this behaviour would look like:
import numpy as np
from qat.qpus import QutipQPU
from qat.core import Observable, Term, Schedule
from qat.core.variables import Variable, sin
# Define a time Variable
t = Variable("t", float)
# Create the Schedule
drive = Observable(2, pauli_terms=[Term(1, "Cc", [0, 1]), Term(1, "Cc", [1, 0])])
schedule = Schedule(drive=drive,
tmax=np.pi / 2)
# Construct a job with an observable to measure
job = schedule.to_job(psi_0="01", # start from the 0th site unoccupied and the 1st - occupied
job_type="OBS",
observable=Observable(2, pauli_terms=[Term(1, 'Cc', [0, 0])]))
# Create a QPU and submit the job
qpu = QutipQPU(nsteps=200) # can specify the number of time steps for the integration
res = qpu.submit(job)
print("<n_0 (pi/2)> =", res.value)
<n_0 (pi/2)> = 0.9999999999845415
For a more involved Hamiltonian considering interactions between the fermions in a noisy setting, take a look at the following fermionic notebook.
On Qaptiva there is also the module qat.fermion
specifically dedicated to spin and fermionic computations.
Note
Fermionic simulations are currently only supported for QutipQPU
.