CHSH-Ungleichung
Nutzungsschätzung: Zwee Minuten uff'n Heron r2-Prozessor (HINWEIS: Dit is bloß 'ne Schätzung. Deine Laufzeit kann variiern.)
Hintergrund
In dem Tutorial machen wa 'n Experiment uff'n Quantenrechner, umde Verletzung von de CHSH-Ungleichung mitn Estimator-Primitiv zu zeijen.
De CHSH-Ungleichung, benannt nach de Autoren Clauser, Horne, Shimony und Holt, wird jenutzt, um Bells Theorem (1969) experimentell zu beweisen. Dit Theorem sagt aus, datte lokale Theorien mit verborgene Variabln nich alle Konsequenzen von de Verschränkung in de Quantenmechanik erklären können. De Verletzung von de CHSH-Ungleichung wird jenutzt, um zu zeijen, datte Quantenmechanik mit lokale Theorien mit verborgene Variabln nich vereinbar is. Dit is'n wichtijet Experiment für't Verständnis von de Grundlagen von de Quantenmechanik.
De Nobelpreis für Physik 2022 wurde an Alain Aspect, John Clauser und Anton Zeilinger verjebn, unter anderm für ihre Pionierarbeit in de Quanteninformationswissenschaft und besondas für ihre Experimente mit verschränkte Photonen, de de Verletzung von de Bellschen Ungleichungen jzeigt habn.
Anforderungen
Bevor du mit dem Tutorial anfängst, stell sicher, dasse Foljendes installiert hast:
- Qiskit SDK v1.0 oda neuer, mit visualization-Unterstützung
- Qiskit Runtime (
pip install qiskit-ibm-runtime) v0.22 oda 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 uff'n Quantenproblem abbildn
Für dit Experiment machen wa'n verschränktes Paar, wo wa jedes Qubit uff zwee verschiedene Basen messen. Wa kennzeichnen de Basen für't erste Qubit mit und und de Basen für't zweete Qubit mit und . Dit erlaubt uns, de CHSH-Jröße zu berechnen:
Jede Observable is entweder oda . Klar is, datt eena von de Terme jleich sein muss und de andre sein muss. Deshalb is . De Durchschnittswert von muss de Ungleichung erfülln:
Wennwa in Bezug uff , , und auswickeln, kriejn wa:
Du kannste noch 'ne weitere CHSH-Jröße definiern:
Dit führt zu 'ner weitern Ungleichung:
Wennde Quantenmechanik durch lokale Theorien mit verborgene Variabln beschriebn werdn kann, müssen de vorijen Ungleichungen wahr sein. Aba wie in dem Tutorial jezeigt wird, können diese Ungleichungen uff'n Quantenrechner verletzt werdn. Deshalb is de Quantenmechanik nich mit lokale Theorien mit verborgene Variabln vereinbar. Fallste mehr Theorie lernen willst, juck dir Entanglement in Action mitn John Watrous an. Wa machen 'n verschränktes Paar zwischen zwee Qubits in 'n Quantenrechner, indemt wa'n Bell-Zustand erzeugen. Mitn Estimator-Primitiv kannste direkt de nötijen Erwartungswerte ( und ) kriejn, um de Erwartungswerte von de beedn CHSH-Jrößen und zu berechnen. Vor de Einführung vom Estimator-Primitiv hätteste de Erwartungswerte aus de Messerjebnisse konstruiern müssen.
Wa messen dit zweete Qubit in de - und -Basen. Dit erste Qubit wird ooch in orthogonale Basen jemessen, aba mit 'n Winkel bezüglich vom zweeten Qubit, den wa zwischen und variiern werdn. Wie du sehn wirst, macht dit Estimator-Primitiv dit Ausführn von parametrisierten Schaltkreisen sehr einfach. Anstatt 'ne Reihe von CHSH-Schaltkreisen zu machen, musste bloß een CHSH-Schaltkreis mit 'n Parameter machen, de'n Messwinkel angibt, und 'ne Reihe von Phasenwerte für'n Parameter.
Schließlich werdn wa de Erjebnisse analysiern und jegen Messwinkel auftrahn. Du wirst sehn, datt für 'n bestimmten Bereich von Messwinkeln de Erwartungswerte von de CHSH-Jrößen oda sind, wat de Verletzung von de 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'
'N parametrisierten CHSH-Schaltkreis machen
Erst schreibn wa'n Schaltkreis mitn Parameter , den wa theta nennen. Dit Estimator-Primitiv kann'n Schaltkreisaufbau und de Ausgabeanalyse jigantisch vereinfachen, indemmet direkt Erwartungswerte von Observabeln liefert. Ville interessante Probleme, besondas für kurzfristije Anwendungen uff verrauschte Systeme, können in Form von Erwartungswerte formuliert werdn. Dit Estimator (V2)-Primitiv kann automatisch de Messbasis basiernd uff de bereitjestellte 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")

