انتقل إلى المحتوى الرئيسي

متباينة CHSH

تقدير الاستخدام: دقيقتان على معالج Heron r3 (ملاحظة: هذا تقدير فقط. قد يختلف وقت التشغيل الفعلي لديك.)

نتائج التعلم

بعد إتمام هذا البرنامج التعليمي، يمكنك توقع فهم المعلومات التالية:

  • كيفية بناء دائرة CHSH لحالة Bell ذات معاملات وقياس قيم التوقع الأربع التي تشكّل شواهد CHSH.
  • كيفية حساب قيم التوقع لرواصد متعددة على مسح للمعاملات في استدعاء واحد للأداة الأولية EstimatorV2.
  • كيفية التحقق من صحة سير عمل كمومي على محاكٍ محلي بضوضاء باستخدام AerSimulator.from_backend قبل الإرسال إلى العتاد.
  • كيفية توسيع تجربة CHSH لتصبح معياراً شاملاً للتشابك على مستوى الجهاز، عبر تشغيل أزواج Bell المستقلة بشكل متوازٍ على عتاد IBM Quantum®.

المتطلبات الأساسية

يُنصح بالتعرف على هذه المواضيع:

الخلفية النظرية

في هذا البرنامج التعليمي، ستُجري تجربة على حاسوب كمومي لإثبات انتهاك متباينة CHSH باستخدام الأداة الأولية Estimator.

متباينة CHSH، المسماة نسبةً إلى مؤلفيها Clauser وHorne وShimony وHolt، تُستخدم لإثبات نظرية Bell تجريبياً (1969). تؤكد هذه النظرية أن نظريات المتغيرات الخفية المحلية لا يمكنها تفسير بعض نتائج التشابك الكمومي في ميكانيكا الكم. يُستخدم انتهاك متباينة CHSH لإثبات أن ميكانيكا الكم غير متوافقة مع نظريات المتغيرات الخفية المحلية. وتُعدّ هذه التجربة بالغة الأهمية لفهم أسس ميكانيكا الكم.

في عام 2022، مُنحت جائزة نوبل في الفيزياء إلى Alain Aspect وJohn Clauser وAnton Zeilinger، جزئياً تقديراً لأعمالهم الرائدة في علم المعلومات الكمومية، ولا سيما تجاربهم مع الفوتونات المتشابكة التي تُثبت انتهاك متباينات Bell.

في هذه التجربة، سننشئ زوجاً متشابكاً نقيس فيه كل Qubit على أساسين مختلفين. سنسمي الأساسين للـ Qubit الأول AA وaa، والأساسين للـ Qubit الثاني BB وbb. يتيح لنا ذلك حساب كمية CHSH S1S_1:

S1=A(Bb)+a(B+b).S_1 = A(B-b) + a(B+b).

كل راصد يأخذ قيمة +1+1 أو 1-1. من الواضح أن أحد الحدين B±bB\pm b يساوي 00، والآخر يساوي ±2\pm 2. لذلك، S1=±2S_1 = \pm 2. يجب أن تُحقق القيمة المتوسطة لـ S1S_1 المتباينة:

S12.|\langle S_1 \rangle|\leq 2.

بتوسيع S1S_1 بدلالة AA وaa وBB وbb نحصل على:

S1=ABAb+aB+ab2.|\langle S_1 \rangle| = |\langle AB \rangle - \langle Ab \rangle + \langle aB \rangle + \langle ab \rangle| \leq 2.

يمكنك تعريف كمية CHSH أخرى S2S_2:

S2=A(B+b)a(Bb),S_2 = A(B+b) - a(B-b),

وهذا يؤدي إلى متباينة أخرى:

S2=AB+AbaB+ab2.|\langle S_2 \rangle| = |\langle AB \rangle + \langle Ab \rangle - \langle aB \rangle + \langle ab \rangle| \leq 2.

لو كان يمكن وصف ميكانيكا الكم بنظريات المتغيرات الخفية المحلية، لكانت هذه المتباينتان تتحققان دائماً. غير أنه كما يُوضح هذا البرنامج التعليمي، يمكن انتهاكهما على الحاسوب الكمومي، مما يعني أن ميكانيكا الكم غير متوافقة مع نظريات المتغيرات الخفية المحلية.

