Observable Job
The second type of final measurement, the “OBSERVABLE” mode can be used to compute the average value of an observable. We will reuse the simple Bell pair \(|\psi\rangle=(|00\rangle+|11\rangle)/\sqrt{2}\) circuit, and compute the average value of the following observable:
A straightforward computation yields \(\langle O \rangle = 0\). Let us now perform this computation with Qaptiva and verify the result.
We start with a computation devoid of any shot noise (infinite number of shots).
from qat.lang.AQASM import Program, H, CNOT
from qat.qpus import get_default_qpu
# Create a circuit
qprog = Program()
qbits = qprog.qalloc(2)
H(qbits[0])
CNOT(qbits[0], qbits[1])
circuit = qprog.to_circ()
# Create an observable
from qat.core import Observable, Term
obs = Observable(2, pauli_terms=[Term(1, "XZ", [0, 1])])
# Create a job
job = circuit.to_job(observable=obs)
# Execute
result = get_default_qpu().submit(job)
print("<O> = ", result.value)
<O> = 0.0
We verify that the expectation value
\(\langle O \rangle\) of the result is 0.
We now look at the effect of shot noise. In practice one can only repeat the measurement a finite number of times.
Here, we will submit three jobs, each with a different number of shots nbshots
, to the QPU.
from qat.lang.AQASM import Program, H, CNOT
from qat.qpus import get_default_qpu
# Create a circuit
qprog = Program()
qbits = qprog.qalloc(2)
H(qbits[0])
CNOT(qbits[0], qbits[1])
circuit = qprog.to_circ()
# Create an observable
from qat.core import Observable, Term
obs = Observable(2, pauli_terms=[Term(1, "XZ", [0, 1])])
# Create a job
for nbshots in [100, 1000, 10000]:
job = circuit.to_job(observable=obs, nbshots=nbshots)
# The QPU is stacked with ObservableSplitter, as the default QPU does not support
# a finite number of shots for observable sampling
from qat.plugins import ObservableSplitter
result = (ObservableSplitter() | get_default_qpu()).submit(job)
print(f"<O> ({nbshots} shots) = {result.value} +/- {result.error}")
<O> (100 shots) = -0.06 +/- 0.10032271160931837
<O> (1000 shots) = -0.02400000000000002 +/- 0.03162948662916337
<O> (10000 shots) = 0.005399999999999988 +/- 0.010000354229149628
We can see that the expectation value
\(\langle O \rangle\) of the result differs from the ideal one due to “shot noise”.
The error
field contains the standard error of the estimated expectation value.