Aller au contenu principal

Inégalité CHSH

Estimation d'utilisation : deux minutes sur un processeur Heron r2 (REMARQUE : il s'agit uniquement d'une estimation. Votre temps d'exécution peut varier.)

Contexte

Dans ce tutoriel, vous allez exécuter une expérience sur un ordinateur quantique pour démontrer la violation de l'inégalité CHSH avec la primitive Estimator.

L'inégalité CHSH, nommée d'après ses auteurs Clauser, Horne, Shimony et Holt, est utilisée pour prouver expérimentalement le théorème de Bell (1969). Ce théorème affirme que les théories à variables cachées locales ne peuvent pas rendre compte de certaines conséquences de l'intrication en mécanique quantique. La violation de l'inégalité CHSH est utilisée pour montrer que la mécanique quantique est incompatible avec les théories à variables cachées locales. Il s'agit d'une expérience importante pour comprendre les fondements de la mécanique quantique.

Le prix Nobel de physique 2022 a été décerné à Alain Aspect, John Clauser et Anton Zeilinger en partie pour leurs travaux pionniers en science de l'information quantique, et en particulier pour leurs expériences avec des photons intriqués démontrant la violation des inégalités de Bell.

Prérequis

Avant de commencer ce tutoriel, assurez-vous que les éléments suivants sont installés :

  • Qiskit SDK v1.0 ou version ultérieure, avec le support de visualisation
  • Qiskit Runtime (pip install qiskit-ibm-runtime) v0.22 ou version ultérieure

Configuration

# 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

Étape 1 : Formuler les entrées classiques en un problème quantique

Pour cette expérience, nous allons créer une paire intriquée sur laquelle nous mesurerons chaque qubit dans deux bases différentes. Nous désignerons les bases du premier qubit par AA et aa, et les bases du second qubit par BB et bb. Cela nous permet de calculer la quantité CHSH S1S_1 :

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

Chaque observable vaut soit +1+1, soit 1-1. De toute évidence, l'un des termes B±bB\pm b doit être 00, et l'autre doit être ±2\pm 2. Par conséquent, S1=±2S_1 = \pm 2. La valeur moyenne de S1S_1 doit satisfaire l'inégalité :

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

En développant S1S_1 en fonction de AA, aa, BB et bb, on obtient :

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

Vous pouvez définir une autre quantité CHSH S2S_2 :

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

Cela conduit à une autre inégalité :

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

Si la mécanique quantique peut être décrite par des théories à variables cachées locales, les inégalités précédentes doivent être vérifiées. Cependant, comme le démontre ce tutoriel, ces inégalités peuvent être violées sur un ordinateur quantique. Par conséquent, la mécanique quantique n'est pas compatible avec les théories à variables cachées locales. Si vous souhaitez approfondir la théorie, explorez l'intrication en action avec John Watrous. Vous allez créer une paire intriquée entre deux qubits dans un ordinateur quantique en créant l'état de Bell Φ+=00+112|\Phi^+\rangle = \frac{|00\rangle + |11\rangle}{\sqrt{2}}. En utilisant la primitive Estimator, vous pouvez obtenir directement les valeurs d'espérance nécessaires (AB,Ab,aB\langle AB \rangle, \langle Ab \rangle, \langle aB \rangle et ab\langle ab \rangle) pour calculer les valeurs d'espérance des deux quantités CHSH S1\langle S_1\rangle et S2\langle S_2\rangle. Avant l'introduction de la primitive Estimator, il fallait construire les valeurs d'espérance à partir des résultats de mesure.

Vous mesurerez le second qubit dans les bases ZZ et XX. Le premier qubit sera également mesuré dans des bases orthogonales, mais avec un angle par rapport au second qubit, que nous allons faire varier entre 00 et 2π2\pi. Comme vous le verrez, la primitive Estimator rend l'exécution de circuits paramétrés très facile. Plutôt que de créer une série de circuits CHSH, vous n'avez besoin de créer qu'un seul circuit CHSH avec un paramètre spécifiant l'angle de mesure et une série de valeurs de phase pour ce paramètre.

Enfin, vous analyserez les résultats et les tracerez en fonction de l'angle de mesure. Vous verrez que pour certaines plages d'angles de mesure, les valeurs d'espérance des quantités CHSH S1>2|\langle S_1\rangle| > 2 ou S2>2|\langle S_2\rangle| > 2, ce qui démontre la violation de l'inégalité CHSH.

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

Créer un circuit CHSH paramétré

Tout d'abord, nous écrivons le circuit avec le paramètre θ\theta, que nous appelons theta. La primitive Estimator peut considérablement simplifier la construction des circuits et l'analyse des résultats en fournissant directement les valeurs d'espérance des observables. De nombreux problèmes d'intérêt, en particulier pour les applications à court terme sur des systèmes bruités, peuvent être formulés en termes de valeurs d'espérance. La primitive Estimator (V2) peut automatiquement changer la base de mesure en fonction de l'observable fourni.

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

Output of the previous code cell

Créer une liste de valeurs de phase à assigner ultérieurement

Après avoir créé le circuit CHSH paramétré, vous allez créer une liste de valeurs de phase à assigner au circuit à l'étape suivante. Vous pouvez utiliser le code suivant pour créer une liste de 21 valeurs de phase allant de 00 à 2π2 \pi avec un espacement régulier, c'est-à-dire 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 list of lists in order to work
individual_phases = [[ph] for ph in phases]

Observables

Nous avons maintenant besoin d'observables à partir desquels calculer les valeurs d'espérance. Dans notre cas, nous examinons des bases orthogonales pour chaque qubit, en laissant la rotation paramétrée en YY du premier qubit balayer la base de mesure de manière quasi continue par rapport à la base du second qubit. Nous choisirons donc les observables ZZZZ, ZXZX, XZXZ et XXXX.

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

Étape 2 : Optimiser le problème pour l'exécution sur du matériel quantique

Pour réduire le temps total d'exécution des tâches, les primitives V2 n'acceptent que des circuits et des observables conformes aux instructions et à la connectivité prises en charge par le système cible (appelés circuits et observables ISA, pour Instruction Set Architecture).

Circuit ISA

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

Output of the previous code cell

Observables ISA

De même, nous devons transformer les observables pour les rendre compatibles avec le backend avant d'exécuter les tâches avec Runtime Estimator V2. Nous pouvons effectuer cette transformation en utilisant la méthode apply_layout de l'objet SparsePauliOp.

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

Étape 3 : Exécuter à l'aide des primitives Qiskit

Afin d'exécuter l'ensemble de l'expérience en un seul appel à l'Estimator. Nous pouvons créer une primitive Qiskit Runtime Estimator pour calculer nos valeurs d'espérance. La méthode EstimatorV2.run() prend un itérable de primitive unified blocs (PUBs). Chaque PUB est un itérable au 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()

Étape 4 : Post-traiter et renvoyer le résultat dans le format classique souhaité

L'estimateur renvoie les valeurs d'espérance pour les deux observables, ZZZX+XZ+XX\langle ZZ \rangle - \langle ZX \rangle + \langle XZ \rangle + \langle XX \rangle et ZZ+ZXXZ+XX\langle ZZ \rangle + \langle ZX \rangle - \langle XZ \rangle + \langle XX \rangle.

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

Output of the previous code cell

Dans la figure, les lignes et les zones grises délimitent les bornes ; les lignes extérieures (en pointillés alternés) délimitent les bornes quantiques (±2\pm 2), tandis que les lignes intérieures (en tirets) délimitent les bornes classiques (±22\pm 2\sqrt{2}). Vous pouvez observer qu'il existe des régions où les quantités témoins CHSH dépassent les bornes classiques. Félicitations ! Vous avez démontré avec succès la violation de l'inégalité CHSH dans un véritable système quantique !

Enquête sur le tutoriel

Veuillez répondre à cette courte enquête pour nous faire part de vos commentaires sur ce tutoriel. Vos retours nous aideront à améliorer notre contenu et l'expérience utilisateur.

Lien vers l'enquête