Measuring subsets of qubits¶
In this notebook, we explore the possibility to measure a subset of qubits of a given output state.
First example (Bell state)¶
Let us consider the Bell state $$|\psi\rangle=\frac{|00\rangle+|11\rangle}{\sqrt{2}}$$
Its vector of amplitudes is $(1/\sqrt{2},0,0,1/\sqrt{2})$.
Let us measure its first qubit. Then we should obtain
the value 0 with probability p=1/2, in which case the system is in state $|00\rangle$
the value 1 with probability p=1/2, in which case the system is in state $|11\rangle$
The same holds for the second qubit since the state is invariant under a swap of its qubits.
In the cell below, we create a circuit whose output is this Bell state, and output the nonzero amplitudes:
from qat.lang.AQASM import Program, H, CNOT, X
qprog = Program()
nbqbits = 2
qbits = qprog.qalloc(nbqbits)
qprog.apply(H, qbits[0])
qprog.apply(CNOT, qbits[0], qbits[1])
circuit = qprog.to_circ()
from qat.qpus import PyLinalg
result = PyLinalg().submit(circuit.to_job())
for sample in result:
print("State %s, amplitude %s, probability %s"%(sample.state, sample.amplitude, sample.probability))
circuit.display()
State |00>, amplitude (0.7071067811865475+0j), probability 0.4999999999999999 State |11>, amplitude (0.7071067811865475+0j), probability 0.4999999999999999
We now call the to_job method of the task with two arguments:
- the first (
qubits) specifies the indices of the qubits we want to measure, - the second (
nbshots) the number of repetitions of the measurement.
# measuring qubit #0 50 times
result = PyLinalg().submit(circuit.to_job(qubits=[0], nbshots=50))
for res in result:
print("Qubit 0 has value %s (the probability of getting this result is %s +/- %s)"%(int(res.state[0]),
res.probability, res.err))
print()
# measuring qubit #1 50 times
result = PyLinalg().submit(circuit.to_job(qubits=[1], nbshots=50))
for res in result:
print("Qubit 1 has value %s (the probability of getting this result is %s +/- %s)"%(int(res.state[0]),
res.probability, res.err))
Qubit 0 has value 0 (the probability of getting this result is 0.5 +/- 0.07142857142857142) Qubit 0 has value 1 (the probability of getting this result is 0.5 +/- 0.07142857142857142) Qubit 1 has value 1 (the probability of getting this result is 0.52 +/- 0.07137140569598169) Qubit 1 has value 0 (the probability of getting this result is 0.48 +/- 0.07137140569598169)
Example 2¶
In this section, we are interested in a quantum state of the form $$|\psi\rangle=\frac{|00\rangle}{\sqrt{2}}+\frac{|10\rangle+|11\rangle}{2}$$
Its amplitudes are $(1/\sqrt{2},1/2,0, 1/2)$.
Let us measure its first qubit. Then we should obtain
the value 0 with probability p=0.5
the value 1 with probability p=0.5
Let us measure its second qubit. Then we should obtain
the value 0 with probability p=0.5+0.25=0.75,
the value 1 with probability p=0.25.
Let us construct the circuit that prepares this state:
from qat.lang.AQASM import Program, H, CNOT
qprog = Program()
nbqbits = 2
qbits = qprog.qalloc(nbqbits)
qprog.apply(H, qbits[0])
qprog.apply(H.ctrl(), qbits[0], qbits[1])
circuit = qprog.to_circ(submatrices_only=False)
circuit.display()
Let us check we obtain the correct amplitudes:
result = PyLinalg().submit(circuit.to_job())
for sample in result:
print("State %s, amplitude %s, probability %s"%(sample.state, sample.amplitude, sample.probability))
State |00>, amplitude (0.7071067811865475+0j), probability 0.4999999999999999 State |10>, amplitude (0.4999999999999999+0j), probability 0.2499999999999999 State |11>, amplitude (0.4999999999999999+0j), probability 0.2499999999999999
Let us execute partial measurements.
# measuring qubit #0 200 times
result = PyLinalg().submit(circuit.to_job(qubits=[0], nbshots=200))
for res in result:
print("Qubit 0 has value %s (the probability of getting this result is %s)"%(int(res.state[0]), res.probability))
print()
# measuring qubit #1 200 times
result = PyLinalg().submit(circuit.to_job(qubits=[1], nbshots=200))
for res in result:
print("Qubit 1 has value %s (the probability of getting this result is %s)"%(int(res.state[0]), res.probability))
Qubit 0 has value 0 (the probability of getting this result is 0.445) Qubit 0 has value 1 (the probability of getting this result is 0.555) Qubit 1 has value 0 (the probability of getting this result is 0.77) Qubit 1 has value 1 (the probability of getting this result is 0.23)
Example 3: measuring several qubits¶
In this last section, we are interested in a quantum state of the form $$|\psi\rangle=\frac{|000\rangle}{\sqrt{2}}+\frac{|100\rangle+|111\rangle}{2}$$
Its amplitudes are $(1/\sqrt{2},0,0,0, 1/2, 0, 0, 1/2)$.
Let us measure its first and second qubit. Then we should obtain
- the value 0,0 with probability $p=0.5$
- the value 0,1 with probability $p=0$
- the value 1,0 with probability $p=0.25$
- the value 1,1 with probability $p=0.25$
Let us measure its second and third qubit. Then we should obtain
- the value 0,0 with probability $p=0.75$
- the value 0,1 with probability $p=0$
- the value 1,0 with probability $p=0$
- the value 1,1 with probability $p=0.25$
Let us first build the circuit that prepares this state, and check the amplitudes are correct:
from qat.lang.AQASM import Program, H, CNOT
qprog = Program()
nbqbits = 3
qbits = qprog.qalloc(nbqbits)
qprog.apply(H, qbits[0])
qprog.apply(H.ctrl(), qbits[0], qbits[1])
qprog.apply(CNOT, qbits[1], qbits[2])
circuit = qprog.to_circ(submatrices_only=False)
result = PyLinalg().submit(circuit.to_job())
for sample in result:
print("State %s, amplitude %s, probability %s"%(sample.state, sample.amplitude, sample.probability))
circuit.display()
State |000>, amplitude (0.7071067811865475+0j), probability 0.4999999999999999 State |100>, amplitude (0.4999999999999999+0j), probability 0.2499999999999999 State |111>, amplitude (0.4999999999999999+0j), probability 0.2499999999999999
Let us now perform measurements on q0, q1 on the one hand, and q1, q2 on the other hand:
# measuring qubit #0 and #1 200 times
result = PyLinalg().submit(circuit.to_job(qubits=[0, 1], nbshots=200))
for res in result:
print("Qubits 0,1 have value %s,%s (the probability of getting this result is %s +/- %s)"%(int(res.state[0]),
int(res.state[1]),
res.probability,
res.err))
print()
# measuring qubit #1 and #2 200 times
result = PyLinalg().submit(circuit.to_job(qubits=[1, 2], nbshots=200))
for res in result:
print("Qubits 1,2 have value %s,%s (the probability of getting this result is %s +/- %s)"%(int(res.state[0]),
int(res.state[1]),
res.probability,
res.err))
Qubits 0,1 have value 1,0 (the probability of getting this result is 0.255 +/- 0.030897382432918653) Qubits 0,1 have value 0,0 (the probability of getting this result is 0.44 +/- 0.035187937631720755) Qubits 0,1 have value 1,1 (the probability of getting this result is 0.305 +/- 0.03263741725420573) Qubits 1,2 have value 0,0 (the probability of getting this result is 0.745 +/- 0.030897382432918653) Qubits 1,2 have value 1,1 (the probability of getting this result is 0.255 +/- 0.030897382432918653)