From 439a80ee1d1faca57e7d8215b3c421970cf480b8 Mon Sep 17 00:00:00 2001 From: Henry Zou Date: Wed, 20 May 2026 09:20:26 -0400 Subject: [PATCH 1/4] Update CHSH inequality tutorial MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Bump dependencies to Qiskit SDK v2.0, Qiskit Runtime v0.40, and add Qiskit Aer v0.17 - Add a local noisy-simulator validation step using AerSimulator.from_backend before submitting to hardware - Add a section on scaling the experiment by tiling the backend with disjoint Bell pairs and running many CHSH tests in parallel - Modernize API doc links (docs.quantum-computing.ibm.com → /docs/...) - Clarify prose throughout and refresh extracted output images --- docs/tutorials/chsh-inequality.ipynb | 592 ++++++++++++------ .../extracted-outputs/3376bc73-1.avif | Bin 0 -> 10885 bytes .../extracted-outputs/3e139a89-0.avif | Bin 0 -> 3287 bytes .../extracted-outputs/6c77e40a-0.avif | Bin 1369 -> 0 bytes .../extracted-outputs/9a5561eb-0.avif | Bin 2837 -> 0 bytes .../extracted-outputs/c3f57d25-0.avif | Bin 0 -> 1380 bytes .../extracted-outputs/c8fd5140-0.avif | Bin 0 -> 9776 bytes .../extracted-outputs/f6267448-0.avif | Bin 7125 -> 0 bytes 8 files changed, 396 insertions(+), 196 deletions(-) create mode 100644 public/docs/images/tutorials/chsh-inequality/extracted-outputs/3376bc73-1.avif create mode 100644 public/docs/images/tutorials/chsh-inequality/extracted-outputs/3e139a89-0.avif delete mode 100644 public/docs/images/tutorials/chsh-inequality/extracted-outputs/6c77e40a-0.avif delete mode 100644 public/docs/images/tutorials/chsh-inequality/extracted-outputs/9a5561eb-0.avif create mode 100644 public/docs/images/tutorials/chsh-inequality/extracted-outputs/c3f57d25-0.avif create mode 100644 public/docs/images/tutorials/chsh-inequality/extracted-outputs/c8fd5140-0.avif delete mode 100644 public/docs/images/tutorials/chsh-inequality/extracted-outputs/f6267448-0.avif diff --git a/docs/tutorials/chsh-inequality.ipynb b/docs/tutorials/chsh-inequality.ipynb index fce48a2c44c..449a52c79f3 100644 --- a/docs/tutorials/chsh-inequality.ipynb +++ b/docs/tutorials/chsh-inequality.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "30734ce9", + "id": "492d7cec", "metadata": {}, "source": [ "---\n", @@ -10,109 +10,60 @@ "description: Run an experiment on a quantum computer to demonstrate the violation of the CHSH inequality with the Estimator primitive.\n", "---\n", "\n", + "{/* cspell:ignore zorder Tsirelson */}\n", "\n", - "{/* cspell:ignore zorder */}\n", + "# CHSH inequality\n", "\n", - "# CHSH inequality" + "*Usage estimate: A few minutes on a Heron r3 processor (NOTE: This is an estimate only. Your runtime might vary.)*" ] }, { "cell_type": "markdown", - "id": "6b41d6b3", + "id": "a57d9139", "metadata": {}, "source": [ - "*Usage estimate: Two minutes on a Heron r2 processor (NOTE: This is an estimate only. Your runtime might vary.)*" + "## Learning outcomes\n", + "After completing this tutorial, you can expect to understand the following information:\n", + "- How to construct a parameterized Bell-state CHSH circuit and measure the four expectation values that make up the CHSH witnesses.\n", + "- How to compute expectation values of multiple observables on a parameter sweep in a single call to the [`EstimatorV2`](/docs/api/qiskit-ibm-runtime/estimator-v2) primitive.\n", + "- How to validate a quantum workflow on a noisy local simulator with `AerSimulator.from_backend` before submitting to hardware.\n", + "- How to scale a CHSH experiment into a device-wide entanglement benchmark by running many independent Bell pairs in parallel on IBM Quantum hardware.\n", + "\n", + "## Prerequisites\n", + "It is recommended that you familiarize yourself with these topics:\n", + "- [Entanglement in Action](/learning/courses/basics-of-quantum-information/entanglement-in-action/chsh-game), a course lesson on Bell states and the CHSH game.\n", + "- [`SparsePauliOp`](/docs/api/qiskit/qiskit.quantum_info.SparsePauliOp) and the Qiskit primitives [introduction](/docs/guides/primitives)." ] }, { "cell_type": "markdown", - "id": "93ae1484", + "id": "f956eda1", "metadata": {}, "source": [ "## Background\n", "\n", "In this tutorial, you will run an experiment on a quantum computer to demonstrate the violation of the CHSH inequality with the Estimator primitive.\n", "\n", - "The CHSH inequality, named after the authors Clauser, Horne, Shimony, and Holt, is used to experimentally prove Bell's theorem (1969). This theorem asserts that local hidden variable theories cannot account for some consequences of entanglement in quantum mechanics. The violation of the CHSH inequality is used to show that quantum mechanics is incompatible with local hidden-variable theories. This is an important experiment for understanding the foundation of quantum mechanics.\n", - "\n", - "The 2022 Nobel Prize for Physics was awarded to Alain Aspect, John Clauser and Anton Zeilinger in part for their pioneering work in quantum information science, and in particular, for their experiments with entangled photons demonstrating violation of Bell’s inequalities." - ] - }, - { - "cell_type": "markdown", - "id": "6f5d9398-5aaa-4596-a554-61c923f0c2d2", - "metadata": {}, - "source": [ - "## Requirements\n", - "\n", - "Before starting this tutorial, ensure that you have the following installed:\n", - "\n", - "* Qiskit SDK v1.0 or later, with [visualization](/docs/api/qiskit/visualization) support\n", - "* Qiskit Runtime (`pip install qiskit-ibm-runtime`) v0.22 or later" - ] - }, - { - "cell_type": "markdown", - "id": "b5df762e", - "metadata": {}, - "source": [ - "## Setup" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "3938d4a6", - "metadata": {}, - "outputs": [], - "source": [ - "# General\n", - "import numpy as np\n", + "The CHSH inequality, named after Clauser, Horne, Shimony, and Holt, is used to experimentally test Bell's theorem (1969). The theorem asserts that local hidden-variable theories cannot account for some consequences of entanglement in quantum mechanics. Demonstrating a violation of the CHSH inequality shows that quantum mechanics is incompatible with local hidden-variable theories, an experiment that is foundational to our understanding of quantum mechanics.\n", "\n", - "# Qiskit imports\n", - "from qiskit import QuantumCircuit\n", - "from qiskit.circuit import Parameter\n", - "from qiskit.quantum_info import SparsePauliOp\n", - "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n", + "The 2022 Nobel Prize for Physics was awarded to Alain Aspect, John Clauser, and Anton Zeilinger in part for their pioneering work in quantum information science, and in particular, for their experiments with entangled photons demonstrating violation of Bell's inequalities.\n", "\n", - "# Qiskit Runtime imports\n", - "from qiskit_ibm_runtime import QiskitRuntimeService\n", - "from qiskit_ibm_runtime import EstimatorV2 as Estimator\n", - "\n", - "# Plotting routines\n", - "import matplotlib.pyplot as plt\n", - "import matplotlib.ticker as tck" - ] - }, - { - "cell_type": "markdown", - "id": "66d5e2e2", - "metadata": {}, - "source": [ - "## Step 1: Map classical inputs to a quantum problem" - ] - }, - { - "cell_type": "markdown", - "id": "36669708", - "metadata": {}, - "source": [ - "For this experiment, we will create an entangled pair on which we measure each qubit on two different bases. We will label the bases for the first qubit $A$ and $a$ and the bases for the second qubit $B$ and $b$. This allows us to compute the CHSH quantity $S_1$:\n", + "For this experiment, we will create an entangled pair on which we measure each qubit on two different bases. We will label the bases for the first qubit $A$ and $a$ and the bases for the second qubit $B$ and $b$. This allows us to compute the CHSH quantity $S_1$:\n", "\n", "$$\n", "S_1 = A(B-b) + a(B+b).\n", "$$\n", "\n", - "Each observable is either $+1$ or $-1$. Clearly, one of the terms $B\\pm b$ must be $0$, and the other must be $\\pm 2$. Therefore, $S_1 = \\pm 2$. The average value of $S_1$ must satisfy the inequality:\n", + "Each observable is either $+1$ or $-1$. Clearly, one of the terms $B\\pm b$ must be $0$, and the other must be $\\pm 2$. Therefore, $S_1 = \\pm 2$. The average value of $S_1$ must satisfy the inequality:\n", "\n", "$$\n", "|\\langle S_1 \\rangle|\\leq 2.\n", "$$\n", "\n", - "Expanding $S_1$ in terms of $A$, $a$, $B$, and $b$ results in:\n", + "Expanding $S_1$ in terms of $A$, $a$, $B$, and $b$ gives:\n", "\n", "$$\n", - "|\\langle S_1 \\rangle| = |\\langle AB \\rangle - \\langle Ab \\rangle + \\langle aB \\rangle + \\langle ab \\rangle| \\leq 2\n", + "|\\langle S_1 \\rangle| = |\\langle AB \\rangle - \\langle Ab \\rangle + \\langle aB \\rangle + \\langle ab \\rangle| \\leq 2.\n", "$$\n", "\n", "You can define another CHSH quantity $S_2$:\n", @@ -121,45 +72,90 @@ "S_2 = A(B+b) - a(B-b),\n", "$$\n", "\n", - "This leads to another inequality:\n", + "which leads to another inequality:\n", "\n", "$$\n", - "|\\langle S_2 \\rangle| = |\\langle AB \\rangle + \\langle Ab \\rangle - \\langle aB \\rangle + \\langle ab \\rangle| \\leq 2\n", + "|\\langle S_2 \\rangle| = |\\langle AB \\rangle + \\langle Ab \\rangle - \\langle aB \\rangle + \\langle ab \\rangle| \\leq 2.\n", "$$\n", "\n", - "If quantum mechanics can be described by local hidden variable theories, the previous inequalities must hold true. However, as is demonstrated in this tutorial, these inequalities can be violated in a quantum computer. Therefore, quantum mechanics is not compatible with local hidden variable theories." + "If quantum mechanics could be described by local hidden-variable theories, these inequalities would always hold. As demonstrated in this tutorial, they can be violated on a quantum computer, so quantum mechanics is not compatible with local hidden-variable theories.\n", + "\n", + "We create the entangled pair by preparing the Bell state $|\\Phi^+\\rangle = \\frac{|00\\rangle + |11\\rangle}{\\sqrt{2}}$. Using the Estimator primitive, we obtain the expectation values $\\langle AB \\rangle, \\langle Ab \\rangle, \\langle aB \\rangle$, and $\\langle ab \\rangle$ directly, without reconstructing them from raw counts. We measure the second qubit in the $Z$ and $X$ bases. The first qubit is measured in orthogonal bases as well, but with a rotation angle $\\theta$ that we sweep between $0$ and $2\\pi$. The Estimator primitive evaluates this parameter sweep in a single PUB." ] }, { "cell_type": "markdown", - "id": "2033cfcd", + "id": "c7346a67", "metadata": {}, "source": [ - "If you want to learn more theory, explore [Entanglement in Action](/learning/courses/basics-of-quantum-information/entanglement-in-action/chsh-game) with John Watrous." + "## Requirements\n", + "Before starting this tutorial, be sure you have the following installed:\n", + "\n", + "- Qiskit SDK v2.0 or later, with [visualization](/docs/api/qiskit/visualization) support\n", + "- Qiskit Runtime v0.40 or later (`pip install qiskit-ibm-runtime`)\n", + "- Qiskit Aer v0.17 or later (`pip install qiskit-aer`)" ] }, { "cell_type": "markdown", - "id": "d4cec8d8", + "id": "d5ffeb42", "metadata": {}, "source": [ - "You will create an entangled pair between two qubits in a quantum computer by creating the Bell state $|\\Phi^+\\rangle = \\frac{|00\\rangle + |11\\rangle}{\\sqrt{2}}$. Using the Estimator primitive, you can directly obtain the expectation values needed ($\\langle AB \\rangle, \\langle Ab \\rangle, \\langle aB \\rangle$, and $\\langle ab \\rangle$) to calculate the expectation values of the two CHSH quantities $\\langle S_1\\rangle$ and $\\langle S_2\\rangle$. Before the introduction of the Estimator primitive, you would have to construct the expectation values from the measurement outcomes.\n", + "## Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "323b27db", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-19T22:38:49.177326Z", + "iopub.status.busy": "2026-05-19T22:38:49.177203Z", + "iopub.status.idle": "2026-05-19T22:38:49.804694Z", + "shell.execute_reply": "2026-05-19T22:38:49.804154Z" + } + }, + "outputs": [], + "source": [ + "# General\n", + "import numpy as np\n", "\n", - "You will measure the second qubit in the $Z$ and $X$ bases. The first qubit will be measured also in orthogonal bases, but with an angle with respect to the second qubit, which we are going to sweep between $0$ and $2\\pi$. As you will see, the Estimator primitive makes running parameterized circuits very easy. Rather than creating a series of CHSH circuits, you only need to create *one* CHSH circuit with a parameter specifying the measurement angle and a series of phase values for the parameter.\n", + "# Qiskit imports\n", + "from qiskit import QuantumCircuit\n", + "from qiskit.circuit import Parameter\n", + "from qiskit.quantum_info import SparsePauliOp\n", + "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n", "\n", - "Finally, you will analyze the results and plot them against the measurement angle. You will see that for certain range of measurement angles, the expectation values of CHSH quantities $|\\langle S_1\\rangle| > 2$ or $|\\langle S_2\\rangle| > 2$, which demonstrates the violation of the CHSH inequality." + "# Qiskit Runtime imports\n", + "from qiskit_ibm_runtime import QiskitRuntimeService\n", + "from qiskit_ibm_runtime import EstimatorV2 as Estimator\n", + "\n", + "# Qiskit Aer for local noisy simulation\n", + "from qiskit_aer import AerSimulator\n", + "\n", + "# Plotting routines\n", + "import matplotlib.pyplot as plt\n", + "import matplotlib.ticker as tck" ] }, { "cell_type": "code", - "execution_count": 2, - "id": "16f323fb", - "metadata": {}, + "execution_count": null, + "id": "fd284a0f", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-19T22:38:49.806301Z", + "iopub.status.busy": "2026-05-19T22:38:49.806113Z", + "iopub.status.idle": "2026-05-19T22:38:53.208796Z", + "shell.execute_reply": "2026-05-19T22:38:53.208025Z" + } + }, "outputs": [ { "data": { "text/plain": [ - "'ibm_kingston'" + "'ibm_pittsburgh'" ] }, "execution_count": 2, @@ -168,34 +164,51 @@ } ], "source": [ - "# To run on hardware, select the backend with the fewest number of jobs in the queue\n", + "# Select an IBM Quantum backend.\n", "service = QiskitRuntimeService()\n", "backend = service.least_busy(\n", - " operational=True, simulator=False, min_num_qubits=127\n", + " min_num_qubits=127, operational=True, simulator=False\n", ")\n", "backend.name" ] }, { "cell_type": "markdown", - "id": "1ab329f2", + "id": "ca035271", + "metadata": {}, + "source": [ + "## Small-scale simulator example\n", + "\n", + "Before submitting a hardware job, we validate the entire workflow on a local noisy simulator. We use `AerSimulator.from_backend(backend)` to build a simulator that inherits the noise model and coupling map of the backend you selected, so the simulator response is qualitatively similar to what we expect from hardware." + ] + }, + { + "cell_type": "markdown", + "id": "0539a796", "metadata": {}, "source": [ - "### Create a parameterized CHSH circuit\n", + "### Step 1: Map classical inputs to a quantum problem\n", "\n", - "First, we write the circuit with the parameter $\\theta$, which we call `theta`. The [`Estimator` primitive](https://docs.quantum-computing.ibm.com/api/qiskit-ibm-runtime/qiskit_ibm_runtime.EstimatorV2) can enormously simplify circuit building and output analysis by directly providing expectation values of observables. Many problems of interest, especially for near-term applications on noisy systems, can be formulated in terms of expectation values. `Estimator` (V2) primitive can automatically change measurement basis based on the supplied observable." + "We write the CHSH circuit with a single parameter $\\theta$, which sweeps the measurement basis of the first qubit. The [`Estimator`](/docs/api/qiskit-ibm-runtime/estimator-v2) primitive simplifies the analysis: it returns expectation values of observables directly, and it can evaluate a parameterized circuit at many parameter values in a single call." ] }, { "cell_type": "code", "execution_count": 3, - "id": "6c77e40a", - "metadata": {}, + "id": "c3f57d25", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-19T22:38:53.210931Z", + "iopub.status.busy": "2026-05-19T22:38:53.210786Z", + "iopub.status.idle": "2026-05-19T22:38:53.349189Z", + "shell.execute_reply": "2026-05-19T22:38:53.348782Z" + } + }, "outputs": [ { "data": { "text/plain": [ - "\"Output" + "\"Output" ] }, "execution_count": 3, @@ -204,7 +217,7 @@ } ], "source": [ - "theta = Parameter(\"$\\\\theta$\")\n", + "theta = Parameter(r\"$\\theta$\")\n", "\n", "chsh_circuit = QuantumCircuit(2)\n", "chsh_circuit.h(0)\n", @@ -215,50 +228,68 @@ }, { "cell_type": "markdown", - "id": "de760250", + "id": "af999dde", "metadata": {}, "source": [ - "### Create a list of phase values to be assigned later\n", - "\n", - "After creating the parameterized CHSH circuit, you will create a list of phase values to be assigned to the circuit in the next step. You can use the following code to create a list of 21 phase values range from $0$ to $2 \\pi$ with equal spacing, that is, $0$, $0.1 \\pi$, $0.2 \\pi$, ..., $1.9 \\pi$, $2 \\pi$." + "Next, we create a list of 21 phase values from $0$ to $2\\pi$ at which to evaluate the parameterized circuit ($0$, $0.1\\pi$, $0.2\\pi$, ..., $1.9\\pi$, $2\\pi$)." ] }, { "cell_type": "code", "execution_count": 4, - "id": "bcb3b32b", - "metadata": {}, + "id": "9d587e2f", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-19T22:38:53.350400Z", + "iopub.status.busy": "2026-05-19T22:38:53.350337Z", + "iopub.status.idle": "2026-05-19T22:38:53.352045Z", + "shell.execute_reply": "2026-05-19T22:38:53.351729Z" + } + }, "outputs": [], "source": [ "number_of_phases = 21\n", "phases = np.linspace(0, 2 * np.pi, number_of_phases)\n", - "# Phases need to be expressed as list of lists in order to work\n", + "# Phases need to be expressed as a list of lists for the Estimator PUB\n", "individual_phases = [[ph] for ph in phases]" ] }, { "cell_type": "markdown", - "id": "6e559aed", + "id": "af917afb", "metadata": {}, "source": [ - "### Observables\n", + "Finally we define the observables. The first qubit is measured along axes rotated by $\\theta$; the second qubit is measured in $Z$ and $X$. With those choices, the four CHSH correlators map to the Pauli operators $ZZ$, $ZX$, $XZ$, and $XX$:\n", "\n", - "Now we need observables from which to compute the expectation values. In our case we are looking at orthogonal bases for each qubit, letting the parameterized $Y-$ rotation for the first qubit sweep the measurement basis nearly continuously with respect to the second qubit basis. We will therefore choose the observables $ZZ$, $ZX$, $XZ$, and $XX$." + "$$\n", + "\\langle S_1 \\rangle = \\langle ZZ \\rangle - \\langle ZX \\rangle + \\langle XZ \\rangle + \\langle XX \\rangle,\n", + "$$\n", + "\n", + "$$\n", + "\\langle S_2 \\rangle = \\langle ZZ \\rangle + \\langle ZX \\rangle - \\langle XZ \\rangle + \\langle XX \\rangle.\n", + "$$" ] }, { "cell_type": "code", "execution_count": 5, - "id": "940fc1dc-89c5-4137-bea7-5e892dd7f36e", - "metadata": {}, + "id": "21ae6238", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-19T22:38:53.353007Z", + "iopub.status.busy": "2026-05-19T22:38:53.352948Z", + "iopub.status.idle": "2026-05-19T22:38:53.355217Z", + "shell.execute_reply": "2026-05-19T22:38:53.354857Z" + } + }, "outputs": [], "source": [ - "# = - + + -> - + + \n", + "# = - + + \n", "observable1 = SparsePauliOp.from_list(\n", " [(\"ZZ\", 1), (\"ZX\", -1), (\"XZ\", 1), (\"XX\", 1)]\n", ")\n", "\n", - "# = + - + -> + - + \n", + "# = + - + \n", "observable2 = SparsePauliOp.from_list(\n", " [(\"ZZ\", 1), (\"ZX\", 1), (\"XZ\", -1), (\"XX\", 1)]\n", ")" @@ -266,38 +297,31 @@ }, { "cell_type": "markdown", - "id": "efabedc4", + "id": "2d571aa2", "metadata": {}, "source": [ - "## Step 2: Optimize problem for quantum hardware execution" - ] - }, - { - "cell_type": "markdown", - "id": "4b2b4637-a2d4-41d6-a9c5-98fe3b8a2cd2", - "metadata": {}, - "source": [ - "To reduce the total job execution time, V2 primitives only accept circuits and observables that conforms to the instructions and connectivity supported by the target system (referred to as instruction set architecture (ISA) circuits and observables)." - ] - }, - { - "cell_type": "markdown", - "id": "5dcd3fea-3754-4c75-b11e-9216570336b7", - "metadata": {}, - "source": [ - "### ISA Circuit" + "### Step 2: Optimize problem for quantum hardware execution\n", + "\n", + "V2 primitives only accept circuits and observables that conform to the instructions and connectivity supported by the target system (instruction set architecture, or ISA, circuits and observables). We build the `AerSimulator` from the backend and transpile against the simulator's target so the same pass manager is exercised end-to-end." ] }, { "cell_type": "code", "execution_count": 6, - "id": "9a5561eb", - "metadata": {}, + "id": "3e139a89", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-19T22:38:53.356197Z", + "iopub.status.busy": "2026-05-19T22:38:53.356140Z", + "iopub.status.idle": "2026-05-19T22:38:56.713188Z", + "shell.execute_reply": "2026-05-19T22:38:56.712683Z" + } + }, "outputs": [ { "data": { "text/plain": [ - "\"Output" + "\"Output" ] }, "execution_count": 6, @@ -306,34 +330,34 @@ } ], "source": [ - "target = backend.target\n", - "pm = generate_preset_pass_manager(target=target, optimization_level=3)\n", + "# Build a noisy simulator from the ibm_pittsburgh backend\n", + "aer_sim = AerSimulator.from_backend(backend)\n", "\n", + "pm = generate_preset_pass_manager(target=aer_sim.target, optimization_level=3)\n", "chsh_isa_circuit = pm.run(chsh_circuit)\n", "chsh_isa_circuit.draw(output=\"mpl\", idle_wires=False, style=\"iqp\")" ] }, { "cell_type": "markdown", - "id": "718759d4-f1d8-45c3-9142-c8404059a892", + "id": "2817b069", "metadata": {}, "source": [ - "### ISA Observables" - ] - }, - { - "cell_type": "markdown", - "id": "76b721cc-7f45-4195-ae61-53d29e2bf8d4", - "metadata": {}, - "source": [ - "Similarly, we need to transform the observables to make it backend compatible before running jobs with [`Runtime Estimator V2`](/docs/api/qiskit-ibm-runtime/estimator-v2#run). We can perform the transformation using the `apply_layout` the method of `SparsePauliOp` object." + "We also transform the observables to match the transpiled circuit's qubit layout using `SparsePauliOp.apply_layout`." ] }, { "cell_type": "code", "execution_count": 7, - "id": "a787d6f9-5df4-4e0b-b2f0-07948b882a94", - "metadata": {}, + "id": "d1faa7ab", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-19T22:38:56.714405Z", + "iopub.status.busy": "2026-05-19T22:38:56.714288Z", + "iopub.status.idle": "2026-05-19T22:38:56.716319Z", + "shell.execute_reply": "2026-05-19T22:38:56.715992Z" + } + }, "outputs": [], "source": [ "isa_observable1 = observable1.apply_layout(layout=chsh_isa_circuit.layout)\n", @@ -342,74 +366,164 @@ }, { "cell_type": "markdown", - "id": "b7194399", + "id": "e734572e", "metadata": {}, "source": [ - "## Step 3: Execute using Qiskit primitives\n", + "### Step 3: Execute using Qiskit primitives\n", "\n", - "In order to execute the entire experiment in one call to the [`Estimator`](https://docs.quantum-computing.ibm.com/api/qiskit-ibm-runtime/qiskit_ibm_runtime.EstimatorV2)." - ] - }, - { - "cell_type": "markdown", - "id": "2d8ad9e1", - "metadata": {}, - "source": [ - "We can create a [Qiskit Runtime `Estimator`](/docs/api/qiskit-ibm-runtime/estimator-v2) primitive to compute our expectation values. The `EstimatorV2.run()` method takes an iterable of `primitive unified blocs (PUBs)`. Each PUB is an iterable in the format `(circuit, observables, parameter_values: Optional, precision: Optional)`." + "Run the parameter sweep with `EstimatorV2` in `aer_sim` mode. The Estimator `run()` method takes an iterable of primitive unified blocs (PUBs). Each PUB has the format `(circuit, observables, parameter_values, precision)`. We pass both observables together so they share the same parameter sweep." ] }, { "cell_type": "code", "execution_count": 8, - "id": "e73db51f", - "metadata": {}, + "id": "7f954aeb", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-19T22:38:56.717549Z", + "iopub.status.busy": "2026-05-19T22:38:56.717473Z", + "iopub.status.idle": "2026-05-19T22:38:58.217539Z", + "shell.execute_reply": "2026-05-19T22:38:58.217000Z" + } + }, "outputs": [], "source": [ - "# To run on a local simulator:\n", - "# Use the StatevectorEstimator from qiskit.primitives instead.\n", - "\n", - "estimator = Estimator(mode=backend)\n", + "# Use the AerSimulator-backed Estimator to validate the workflow locally\n", + "estimator_sim = Estimator(mode=aer_sim)\n", "\n", "pub = (\n", " chsh_isa_circuit, # ISA circuit\n", - " [[isa_observable1], [isa_observable2]], # ISA Observables\n", + " [[isa_observable1], [isa_observable2]], # ISA observables\n", " individual_phases, # Parameter values\n", ")\n", "\n", - "job_result = estimator.run(pubs=[pub]).result()" + "sim_result = estimator_sim.run(pubs=[pub]).result()" ] }, { "cell_type": "markdown", - "id": "ace7dc90", + "id": "9c5230fc", "metadata": {}, "source": [ - "## Step 4: Post-process and return result in desired classical format\n", + "### Step 4: Post-process and return result in desired classical format\n", "\n", - "The estimator returns expectation values for both of the observables, $\\langle ZZ \\rangle - \\langle ZX \\rangle + \\langle XZ \\rangle + \\langle XX \\rangle$ and $\\langle ZZ \\rangle + \\langle ZX \\rangle - \\langle XZ \\rangle + \\langle XX \\rangle$." + "The Estimator returns expectation values for both observables. We plot them against $\\theta$ together with the classical bound ($\\pm 2$) and the Tsirelson bound ($\\pm 2\\sqrt{2}$). The shaded grey regions mark the gap between the two. Points that lie inside these bands violate the CHSH inequality." ] }, { "cell_type": "code", "execution_count": 9, - "id": "947fc660-073b-4dee-b347-358fd3e52ea2", + "id": "c8fd5140", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-19T22:38:58.219407Z", + "iopub.status.busy": "2026-05-19T22:38:58.219306Z", + "iopub.status.idle": "2026-05-19T22:38:58.285202Z", + "shell.execute_reply": "2026-05-19T22:38:58.284609Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "\"Output" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "chsh1_sim = sim_result[0].data.evs[0]\n", + "chsh2_sim = sim_result[0].data.evs[1]\n", + "\n", + "\n", + "def plot_chsh(phases, chsh1, chsh2, title):\n", + " fig, ax = plt.subplots(figsize=(10, 6))\n", + "\n", + " ax.plot(\n", + " phases / np.pi, chsh1, \"o-\", label=r\"$\\langle S_1 \\rangle$\", zorder=3\n", + " )\n", + " ax.plot(\n", + " phases / np.pi, chsh2, \"o-\", label=r\"$\\langle S_2 \\rangle$\", zorder=3\n", + " )\n", + "\n", + " # classical bound +-2\n", + " ax.axhline(y=2, color=\"0.9\", linestyle=\"--\")\n", + " ax.axhline(y=-2, color=\"0.9\", linestyle=\"--\")\n", + "\n", + " # quantum bound, +-2*sqrt(2)\n", + " ax.axhline(y=np.sqrt(2) * 2, color=\"0.9\", linestyle=\"-.\")\n", + " ax.axhline(y=-np.sqrt(2) * 2, color=\"0.9\", linestyle=\"-.\")\n", + " ax.fill_between(phases / np.pi, 2, 2 * np.sqrt(2), color=\"0.6\", alpha=0.7)\n", + " ax.fill_between(\n", + " phases / np.pi, -2, -2 * np.sqrt(2), color=\"0.6\", alpha=0.7\n", + " )\n", + "\n", + " ax.xaxis.set_major_formatter(tck.FormatStrFormatter(\"%g $\\\\pi$\"))\n", + " ax.xaxis.set_major_locator(tck.MultipleLocator(base=0.5))\n", + "\n", + " ax.set_xlabel(r\"$\\theta$\")\n", + " ax.set_ylabel(\"CHSH witness\")\n", + " ax.set_title(title)\n", + " ax.legend()\n", + " plt.show()\n", + "\n", + "\n", + "plot_chsh(\n", + " phases,\n", + " chsh1_sim,\n", + " chsh2_sim,\n", + " \"CHSH witnesses from AerSimulator (ibm_pittsburgh noise model)\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "e9744b84", "metadata": {}, - "outputs": [], "source": [ - "chsh1_est = job_result[0].data.evs[0]\n", - "chsh2_est = job_result[0].data.evs[1]" + "The simulator's CHSH witnesses already exceed the classical bound of $\\pm 2$ at several values of $\\theta$, even with the backend's noise model. The peaks fall just short of the Tsirelson bound $\\pm 2\\sqrt{2}$ because of simulated device noise. With the workflow validated, we move on to actual hardware." + ] + }, + { + "cell_type": "markdown", + "id": "747e948d", + "metadata": {}, + "source": [ + "## Large-scale hardware example\n", + "\n", + "A CHSH test is intrinsically a *two-qubit* experiment, so it does not scale by making one circuit bigger. Instead, it scales by running **many tests in parallel**. Here we tile the backend with as many disjoint Bell pairs as its connectivity allows (a *matching* of the coupling map) and run an independent CHSH sub-circuit on every pair, all in a single job.\n", + "\n", + "This turns CHSH into a **device-wide benchmark of entanglement quality**: rather than a single hand-picked pair, we test entanglement across a large fraction of the chip at once, under realistic conditions where every pair contends with its neighbors' crosstalk and parallel-gate errors. Violating the inequality on every pair *simultaneously* certifies that genuine entanglement is available everywhere on the device." ] }, { "cell_type": "code", "execution_count": 10, - "id": "f6267448", - "metadata": {}, + "id": "3376bc73", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-19T22:38:58.286726Z", + "iopub.status.busy": "2026-05-19T22:38:58.286656Z", + "iopub.status.idle": "2026-05-19T22:38:59.198086Z", + "shell.execute_reply": "2026-05-19T22:38:59.197690Z" + } + }, "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Tiling ibm_pittsburgh with 64 parallel Bell pairs (128 of 156 qubits)\n", + "Job ID: d86efd5g7okc73el0rp0\n", + "63/64 Bell pairs violated the CHSH inequality (mean peak witness 2.75, classical bound 2)\n" + ] + }, { "data": { "text/plain": [ - "\"Output" + "\"Output" ] }, "metadata": {}, @@ -417,51 +531,142 @@ } ], "source": [ + "# -------------------------Step 1: Map classical inputs to a quantum problem-------------------------\n", + "# A CHSH test is bipartite, so we scale up by running one independent CHSH\n", + "# experiment on every disjoint Bell pair the device can host. A greedy\n", + "# matching of the coupling map gives a set of edges that share no qubits.\n", + "num_qubits = backend.num_qubits\n", + "used = set()\n", + "pairs = []\n", + "for qa, qb in backend.coupling_map.get_edges():\n", + " if qa not in used and qb not in used:\n", + " pairs.append((qa, qb))\n", + " used.update((qa, qb))\n", + "num_pairs = len(pairs)\n", + "print(\n", + " f\"Tiling {backend.name} with {num_pairs} parallel Bell pairs \"\n", + " f\"({2 * num_pairs} of {num_qubits} qubits)\"\n", + ")\n", + "\n", + "# One parameterized CHSH sub-circuit per pair, all sharing the angle theta\n", + "theta = Parameter(r\"$\\theta$\")\n", + "chsh_circuit = QuantumCircuit(num_qubits)\n", + "for qa, qb in pairs:\n", + " chsh_circuit.h(qa)\n", + " chsh_circuit.cx(qa, qb)\n", + " chsh_circuit.ry(theta, qa)\n", + "\n", + "# Embed the two CHSH observables onto each pair's qubits (identity elsewhere)\n", + "obs1 = SparsePauliOp.from_list([(\"ZZ\", 1), (\"ZX\", -1), (\"XZ\", 1), (\"XX\", 1)])\n", + "obs2 = SparsePauliOp.from_list([(\"ZZ\", 1), (\"ZX\", 1), (\"XZ\", -1), (\"XX\", 1)])\n", + "observables = []\n", + "for qa, qb in pairs:\n", + " observables.append([obs1.apply_layout([qa, qb], num_qubits)])\n", + " observables.append([obs2.apply_layout([qa, qb], num_qubits)])\n", + "\n", + "number_of_phases = 21\n", + "phases = np.linspace(0, 2 * np.pi, number_of_phases)\n", + "individual_phases = [[ph] for ph in phases]\n", + "\n", + "# -------------------------Step 2: Optimize problem for quantum hardware execution-------------------------\n", + "pm = generate_preset_pass_manager(target=backend.target, optimization_level=3)\n", + "chsh_isa_circuit = pm.run(chsh_circuit)\n", + "isa_observables = [\n", + " [o[0].apply_layout(chsh_isa_circuit.layout)] for o in observables\n", + "]\n", + "\n", + "# -------------------------Step 3: Execute using Qiskit primitives-------------------------\n", + "estimator_hw = Estimator(mode=backend)\n", + "estimator_hw.options.environment.job_tags = [\"TUT_CI\"]\n", + "\n", + "pub = (chsh_isa_circuit, isa_observables, individual_phases)\n", + "job = estimator_hw.run(pubs=[pub])\n", + "print(f\"Job ID: {job.job_id()}\")\n", + "hw_result = job.result()\n", + "\n", + "# -------------------------Step 4: Post-process and return result in desired classical format-------------------------\n", + "# evs has shape (2 * num_pairs, number_of_phases); rows alternate S1, S2\n", + "evs = np.asarray(hw_result[0].data.evs)\n", + "chsh1_all = evs[0::2]\n", + "chsh2_all = evs[1::2]\n", + "\n", + "# A pair \"violates\" CHSH if its strongest witness exceeds the classical bound\n", + "peak = np.maximum(\n", + " np.abs(chsh1_all).max(axis=1), np.abs(chsh2_all).max(axis=1)\n", + ")\n", + "n_violate = int(np.sum(peak > 2))\n", + "print(\n", + " f\"{n_violate}/{num_pairs} Bell pairs violated the CHSH inequality \"\n", + " f\"(mean peak witness {peak.mean():.2f}, classical bound 2)\"\n", + ")\n", + "\n", "fig, ax = plt.subplots(figsize=(10, 6))\n", "\n", - "# results from hardware\n", - "ax.plot(phases / np.pi, chsh1_est, \"o-\", label=\"CHSH1\", zorder=3)\n", - "ax.plot(phases / np.pi, chsh2_est, \"o-\", label=\"CHSH2\", zorder=3)\n", + "# Faint individual per-pair curves\n", + "for row in chsh1_all:\n", + " ax.plot(phases / np.pi, row, color=\"#1f77b4\", alpha=0.2, lw=1)\n", + "for row in chsh2_all:\n", + " ax.plot(phases / np.pi, row, color=\"#ff7f0e\", alpha=0.2, lw=1)\n", + "\n", + "# Bold mean curves across all pairs\n", + "ax.plot(\n", + " phases / np.pi,\n", + " chsh1_all.mean(axis=0),\n", + " color=\"#1f77b4\",\n", + " lw=2.5,\n", + " label=r\"$\\langle S_1 \\rangle$ (mean)\",\n", + ")\n", + "ax.plot(\n", + " phases / np.pi,\n", + " chsh2_all.mean(axis=0),\n", + " color=\"#ff7f0e\",\n", + " lw=2.5,\n", + " label=r\"$\\langle S_2 \\rangle$ (mean)\",\n", + ")\n", "\n", - "# classical bound +-2\n", + "# classical bound +-2 and Tsirelson bound +-2*sqrt(2)\n", "ax.axhline(y=2, color=\"0.9\", linestyle=\"--\")\n", "ax.axhline(y=-2, color=\"0.9\", linestyle=\"--\")\n", - "\n", - "# quantum bound, +-2√2\n", "ax.axhline(y=np.sqrt(2) * 2, color=\"0.9\", linestyle=\"-.\")\n", "ax.axhline(y=-np.sqrt(2) * 2, color=\"0.9\", linestyle=\"-.\")\n", "ax.fill_between(phases / np.pi, 2, 2 * np.sqrt(2), color=\"0.6\", alpha=0.7)\n", "ax.fill_between(phases / np.pi, -2, -2 * np.sqrt(2), color=\"0.6\", alpha=0.7)\n", "\n", - "# set x tick labels to the unit of pi\n", "ax.xaxis.set_major_formatter(tck.FormatStrFormatter(\"%g $\\\\pi$\"))\n", "ax.xaxis.set_major_locator(tck.MultipleLocator(base=0.5))\n", - "\n", - "# set labels, and legend\n", - "plt.xlabel(\"Theta\")\n", - "plt.ylabel(\"CHSH witness\")\n", - "plt.legend()\n", + "ax.set_xlabel(r\"$\\theta$\")\n", + "ax.set_ylabel(\"CHSH witness\")\n", + "ax.set_title(\n", + " f\"CHSH witnesses for {num_pairs} parallel Bell pairs on {backend.name}\"\n", + ")\n", + "ax.legend()\n", "plt.show()" ] }, { "cell_type": "markdown", - "id": "63e63853", + "id": "3c32f01c", "metadata": {}, "source": [ - "In the figure, the lines and gray areas delimit the bounds; the outer-most (dash-dotted) lines delimit the quantum-bounds ($\\pm 2\\sqrt{2}$), whereas the inner (dashed) lines delimit the classical bounds ($\\pm 2$). You can see that there are regions where the CHSH witness quantities exceeds the classical bounds. Congratulations! You have successfully demonstrated the violation of CHSH inequality in a real quantum system!" + "The faint curves are the individual Bell pairs and the bold curves are their mean across the device. Every pair traces the same sinusoid predicted by quantum mechanics, and the spread between the faint curves reflects the variation in noise from pair to pair. Wherever a curve enters the grey bands, it has crossed the classical bound of $\\pm 2$, and the printed summary confirms that essentially every pair violates the CHSH inequality at the same time.\n", + "\n", + "The peaks fall short of the Tsirelson bound $\\pm 2\\sqrt{2}$ because of device noise, but the conclusion is unambiguous: the backend sustains genuine entanglement across the whole chip simultaneously, not just on a single hand-picked pair. This is the sense in which the CHSH experiment \"scales\": not as one larger circuit, but as a parallel benchmark that certifies entanglement everywhere at once." ] }, { "cell_type": "markdown", - "id": "24942533", + "id": "86e635a3", "metadata": {}, "source": [ - "## Tutorial survey\n", - "\n", - "Please take this short survey to provide feedback on this tutorial. Your insights will help us improve our content offerings and user experience.\n", + "## Next steps\n", + "\n", "\n", - "[Link to survey](https://your.feedback.ibm.com/jfe/form/SV_3xxAgm1SF1wGp9k)" + "If you found this work interesting, you might be interested in the following material:\n", + "- [Entanglement in Action](/learning/courses/basics-of-quantum-information/entanglement-in-action/chsh-game): a course lesson by John Watrous on Bell states and the CHSH game.\n", + "- [Get started with the Estimator primitive](/docs/guides/primitives): a guide on PUBs and parameter sweeps.\n", + "- [Real-time benchmarking for qubit selection](/docs/tutorials/real-time-benchmarking-for-qubit-selection): another way to characterize qubit and entanglement quality across a device.\n", + "- [`SparsePauliOp` API reference](/docs/api/qiskit/qiskit.quantum_info.SparsePauliOp).\n", + "" ] } ], @@ -482,11 +687,6 @@ "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3" - }, - "vscode": { - "interpreter": { - "hash": "1910f834ba40d1043b9ae723a4d216fb6c2faf55822807adca52e5ece8e3f1c8" - } } }, "nbformat": 4, diff --git a/public/docs/images/tutorials/chsh-inequality/extracted-outputs/3376bc73-1.avif b/public/docs/images/tutorials/chsh-inequality/extracted-outputs/3376bc73-1.avif new file mode 100644 index 0000000000000000000000000000000000000000..8b7344f679867dcd18d38c0521822aa71b7ab6c8 GIT binary patch literal 10885 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 Bz})}< literal 0 HcmV?d00001 diff --git a/public/docs/images/tutorials/chsh-inequality/extracted-outputs/6c77e40a-0.avif b/public/docs/images/tutorials/chsh-inequality/extracted-outputs/6c77e40a-0.avif deleted file mode 100644 index 2c0ff5513af2d8e227c90a5bf9a02cbb38263d72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1369 zcmZQzV30{GsVqn=%S>Yc0uY^>nP!-qnF!=F7UZUuB!a|&KrtgFrwGDiU?|8;E`hOO zG+#kxNiLYf2qaB1bMlixJQoKBCI*lQ1LG73&A`As9Vi9_tlBUU20b9xA~Q1&>rbx4@iSZW^q9(hyk=8 zWWqWi7AVN9$OMTnb8v6~DX4lGkPy%p5IIJWj74H;g)>OFv?$Liw;(kgOgLF3XC@a| z6;~FQq~;b|0o7#YWF{6>S|#QbWPrmHg3 z>4*J#_B6%B+RM6szmT@$is7Wy4SDnHNSF1BKC9{2KTA8-g{LA-u<_`T12^p%)I@)-Uz@kxD0yk{g6aR( zNq7WpJ;b&^rE*iTnRL3dzkJV*ncl??w|DQgsE{@iFDOW!d*#!0t_y|lRNjQt&3<}@ zKizV}y6bH^9ij_QDSb2j_TLMsjpUN?JkJwYUv*e*XX|kemqWH3 z(Xn~u2|5q2GHejDuH2yYn0>NG^1aIe1=<3dYlSDA?|-}7ex8mW}JFOr7UGwNx%FVM*dG8L)zO;0nv)4Ssu5GJVZII# z2sK|IYkK3{oYd!f#%>&2wYMfXvdzEie?YSMTf#iPwe~4HuB@QhGdK21|R^XbuqmG5GunjURAX2~0!wmy7$ZrJucY8mcasgeoz zIVGoURaGvt@@$=OeVcFXtBhFP(v%xnli0SLtvy)j(slgrp|yR>sFs zNY?JfU;NurP83xoP4auuQn34uy_|99_8U{zx%&TJaqr=Rwf}BPKDs`+>DSY3lmGf( zkoLNuhmbBUF zn#Jq0e`>4wu$s}>GDY9b=EpW+gXG5yPQ6dcD(gxG*GLCF7uocyP^W$$o7|%6?FQ`E zmVdoG-QeF;xwg30r2_6u%lIzKv$XHjJ3F^4sQpvMZ_aNo7QK4^=jFQnB2V0NHoMoh zM?cxMX7di8PaAK?X3V{FI(Ms1zQUoir5jYTvb0YLzH;1s{Qe2?C4QXu6*;?B1x&A5 zBU#IJ8c?bX7azGmy?6Ztdzn8|4_x5CaA@+Wo(4NrS=0Y|GQe!f t2F{jRMoK`ohQl_A%T_g?=N#a?DY-%9a=@>J8ywiXZamV63gK9o1OP=f89V?0 diff --git a/public/docs/images/tutorials/chsh-inequality/extracted-outputs/9a5561eb-0.avif b/public/docs/images/tutorials/chsh-inequality/extracted-outputs/9a5561eb-0.avif deleted file mode 100644 index 02ce749488b7d8e9cc21c299b447ee7d951e67eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2837 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 S7MXLfmrw~;$fmPmy54_}NcuMb diff --git a/public/docs/images/tutorials/chsh-inequality/extracted-outputs/c3f57d25-0.avif b/public/docs/images/tutorials/chsh-inequality/extracted-outputs/c3f57d25-0.avif new file mode 100644 index 0000000000000000000000000000000000000000..01fb6787f08b67103bb74ff21559b9e4ac8efd68 GIT binary patch literal 1380 zcmZQzV30{GsVqn=%S>Ycg51nBLl8SRGZDyVEXYkQNd$=lfnr8VP7#F3z)+BxTmoam zXug8Xl3Xx{5lEV3=Hw@XcrFeMObj3q2F586nt_3N5l{>WSj}J}40=GWMP_Cm*co71 zQ6MK3tPH3-vCO~_qyr%clz|DZ&nze^07`ac79{5bX`aL~L+3^Y9*_o+%;JJn5CdpG z$b@x3EKrbHkqHuE=HTD}Qc(3WAR(YHAaaZ#8H>cy3TKdTX;Ge4Zb51~m~gU6&P*<_ zDy}RpNzE;`0;$snO|KoAGL_yr(lrp36o%+u*Zl_ZIl&p;pFX&2gNaBtA5N2!W{&!x<_r6)D zrXTj}+0zsgYcK2m{X*J~D~6L+H{{K)ms@pYR>@9@s8;_smvZhuYg_jvlT&%VW&TG? z?>DvAg?8(l#n!ybcilIrS#48+mk-in7?@3emScg>?)DL2nL<-I#F`_j^R&R+8jySA-fwLywcI95Mh zBGi0=tm%z&b5ft{8M|?8)!v%m$Tt73{{hM3Zwd4G*4n4+xU#}>+1`~0zVO7RpR_eP zlJ2zUZ{@$sa%!K0t4|r-`!r4Q%%?{aR=$gsYI?Ngm?dv?+WPS2xnbM)sAafwrAnr~ zy!B#I>a+Tp>Dx{o|8!~lSsBaDd7kg~by%!=$@_P|{i9O`JIal|eR*#!wIg|h|5nz@ zD^{zWVoHn4LYA1g@l|BUx!zj3ZAF_`NB_mMHkFwd>@P$wz96M{`t*+WbzgUD38-uJ zF8j~>k>#gIT)0<~e%Iorv#R!i;SSGu{Tp`ASoBuw*d|_yjk`DN&5hUFn;IH;L*;R` zt-?#U%1tGK9SCijgYU-N zSJ#BMKAA7!bG*#k*6DU!#5uW!85%bf&VC8B=xq|R?UJ9lZbm literal 0 HcmV?d00001 diff --git a/public/docs/images/tutorials/chsh-inequality/extracted-outputs/c8fd5140-0.avif b/public/docs/images/tutorials/chsh-inequality/extracted-outputs/c8fd5140-0.avif new file mode 100644 index 0000000000000000000000000000000000000000..ac9c1ea7b1ff36f4be60407519f72d7678bbe9e2 GIT binary patch literal 9776 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 literal 0 HcmV?d00001 diff --git a/public/docs/images/tutorials/chsh-inequality/extracted-outputs/f6267448-0.avif b/public/docs/images/tutorials/chsh-inequality/extracted-outputs/f6267448-0.avif deleted file mode 100644 index ed89b30c4275263584a53fe1d8a7a6b7c94e411e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7125 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 wR}apMo+1Aky~ Date: Thu, 21 May 2026 14:22:02 -0400 Subject: [PATCH 2/4] Apply suggestions from code review --- docs/tutorials/chsh-inequality.ipynb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tutorials/chsh-inequality.ipynb b/docs/tutorials/chsh-inequality.ipynb index 449a52c79f3..dd703ef4cea 100644 --- a/docs/tutorials/chsh-inequality.ipynb +++ b/docs/tutorials/chsh-inequality.ipynb @@ -27,11 +27,11 @@ "- How to construct a parameterized Bell-state CHSH circuit and measure the four expectation values that make up the CHSH witnesses.\n", "- How to compute expectation values of multiple observables on a parameter sweep in a single call to the [`EstimatorV2`](/docs/api/qiskit-ibm-runtime/estimator-v2) primitive.\n", "- How to validate a quantum workflow on a noisy local simulator with `AerSimulator.from_backend` before submitting to hardware.\n", - "- How to scale a CHSH experiment into a device-wide entanglement benchmark by running many independent Bell pairs in parallel on IBM Quantum hardware.\n", + "- How to scale a CHSH experiment into a device-wide entanglement benchmark by running many independent Bell pairs in parallel on IBM Quantum® hardware.\n", "\n", "## Prerequisites\n", "It is recommended that you familiarize yourself with these topics:\n", - "- [Entanglement in Action](/learning/courses/basics-of-quantum-information/entanglement-in-action/chsh-game), a course lesson on Bell states and the CHSH game.\n", + "- [Entanglement in action](/learning/courses/basics-of-quantum-information/entanglement-in-action/chsh-game), a course lesson on Bell states and the CHSH game.\n", "- [`SparsePauliOp`](/docs/api/qiskit/qiskit.quantum_info.SparsePauliOp) and the Qiskit primitives [introduction](/docs/guides/primitives)." ] }, @@ -662,7 +662,7 @@ "\n", "\n", "If you found this work interesting, you might be interested in the following material:\n", - "- [Entanglement in Action](/learning/courses/basics-of-quantum-information/entanglement-in-action/chsh-game): a course lesson by John Watrous on Bell states and the CHSH game.\n", + "- [Entanglement in action](/learning/courses/basics-of-quantum-information/entanglement-in-action/chsh-game): a course lesson by John Watrous on Bell states and the CHSH game.\n", "- [Get started with the Estimator primitive](/docs/guides/primitives): a guide on PUBs and parameter sweeps.\n", "- [Real-time benchmarking for qubit selection](/docs/tutorials/real-time-benchmarking-for-qubit-selection): another way to characterize qubit and entanglement quality across a device.\n", "- [`SparsePauliOp` API reference](/docs/api/qiskit/qiskit.quantum_info.SparsePauliOp).\n", From 6bf328c38a588587913538d9990e700af6e0aa76 Mon Sep 17 00:00:00 2001 From: Henry Zou <87874865+henryzou50@users.noreply.github.com> Date: Thu, 21 May 2026 14:46:25 -0400 Subject: [PATCH 3/4] Update docs/tutorials/chsh-inequality.ipynb Co-authored-by: abbycross --- docs/tutorials/chsh-inequality.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/chsh-inequality.ipynb b/docs/tutorials/chsh-inequality.ipynb index dd703ef4cea..48e9375e25a 100644 --- a/docs/tutorials/chsh-inequality.ipynb +++ b/docs/tutorials/chsh-inequality.ipynb @@ -48,7 +48,7 @@ "\n", "The 2022 Nobel Prize for Physics was awarded to Alain Aspect, John Clauser, and Anton Zeilinger in part for their pioneering work in quantum information science, and in particular, for their experiments with entangled photons demonstrating violation of Bell's inequalities.\n", "\n", - "For this experiment, we will create an entangled pair on which we measure each qubit on two different bases. We will label the bases for the first qubit $A$ and $a$ and the bases for the second qubit $B$ and $b$. This allows us to compute the CHSH quantity $S_1$:\n", + "For this experiment, we will create an entangled pair on which we measure each qubit in two different bases. We will label the bases for the first qubit $A$ and $a$ and the bases for the second qubit $B$ and $b$. This allows us to compute the CHSH quantity $S_1$:\n", "\n", "$$\n", "S_1 = A(B-b) + a(B+b).\n", From c92070bb58d7cd3d3ed2846962f50d819f45c3c0 Mon Sep 17 00:00:00 2001 From: Henry Zou Date: Thu, 21 May 2026 14:56:57 -0400 Subject: [PATCH 4/4] Addressed review feedback on PR. Spell out PUB at first use in CHSH tutorial Define "primitive unified bloc (PUB)" where the term first appears in the Background section, linked to the primitive I/O guide, instead of interrupting Step 3 with the explanation. Step 3 now just uses "PUBs". --- docs/tutorials/chsh-inequality.ipynb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tutorials/chsh-inequality.ipynb b/docs/tutorials/chsh-inequality.ipynb index 48e9375e25a..9b65a070fc7 100644 --- a/docs/tutorials/chsh-inequality.ipynb +++ b/docs/tutorials/chsh-inequality.ipynb @@ -14,7 +14,7 @@ "\n", "# CHSH inequality\n", "\n", - "*Usage estimate: A few minutes on a Heron r3 processor (NOTE: This is an estimate only. Your runtime might vary.)*" + "*Usage estimate: Two minutes on a Heron r3 processor (NOTE: This is an estimate only. Your runtime might vary.)*" ] }, { @@ -80,7 +80,7 @@ "\n", "If quantum mechanics could be described by local hidden-variable theories, these inequalities would always hold. As demonstrated in this tutorial, they can be violated on a quantum computer, so quantum mechanics is not compatible with local hidden-variable theories.\n", "\n", - "We create the entangled pair by preparing the Bell state $|\\Phi^+\\rangle = \\frac{|00\\rangle + |11\\rangle}{\\sqrt{2}}$. Using the Estimator primitive, we obtain the expectation values $\\langle AB \\rangle, \\langle Ab \\rangle, \\langle aB \\rangle$, and $\\langle ab \\rangle$ directly, without reconstructing them from raw counts. We measure the second qubit in the $Z$ and $X$ bases. The first qubit is measured in orthogonal bases as well, but with a rotation angle $\\theta$ that we sweep between $0$ and $2\\pi$. The Estimator primitive evaluates this parameter sweep in a single PUB." + "We create the entangled pair by preparing the Bell state $|\\Phi^+\\rangle = \\frac{|00\\rangle + |11\\rangle}{\\sqrt{2}}$. Using the Estimator primitive, we obtain the expectation values $\\langle AB \\rangle, \\langle Ab \\rangle, \\langle aB \\rangle$, and $\\langle ab \\rangle$ directly, without reconstructing them from raw counts. We measure the second qubit in the $Z$ and $X$ bases. The first qubit is measured in orthogonal bases as well, but with a rotation angle $\\theta$ that we sweep between $0$ and $2\\pi$. The Estimator primitive evaluates this parameter sweep in a single [primitive unified bloc (PUB)](/docs/guides/primitive-input-output)." ] }, { @@ -371,7 +371,7 @@ "source": [ "### Step 3: Execute using Qiskit primitives\n", "\n", - "Run the parameter sweep with `EstimatorV2` in `aer_sim` mode. The Estimator `run()` method takes an iterable of primitive unified blocs (PUBs). Each PUB has the format `(circuit, observables, parameter_values, precision)`. We pass both observables together so they share the same parameter sweep." + "Run the parameter sweep with `EstimatorV2` in `aer_sim` mode. The Estimator `run()` method takes an iterable of PUBs. Each PUB has the format `(circuit, observables, parameter_values, precision)`. We pass both observables together so they share the same parameter sweep." ] }, {