{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"tags": [
"remove_cell"
]
},
"source": [
"# Local Reality and the CHSH inequality"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We have seen in a previous module how quantum entanglement results in strong correlations in a multi-partite system. In fact these correlations appear to be stronger than anything that could be explained using classical physics. \n",
"\n",
"The historical development of quantum mechanics is filled with agitated discussions about the true nature of reality and the extent to which quantum mechanics can explain it. Given the spectacular empirical success of quantum mechanics, it was going to be clear that people would not simply give it up just because some of its aspects were hard to reconcile with intuition.\n",
"\n",
"At the root of these different points of views was the question of the nature of measurement. We know there is an element of randomness in quantum measurements, but is that really so? Is there a sneaky way by which the Universe has already decided beforehand which value a given measurement is going to yield at a future time? This hypothesis was the basis for different _hidden variable_ theories. But these theories did not only need to explain randomness at the single particle level. They also needed to explain what happens when different observers measure different parts of a multi-partite entangled system! This went beyond just hidden variable theories. Now a local hidden variable theory was needed in order to reconcile the observations of quantum mechanics with a Universe in which local reality was valid.\n",
"\n",
"What is local reality? In an Universe where locality holds, it should be possible to separate two systems so far in space that they could not interact with each other. The concept of reality is related to whether a measurable quantity holds a particular value _in the absence of any future measurement_. \n",
"\n",
"In 1963, John Stewart Bell published what could be argued as one of the most profound discoveries in the history of science. Bell stated that any theory invoking local hidden variables could be experimentally ruled out. In this section we are going to see how, and we will run a real experiment that demonstrates so! (with some remaining loopholes to close...)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### The CHSH inequality\n",
"\n",
"Imagine Alice and Bob are given each one part of a bipartite entangled system. Each of them then performs two measurements on their part in two different bases. Let's call Alice's bases _A_ and _a_ and Bob's _B_ and _b_. What is the expectation value of the quantity $\\langle CHSH \\rangle = \\langle AB \\rangle - \\langle Ab \\rangle + \\langle aB \\rangle + \\langle ab \\rangle$ ? \n",
"\n",
"Now, Alice and Bob have one qubit each, so any measurement they perform on their system (qubit) can only yield one of two possible outcomes: +1 or -1. Note that whereas we typically refer to the two qubit states as $|0\\rangle$ and $|1\\rangle$, these are *eigenstates*, and a projective measurement will yield their *eigenvalues*, +1 and -1, respectively. \n",
"\n",
"Therefore, if any measurement of _A_, _a_, _B_, and _b_ can only yield $\\pm 1$, the quantities $(B-b)$ and $(B+b)$ can only be 0 or $\\pm2$. And thus, the quantity $A(B-b) + a(B+b)$ can only be either +2 or -2, which means that there should be a bound for the expectation value of the quantity we have called $|\\langle CHSH \\rangle| =|\\langle AB \\rangle - \\langle Ab \\rangle + \\langle aB \\rangle + \\langle ab \\rangle| \\leq 2$.\n",
"\n",
"Now, the above discussion is oversimplified, because we could consider that the outcome on any set of measurements from Alice and Bob could depend on a set of local hidden variables, but it can be shown with some math that, even when that is the case, the expectation value of the quantity $CHSH$ should be bounded by 2 if local realism held.\n",
"\n",
"But what happens when we do these experiments with an entangled system? Let's try it!"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"#import qiskit tools\n",
"import qiskit\n",
"from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister, execute, transpile, Aer, IBMQ\n",
"from qiskit.tools.visualization import circuit_drawer\n",
"from qiskit.tools.monitor import job_monitor, backend_monitor, backend_overview\n",
"from qiskit.providers.aer import noise\n",
"\n",
"#import python stuff\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import time"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"uses-hardware"
]
},
"outputs": [],
"source": [
"# Set devices, if using a real device\n",
"IBMQ.load_account()\n",
"provider = IBMQ.get_provider(hub='ibm-q', group='open', project='main')\n",
"lima = provider.get_backend('ibmq_lima')"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"sv_sim = Aer.get_backend('statevector_simulator')\n",
"qasm_sim = Aer.get_backend('qasm_simulator')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First we are going to define a function to create our CHSH circuits. We are going to choose, without loss of generality, that Bob always uses the computational ($Z$) and the $X$ bases for his $B$ and $b$ measurements, respectively, whereas Alice chooses also orthogonal bases but whose angle we are going to vary between $0$ and $2\\pi$ with respect to Bob's bases. This set of angles is going to be the input argument to our $CHSH$ circuit building function."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"def make_chsh_circuit(theta_vec):\n",
" \"\"\"Return a list of QuantumCircuits for use in a CHSH experiemnt\n",
" (one for each value of theta in theta_vec)\n",
" \n",
" Args:\n",
" theta_vec (list): list of values of angles between the bases of Alice and Bob\n",
" \n",
" Returns:\n",
" List[QuantumCircuit]: CHSH QuantumCircuits for each value of theta\n",
" \"\"\"\n",
" chsh_circuits = []\n",
" \n",
" for theta in theta_vec:\n",
" obs_vec = ['00', '01', '10', '11']\n",
" for el in obs_vec:\n",
" qc = QuantumCircuit(2,2)\n",
" qc.h(0)\n",
" qc.cx(0, 1)\n",
" qc.ry(theta, 0)\n",
" for a in range(2):\n",
" if el[a] == '1':\n",
" qc.h(a) \n",
" qc.measure(range(2),range(2))\n",
" chsh_circuits.append(qc)\n",
"\n",
" return chsh_circuits "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Next, we are going to define a function for estimating the quantity $\\langle CHSH \\rangle$. One can define two of such quantities, actually, $\\langle CHSH1 \\rangle = \\langle AB \\rangle - \\langle Ab \\rangle + \\langle aB \\rangle + \\langle ab \\rangle$ and $\\langle CHSH2 \\rangle = \\langle AB \\rangle + \\langle Ab \\rangle - \\langle aB \\rangle + \\langle ab \\rangle$. Once chosen the corresponding measurement axes for both parties, each expectation value can be simply estimated by adding the counts from the output bitstrings with the appropiate sign (plus for the even terms $00$ and $11$ and minus for odd terms $01$ and $10$."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"def compute_chsh_witness(counts):\n",
" \"\"\"Computes expectation values for the CHSH inequality, for each\n",
" angle (theta) between measurement axis.\n",
"\n",
" Args: counts (list[dict]): dict of counts for each experiment\n",
" (4 per value of theta)\n",
"\n",
" Returns:\n",
" Tuple(List, List): Tuple of lists with the two CHSH witnesses\n",
" \"\"\"\n",
" # Order is ZZ,ZX,XZ,XX\n",
" \n",
" CHSH1 = []\n",
" CHSH2 = []\n",
" # Divide the list of dictionaries in sets of 4\n",
" for i in range(0, len(counts), 4): \n",
" theta_dict = counts[i:i + 4]\n",
" zz = theta_dict[0]\n",
" zx = theta_dict[1]\n",
" xz = theta_dict[2]\n",
" xx = theta_dict[3]\n",
"\n",
" no_shots = sum(xx[y] for y in xx)\n",
"\n",
" chsh1 = 0\n",
" chsh2 = 0\n",
"\n",
" for element in zz:\n",
" parity = (-1)**(int(element[0])+int(element[1]))\n",
" chsh1+= parity*zz[element]\n",
" chsh2+= parity*zz[element]\n",
"\n",
" for element in zx:\n",
" parity = (-1)**(int(element[0])+int(element[1]))\n",
" chsh1+= parity*zx[element]\n",
" chsh2-= parity*zx[element]\n",
"\n",
" for element in xz:\n",
" parity = (-1)**(int(element[0])+int(element[1]))\n",
" chsh1-= parity*xz[element]\n",
" chsh2+= parity*xz[element]\n",
"\n",
" for element in xx:\n",
" parity = (-1)**(int(element[0])+int(element[1]))\n",
" chsh1+= parity*xx[element]\n",
" chsh2+= parity*xx[element]\n",
"\n",
" CHSH1.append(chsh1/no_shots)\n",
" CHSH2.append(chsh2/no_shots)\n",
" \n",
" return CHSH1, CHSH2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, we are going to split the interval $[0, 2\\pi)$ into 15 angles and will build the corresponding set of $CHSH$ circuits"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"number_of_thetas = 15\n",
"theta_vec = np.linspace(0,2*np.pi,number_of_thetas)\n",
"my_chsh_circuits = make_chsh_circuit(theta_vec)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now, let's have a brief look at how four of these circuits look like for a given $\\theta$"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
"