سننشئ الزوج المتشابك بإعداد حالة Bell Φ+=00+112|\Phi^+\rangle = \frac{|00\rangle + |11\rangle}{\sqrt{2}}. باستخدام الأداة الأولية Estimator، نحصل مباشرةً على قيم التوقع AB,Ab,aB\langle AB \rangle, \langle Ab \rangle, \langle aB \rangle، وab\langle ab \rangle دون الحاجة إلى استنتاجها من العدادات الخام. نقيس الـ Qubit الثاني في الأساسين ZZ وXX. أما الـ Qubit الأول فيُقاس أيضاً في أساسين متعامدين، لكن بزاوية دوران θ\theta نجري مسحاً لها بين 00 و2π2\pi. تُقيّم الأداة الأولية Estimator هذا المسح للمعاملات في primitive unified bloc (PUB) واحد.

المتطلبات

قبل البدء بهذا البرنامج التعليمي، تأكد من تثبيت ما يلي:

  • Qiskit SDK الإصدار 2.0 أو أحدث، مع دعم التصور البياني
  • Qiskit Runtime الإصدار 0.40 أو أحدث (pip install qiskit-ibm-runtime)
  • Qiskit Aer الإصدار 0.17 أو أحدث (pip install qiskit-aer)

الإعداد

# 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'

مثال على محاكٍ صغير الحجم

قبل إرسال مهمة إلى العتاد، نتحقق من صحة سير العمل بالكامل على محاكٍ محلي بضوضاء. نستخدم AerSimulator.from_backend(backend) لبناء محاكٍ يرث نموذج الضوضاء وخريطة الاتصال للـ Backend الذي اخترته، بحيث تكون استجابة المحاكٍ نوعياً مشابهة لما نتوقعه من العتاد.

الخطوة 1: تحويل المدخلات الكلاسيكية إلى مسألة كمومية

نكتب دائرة CHSH بمعامل واحد θ\theta، الذي يمسح أساس القياس للـ Qubit الأول. تُبسّط الأداة الأولية Estimator التحليل: فهي تُعيد قيم التوقع للرواصد مباشرةً، ويمكنها تقييم دائرة ذات معاملات عند قيم معاملات كثيرة في استدعاء واحد.

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")

Output of the previous code cell

بعد ذلك، ننشئ قائمة من 21 قيمة طور تتراوح من 00 إلى 2π2\pi لتقييم الدائرة ذات المعاملات عندها (00، 0.1π0.1\pi، 0.2π0.2\pi، ...، 1.9π1.9\pi، 2π2\pi).

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]

أخيراً، نحدد الرواصد. يُقاس الـ Qubit الأول على محاور مدوّرة بـ θ\theta؛ ويُقاس الـ Qubit الثاني في ZZ وXX. مع هذه الاختيارات، تنعكس المترابطات الأربعة لـ CHSH على مؤثرات Pauli ZZZZ وZXZX وXZXZ وXXXX:

S1=ZZZX+XZ+XX,\langle S_1 \rangle = \langle ZZ \rangle - \langle ZX \rangle + \langle XZ \rangle + \langle XX \rangle, S2=ZZ+ZXXZ+XX.\langle S_2 \rangle = \langle ZZ \rangle + \langle ZX \rangle - \langle XZ \rangle + \langle XX \rangle.
# <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)]
)

الخطوة 2: تحسين المسألة لتنفيذها على العتاد الكمومي

تقبل الأدوات الأولية V2 فقط الدوائر والرواصد المتوافقة مع التعليمات والتوصيلية المدعومة من قبل النظام المستهدف (دوائر ورواصد معمارية مجموعة التعليمات، أو ISA). نبني AerSimulator من الـ Backend وننقل الدوائر وفقاً لهدف المحاكٍ، بحيث يُمارَس نفس مدير التمريرات من الطرف إلى الطرف.

# 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")

Output of the previous code cell

نحوّل أيضاً الرواصد لمطابقة تخطيط الـ Qubit للدائرة المُحوَّلة باستخدام SparsePauliOp.apply_layout.

