Ketidaksetaraan CHSH
Perkiraan penggunaan: Dua menit di prosesor Heron r3 (CATATAN: Ini hanya perkiraan. Waktu eksekusi kamu bisa berbeda.)
Hasil pembelajaran
Setelah menyelesaikan tutorial ini, kamu diharapkan memahami hal-hal berikut:
- Cara membuat Circuit CHSH Bell-state berparameter dan mengukur empat nilai ekspektasi yang membentuk saksi CHSH.
- Cara menghitung nilai ekspektasi dari beberapa observabel pada sapuan parameter dalam satu panggilan ke primitif
EstimatorV2. - Cara memvalidasi alur kerja kuantum di simulator lokal yang berisik dengan
AerSimulator.from_backendsebelum mengirimkan ke perangkat keras. - Cara memperluas eksperimen CHSH menjadi benchmark keterikatan sekala perangkat dengan menjalankan banyak pasangan Bell secara paralel pada perangkat keras IBM Quantum®.
Prasyarat
Disarankan untuk memahami topik-topik berikut terlebih dahulu:
- Entanglement in action, pelajaran kursus tentang keadaan Bell dan permainan CHSH.
SparsePauliOpdan pengantar primitif Qiskit.
Latar Belakang
Dalam tutorial ini, kamu akan menjalankan eksperimen di komputer kuantum untuk mendemonstrasikan pelanggaran ketidaksetaraan CHSH dengan primitif Estimator.
Ketidaksetaraan CHSH, dinamai berdasarkan Clauser, Horne, Shimony, dan Holt, digunakan untuk menguji teorema Bell secara eksperimental (1969). Teorema ini menyatakan bahwa teori variabel tersembunyi lokal tidak dapat menjelaskan beberapa konsekuensi dari keterikatan dalam mekanika kuantum. Mendemonstrasikan pelanggaran ketidaksetaraan CHSH menunjukkan bahwa mekanika kuantum tidak kompatibel dengan teori variabel tersembunyi lokal — sebuah eksperimen yang menjadi fondasi pemahaman kita tentang mekanika kuantum.
Hadiah Nobel Fisika 2022 diberikan kepada Alain Aspect, John Clauser, dan Anton Zeilinger sebagian atas karya perintis mereka dalam ilmu informasi kuantum, dan khususnya, atas eksperimen mereka dengan foton yang saling terikat yang mendemonstrasikan pelanggaran ketidaksetaraan Bell.
Untuk eksperimen ini, kita akan membuat pasangan yang saling terikat di mana kita mengukur setiap qubit dalam dua basis yang berbeda. Kita akan memberi label basis untuk qubit pertama sebagai dan , dan basis untuk qubit kedua sebagai dan . Ini memungkinkan kita menghitung kuantitas CHSH :
Setiap observabel bernilai atau . Jelas, salah satu suku harus , dan yang lainnya harus . Oleh karena itu, . Nilai rata-rata harus memenuhi ketidaksetaraan:
Dengan menguraikan dalam bentuk , , , dan , diperoleh:
Kamu bisa mendefinisikan kuantitas CHSH lainnya yaitu :
yang menghasilkan ketidaksetaraan lain:
Jika mekanika kuantum dapat dijelaskan oleh teori variabel tersembunyi lokal, ketidaksetaraan ini akan selalu berlaku. Seperti yang didemonstrasikan dalam tutorial ini, ketidaksetaraan ini bisa dilanggar di komputer kuantum, sehingga mekanika kuantum tidak kompatibel dengan teori variabel tersembunyi lokal.
Kita membuat pasangan yang saling terikat dengan mempersiapkan keadaan Bell . Dengan menggunakan primitif Estimator, kita mendapatkan nilai ekspektasi , dan secara langsung, tanpa harus merekonstruksinya dari hasil pengukuran mentah. Kita mengukur qubit kedua dalam basis dan . Qubit pertama juga diukur dalam basis yang ortogonal, tetapi dengan sudut rotasi yang kita sapu antara dan . Primitif Estimator mengevaluasi sapuan parameter ini dalam satu primitive unified bloc (PUB).
Persyaratan
Sebelum memulai tutorial ini, pastikan kamu telah menginstal hal-hal berikut:
- Qiskit SDK v2.0 atau lebih baru, dengan dukungan visualisasi
- Qiskit Runtime v0.40 atau lebih baru (
pip install qiskit-ibm-runtime) - Qiskit Aer v0.17 atau lebih baru (
pip install qiskit-aer)
Persiapan
# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-aer qiskit-ibm-runtime
# General
import numpy as np
# Qiskit imports
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
# Qiskit Runtime imports
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import EstimatorV2 as Estimator
# Qiskit Aer for local noisy simulation
from qiskit_aer import AerSimulator
# Plotting routines
import matplotlib.pyplot as plt
import matplotlib.ticker as tck
# Select an IBM Quantum backend.
service = QiskitRuntimeService()
backend = service.least_busy(
min_num_qubits=127, operational=True, simulator=False
)
backend.name
'ibm_pittsburgh'
Contoh simulator skala kecil
Sebelum mengirimkan job ke perangkat keras, kita memvalidasi seluruh alur kerja pada simulator lokal yang berisik. Kita menggunakan AerSimulator.from_backend(backend) untuk membangun simulator yang mewarisi model noise dan coupling map dari backend yang dipilih, sehingga respons simulator secara kualitatif mirip dengan yang diharapkan dari perangkat keras.
Langkah 1: Petakan input klasikal ke masalah kuantum
Kita menulis Circuit CHSH dengan satu parameter , yang menyapu basis pengukuran qubit pertama. Primitif Estimator menyederhanakan analisis: primitif ini mengembalikan nilai ekspektasi observabel secara langsung, dan dapat mengevaluasi Circuit berparameter pada banyak nilai parameter dalam satu panggilan.
theta = Parameter(r"$\theta$")
chsh_circuit = QuantumCircuit(2)
chsh_circuit.h(0)
chsh_circuit.cx(0, 1)
chsh_circuit.ry(theta, 0)
chsh_circuit.draw(output="mpl", idle_wires=False, style="iqp")
Selanjutnya, kita membuat daftar 21 nilai fase dari hingga untuk mengevaluasi Circuit berparameter (, , , ..., , ).
number_of_phases = 21
phases = np.linspace(0, 2 * np.pi, number_of_phases)
# Phases need to be expressed as a list of lists for the Estimator PUB
individual_phases = [[ph] for ph in phases]
Terakhir, kita mendefinisikan observabel. Qubit pertama diukur di sepanjang sumbu yang dirotasi oleh ; qubit kedua diukur dalam dan . Dengan pilihan tersebut, empat korelator CHSH dipetakan ke operator Pauli , , , dan :
# <S_1> = <ZZ> - <ZX> + <XZ> + <XX>
observable1 = SparsePauliOp.from_list(
[("ZZ", 1), ("ZX", -1), ("XZ", 1), ("XX", 1)]
)
# <S_2> = <ZZ> + <ZX> - <XZ> + <XX>
observable2 = SparsePauliOp.from_list(
[("ZZ", 1), ("ZX", 1), ("XZ", -1), ("XX", 1)]
)
Langkah 2: Optimalkan masalah untuk eksekusi perangkat keras kuantum
Primitif V2 hanya menerima Circuit dan observabel yang sesuai dengan instruksi dan konektivitas yang didukung oleh sistem target (circuit dan observabel ISA — instruction set architecture). Kita membangun AerSimulator dari backend dan melakukan transpilasi terhadap target simulator agar pass manager yang sama digunakan secara menyeluruh.
# Build a noisy simulator from the ibm_pittsburgh backend
aer_sim = AerSimulator.from_backend(backend)
pm = generate_preset_pass_manager(target=aer_sim.target, optimization_level=3)
chsh_isa_circuit = pm.run(chsh_circuit)
chsh_isa_circuit.draw(output="mpl", idle_wires=False, style="iqp")
Kita juga mentransformasi observabel agar sesuai dengan tata letak qubit Circuit yang telah ditranspilasi menggunakan SparsePauliOp.apply_layout.
isa_observable1 = observable1.apply_layout(layout=chsh_isa_circuit.layout)
isa_observable2 = observable2.apply_layout(layout=chsh_isa_circuit.layout)
Langkah 3: Eksekusi menggunakan primitif Qiskit
Jalankan sapuan parameter dengan EstimatorV2 dalam mode aer_sim. Metode run() dari Estimator menerima iterable dari PUB. Setiap PUB memiliki format (circuit, observables, parameter_values, precision). Kita memasukkan kedua observabel bersama-sama agar mereka berbagi sapuan parameter yang sama.
# Use the AerSimulator-backed Estimator to validate the workflow locally
estimator_sim = Estimator(mode=aer_sim)
pub = (
chsh_isa_circuit, # ISA circuit
[[isa_observable1], [isa_observable2]], # ISA observables
individual_phases, # Parameter values
)
sim_result = estimator_sim.run(pubs=[pub]).result()
Langkah 4: Pasca-proses dan kembalikan hasil dalam format klasikal yang diinginkan
Estimator mengembalikan nilai ekspektasi untuk kedua observabel. Kita memplotnya terhadap bersama dengan batas klasikal () dan batas Tsirelson (). Area abu-abu yang diarsir menandai celah antara keduanya. Titik-titik yang berada di dalam band ini melanggar ketidaksetaraan CHSH.
chsh1_sim = sim_result[0].data.evs[0]
chsh2_sim = sim_result[0].data.evs[1]
def plot_chsh(phases, chsh1, chsh2, title):
fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(
phases / np.pi, chsh1, "o-", label=r"$\langle S_1 \rangle$", zorder=3
)
ax.plot(
phases / np.pi, chsh2, "o-", label=r"$\langle S_2 \rangle$", zorder=3
)
# classical bound +-2
ax.axhline(y=2, color="0.9", linestyle="--")
ax.axhline(y=-2, color="0.9", linestyle="--")
# quantum bound, +-2*sqrt(2)
ax.axhline(y=np.sqrt(2) * 2, color="0.9", linestyle="-.")
ax.axhline(y=-np.sqrt(2) * 2, color="0.9", linestyle="-.")
ax.fill_between(phases / np.pi, 2, 2 * np.sqrt(2), color="0.6", alpha=0.7)
ax.fill_between(
phases / np.pi, -2, -2 * np.sqrt(2), color="0.6", alpha=0.7
)
ax.xaxis.set_major_formatter(tck.FormatStrFormatter("%g $\\pi$"))
ax.xaxis.set_major_locator(tck.MultipleLocator(base=0.5))
ax.set_xlabel(r"$\theta$")
ax.set_ylabel("CHSH witness")
ax.set_title(title)
ax.legend()
plt.show()
plot_chsh(
phases,
chsh1_sim,
chsh2_sim,
"CHSH witnesses from AerSimulator (ibm_pittsburgh noise model)",
)
Saksi CHSH dari simulator sudah melampaui batas klasikal pada beberapa nilai , bahkan dengan model noise backend. Puncaknya sedikit di bawah batas Tsirelson karena noise perangkat yang disimulasikan. Dengan alur kerja yang telah divalidasi, kita beralih ke perangkat keras yang sebenarnya.
Contoh perangkat keras skala besar
Uji CHSH pada dasarnya adalah eksperimen dua-qubit, sehingga tidak bisa diskalakan dengan membuat satu Circuit yang lebih besar. Sebaliknya, skalanya ditingkatkan dengan menjalankan banyak uji secara paralel. Di sini kita mengisi backend dengan sebanyak mungkin pasangan Bell yang tidak saling berbagi qubit sesuai konektivitasnya (sebuah matching dari coupling map) dan menjalankan sub-Circuit CHSH independen pada setiap pasangan, semuanya dalam satu job.
Ini mengubah CHSH menjadi benchmark keterikatan sekala perangkat: alih-alih satu pasangan yang dipilih sendiri, kita menguji keterikatan di sebagian besar chip sekaligus, dalam kondisi nyata di mana setiap pasangan bersaing dengan crosstalk tetangganya dan kesalahan gate paralel. Melanggar ketidaksetaraan pada setiap pasangan secara bersamaan membuktikan bahwa keterikatan sejati tersedia di seluruh perangkat.
# -------------------------Step 1: Map classical inputs to a quantum problem-------------------------
# A CHSH test is bipartite, so we scale up by running one independent CHSH
# experiment on every disjoint Bell pair the device can host. A greedy
# matching of the coupling map gives a set of edges that share no qubits.
num_qubits = backend.num_qubits
used = set()
pairs = []
for qa, qb in backend.coupling_map.get_edges():
if qa not in used and qb not in used:
pairs.append((qa, qb))
used.update((qa, qb))
num_pairs = len(pairs)
print(
f"Tiling {backend.name} with {num_pairs} parallel Bell pairs "
f"({2 * num_pairs} of {num_qubits} qubits)"
)
# One parameterized CHSH sub-circuit per pair, all sharing the angle theta
theta = Parameter(r"$\theta$")
chsh_circuit = QuantumCircuit(num_qubits)
for qa, qb in pairs:
chsh_circuit.h(qa)
chsh_circuit.cx(qa, qb)
chsh_circuit.ry(theta, qa)
# Embed the two CHSH observables onto each pair's qubits (identity elsewhere)
obs1 = SparsePauliOp.from_list([("ZZ", 1), ("ZX", -1), ("XZ", 1), ("XX", 1)])
obs2 = SparsePauliOp.from_list([("ZZ", 1), ("ZX", 1), ("XZ", -1), ("XX", 1)])
observables = []
for qa, qb in pairs:
observables.append([obs1.apply_layout([qa, qb], num_qubits)])
observables.append([obs2.apply_layout([qa, qb], num_qubits)])
number_of_phases = 21
phases = np.linspace(0, 2 * np.pi, number_of_phases)
individual_phases = [[ph] for ph in phases]
# -------------------------Step 2: Optimize problem for quantum hardware execution-------------------------
pm = generate_preset_pass_manager(target=backend.target, optimization_level=3)
chsh_isa_circuit = pm.run(chsh_circuit)
isa_observables = [
[o[0].apply_layout(chsh_isa_circuit.layout)] for o in observables
]
# -------------------------Step 3: Execute using Qiskit primitives-------------------------
estimator_hw = Estimator(mode=backend)
estimator_hw.options.environment.job_tags = ["TUT_CI"]
pub = (chsh_isa_circuit, isa_observables, individual_phases)
job = estimator_hw.run(pubs=[pub])
print(f"Job ID: {job.job_id()}")
hw_result = job.result()
# -------------------------Step 4: Post-process and return result in desired classical format-------------------------
# evs has shape (2 * num_pairs, number_of_phases); rows alternate S1, S2
evs = np.asarray(hw_result[0].data.evs)
chsh1_all = evs[0::2]
chsh2_all = evs[1::2]
# A pair "violates" CHSH if its strongest witness exceeds the classical bound
peak = np.maximum(
np.abs(chsh1_all).max(axis=1), np.abs(chsh2_all).max(axis=1)
)
n_violate = int(np.sum(peak > 2))
print(
f"{n_violate}/{num_pairs} Bell pairs violated the CHSH inequality "
f"(mean peak witness {peak.mean():.2f}, classical bound 2)"
)
fig, ax = plt.subplots(figsize=(10, 6))
# Faint individual per-pair curves
for row in chsh1_all:
ax.plot(phases / np.pi, row, color="#1f77b4", alpha=0.2, lw=1)
for row in chsh2_all:
ax.plot(phases / np.pi, row, color="#ff7f0e", alpha=0.2, lw=1)
# Bold mean curves across all pairs
ax.plot(
phases / np.pi,
chsh1_all.mean(axis=0),
color="#1f77b4",
lw=2.5,
label=r"$\langle S_1 \rangle$ (mean)",
)
ax.plot(
phases / np.pi,
chsh2_all.mean(axis=0),
color="#ff7f0e",
lw=2.5,
label=r"$\langle S_2 \rangle$ (mean)",
)
# classical bound +-2 and Tsirelson bound +-2*sqrt(2)
ax.axhline(y=2, color="0.9", linestyle="--")
ax.axhline(y=-2, color="0.9", linestyle="--")
ax.axhline(y=np.sqrt(2) * 2, color="0.9", linestyle="-.")
ax.axhline(y=-np.sqrt(2) * 2, color="0.9", linestyle="-.")
ax.fill_between(phases / np.pi, 2, 2 * np.sqrt(2), color="0.6", alpha=0.7)
ax.fill_between(phases / np.pi, -2, -2 * np.sqrt(2), color="0.6", alpha=0.7)
ax.xaxis.set_major_formatter(tck.FormatStrFormatter("%g $\\pi$"))
ax.xaxis.set_major_locator(tck.MultipleLocator(base=0.5))
ax.set_xlabel(r"$\theta$")
ax.set_ylabel("CHSH witness")
ax.set_title(
f"CHSH witnesses for {num_pairs} parallel Bell pairs on {backend.name}"
)
ax.legend()
plt.show()
Tiling ibm_pittsburgh with 64 parallel Bell pairs (128 of 156 qubits)
Job ID: d86efd5g7okc73el0rp0
63/64 Bell pairs violated the CHSH inequality (mean peak witness 2.75, classical bound 2)

