Implémentation Qiskit
Dans cette leçon, nous mettons en œuvre quelques-unes des idées de la leçon sur l'intrication en action, à l'aide de Qiskit.
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-aer
from qiskit import __version__
print(__version__)
2.1.1
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit_aer import AerSimulator
from qiskit.visualization import plot_histogram, array_to_latex
from qiskit.result import marginal_distribution
from qiskit.circuit.library import UGate
from numpy import pi, random
Voici une implémentation en circuit quantique du protocole de téléportation.
qubit = QuantumRegister(1, "Q")
ebit0 = QuantumRegister(1, "A")
ebit1 = QuantumRegister(1, "B")
a = ClassicalRegister(1, "a")
b = ClassicalRegister(1, "b")
protocol = QuantumCircuit(qubit, ebit0, ebit1, a, b)
# Prepare ebit used for teleportation
protocol.h(ebit0)
protocol.cx(ebit0, ebit1)
protocol.barrier()
# Alice's operations
protocol.cx(qubit, ebit0)
protocol.h(qubit)
protocol.barrier()
# Alice measures and sends classical bits to Bob
protocol.measure(ebit0, a)
protocol.measure(qubit, b)
protocol.barrier()
# Bob uses the classical bits to conditionally apply gates
with protocol.if_test((a, 1)):
protocol.x(ebit1)
with protocol.if_test((b, 1)):
protocol.z(ebit1)
display(protocol.draw(output="mpl"))

Le circuit utilise quelques fonctionnalités de Qiskit que nous n'avons pas encore vues dans les leçons précédentes, notamment les fonctions barrier et if_test.
La fonction barrier crée une séparation visuelle rendant le schéma du circuit plus lisible, et elle empêche également Qiskit d'effectuer diverses simplifications et optimisations à travers la barrière lors de la compilation, quand les circuits sont exécutés sur du vrai matériel.
La fonction if_test applique une opération de façon conditionnelle en fonction d'un bit ou d'un registre classique.
Le circuit initialise d'abord dans l'état (ce qui ne fait pas partie du protocole lui-même), puis viennent les opérations d'Alice, ses mesures, et enfin les opérations de Bob. Pour vérifier que le protocole fonctionne correctement, nous allons appliquer une porte à qubit unique générée aléatoirement à l'état initialisé de afin d'obtenir un vecteur d'état quantique aléatoire à téléporter. En appliquant l'inverse (c'est-à-dire la transposée conjuguée) de cette porte à après l'exécution du protocole, on peut vérifier que l'état a bien été téléporté en mesurant pour s'assurer qu'il est revenu à l'état .
D'abord, choisissons aléatoirement une porte unitaire à qubit.
random_gate = UGate(
theta=random.random() * 2 * pi,
phi=random.random() * 2 * pi,
lam=random.random() * 2 * pi,
)
display(array_to_latex(random_gate.to_matrix()))
Nous allons maintenant créer un nouveau circuit de test qui commence par appliquer notre porte aléatoire à puis exécute le circuit de téléportation, et enfin applique l'inverse de notre porte aléatoire au qubit et mesure. Le résultat devrait être avec certitude.
# Create a new circuit including the same bits and qubits used in the
# teleportation protocol.
test = QuantumCircuit(qubit, ebit0, ebit1, a, b)
# Start with the randomly selected gate on Q
test.append(random_gate, qubit)
test.barrier()
# Append the entire teleportation protocol from above.
test = test.compose(protocol)
test.barrier()
# Finally, apply the inverse of the random unitary to B and measure.
test.append(random_gate.inverse(), ebit1)
result = ClassicalRegister(1, "Result")
test.add_register(result)
test.measure(ebit1, result)
display(test.draw(output="mpl"))

