#!/usr/bin/env python # coding: utf-8 # # # # 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: # In[1]: 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)) get_ipython().run_line_magic('qatdisplay', 'circuit') # 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. # In[10]: # 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)) # ## 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: # In[ ]: 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) get_ipython().run_line_magic('qatdisplay', 'circuit') # Let us check we obtain the correct amplitudes: # In[ ]: result = PyLinalg().submit(circuit.to_job()) for sample in result: print("State %s, amplitude %s, probability %s"%(sample.state, sample.amplitude, sample.probability)) # Let us execute partial measurements. # In[ ]: # 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)) # ## 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: # In[ ]: 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)) get_ipython().run_line_magic('qatdisplay', 'circuit') # Let us now perform measurements on q0, q1 on the one hand, and q1, q2 on the other hand: # In[ ]: # 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)) # In[ ]: