qoqo 0.4.4

Quantum computing circuit toolkit. Python interface of roqoq
Documentation
{
 "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": []
  }
 ]
}