{ "cells": [ { "cell_type": "markdown", "source": [ "# Multiple Qubits & Entangled States" ], "metadata": { "tags": [ "remove_cell" ] } }, { "cell_type": "markdown", "source": [ "Single qubits are interesting, but individually they offer no computational advantage. We will now look at how we represent multiple qubits, and how these qubits can interact with each other. We have seen how we can represent the state of a qubit using a 2D-vector, now we will see how we can represent the state of multiple qubits." ], "metadata": {} }, { "cell_type": "markdown", "source": [ "## Contents\n", "1. [Representing Multi-Qubit States](#represent) \n", " 1.1 [Exercises](#ex1)\n", "2. [Single Qubit Gates on Multi-Qubit Statevectors](#single-qubit-gates) \n", " 2.1 [Exercises](#ex2)\n", "3. [Multi-Qubit Gates](#multi-qubit-gates) \n", " 3.1 [The CNOT-gate](#cnot) \n", " 3.2 [Entangled States](#entangled) \n", " 3.3 [Visualizing Entangled States](#visual) \n", " 3.4 [Exercises](#ex3)\n", "\n", "\n", "## 1. Representing Multi-Qubit States \n", "\n", "We saw that a single bit has two possible states, and a qubit state has two complex amplitudes. Similarly, two bits have four possible states:\n", "\n", "00 01 10 11\n", "\n", "And to describe the state of two qubits requires four complex amplitudes. We store these amplitudes in a 4D-vector like so:\n", "\n", "$$|a\\rangle = a_{00}|00\\rangle + a_{01}|01\\rangle + a_{10}|10\\rangle + a_{11}|11\\rangle = \\begin{bmatrix} a_{00} \\\\ a_{01} \\\\ a_{10} \\\\ a_{11} \\end{bmatrix}$$\n", "\n", "The rules of measurement still work in the same way:\n", "\n", "$$p(|00\\rangle) = |\\langle 00 | a \\rangle |^2 = |a_{00}|^2$$\n", "\n", "And the same implications hold, such as the normalisation condition:\n", "\n", "$$|a_{00}|^2 + |a_{01}|^2 + |a_{10}|^2 + |a_{11}|^2 = 1$$\n", "\n", "If we have two separated qubits, we can describe their collective state using the kronecker product:\n", "\n", "$$|a\\rangle = \\begin{bmatrix} a_0 \\\\ a_1 \\end{bmatrix}, \\quad |b\\rangle = \\begin{bmatrix} b_0 \\\\ b_1 \\end{bmatrix}$$\n", "\n", "$$\n", "|ba\\rangle = |b\\rangle \\otimes |a\\rangle = \\begin{bmatrix} b_0 \\times \\begin{bmatrix} a_0 \\\\ a_1 \\end{bmatrix} \\\\ b_1 \\times \\begin{bmatrix} a_0 \\\\ a_1 \\end{bmatrix} \\end{bmatrix} = \\begin{bmatrix} b_0 a_0 \\\\ b_0 a_1 \\\\ b_1 a_0 \\\\ b_1 a_1 \\end{bmatrix}\n", "$$\n", "\n", "And following the same rules, we can use the kronecker product to describe the collective state of any number of qubits. Here is an example with three qubits:\n", "\n", "$$\n", "|cba\\rangle = \\begin{bmatrix} c_0 b_0 a_0 \\\\ c_0 b_0 a_1 \\\\ c_0 b_1 a_0 \\\\ c_0 b_1 a_1 \\\\\n", " c_1 b_0 a_0 \\\\ c_1 b_0 a_1 \\\\ c_1 b_1 a_0 \\\\ c_1 b_1 a_1 \\\\\n", " \\end{bmatrix}\n", "$$\n", "\n", "If we have $n$ qubits, we will need to keep track of $2^n$ complex amplitudes. As we can see, these vectors grow exponentially with the number of qubits. This is the reason quantum computers with large numbers of qubits are so difficult to simulate. A modern laptop can easily simulate a general quantum state of around 20 qubits, but simulating 100 qubits is too difficult for the largest supercomputers.\n", "\n", "Let's look at an example circuit:" ], "metadata": {} }, { "cell_type": "code", "execution_count": 1, "source": [ "from qiskit import QuantumCircuit, Aer, assemble\n", "import numpy as np\n", "from qiskit.visualization import plot_histogram, plot_bloch_multivector" ], "outputs": [], "metadata": { "tags": [ "thebelab-init" ] } }, { "cell_type": "code", "execution_count": 2, "source": [ "qc = QuantumCircuit(3)\n", "# Apply H-gate to each qubit:\n", "for qubit in range(3):\n", " qc.h(qubit)\n", "# See the circuit:\n", "qc.draw()" ], "outputs": [ { "output_type": "execute_result", "data": { "image/svg+xml": "\n\n\n\n", "text/plain": [ "