CHSH-Ungleichung
Nutzungsschätzung: Zwei Minuten auf einem Heron r2-Prozessor (HINWEIS: Dies ist nur eine Schätzung. Deine Laufzeit kann variieren.)
Hintergrund
In diesem Tutorial führst du ein Experiment auf einem Quantencomputer aus, um die Verletzung der CHSH-Ungleichung mit dem Estimator-Primitiv zu demonstrieren.
Die CHSH-Ungleichung, benannt nach den Autoren Clauser, Horne, Shimony und Holt, wird verwendet, um Bells Theorem (1969) experimentell zu beweisen. Dieses Theorem besagt, dass lokale Theorien mit verborgenen Variablen einige Konsequenzen der Verschränkung in der Quantenmechanik nicht erklären können. Die Verletzung der CHSH-Ungleichung wird verwendet, um zu zeigen, dass die Quantenmechanik mit lokalen Theorien mit verborgenen Variablen nicht vereinbar ist. Dies ist ein wichtiges Experiment zum Verständnis der Grundlagen der Quantenmechanik.
Der Nobelpreis für Physik 2022 wurde an Alain Aspect, John Clauser und Anton Zeilinger verliehen, unter anderem für ihre Pionierarbeit in der Quanteninformationswissenschaft und insbesondere für ihre Experimente mit verschränkten Photonen, die die Verletzung der Bellschen Ungleichungen demonstrierten.
Anforderungen
Stelle vor Beginn dieses Tutorials sicher, dass du Folgendes installiert hast:
- Qiskit SDK v1.0 oder neuer, mit Visualisierung-Unterstützung
- Qiskit Runtime (
pip install qiskit-ibm-runtime) v0.22 oder neuer
Einrichtung
# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit 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
# Plotting routines
import matplotlib.pyplot as plt
import matplotlib.ticker as tck
Schritt 1: Klassische Eingaben auf ein Quantenproblem abbilden
Für dieses Experiment erstellen wir ein verschränktes Paar, bei dem wir jedes Qubit auf zwei verschiedenen Basen messen. Wir bezeichnen die Basen für das erste Qubit mit und und die Basen für das zweite Qubit mit und . Dies ermöglicht es uns, die CHSH-Größe zu berechnen:
Jede Observable ist entweder oder . Klar ist, dass einer der Terme gleich sein muss und der andere sein muss. Daher ist . Der Durchschnittswert von muss die Ungleichung erfüllen:
Die Entwicklung von in Bezug auf , , und ergibt:
Du kannst eine weitere CHSH-Größe definieren:
Dies führt zu einer weiteren Ungleichung:
Wenn die Quantenmechanik durch lokale Theorien mit verborgenen Variablen beschrieben werden kann, müssen die vorherigen Ungleichungen wahr sein. Wie jedoch in diesem Tutorial demonstriert wird, können diese Ungleichungen auf einem Quantencomputer verletzt werden. Daher ist die Quantenmechanik nicht mit lokalen Theorien mit verborgenen Variablen vereinbar. Falls du mehr Theorie lernen möchtest, erkunde Entanglement in Action mit John Watrous. Du wirst ein verschränktes Paar zwischen zwei Qubits in einem Quantencomputer erstellen, indem du den Bell-Zustand erzeugst. Mit dem Estimator-Primitiv kannst du direkt die benötigten Erwartungswerte ( und ) erhalten, um die Erwartungswerte der beiden CHSH-Größen und zu berechnen. Vor der Einführung des Estimator-Primitivs musstest du die Erwartungswerte aus den Messergebnissen konstruieren.
Du wirst das zweite Qubit in den - und -Basen messen. Das erste Qubit wird ebenfalls in orthogonalen Basen gemessen, jedoch mit einem Winkel bezüglich des zweiten Qubits, den wir zwischen und variieren werden. Wie du sehen wirst, macht das Estimator-Primitiv das Ausführen parametrisierter Schaltkreise sehr einfach. Anstatt eine Reihe von CHSH-Schaltkreisen zu erstellen, musst du nur einen CHSH-Schaltkreis mit einem Parameter erstellen, der den Messwinkel angibt, und eine Reihe von Phasenwerten für den Parameter.
Schließlich wirst du die Ergebnisse analysieren und gegen den Messwinkel auftragen. Du wirst sehen, dass für einen bestimmten Bereich von Messwinkeln die Erwartungswerte der CHSH-Größen oder sind, was die Verletzung der 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'
Einen parametrisierten CHSH-Schaltkreis erstellen
Zuerst schreiben wir den Schaltkreis mit dem Parameter , den wir theta nennen. Das Estimator-Primitiv kann den Schaltkreisaufbau und die Ausgabeanalyse enorm vereinfachen, indem es direkt Erwartungswerte von Observablen liefert. Viele interessante Probleme, insbesondere für kurzfristige Anwendungen auf verrauschten Systemen, können in Form von Erwartungswerten formuliert werden. Das Estimator (V2)-Primitiv kann automatisch die Messbasis basierend auf der bereitgestellten 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")
Eine Liste von Phasenwerten erstellen, die später zugewiesen werden
Nachdem du den parametrisierten CHSH-Schaltkreis erstellt hast, erstelle eine Liste von Phasenwerten, die dem Schaltkreis im nächsten Schritt zugewiesen werden. Du kannst den folgenden Code verwenden, um eine Liste von 21 Phasenwerten im Bereich von bis mit gleichem Abstand zu erstellen, d.h. , , , ..., , .
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
Nun benötigen wir Observablen, aus denen wir die Erwartungswerte berechnen können. In unserem Fall betrachten wir orthogonale Basen für jedes Qubit, wobei die parametrisierte -Rotation für das erste Qubit die Messbasis nahezu kontinuierlich in Bezug auf die Basis des zweiten Qubits variiert. Wir wählen daher die 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 die Ausführung auf Quantenhardware optimieren
Um die Gesamtausführungszeit des Jobs zu reduzieren, akzeptieren V2-Primitive nur Schaltkreise und Observablen, die den vom Zielsystem unterstützten Anweisungen und der 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üssen wir die Observablen transformieren, um sie backend-kompatibel zu machen, bevor wir Jobs mit Runtime Estimator V2 ausführen. Wir können die Transformation mit der apply_layout-Methode des SparsePauliOp-Objekts 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 das gesamte Experiment in einem einzigen Aufruf des Estimator auszuführen.
Wir können ein Qiskit Runtime Estimator-Primitiv erstellen, um unsere Erwartungswerte zu berechnen. Die EstimatorV2.run()-Methode akzeptiert ein Iterable von primitive unified blocs (PUBs). Jedes PUB ist ein 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 des Ergebnisses im gewünschten klassischen Format
Der 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 der Abbildung grenzen die Linien und grauen Bereiche die Grenzen ab; die äußersten (strichpunktierten) Linien begrenzen die Quantengrenzen (), während die inneren (gestrichelten) Linien die klassischen Grenzen () begrenzen. Du kannst sehen, dass es Bereiche gibt, in denen die CHSH-Zeugengröße die klassischen Grenzen überschreitet. Herzlichen Glückwunsch! Du hast erfolgreich die Verletzung der CHSH-Ungleichung in einem echten Quantensystem demonstriert!
Tutorial-Umfrage
Bitte nimm an dieser kurzen Umfrage teil, um Feedback zu diesem Tutorial zu geben. Deine Erkenntnisse helfen uns, unsere Inhaltsangebote und Benutzererfahrung zu verbessern.