'Ne Liste von Phasenwerte machen, de späta zujewiesen werdn
Nachdem du'n parametrisierten CHSH-Schaltkreis jemacht hast, machste 'ne Liste von Phasenwerte, de dem Schaltkreis im nächsten Schritt zujewiesen werdn. Du kannst'n folgenden Code nutzen, um 'ne Liste von 21 Phasenwerte im Bereich von bis mit jleichem Abstand zu machen, 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]
Observabeln
Jetzt brauchen wa Observabeln, aus dene wa de Erwartungswerte berechnen können. In unserm Fall betrachtm wa orthogonale Basen für jedes Qubit, wobei de parametrisierte -Rotation für't erste Qubit de Messbasis beinah kontinuierlich bezüglich von de Basis vom zweeten Qubit variiert. Wa wähln deshalb de Observabeln , , 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 uff Quantenhardware optimiern
Um de Jesamtausführungszeit vom Job zu reduzieren, akzeptiern V2-Primitive bloß Schaltkreise und Observabeln, de de vom Zielsystem unterstützten Anweisungen und de Konnektivität entsprechn (bezeichnet als Instruction Set Architecture (ISA)-Schaltkreise und -Observabeln).
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-Observabeln
Ebenfalls müssen wa de Observabeln transformiern, umse backend-kompatibel zu machen, bevor wa Jobs mit Runtime Estimator V2 ausführn. Wa können de Transformation mit de apply_layout-Methode vom SparsePauliOp-Objekt durchführn.
isa_observable1 = observable1.apply_layout(layout=chsh_isa_circuit.layout)
isa_observable2 = observable2.apply_layout(layout=chsh_isa_circuit.layout)
Schritt 3: Ausführn mit Qiskit-Primitiven
Um dit jesamte Experiment in 'n einzijen Aufruf vom Estimator auszuführn.
Wa können 'n Qiskit Runtime Estimator-Primitiv machen, um unsre Erwartungswerte zu berechnen. De EstimatorV2.run()-Methode nimmt 'n Iterable von primitive unified blocs (PUBs). Jedes PUB is 'n 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ückjabe vom Erjeebnis im jewünschten klassischen Format
De Estimator jibt Erwartungswerte für beede Observabeln 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 de Abbildung jrenzen de Linien und jraue Bereiche de Jrenzen ab; de äußersten (strich-punktierten) Linien bejrenzen de Quantenjrenzen (), während de inneren (jestrichelten) Linien de klassischen Jrenzen () bejrenzen. Du kannst sehn, datt's Bereiche jibt, wo de CHSH-Zeugenjröße de klassischen Jrenzen überschreitet. Herzlichen Jlückwunsch! Du hast erfoljreich de Verletzung von de CHSH-Ungleichung in 'n echten Quantensystem demonstriert!
Tutorial-Umfrache
Bitte nimm an dieser kurzen Umfrache teil, um Feedback zu dem Tutorial zu jeben. Deine Erkenntnisse helfn uns, unsre Inhaltsanjebote und Benutzererfahrung zu verbessern.