{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.5"
},
"orig_nbformat": 2,
"kernelspec": {
"name": "python385jvsc74a57bd0379f303adb6a381777e199a378df62c5bd2528f4cad60f82c70a3b682fb35459",
"display_name": "Python 3.8.5 64-bit ('venv': conda)"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"source": [
"# Measuring qubits in qoqo\n",
"\n",
"This notebook is designed to demonstrate the use of measurements in qoqo. We will look at several examples of measuring qubits, from single and multi-qubit registers. To learn about the effect of measurement, we will look at the state vectors before and after measurement. "
],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from qoqo_pyquest import PyQuestBackend\n",
"from qoqo import Circuit\n",
"from qoqo import operations as ops "
]
},
{
"source": [
"## Measuring a single qubit\n",
"\n",
"Here we first prepare the qubit in a superposition state, \n",
"\\begin{equation}\n",
"|+ \\rangle = \\frac{1}{\\sqrt{2}} \\big{(} |0 \\rangle + |1 \\rangle \\big{)}.\n",
"\\end{equation}\n",
"We look at the state after preparation, then do a measurement in the Z basis, and finally look again at the state after measurement. \n",
"\n",
"We see that the state after measurement has been projected into the state either $|0>$ or $|1>$, consistently with the measurement outcome. Running this code many times should result in a random distribution of 'True' and 'False' outcomes."
],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Input state: [0.70710678+0.j 0.70710678+0.j] \n\nMeasurement result: False \n\nState after measurement: [1.+0.j 0.+0.j]\n"
]
}
],
"source": [
"state_init = Circuit()\n",
"state_init += ops.Hadamard(qubit=0) # prepare |+> state\n",
"\n",
"# write state before measuring to readout register 'psi_in'\n",
"read_input = Circuit()\n",
"read_input += ops.DefinitionComplex(name='psi_in', length=2, is_output=True)\n",
"read_input += ops.PragmaGetStateVector(readout='psi_in', circuit=Circuit())\n",
"\n",
"# measure qubit in Z basis and write result to classical register 'M1'\n",
"meas_circ = Circuit()\n",
"meas_circ += ops.DefinitionBit(name='M1', length=1, is_output=True)\n",
"meas_circ += ops.MeasureQubit(qubit=0,readout='M1',readout_index=0)\n",
"\n",
"# write state after measuring to readout register 'psi_out'\n",
"read_output = Circuit()\n",
"read_output += ops.DefinitionComplex(name='psi_out', length=2, is_output=True)\n",
"read_output += ops.PragmaGetStateVector(readout='psi_out', circuit=Circuit())\n",
"\n",
"# put each step of the circuit together\n",
"circuit = state_init + read_input + meas_circ + read_output\n",
"\n",
"# run the circuit and collect output\n",
"backend = PyQuestBackend(number_qubits=1)\n",
"(result_bit_registers, result_float_registers, result_complex_registers) \\\n",
" = backend.run_circuit(circuit)\n",
"\n",
"print('Input state: \\n', result_complex_registers['psi_in'][0], '\\n')\n",
"print('Measurement result: ', result_bit_registers['M1'][0][0], '\\n')\n",
"print('State after measurement: \\n', result_complex_registers['psi_out'][0])"
]
},
{
"source": [
"## Measuring a single qubit in the X basis\n",
"\n",
"Instead of measuring in the Z basis, we can measure the qubit in the X basis by performing a Hadamard operator before the measurement. \n",
"\n",
"This time we see that the measurement result is always 'False', since we are measuring the $|+ \\rangle$ state in the X basis, and it is an X eigenvector of the X operator. "
],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Input state: [0.70710678+0.j 0.70710678+0.j] \n\nMeasurement result: False \n\nState after measurement: [0.70710678+0.j 0.70710678+0.j]\n"
]
}
],
"source": [
"# add Hadamard operator to change from Z to X basis\n",
"meas_X_circ = Circuit()\n",
"meas_X_circ += ops.DefinitionBit(name='M1', length=1, is_output=True)\n",
"meas_X_circ += ops.Hadamard(qubit=0)\n",
"meas_X_circ += ops.MeasureQubit(qubit=0,readout='M1',readout_index=0)\n",
"\n",
"# perform additional Hadamard after measurement to readout in Z basis\n",
"read_output = Circuit()\n",
"read_output += ops.DefinitionComplex(name='psi_out', length=2, is_output=True)\n",
"read_output += ops.Hadamard(qubit=0)\n",
"read_output += ops.PragmaGetStateVector(readout='psi_out', circuit=Circuit())\n",
"\n",
"circuit = state_init + read_input + meas_X_circ + read_output\n",
"\n",
"# run the circuit and collect output\n",
"backend = PyQuestBackend(number_qubits=1)\n",
"(result_bit_registers, result_float_registers, result_complex_registers) \\\n",
" = backend.run_circuit(circuit)\n",
"\n",
"print('Input state: \\n', result_complex_registers['psi_in'][0], '\\n')\n",
"print('Measurement result: ', result_bit_registers['M1'][0][0], '\\n')\n",
"print('State after measurement: \\n', result_complex_registers['psi_out'][0])"
]
},
{
"source": [
"## Measuring a multi-qubit register\n",
"\n",
"Here we first prepare a multi-qubit register and demonstrate how it is possible to measure the entire register. As an example we prepare the multi-qubit register in the state, \n",
"\\begin{equation}\n",
"|\\psi \\rangle = \\frac{1}{\\sqrt{2}} |010 \\rangle + \\frac{i}{\\sqrt{2}} |101 \\rangle.\n",
"\\end{equation}\n",
"\n",
"After preparation we read out the simulated state, before measurement. Next we measure each qubit of the state, and finally we readout out the post-measurement state. "
],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Input state: \n [0. +0.j 0. +0.j 0.70710678+0.j\n 0. +0.j 0. +0.j 0. +0.70710678j\n 0. +0.j 0. +0.j ] \n\nMeasurement results: [False, True, False] \n\nState after measurement: \n [0.+0.j 0.+0.j 1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]\n"
]
}
],
"source": [
"number_of_qubits = 3\n",
"\n",
"state_init = Circuit()\n",
"state_init += ops.PauliX(qubit=1) \n",
"state_init += ops.Hadamard(qubit=0) \n",
"state_init += ops.CNOT(control=0, target=1) \n",
"state_init += ops.CNOT(control=0, target=2)\n",
"state_init += ops.SGate(qubit=0)\n",
"\n",
"# write state before measuring to readout register 'psi_in'\n",
"read_input = Circuit()\n",
"read_input += ops.DefinitionComplex(name='psi_in', length=2**number_of_qubits,\n",
" is_output=True)\n",
"read_input += ops.PragmaGetStateVector(readout='psi_in', circuit=Circuit())\n",
"\n",
"# measure qubits in Z basis and write result to classical register 'M1M2M3'\n",
"meas_circ = Circuit()\n",
"meas_circ += ops.DefinitionBit(name='M1M2M3', length=3, is_output=True)\n",
"meas_circ += ops.MeasureQubit(qubit=0,readout='M1M2M3',readout_index=0)\n",
"meas_circ += ops.MeasureQubit(qubit=1,readout='M1M2M3',readout_index=1)\n",
"meas_circ += ops.MeasureQubit(qubit=2,readout='M1M2M3',readout_index=2)\n",
"\n",
"# write state after measuring to readout register 'psi_out'\n",
"read_output = Circuit()\n",
"read_output += ops.DefinitionComplex(name='psi_out', length=2**number_of_qubits,\n",
" is_output=True)\n",
"read_output += ops.PragmaGetStateVector(readout='psi_out', circuit=Circuit())\n",
"\n",
"\n",
"\n",
"circuit = state_init + read_input + meas_circ + read_output\n",
"\n",
"# run the circuit and collect output\n",
"backend = PyQuestBackend(number_qubits=number_of_qubits)\n",
"(result_bit_registers, result_float_registers, result_complex_registers) \\\n",
" = backend.run_circuit(circuit)\n",
"\n",
"print('Input state: \\n', result_complex_registers['psi_in'][0], '\\n')\n",
"print('Measurement results: ', result_bit_registers['M1M2M3'][0], '\\n')\n",
"print('State after measurement: \\n', result_complex_registers['psi_out'][0])"
]
},
{
"source": [
"## Measuring one qubit from a multi-qubit register\n",
"\n",
"Measuring only a single qubit from a multi-qubit register is an almost identical process to measuring the entire register, except we only add a single measurement in this case. \n",
"\n",
"Here we again prepare the input state, \n",
"\\begin{equation}\n",
"|\\psi \\rangle = \\frac{1}{\\sqrt{2}} |010 \\rangle + \\frac{i}{\\sqrt{2}} |101 \\rangle.\n",
"\\end{equation}\n",
"\n",
"After preparation we read out the simulated state, before measurement. Next we measure the first qubit of the state, and finally we readout out the post-measurement state."
],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Input state: \n [0. +0.j 0. +0.j 0.70710678+0.j\n 0. +0.j 0. +0.j 0. +0.70710678j\n 0. +0.j 0. +0.j ] \n\nMeasurement results: [True] \n\nState after measurement: \n [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+1.j 0.+0.j 0.+0.j]\n"
]
}
],
"source": [
"number_of_qubits = 3\n",
"\n",
"state_init = Circuit()\n",
"state_init += ops.PauliX(qubit=1) \n",
"state_init += ops.Hadamard(qubit=0) \n",
"state_init += ops.CNOT(control=0, target=1) \n",
"state_init += ops.CNOT(control=0, target=2)\n",
"state_init += ops.SGate(qubit=0)\n",
"\n",
"# write state before measuring to readout register 'psi_in'\n",
"read_input = Circuit()\n",
"read_input += ops.DefinitionComplex(name='psi_in', length=2**number_of_qubits,\n",
" is_output=True)\n",
"read_input += ops.PragmaGetStateVector(readout='psi_in', circuit=Circuit())\n",
"\n",
"# measure qubit in Z basis and write result to classical register 'M1'\n",
"meas_circ = Circuit()\n",
"meas_circ += ops.DefinitionBit(name='M1', length=1, is_output=True)\n",
"meas_circ += ops.MeasureQubit(qubit=0,readout='M1',readout_index=0)\n",
"\n",
"\n",
"# write state after measuring to readout register 'psi_out'\n",
"read_output = Circuit()\n",
"read_output += ops.DefinitionComplex(name='psi_out', length=2**number_of_qubits,\n",
" is_output=True)\n",
"read_output += ops.PragmaGetStateVector(readout='psi_out', circuit=Circuit())\n",
"\n",
"\n",
"\n",
"circuit = state_init + read_input + meas_circ + read_output\n",
"\n",
"# run the circuit and collect output\n",
"backend = PyQuestBackend(number_qubits=number_of_qubits)\n",
"(result_bit_registers, result_float_registers, result_complex_registers) \\\n",
" = backend.run_circuit(circuit)\n",
"\n",
"print('Input state: \\n', result_complex_registers['psi_in'][0], '\\n')\n",
"print('Measurement results: ', result_bit_registers['M1'][0], '\\n')\n",
"print('State after measurement: \\n', result_complex_registers['psi_out'][0])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
]
}