Enfin, exécutons le simulateur Aer sur ce circuit et affichons un histogramme des résultats. Nous verrons les statistiques pour les trois bits classiques : le bit du bas/de gauche devrait toujours valoir ce qui indique que le qubit a bien été téléporté dans tandis que les deux autres bits devraient être à peu près uniformes.
result = AerSimulator().run(test).result()
statistics = result.get_counts()
display(plot_histogram(statistics))
On peut aussi filtrer les statistiques pour se concentrer uniquement sur le qubit de résultat du test si on le souhaite, comme ceci :
filtered_statistics = marginal_distribution(statistics, [2])
display(plot_histogram(filtered_statistics))
Codage superdense
Le codage superdense est un protocole qui, en un certain sens, vise un objectif complémentaire à celui de la téléportation. Plutôt que de permettre la transmission d'un qubit en utilisant deux bits classiques de communication (au coût d'un e-bit d'intrication), il permet la transmission de deux bits classiques en utilisant un qubit de communication quantique (toujours au coût d'un e-bit d'intrication).
Plus en détail, nous avons un émetteur (Alice) et un récepteur (Bob) qui partagent un e-bit d'intrication. Selon les conventions établies pour la leçon, cela signifie qu'Alice détient un qubit Bob détient un qubit et ensemble la paire est dans l'état Alice souhaite transmettre deux bits classiques à Bob, que nous noterons et et elle y parviendra en lui envoyant un qubit.
Il est raisonnable de considérer cet exploit comme moins intéressant que celui accompli par la téléportation. L'envoi de qubits sera vraisemblablement bien plus difficile que celui de bits classiques dans un avenir prévisible, de sorte qu'échanger un qubit de communication quantique contre deux bits de communication classique, au coût d'un e-bit de surcroît, semble à peine en valoir la peine. Cependant, cela n'implique pas que le codage superdense n'est pas intéressant, car il l'est assurément.
Dans le thème de la leçon, l'une des raisons pour lesquelles le codage superdense est intéressant est qu'il démontre une utilisation concrète et (dans le contexte de la théorie de l'information) plutôt frappante de l'intrication. Un théorème célèbre de la théorie de l'information quantique, connu sous le nom du théorème de Holevo, implique que sans l'utilisation d'un état intriqué partagé, il est impossible de communiquer plus d'un bit d'information classique en envoyant un seul qubit. (Le théorème de Holevo est plus général que cela. Son énoncé précis est technique et nécessite des explications, mais c'en est une conséquence.) Ainsi, grâce au codage superdense, l'intrication partagée permet effectivement de doubler la capacité de transport d'information classique lors de l'envoi de qubits.
Protocole
Le schéma de circuit quantique suivant décrit le protocole de codage superdense :

En résumé, voici ce qu'Alice fait :
-
Si Alice applique une porte sur son qubit (et si elle ne fait rien).
-
Si Alice applique une porte sur son qubit (et si elle ne fait rien).
Alice envoie ensuite son qubit à Bob.
Ce que fait Bob à la réception du qubit consiste d'abord à appliquer une porte CNOT, avec comme contrôle et comme cible, puis il applique une porte Hadamard à Il mesure ensuite pour obtenir et pour obtenir avec des mesures en base standard dans les deux cas.
Analyse
L'idée sous-jacente à ce protocole est simple : Alice choisit effectivement quel état de Bell elle souhaite partager avec Bob, elle lui envoie son qubit, et Bob mesure pour déterminer quel état de Bell Alice a choisi.
Autrement dit, ils partagent initialement et selon les bits et Alice laisse cet état tel quel ou le fait basculer vers l'un des autres états de Bell en appliquant ou à son qubit
Les actions de Bob ont les effets suivants sur les quatre états de Bell :
Cela peut être vérifié directement en calculant les résultats des opérations de Bob sur ces états un par un.
Ainsi, lorsque Bob effectue ses mesures, il est capable de déterminer quel état de Bell Alice a choisi. Vérifier que le protocole fonctionne correctement revient à examiner chaque cas :
-
Si alors l'état de quand Bob reçoit est Il transforme cet état en et obtient
-
Si alors l'état de quand Bob reçoit est Il transforme cet état en et obtient
-
Si alors l'état de quand Bob reçoit est Il transforme cet état en et obtient
-
Si alors l'état de quand Bob reçoit est Il transforme cet état en et obtient (Le facteur de phase moins un n'a aucun effet ici.)
Implémentation du codage superdense
Voici une implémentation simple du codage superdense où nous spécifions le circuit lui-même en fonction des bits à transmettre. Nous allons d'abord choisir deux bits à transmettre. (Plus tard, nous les choisirons aléatoirement, mais pour l'instant nous faisons simplement un choix arbitraire.)
c = "1"
d = "0"
Maintenant, nous allons construire le circuit en conséquence. Ici, nous laisserons Qiskit utiliser les noms par défaut pour les qubits : pour le qubit du haut et pour celui du bas.
protocol = QuantumCircuit(2)
# Prepare ebit used for superdense coding
protocol.h(0)
protocol.cx(0, 1)
protocol.barrier()
# Alice's operations
if d == "1":
protocol.z(0)
if c == "1":
protocol.x(0)
protocol.barrier()
# Bob's actions
protocol.cx(0, 1)
protocol.h(0)
protocol.measure_all()
display(protocol.draw(output="mpl"))

Il n'y a pas grand-chose de nouveau ici, si ce n'est la fonction measure_all, qui mesure tous les qubits et place les résultats dans un unique registre classique (ayant donc deux bits dans ce cas).
L'exécution du simulateur Aer produit le résultat attendu.
result = AerSimulator().run(protocol).result()
statistics = result.get_counts()
for outcome, frequency in statistics.items():
print(f"Measured {outcome} with frequency {frequency}")
display(plot_histogram(statistics))
Measured 10 with frequency 1024
Utilisons maintenant un qubit supplémentaire comme générateur de bits aléatoires — essentiellement pour lancer des pièces de monnaie équilibrées. Nous l'utiliserons pour choisir aléatoirement et puis exécuterons le protocole de codage superdense.
rbg = QuantumRegister(1, "coin")
ebit0 = QuantumRegister(1, "A")
ebit1 = QuantumRegister(1, "B")
Alice_c = ClassicalRegister(1, "Alice c")
Alice_d = ClassicalRegister(1, "Alice d")
test = QuantumCircuit(rbg, ebit0, ebit1, Alice_d, Alice_c)
# Initialize the ebit
test.h(ebit0)
test.cx(ebit0, ebit1)
test.barrier()
# Use the 'coin' qubit twice to generate Alice's bits c and d.
test.h(rbg)
test.measure(rbg, Alice_c)
test.h(rbg)
test.measure(rbg, Alice_d)
test.barrier()
# Now the protocol runs, starting with Alice's actions, which depend
# on her bits.
with test.if_test((Alice_d, 1), label="Z"):
test.z(ebit0)
with test.if_test((Alice_c, 1), label="X"):
test.x(ebit0)
test.barrier()
# Bob's actions
test.cx(ebit0, ebit1)
test.h(ebit0)
test.barrier()
Bob_c = ClassicalRegister(1, "Bob c")
Bob_d = ClassicalRegister(1, "Bob d")
test.add_register(Bob_d)
test.add_register(Bob_c)
test.measure(ebit0, Bob_d)
test.measure(ebit1, Bob_c)
display(test.draw(output="mpl"))

L'exécution du simulateur Aer montre les résultats : les bits classiques d'Alice et de Bob sont toujours identiques.
result = AerSimulator().run(test).result()
statistics = result.get_counts()
display(plot_histogram(statistics))

Le jeu CHSH
Le dernier exemple abordé dans cette leçon n'est pas un protocole, mais un jeu connu sous le nom de jeu CHSH.
Quand on parle de jeu dans ce contexte, il ne s'agit pas de quelque chose destiné à être joué pour le plaisir ou le sport, mais plutôt d'une abstraction mathématique au sens de la théorie des jeux. Les abstractions mathématiques de jeux sont étudiées en économie et en informatique, par exemple, et elles sont à la fois fascinantes et utiles.
Les lettres CHSH renvoient aux auteurs — John Clauser, Michael Horne, Abner Shimony et Richard Holt — d'un article de 1969 dans lequel l'exemple a été décrit pour la première fois. Ils n'ont pas décrit l'exemple comme un jeu, mais plutôt comme une expérience. Sa description sous forme de jeu est néanmoins à la fois naturelle et intuitive.
Le jeu CHSH appartient à une classe de jeux appelés jeux non locaux. Les jeux non locaux sont incroyablement intéressants et entretiennent des liens profonds avec la physique, l'informatique et les mathématiques — recélant des mystères qui demeurent encore irrésolus. Nous commencerons cette section en expliquant ce que sont les jeux non locaux, puis nous nous concentrerons sur le jeu CHSH et ce qui le rend si intéressant.
Jeux non locaux
Un jeu non local est un jeu coopératif dans lequel deux joueurs, Alice et Bob, travaillent ensemble pour atteindre un résultat particulier. Le jeu est animé par un arbitre, qui se comporte selon des règles strictes connues d'Alice et de Bob.
Alice et Bob peuvent se préparer au jeu comme ils le souhaitent, mais une fois le jeu commencé, il leur est interdit de communiquer. On peut imaginer que le jeu se déroule dans une installation sécurisée quelconque — comme si l'arbitre jouait le rôle d'un détective et qu'Alice et Bob étaient des suspects interrogés dans des pièces séparées. Mais une autre façon d'envisager la configuration est qu'Alice et Bob sont séparés par une grande distance, et que la communication est interdite parce que la vitesse de la lumière ne le permet pas dans le temps d'exécution du jeu. Autrement dit, si Alice essaie d'envoyer un message à Bob, le jeu sera terminé avant qu'il le reçoive, et vice versa.
Le fonctionnement d'un jeu non local est que l'arbitre pose d'abord une question à Alice et à Bob chacun. On utilisera la lettre pour désigner la question d'Alice et pour désigner celle de Bob. Ici, et sont considérés comme des états classiques, et dans le jeu CHSH, et sont des bits.
L'arbitre utilise de l'aléatoire pour sélectionner ces questions. Plus précisément, il existe une probabilité associée à chaque paire possible de questions, et l'arbitre s'est engagé à choisir les questions aléatoirement, au moment du jeu, de cette façon. Tout le monde, y compris Alice et Bob, connaît ces probabilités — mais personne ne sait précisément quelle paire sera choisie avant le début du jeu.
Après qu'Alice et Bob ont reçu leurs questions, ils doivent fournir des réponses : la réponse d'Alice est et celle de Bob est Ces réponses sont là encore des états classiques en général, et des bits dans le jeu CHSH.
À ce stade, l'arbitre prend une décision : Alice et Bob gagnent ou perdent selon que la paire de réponses est jugée correcte pour la paire de questions conformément à un ensemble de règles fixées. Des règles différentes définissent des jeux différents, et les règles du jeu CHSH en particulier sont décrites dans la section suivante. Comme cela a déjà été suggéré, les règles sont connues de tous.
Le diagramme suivant fournit une représentation graphique des interactions.

C'est l'incertitude quant aux questions qui seront posées, et en particulier le fait que chaque joueur ignore la question de l'autre joueur, qui rend les jeux non locaux difficiles pour Alice et Bob — tout comme des suspects complices dans des pièces séparées essayant de maintenir une version cohérente des faits.
Une description précise de l'arbitre définit une instance d'un jeu non local. Cela comprend une spécification des probabilités pour chaque paire de questions ainsi que les règles qui déterminent si chaque paire de réponses gagne ou perd pour chaque paire de questions possible
Jetons un coup d'œil au jeu CHSH dans un instant, mais avant cela, reconnaissons brièvement qu'il est également intéressant de considérer d'autres jeux non locaux. En fait, c'est extrêmement intéressant ; il existe des jeux non locaux assez simples pour lesquels on ne sait pas encore avec quelle efficacité Alice et Bob peuvent jouer en utilisant l'intrication. La configuration est simple, mais la complexité est à l'œuvre — et pour certains jeux, il peut être extrêmement difficile de calculer les stratégies optimales ou quasi-optimales pour Alice et Bob. C'est là la nature étonnamment contre-intuitive du modèle des jeux non locaux.
Description du jeu CHSH
Voici la description précise du jeu CHSH, où (comme ci-dessus) est la question d'Alice, est la question de Bob, est la réponse d'Alice, et est la réponse de Bob :
-
Les questions et les réponses sont toutes des bits :
-
L'arbitre choisit les questions uniformément au hasard. C'est-à-dire que chacune des quatre possibilités, et est sélectionnée avec une probabilité
-
Les réponses gagnent pour les questions si et perdent sinon. Le tableau suivant exprime cette règle en listant les conditions de victoire et de défaite sur les réponses pour chaque paire de questions
Limitation des stratégies classiques
Examinons maintenant les stratégies d'Alice et Bob dans le jeu CHSH, en commençant par les stratégies classiques.
Stratégies déterministes
Nous commençons par les stratégies déterministes, où la réponse d'Alice est une fonction de la question qu'elle reçoit, et de même la réponse de Bob est une fonction de la question qu'il reçoit. Ainsi, par exemple, on peut écrire pour représenter la réponse d'Alice lorsque sa question est et pour représenter la réponse d'Alice lorsque sa question est
Aucune stratégie déterministe ne peut gagner le jeu CHSH à chaque fois. Une façon de le comprendre est simplement de parcourir une à une toutes les stratégies déterministes possibles et de vérifier que chacune d'entre elles perd pour au moins une des quatre paires de questions possibles. Alice et Bob peuvent chacun choisir parmi quatre fonctions possibles d'un bit à un bit — que nous avons rencontrées dans la leçon sur les Systèmes uniques — et il y a donc stratégies déterministes différentes à vérifier au total.
On peut également raisonner analytiquement. Si la stratégie d'Alice et Bob gagne quand alors il faut que si leur stratégie gagne quand alors et de même, si la stratégie gagne pour alors Donc, si leur stratégie gagne pour les trois premières possibilités, alors
Cela implique que la stratégie perd dans le dernier cas où gagner exige que Ainsi, il ne peut exister aucune stratégie déterministe qui gagne à chaque fois.
D'autre part, il est facile de trouver des stratégies déterministes qui gagnent dans trois des quatre cas, par exemple On conclut donc que la probabilité maximale pour Alice et Bob de gagner avec une stratégie déterministe est
Stratégies probabilistes
Comme nous venons de le conclure, Alice et Bob ne peuvent pas faire mieux que de gagner le jeu CHSH 75 % du temps avec une stratégie déterministe. Mais qu'en est-il d'une stratégie probabiliste ? L'utilisation de l'aléatoire pourrait-elle aider Alice et Bob — y compris la possibilité d'un aléatoire partagé, où leurs choix aléatoires sont corrélés ?
Il s'avère que les stratégies probabilistes n'aident absolument pas à augmenter la probabilité de victoire d'Alice et Bob. C'est parce que toute stratégie probabiliste peut être vue alternativement comme une sélection aléatoire d'une stratégie déterministe, tout comme (comme mentionné dans la leçon sur les Systèmes uniques) les opérations probabilistes peuvent être vues comme des sélections aléatoires d'opérations déterministes. La moyenne n'est jamais supérieure au maximum, et il s'ensuit que les stratégies probabilistes n'offrent aucun avantage en termes de probabilité de victoire globale.
Ainsi, gagner avec une probabilité est le meilleur qu'Alice et Bob puissent faire avec n'importe quelle stratégie classique, qu'elle soit déterministe ou probabiliste.
Stratégie pour le jeu CHSH
Une question naturelle à poser à ce stade est de savoir si Alice et Bob peuvent faire mieux avec une stratégie quantique. En particulier, s'ils partagent un état quantique intriqué comme le suggère la figure suivante, qu'ils auraient pu préparer avant de jouer, peuvent-ils augmenter leur probabilité de victoire ?

La réponse est oui, et c'est là l'intérêt principal de cet exemple et ce qui le rend si fascinant. Voyons donc exactement comment Alice et Bob peuvent faire mieux dans ce jeu grâce à l'intrication.
Vecteurs et matrices nécessaires
La première chose à faire est de définir un vecteur d'état de qubit pour chaque nombre réel (que l'on considère comme un angle mesuré en radians) comme suit.
Voici quelques exemples simples :
On a également les exemples suivants, qui apparaissent dans l'analyse ci-dessous :
En regardant la forme générale, on voit que le produit intérieur entre deux de ces vecteurs obéit à la formule suivante :
En détail, ces vecteurs ne contiennent que des nombres réels, donc il n'y a pas de conjugués complexes à prendre en compte : le produit intérieur est le produit des cosinus plus le produit des sinus. L'utilisation de l'une des formules d'addition d'angles de la trigonométrie conduit à la simplification ci-dessus. Cette formule révèle l'interprétation géométrique du produit intérieur entre vecteurs unitaires réels comme le cosinus de l'angle entre eux.
Si on calcule le produit intérieur du produit tensoriel de deux de ces vecteurs avec l'état on obtient une expression similaire, sauf qu'elle comporte un