CHSH-Ungleichung
Nutzungsschätzung: Zwoa Minuten auf'n Heron r2-Prozessor (HINWEIS: Des is nur a Schätzung. Dei Laufzeit kau variieren.)
Hintergrund
In dem Tutorial führen mir a Experiment auf'n Quantenrechner durch, um de Verletzung vo da CHSH-Ungleichung mit'n Estimator-Primitiv zum zeign.
De CHSH-Ungleichung, benannt noch de Autoren Clauser, Horne, Shimony und Holt, wird verwendet, um Bells Theorem (1969) experimentell zum beweis'n. Des Theorem sogt aus, dass lokale Theorien mit verborgene Variabeln net olle Konsequenzen vo da Verschränkung in da Quantenmechanik erklären kennan. De Verletzung vo da CHSH-Ungleichung wird verwendet, um zum zeign, dass de Quantenmechanik mit lokale Theorien mit verborgene Variabeln net vereinbar is. Des is a wichtigs Experiment fürs Verständnis vo de Grundlagen vo da Quantenmechanik.
Da Nobelpreis für Physik 2022 is an Alain Aspect, John Clauser und Anton Zeilinger vergeben worn, unter anderem für ihre Pionierarbeit in da Quanteninformationswissenschaft und bsonders für ihre Experimente mit verschränkte Photonen, de de Verletzung vo de Bellschen Ungleichungen demonstriert ham.
Anforderungen
Bevor du mit dem Tutorial anfangst, stell' sicher, dass du Folgendes installiert hast:
- Qiskit SDK v1.0 oda neuer, mit visualization-Unterstützung
- Qiskit Runtime (
pip install qiskit-ibm-runtime) v0.22 oda neuer
Einrichtung
# 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
# Plotting routines
import matplotlib.pyplot as plt
import matplotlib.ticker as tck
Schritt 1: Klassische Eingaben auf a Quantenproblem obbilden
Für des Experiment machen mir a verschränktes Paar, wo mir jedes Qubit auf zwoa verschiedene Basen messen. Mir kennzeichnen de Basen für's erste Qubit mit und und de Basen für's zweite Qubit mit und . Des erlaubt's uns, de CHSH-Größe zum berechnen:
Jede Observable is entweder oda . Klar is, dass oana vo de Terme gleich sei muaß und da andere sei muaß. Deshalb is . Da Durchschnittswert vo muaß de Ungleichung erfüllen:
Wann ma in Bezug auf , , und ausentwickelt, kriegen mir:
Du kennst no a weitere CHSH-Größe definieren:
Des führt zu ana weiteren Ungleichung:
Wann de Quantenmechanik durch lokale Theorien mit verborgene Variabeln beschriebn wern kau, müassen de vorherigen Ungleichungen wahr sei. Aba wia in dem Tutorial gzeigt wird, kennan diese Ungleichungen auf'n Quantenrechner verletzt wern. Deshalb is de Quantenmechanik net mit lokale Theorien mit verborgene Variabeln vereinbar. Falls du mehr Theorie lernen wüllst, schaun dir Entanglement in Action mit'n John Watrous au. Mir machen a verschränktes Paar zwischn zwoa Qubits in an Quantenrechner, indem mir'n Bell-Zustand erzeugen. Mit'n Estimator-Primitiv kennst du direkt de nötigen Erwartungswerte ( und ) kriegen, um de Erwartungswerte vo de beiden CHSH-Größen und zum berechnen. Vor da Einführung vom Estimator-Primitiv hättest du de Erwartungswerte aus de Messergebnisse konstruieren müassen.
Mir messen des zweite Qubit in de - und -Basen. Des erste Qubit wird a in orthogonale Basen gmessen, aba mit an Winkel bezüglich vom zweiten Qubit, den mir zwischn und variieren wern. Wia du sehn wirst, macht des Estimator-Primitiv des Ausführen vo parametrisierten Schaltkreisen sehr einfach. Anstatt a Reihe vo CHSH-Schaltkreisen zum erstellen, muasst du bloß oanen CHSH-Schaltkreis mit an Parameter erstellen, der'n Messwinkel angibt, und a Reihe vo Phasenwerte für'n Parameter.
Schlussendlich wern mir de Ergebnisse analysieren und gegen Messwinkel auftragen. Du wirst sehn, dass für'n bestimmten Bereich vo Messwinkeln de Erwartungswerte vo de CHSH-Größen oda san, was de Verletzung vo da CHSH-Ungleichung demonstriert.
# To run on hardware, select the backend with the fewest number of jobs in the queue
service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=127
)
backend.name
'ibm_kingston'
An parametrisierten CHSH-Schaltkreis erstellen
Zuerscht schreiben mir'n Schaltkreis mit'n Parameter , den mir theta nennan. Des Estimator-Primitiv kau'n Schaltkreisaufbau und de Ausgabeanalyse enorm vereinfachen, indem's direkt Erwartungswerte vo Observablen liefert. Vüle interessante Probleme, bsonders für kurzfristige Anwendungen auf verrauschte Systeme, kennan in Form vo Erwartungswerte formuliert wern. Des Estimator (V2)-Primitiv kau automatisch de Messbasis basierend auf da bereitgstellten Observable ändern.
theta = Parameter("$\\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")
A Liste vo Phasenwerte erstellen, de später zugewiesen wern
Nochdems du'n parametrisierten CHSH-Schaltkreis erstellt hast, erstell' a Liste vo Phasenwerte, de dem Schaltkreis im nächsten Schritt zugewiesen wern. Du kennst'n folgenden Code verwenden, um a Liste vo 21 Phasenwerte im Bereich vo bis mit gleichem Abstand zum erstellen, also , , , ..., , .
number_of_phases = 21
phases = np.linspace(0, 2 * np.pi, number_of_phases)
# Phases need to be expressed as list of lists in order to work
individual_phases = [[ph] for ph in phases]
Observablen
Jetzt brauchen mir Observablen, aus denen mir de Erwartungswerte berechnen kennan. In unserm Fall betrachten mir orthogonale Basen für jedes Qubit, wobei de parametrisierte -Rotation für's erste Qubit de Messbasis beinahe kontinuierlich bezüglich vo da Basis vom zweiten Qubit variiert. Mir wählen deshalb de Observablen , , und .
# <CHSH1> = <AB> - <Ab> + <aB> + <ab> -> <ZZ> - <ZX> + <XZ> + <XX>
observable1 = SparsePauliOp.from_list(
[("ZZ", 1), ("ZX", -1), ("XZ", 1), ("XX", 1)]
)
# <CHSH2> = <AB> + <Ab> - <aB> + <ab> -> <ZZ> + <ZX> - <XZ> + <XX>
observable2 = SparsePauliOp.from_list(
[("ZZ", 1), ("ZX", 1), ("XZ", -1), ("XX", 1)]
)
Schritt 2: Problem für de Ausführung auf Quantenhardware optimieren
Um de Gesamtausführungszeit vom Job zum reduzieren, akzeptieren V2-Primitive bloß Schaltkreise und Observablen, de de vom Zielsystem unterstützten Anweisungen und de Konnektivität entsprechen (bezeichnet als Instruction Set Architecture (ISA)-Schaltkreise und -Observablen).
ISA-Schaltkreis
target = backend.target
pm = generate_preset_pass_manager(target=target, optimization_level=3)
chsh_isa_circuit = pm.run(chsh_circuit)
chsh_isa_circuit.draw(output="mpl", idle_wires=False, style="iqp")
ISA-Observablen
Ebenso müassen mir de Observablen transformieren, um's backend-kompatibel zum machen, bevor mir Jobs mit Runtime Estimator V2 ausführen. Mir kennan de Transformation mit da apply_layout-Methode vom SparsePauliOp-Objekt durchführen.
isa_observable1 = observable1.apply_layout(layout=chsh_isa_circuit.layout)
isa_observable2 = observable2.apply_layout(layout=chsh_isa_circuit.layout)
Schritt 3: Ausführen mit Qiskit-Primitiven
Um des gesamte Experiment in oam einzigen Aufruf vom Estimator auszuführen.
Mir kennan a Qiskit Runtime Estimator-Primitiv erstellen, um unsre Erwartungswerte zum berechnen. De EstimatorV2.run()-Methode nimmt a Iterable vo primitive unified blocs (PUBs). Jedes PUB is a Iterable im Format (circuit, observables, parameter_values: Optional, precision: Optional).
# To run on a local simulator:
# Use the StatevectorEstimator from qiskit.primitives instead.
estimator = Estimator(mode=backend)
pub = (
chsh_isa_circuit, # ISA circuit
[[isa_observable1], [isa_observable2]], # ISA Observables
individual_phases, # Parameter values
)
job_result = estimator.run(pubs=[pub]).result()
Schritt 4: Nachbearbeitung und Rückgabe vom Ergebnis im gewünschten klassischen Format
Da Estimator gibt Erwartungswerte für beide Observablen zurück, und .
chsh1_est = job_result[0].data.evs[0]
chsh2_est = job_result[0].data.evs[1]
fig, ax = plt.subplots(figsize=(10, 6))
# results from hardware
ax.plot(phases / np.pi, chsh1_est, "o-", label="CHSH1", zorder=3)
ax.plot(phases / np.pi, chsh2_est, "o-", label="CHSH2", zorder=3)
# classical bound +-2
ax.axhline(y=2, color="0.9", linestyle="--")
ax.axhline(y=-2, color="0.9", linestyle="--")
# quantum bound, +-2√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)
# set x tick labels to the unit of pi
ax.xaxis.set_major_formatter(tck.FormatStrFormatter("%g $\\pi$"))
ax.xaxis.set_major_locator(tck.MultipleLocator(base=0.5))
# set labels, and legend
plt.xlabel("Theta")
plt.ylabel("CHSH witness")
plt.legend()
plt.show()
In da Abbildung grenzen de Linien und grauen Bereiche de Grenzen ab; de äußersten (strich-punktierten) Linien begrenzen de Quantengrenzen (), während de inneren (gestrichelten) Linien de klassischen Grenzen () begrenzen. Du kennst sehn, dass's Bereiche gibt, wo de CHSH-Zeugengröße de klassischen Grenzen überschreitet. Herzlichen Glückwunsch! Du hast erfolgreich de Verletzung vo da CHSH-Ungleichung in an echten Quantensystem demonstriert!
Tutorial-Umfrage
Bitte nimm an dieser kurzen Umfrage teil, um Feedback zu dem Tutorial zum geben. Deine Erkenntnisse helfen uns, unsre Inhaltsangebote und Benutzererfahrung zum verbessern.