isa_observable1 = observable1.apply_layout(layout=chsh_isa_circuit.layout)
isa_observable2 = observable2.apply_layout(layout=chsh_isa_circuit.layout)

الخطوة 3: التنفيذ باستخدام الأدوات الأولية لـ Qiskit

نُشغّل مسح المعاملات باستخدام EstimatorV2 في وضع aer_sim. تأخذ طريقة run() للـ Estimator متسلسلةً من PUBs. كل PUB يأخذ الصيغة (circuit, observables, parameter_values, precision). نُمرر كلا الراصدين معاً ليشتركا في نفس مسح المعاملات.

# 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()

الخطوة 4: المعالجة اللاحقة وإعادة النتيجة بالتنسيق الكلاسيكي المطلوب

تُعيد الأداة Estimator قيم التوقع لكلا الراصدين. نرسمها مقابل θ\theta مع الحد الكلاسيكي (±2\pm 2) وحد Tsirelson (±22\pm 2\sqrt{2}). تُحدد المناطق الرمادية المظللة الفجوة بين الاثنين. النقاط الواقعة داخل هذه النطاقات تنتهك متباينة 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)",
)

Output of the previous code cell

شواهد CHSH للمحاكٍ تتجاوز بالفعل الحد الكلاسيكي ±2\pm 2 عند عدة قيم لـ θ\theta، حتى مع نموذج الضوضاء للـ Backend. تقع القمم قبل حد Tsirelson ±22\pm 2\sqrt{2} مباشرةً بسبب ضوضاء الجهاز المُحاكاة. بعد التحقق من صحة سير العمل، ننتقل إلى العتاد الفعلي.

مثال على عتاد واسع النطاق

اختبار CHSH هو تجربة ثنائية الـ Qubit بطبيعتها، لذا لا يتوسع بجعل دائرة واحدة أكبر. بدلاً من ذلك، يتوسع بتشغيل اختبارات كثيرة بشكل متوازٍ. هنا نُبلّط الـ Backend بأكبر عدد ممكن من أزواج Bell المتقاطعة تسمح به التوصيلية (مطابقة خريطة الاقتران) ونُشغّل دائرة CHSH فرعية مستقلة على كل زوج، كل ذلك في مهمة واحدة.

هذا يحوّل CHSH إلى معيار شامل لجودة التشابك على مستوى الجهاز: بدلاً من زوج واحد مختار يدوياً، نختبر التشابك عبر جزء كبير من الشريحة في آنٍ واحد، في ظروف واقعية حيث يتعرض كل زوج للتداخل من جيرانه وأخطاء البوابات المتوازية. انتهاك المتباينة على كل زوج في آنٍ واحد يُثبت أن التشابك الحقيقي متاح في كل مكان على الجهاز.

# -------------------------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)

Output of the previous code cell

المنحنيات الخافتة هي أزواج Bell الفردية، والمنحنيات الغامقة هي متوسطها عبر الجهاز. كل زوج يرسم نفس المنحنى الجيبي المتوقع من ميكانيكا الكم، والتباين بين المنحنيات الخافتة يعكس الاختلاف في الضوضاء من زوج لآخر. في أي مكان يدخل فيه منحنى النطاقات الرمادية، يكون قد تجاوز الحد الكلاسيكي ±2\pm 2، والملخص المطبوع يؤكد أن كل زوج تقريباً ينتهك متباينة CHSH في نفس الوقت.

تقع القمم دون حد Tsirelson ±22\pm 2\sqrt{2} بسبب ضوضاء الجهاز، لكن الاستنتاج لا لبس فيه: يحافظ الـ Backend على التشابك الحقيقي عبر الشريحة بأكملها في آنٍ واحد، وليس فقط على زوج واحد مختار يدوياً. وهذا هو المعنى الذي تتوسع به تجربة CHSH: ليس كدائرة واحدة أكبر، بل كمعيار متوازٍ يُثبت التشابك في كل مكان في آنٍ واحد.

الخطوات التالية

توصيات

إذا وجدت هذا العمل مثيراً للاهتمام، فقد تهمك المواد التالية: