CHSH-Ungleichung
Nutzungsschätzung: Zwee Minudn aufm Heron r2-Prozessor (HINNWEIS: Das is bloß ne Schätzung. Dei Laufzeit gann variern.)
Hindergrundn
In dem Tutorial machn mer'n Experiment aufm Quanterechner, um de Verletzung von de CHSH-Ungleichung mitn Estimator-Primitiv zu zeechn.
De CHSH-Ungleichung, benannt nach de Autorn Clauser, Horne, Shimony un Holt, werd genutzt, um Bells Theorem (1969) experimentell zu beweis'n. Das Theorem sacht aus, dass lokale Theorieen mit verborgne Variabln nich alle Gonsequenzn von de Verschränkung in de Quantemechanik erglärn gönn'. De Verletzung von de CHSH-Ungleichung werd genutzt, um zu zeechn, dass de Quantemechanik mit lokale Theorieen mit verborgne Variabln nich vereinbar is. Das is'n wichtichs Experiment för's Verständnis von de Grundlagn von de Quantemechanik.
De Nobelbreis för Physig 2022 wor an Alain Aspect, John Clauser un Anton Zeilinger vergeem worden, unnerm annern för ihre Pionierarbeit in de Quanteinformationswissenschaft un besonders för ihre Experimende mit verschrängte Photonen, de de Verletzung von de Bellschn Ungleichungn demonstriert ham.
Anforderungn
Bevorn de mit dem Tutorial anfängst, stell' secher, dass de Folgends installiert hast:
- Qiskit SDK v1.0 oder neier, mit visualization-Unnerstützung
- Qiskit Runtime (
pip install qiskit-ibm-runtime) v0.22 oder neier
Eirichtung
# 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: Glassische Eingabn auf'n Quantebroblem abbild'n
För das Experiment machn mer'n verschränktes Baar, wo mer jedes Qubit auf zwee verschiedne Basn mess'n. Mer bezeechn' de Basn förn erschte Qubit mit un un de Basn förn zweete Qubit mit un . Das erlaabt's uns, de CHSH-Größe zu berechnen:
Jede Observable is entweder oder . Glar is, dass eener von de Terme gleich sein muss un de annere sein muss. Deshalb is . De Durchschnittswert von muss de Ungleichung erfülln:
Wennmer in Bezug auf , , un auswiggeln, griechn mer:
Mer gönn' noch ne weitere CHSH-Größe definieren:
Das führt zu ner weitern Ungleichung:
Wenn de Quantemechanik durch lokale Theorieen mit verborgne Variabln beschriebn wern gann, müssn de vorischn Ungleichungn wohr sein. Aber wie in dem Tutorial gezeecht werd, gönn' diese Ungleichungn aufm Quanterechner verletzt wern. Deshalb is de Quantemechanik nich mit lokale Theorieen mit verborgne Variabln vereinbar. Falls de mehr Theorie lern willst, gugg dir Entanglement in Action mitn John Watrous an. Mer machn'n verschränktes Baar zwischn zwee Qubits in nem Quanterechner, indem mer'n Bell-Zustand erzeugn. Mitn Estimator-Primitiv gönn' de direggt de nötichn Erwartungswerte ( un ) griechn, um de Erwartungswerte von de beedn CHSH-Größn un zu berechnen. Vorn Einführung vom Estimator-Primitiv häddn de de Erwartungswerte aus de Messergeebnisse konstruiern müss'n.
Mer mess'n das zweete Qubit in de - un -Basn. Das erschte Qubit werd aaoch in orthogonale Basn gemess'n, aber mitn Winkel bezüchlich vom zweeten Qubit, den mer zwischn un variern wern. Wie de sehn werscht, macht das Estimator-Primitiv das Ausführn von parametrisierten Schaltgreesn sehr eenfach. Anstatt ne Reihe von CHSH-Schaltgreesn zu machn, muss de bloß eenen CHSH-Schaltgrees mitn Parameter machn, der'n Messwinkel angibt, un ne Reihe von Phasenwerte förn Parameter.
Schließlich wern mer de Ergeebnisse analysiern un gegn Messwinkel auftraan. De werscht sehn, dass för'n bestimmdn Bereich von Messwinkeln de Erwartungswerte von de CHSH-Größn oder sin, was 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-Schaltgrees machn
Zuerst schreebmer'n Schaltgrees mitn Parameter , den mer theta nenn'. Das Estimator-Primitiv gann'n Schaltgreesaufbau un de Ausgabeanalyse riesig vereinfachen, indemses direggt Erwartungswerte von Observabln liefert. Viele interessande Probleme, besonders för kurzfristige Anwendungn auf verrauschte Systeme, gönn' in Form von Erwartungswerte formuliert wern. Das Estimator (V2)-Primitiv gann automatisch de Messbasis basiernd auf de bereetgestellte Observable ännern.
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 Lischde von Phasenwerte machn, de schbäder zugewiesen wern
Nachdem de'n parametrisierten CHSH-Schaltgrees gemacht hast, mach' ne Lischde von Phasenwerte, de dem Schaltgrees im nächsten Schritt zugewiesen wern. De gönnst folgenden Code nutz'n, um ne Lischde von 21 Phasenwerte im Bereich von bis mit gleichm Abstand zu machn, 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]
Observabln
Jetzt brauchn mer Observabln, aus denen mer de Erwartungswerte berechnen gönn'. In unserm Fall betrachtn mer orthogonale Basn för jedes Qubit, wobei de parametrisierte -Rotation förn erschte Qubit de Messbasis beinah gontinuierlich bezüchlich von de Basis vom zweeten Qubit variiert. Mer wähln deshalb de Observabln , , un .
# <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: Broblem för de Ausführung auf Quantehardware obtimiern
Um de Gesamtausführungszeet vom Job zu reduzieren, aggzebtiern V2-Primitive bloß Schaltgreese un Observabln, de de vom Zielsystem unnerstützten Anweisungn un de Gonneggtivität entsprechn (bezeechnet als Instruction Set Architecture (ISA)-Schaltgreese un -Observabln).
ISA-Schaltgrees
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-Observabln
Ebenfalls müssn mer de Observabln transformiern, um se backend-gompatibel zu machn, bevorn mer Jobs mit Runtime Estimator V2 ausführn. Mer gönn' de Transformation mit de apply_layout-Methode vom SparsePauliOp-Objeggd 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-Primitive
Um das gesambte Experiment in eenm einzichn Aufruf vom Estimator auszuführn.
Mer gönn'n Qiskit Runtime Estimator-Primitiv machn, um unsere 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: Nachbearbeetung un Rüggabe vom Ergeebnis im gewünschdn glassischen Format
De Estimator gibt Erwartungswerte för beede Observabln zurügg, un .
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 Abbieldung grenzn de Linieen un grauen Bereiche de Grenzn ab; de äußersdn (strich-bungktierten) Linieen begrenzn de Quantegrenzn (), während de innern (gestrichelden) Linieen de glassischn Grenzn () begrenzn. De gönnst sehn, dass's Bereiche gibt, wo de CHSH-Zeiechnsgröße de glassischn Grenzn überschreet. Herzlichn Glüggwunsch! De hast erfolgreich de Verletzung von de CHSH-Ungleichung in nem echden Quantesystem demonstriert!
Tutorial-Umfraache
Bidde nimm' an dieser kurzn Umfraache deel, um Feedbagg zu dem Tutorial zu gebn. Dei Ergenndnisse helfn uns, unsere Inhaltsangebode un Benutzererfahrung zu verbesserdn.