Kurva-kurva tipis adalah pasangan Bell individual dan kurva-kurva tebal adalah rata-ratanya di seluruh perangkat. Setiap pasangan menelusuri sinusoid yang sama seperti yang diprediksi mekanika kuantum, dan penyebaran antara kurva-kurva tipis mencerminkan variasi noise dari pasangan ke pasangan. Di mana pun kurva memasuki band abu-abu, kurva tersebut telah melampaui batas klasikal , dan ringkasan yang dicetak mengonfirmasi bahwa pada dasarnya setiap pasangan melanggar ketidaksetaraan CHSH secara bersamaan.
Puncaknya tidak mencapai batas Tsirelson karena noise perangkat, tetapi kesimpulannya tidak ambigu: backend mempertahankan keterikatan sejati di seluruh chip secara bersamaan, bukan hanya pada satu pasangan yang dipilih sendiri. Inilah arti eksperimen CHSH "diskalakan": bukan sebagai satu Circuit yang lebih besar, melainkan sebagai benchmark paralel yang membuktikan keterikatan di mana-mana sekaligus.
Langkah selanjutnya
Jika kamu menemukan topik ini menarik, kamu mungkin tertarik dengan materi berikut:
- Entanglement in action: pelajaran kursus oleh John Watrous tentang keadaan Bell dan permainan CHSH.
- Get started with the Estimator primitive: panduan tentang PUB dan sapuan parameter.
- Real-time benchmarking for qubit selection: cara lain untuk mengkarakterisasi kualitas qubit dan keterikatan di seluruh perangkat.
SparsePauliOpAPI reference.