Téléportation quantique et codage superdense
Kifumi Numata (26 avr. 2024)
Télécharger le PDF du cours original. Attention, certains extraits de code pourraient être obsolètes car il s'agit d'images statiques.
Le temps QPU approximatif pour exécuter cette expérience est de 10 secondes.
1. Introduction
Pour résoudre tout problème quantique à l'échelle utilitaire, nous aurons besoin de déplacer de l'information sur un ordinateur quantique d'un qubit à un autre. Il existe des protocoles bien connus pour ce faire, mais certains des plus fondamentaux ont été formulés dans le contexte de l'envoi d'information entre des parties distantes. Tout au long de cette leçon, nous utiliserons parfois un langage cohérent avec ce contexte, comme « des amis distants qui s'envoient de l'information ». Mais garde à l'esprit que ces protocoles ont une portée plus large en informatique quantique. Dans cette leçon, nous examinons les protocoles de communication quantique suivants :
- Téléportation quantique Utiliser un état intriqué partagé (parfois appelé e-bit) pour envoyer un état quantique inconnu à un ami distant, en nécessitant une communication classique supplémentaire.
- Codage superdense quantique Comment envoyer deux bits d'information en transmettant un seul qubit à un ami distant (là encore en utilisant des qubits intriqués partagés au préalable).
Pour plus de contexte sur ces sujets, nous recommandons la leçon 4 des Bases de l'information quantique sur L'intrication en action.
Dans la description ci-dessus, un « état quantique inconnu » désigne simplement un état de la forme décrite dans la leçon précédente :
où et sont des nombres complexes tels que . Cela nous permet d'écrire l'état quantique sous la forme
Puisque nous voulons pouvoir transférer l'information contenue dans n'importe quel état quantique aléatoire, la génération d'un tel état sera notre point de départ dans cette leçon.
2. Matrices densité
On peut aussi écrire l'état quantique sous forme de matrice densité. Cette représentation est utile pour décrire un mélange probabiliste d'états quantiques purs. Dans le cas d'un seul qubit, on peut écrire
Note que la matrice densité est une combinaison linéaire des matrices de Pauli, comme ci-dessous,
Ou, de manière générale,
où .
Et le vecteur de Bloch est .
Maintenant, créons un état quantique arbitraire à l'aide de nombres aléatoires.
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-aer qiskit-ibm-runtime
import numpy as np
# create a random 1-qubit state from a random (theta, varphi) to define r vector
np.random.seed(1) # fixing seed for repeatibility
theta = np.random.uniform(0.0, 1.0) * np.pi # from 0 to pi
varphi = np.random.uniform(0.0, 2.0) * np.pi # from 0 to 2*pi
def get_r_vec(theta, varphi):
rx = np.sin(theta) * np.cos(varphi)
ry = np.sin(theta) * np.sin(varphi)
rz = np.cos(theta)
return (rx, ry, rz)
# get r vector
rx, ry, rz = get_r_vec(theta, varphi)
print("theta=" + str(theta), ",varphi=" + str(varphi))
print("(rx, ry, rz) = (" + str(rx) + ", " + str(ry) + ", " + str(rz) + ")")
theta=1.3101132663588946 ,varphi=4.525932273597346
(rx, ry, rz) = (-0.1791150283307452, -0.9494670044331133, 0.2577405946274022)
On peut représenter ce vecteur de Bloch sur la sphère de Bloch.
from qiskit.visualization import plot_bloch_vector
r = [rx, ry, rz]
plot_bloch_vector(r)
3. Tomographie d'état quantique
Si tu mesures l'état quantique uniquement dans la base computationnelle ( et ), l'information de phase (l'information sur les nombres complexes) sera perdue. Mais si on dispose de nombreuses copies de en répétant le processus de préparation (on ne peut pas cloner des états, mais on peut répéter les processus de préparation), on peut estimer les valeurs de en réalisant une tomographie d'état quantique pour la matrice densité . Étant donné la forme :
il s'ensuit que
Dans le cas de ,
La dernière transformation de l'équation est valable pour . On peut donc obtenir en calculant la probabilité de moins la probabilité de .
Estimer la valeur de
Pour estimer , nous créons un état quantique et le mesurons. Nous répétons ensuite la préparation et la mesure de nombreuses fois. Enfin, nous utilisons les statistiques des mesures pour estimer les probabilités ci-dessus et ainsi estimer .
Pour créer l'état quantique aléatoire, nous utiliserons la porte unitaire générale avec les paramètres . (Consulter la porte U pour plus d'informations.)
from qiskit import QuantumCircuit
# create a 1-qubit quantum state psi from theta, varphi parameters
qc = QuantumCircuit(1, 1)
qc.u(theta, varphi, 0.0, 0)
# measure in computational basis
qc.measure(0, 0)
qc.draw(output="mpl")
En utilisant l'AerSimulator, nous allons mesurer dans la base computationnelle pour estimer .
# see if the expected value of measuring in the computational basis
# approaches the limit of rz
from qiskit_aer import AerSimulator
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit_ibm_runtime import Sampler
from qiskit.visualization import plot_histogram
# Define backend
backend = AerSimulator()
nshots = 1000 # or 10000
# nshots = 10000
# Transpile to backend
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_qc = pm.run(qc)
# Run the job
sampler = Sampler(mode=backend)
job = sampler.run([isa_qc], shots=nshots)
result = job.result()
# Extract counts data
counts = result[0].data.c.get_counts()
print(counts)
# Plot the counts in a histogram
plot_histogram(counts)
{'1': 375, '0': 625}
rz_approx = (counts["0"] - counts["1"]) / nshots
print("rz = ", rz, " and approx of rz = ", rz_approx)
rz = 0.2577405946274022 and approx of rz = 0.25
En utilisant la méthode de tomographie d'état quantique, nous avons estimé la valeur de . Dans ce cas, comme nous avons choisi un paramètre pour l'état « aléatoire », nous connaissons la valeur de et pouvons vérifier notre résultat. Mais par nature, les travaux à l'échelle utilitaire ne sont pas toujours aussi simples à vérifier. Nous aborderons plus en détail la vérification des résultats quantiques plus loin dans ce cours. Pour l'instant, note simplement que notre estimation était raisonnablement précise.
Exercice 1 : Estimer la valeur de
Rappelle-toi que les ordinateurs quantiques IBM® mesurent le long de l'axe (parfois formulé « dans la base » ou « dans la base computationnelle »). Cependant, en appliquant des rotations avant la mesure, nous pouvons aussi mesurer la projection de l'état quantique sur l'axe x. Pour être plus précis, si nous faisons pivoter notre système de sorte que ce qui pointait le long de pointe maintenant le long de , alors nous pouvons conserver le même matériel de mesure le long de , tout en apprenant des informations sur l'état qui pointait le long de un instant auparavant. C'est ainsi que la plupart des ordinateurs quantiques (et tous les ordinateurs quantiques IBM) effectuent des mesures selon plusieurs axes.
Avec cette compréhension, essaie d'écrire du code pour estimer la valeur de en utilisant la tomographie d'état quantique.
Solution :
# create a 1-qubit quantum state psi from theta, varphi parameters
qc = QuantumCircuit(1, 1)
qc.u(theta, varphi, 0.0, 0)
qc.h(0)
qc.measure(0, 0)
qc.draw(output="mpl")
# Define backend
backend = AerSimulator()
nshots = 10000
# Transpile to backend
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_qc = pm.run(qc)
# Run the job
sampler = Sampler(mode=backend)
job = sampler.run([isa_qc], shots=nshots)
result = job.result()
# Extract counts data
counts = result[0].data.c.get_counts()
print(counts)
# Plot the counts in a histogram
plot_histogram(counts)
{'1': 5925, '0': 4075}
rx_approx = (counts["0"] - counts["1"]) / nshots
print("rx = ", rx, " and approx of rx = ", rx_approx)
rx = -0.1791150283307452 and approx of rx = -0.185
Exercice 2 : Estimer la valeur de
En utilisant les mêmes arguments logiques que précédemment, nous pouvons faire pivoter le système avant la mesure pour obtenir des informations sur .
Essaie d'écrire toi-même du code pour estimer la valeur de en utilisant la tomographie d'état quantique. Tu peux partir de l'exemple précédent, mais effectuer des rotations différentes. (Pour plus d'informations sur les diverses portes utilisées, notamment sdg, consulte la référence API.)
Solution :
# create a 1-qubit quantum state psi from theta, varphi parameters
qc = QuantumCircuit(1, 1)
qc.u(theta, varphi, 0.0, 0)
qc.sdg(0)
qc.h(0)
qc.measure(0, 0)
qc.draw(output="mpl")
# Define backend
backend = AerSimulator()
nshots = 10000
# Transpile to backend
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_qc = pm.run(qc)
# Run the job
sampler = Sampler(mode=backend)
job = sampler.run([isa_qc], shots=nshots)
result = job.result()
# Extract counts data
counts = result[0].data.c.get_counts()
print(counts)
# Plot the counts in a histogram
plot_histogram(counts)
{'1': 9759, '0': 241}
ry_approx = (counts["0"] - counts["1"]) / nshots
print("ry = ", ry, " and approx of ry = ", ry_approx)
ry = -0.9494670044331133 and approx of ry = -0.9518
Nous avons maintenant estimé toutes les composantes de et pouvons écrire le vecteur complet.
print("Estimated vector is (", rx_approx, ",", ry_approx, ",", rz_approx, ").")
print("Original random vector was (" + str(rx) + ", " + str(ry) + ", " + str(rz) + ").")
Estimated vector is ( -0.185 , -0.9518 , 0.25 ).
Original random vector was (-0.1791150283307452, -0.9494670044331133, 0.2577405946274022).
Tu as obtenu une estimation assez précise du vecteur aléatoire original grâce à cette méthode de tomographie d'état quantique.
4. Téléportation quantique
Considérons la situation où un personnage, Alice, souhaite envoyer un état quantique inconnu à son ami Bob, qui est loin. Supposons qu'ils ne peuvent communiquer que par communication classique (par e-mail ou par téléphone). Alice ne peut pas copier l'état quantique (en raison du théorème de non-clonage). Si elle répétait le même processus de préparation de nombreuses fois, elle pourrait accumuler des statistiques comme nous venons de le faire. Mais que se passe-t-il s'il n'y a qu'un seul état inconnu ? Cet état a peut-être émergé d'un processus physique que tu veux étudier. Ou il pourrait faire partie d'un calcul quantique plus grand. Dans ce cas, comment Alice pourrait-elle envoyer l'état à Bob ? Elle le peut, si elle et Bob partagent une précieuse ressource quantique : un état intriqué partagé, comme l'état de Bell introduit dans la leçon précédente : Tu verras parfois aussi cela appelé « paire EPR » ou « e-bit » (unité fondamentale d'intrication). Si Alice partage un tel état intriqué avec Bob, elle peut téléporter l'état quantique inconnu à Bob en effectuant une série d'opérations quantiques et en lui envoyant deux bits d'information classique.
4.1 Le protocole de téléportation quantique
Hypothèse : Alice possède un état quantique inconnu à envoyer à Bob. Alice et Bob partagent un état intriqué à 2 qubits, ou e-bit, chacun ayant physiquement l'un des qubits à son emplacement.
Voici un aperçu de la procédure sans explication. Les détails seront implémentés ci-dessous.
- Alice intrique avec sa partie de l'e-bit en utilisant la porte CNOT.
- Alice applique une porte Hadamard à et mesure ses deux qubits dans la base computationnelle.
- Alice envoie à Bob ses résultats de mesure (soit « 00 », « 01 », « 10 » ou « 11 »)
- Bob effectue un opérateur de correction basé sur les deux bits d'information d'Alice sur sa partie de la paire e-bit.
- Si « 00 », Bob ne fait rien
- Si « 01 », Bob applique la porte X
- Si « 10 », Bob applique la porte Z
- Si « 11 », Bob applique iY = ZX
- La partie de l'e-bit de Bob devient .
Ceci est également développé plus en détail dans Bases de l'information quantique. Mais la situation deviendra plus claire au fur et à mesure que nous l'instancierons dans Qiskit.
4.2 Circuit quantique simulant la téléportation quantique
Comme toujours, nous appliquerons le cadre des Qiskit patterns. Cette sous-section se concentrera uniquement sur la cartographie.
Étape 1 : Mapper le problème sur des circuits et des opérateurs quantiques
Pour décrire le scénario ci-dessus, nous avons besoin d'un circuit à trois qubits : deux pour la paire intriquée partagée par Alice et Bob, et un pour l'état quantique inconnu .
from qiskit import QuantumCircuit
import numpy as np
# create 3-qubits circuit
qc = QuantumCircuit(3, 3)
qc.draw(output="mpl")
Au départ, Alice possède un état quantique inconnu Nous allons le créer en utilisant la porte .
# Create the unknown quantum state using the u-gate. Alice has this.
qc.u(theta, varphi, 0.0, 0)
qc.barrier() # for visual separation
qc.draw(output="mpl")
Nous pouvons visualiser l'état que nous avons créé, mais uniquement parce que nous connaissons les paramètres utilisés dans la porte . Si cet état avait émergé d'un processus quantique complexe, l'état ne serait pas connaissable sans exécuter le processus pour créer l'état de nombreuses fois et collecter des statistiques comme dans la tomographie.
# show the quantum state on bloch sphere
from qiskit.quantum_info import Statevector
from qiskit.visualization import plot_bloch_multivector
out_vector = Statevector(qc)
plot_bloch_multivector(out_vector)

Avant même que ce protocole commence, nous supposons qu'Alice et Bob ont une paire intriquée partagée. Si Alice et Bob se trouvent vraiment à des emplacements différents, ils pourraient avoir établi l'état partagé avant que l'état inconnu ait jamais été créé. Étant donné que ces opérations se déroulent sur des qubits différents, leur ordre n'a pas d'importance ici, et cet ordre est pratique pour la visualisation.
# Alice and Bob are together in the same place and set up an entangled pair.
qc.h(1)
qc.cx(1, 2)
qc.barrier() # for visual separation.
# We can consider that Alice and Bob might move their qubits to different physical locations, now.
qc.draw(output="mpl")
Ensuite, Alice intrique avec sa partie de l'e-bit partagé, en utilisant la porte et la porte , et les mesure dans la base computationnelle.
# Alice entangles the unknown state with her part of the e-bit, using the CNOT gate and H gate.
qc.cx(0, 1)
qc.h(0)
qc.barrier()
# Alice measures the two qubits.
qc.measure(0, 0)
qc.measure(1, 1)
qc.draw(output="mpl")
Alice envoie à Bob ses résultats de mesure (soit « 00 », « 01 », « 10 » ou « 11 »), et Bob effectue un opérateur de correction basé sur les deux bits d'information d'Alice sur sa partie de l'e-bit partagé. Ensuite, la partie de Bob devient .
# Alice sent the results to Bob. Bob applies correction
with qc.if_test((0, 1)):
qc.z(2)
with qc.if_test((1, 1)):
qc.x(2)
qc.barrier()
qc.draw(output="mpl")
Tu as complété un circuit de téléportation quantique ! Voyons l'état de sortie de ce circuit en utilisant le simulateur de vecteur d'état.
from qiskit_aer import StatevectorSimulator
backend = StatevectorSimulator()
out_vector = backend.run(qc, shots=1).result().get_statevector() # set shots = 1
plot_bloch_multivector(out_vector)

Tu peux constater que l'état quantique créé par la porte du qubit 0 (le qubit contenant initialement l'état secret) a été transféré vers le qubit 2 (le qubit de Bob).
Tu peux exécuter la cellule ci-dessus plusieurs fois pour t'en assurer. Tu remarqueras peut-être que les qubits 0 et 1 changent d'état, mais le qubit 2 est toujours dans l'état .
4.3 Exécuter et confirmer le résultat en appliquant l'inverse de U
Ci-dessus, nous avons vérifié visuellement que l'état téléporté semblait correct. Une autre façon de vérifier si l'état quantique a été téléporté correctement est d'appliquer l'inverse de la porte sur le qubit de Bob afin que nous puissions mesurer « 0 ». Autrement dit, puisque est l'identité, si le qubit de Bob est dans l'état créé à partir de , alors l'application de l'inverse devrait donner
# Apply the inverse of u-gate to measure |0>
qc.u(theta, varphi, 0.0, 2).inverse() # inverse of u(theta,varphi,0.0)
qc.measure(2, 2) # add measurement gate
qc.draw(output="mpl")
Nous allons d'abord exécuter le circuit avec l'AerSimulator avant de passer à un vrai ordinateur quantique.
from qiskit_aer import AerSimulator
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit_ibm_runtime import Sampler
from qiskit.visualization import plot_histogram
# Define backend
backend = AerSimulator()
# Transpile to backend
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_qc = pm.run(qc)
# Run the job
sampler = Sampler(mode=backend)
job = sampler.run([isa_qc], shots=nshots)
result = job.result()
# Extract counts data
counts = result[0].data.c.get_counts()
print(counts)
# Plot the counts in a histogram
plot_histogram(counts)
{'011': 2510, '010': 2417, '000': 2635, '001': 2438}
Rappelle-toi qu'en notation little endian, le qubit 2 est le qubit le plus à gauche (ou le plus en bas, dans les étiquettes de colonnes). Note que le qubit le plus à gauche et le plus en bas dans les étiquettes de colonnes est un 0 pour tous les résultats possibles. Cela montre que nous avons 100 % de chance de mesurer dans l'état . C'est le résultat attendu et indique que le protocole de téléportation a fonctionné correctement.
4.4 Téléportation sur un vrai ordinateur quantique
Ensuite, nous allons effectuer la téléportation sur un vrai ordinateur quantique. En utilisant la fonction de circuit dynamique, nous pouvons opérer au milieu du circuit en utilisant les résultats de mesure, implémentant en temps réel les opérations conditionnelles dans le circuit de téléportation. Pour résoudre des problèmes avec de vrais ordinateurs quantiques, nous suivrons les quatre étapes des Qiskit patterns.
- Mapper le problème sur des circuits et des opérateurs quantiques
- Optimiser pour le matériel cible
- Exécuter sur le matériel cible
- Post-traiter les résultats
Exercice 3 : Construire le circuit de téléportation
Essaie de construire l'intégralité du circuit de téléportation de zéro pour tester ta compréhension. Remonte si tu as besoin d'un rappel.
Solution :
# Step 1: Map problem to quantum circuits and operators
# Create the circuit with 3-qubits and 1-bit
qc = QuantumCircuit(3, 3)
# Alice creates an unknown quantum state using the u-gate.
qc.u(theta, varphi, 0.0, 0)
qc.barrier() # for visual separation
# Eve creates EPR pair and sends q1 to Alice and q2 to Bob
##your code goes here##
qc.h(1)
qc.cx(1, 2)
qc.barrier()
# Alice entangles the unknown state with her EPR part, using the CNOT gate and H gate.
##your code goes here##
qc.cx(0, 1)
qc.h(0)
qc.barrier()
# Alice measures the two qubits.
##your code goes here##
qc.measure(0, 0)
qc.measure(1, 1)
# Alice sent the results to Bob. Now, Bob applies correction
##your code goes here##
with qc.if_test((0, 1)):
qc.z(2)
with qc.if_test((1, 1)):
qc.x(2)
qc.barrier()
# Apply the inverse of u-gate to measure |0>
qc.u(theta, varphi, 0.0, 2).inverse()
qc.measure(2, 2)
qc.draw(output="mpl")
Pour rappel, l'application de l'inverse de la porte sert uniquement à vérifier le comportement attendu. Cela ne fait pas partie de l'envoi de l'état à Bob, et nous n'utiliserions pas cette porte inverse si le seul objectif était de transférer de l'information quantique.
Étape 2 : Optimiser pour le matériel cible
Pour s'exécuter sur du matériel, importe QiskitRuntimeService et charge tes identifiants sauvegardés. Sélectionne le backend avec le moins de tâches dans la file d'attente.
from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService()
service.backends()
[<IBMBackend('ibm_brisbane')>,
<IBMBackend('ibm_torino')>]
# You can also identify the least busy device
backend = service.least_busy(operational=True)
print("The least busy device is ", backend)
The least busy device is <IBMBackend('ibm_brisbane')>
# You can specify the device
# backend = service.backend('ibm_brisbane')
Voyons la carte de couplage du dispositif que tu as sélectionné.
from qiskit.visualization import plot_gate_map
plot_gate_map(backend)

Différents dispositifs peuvent avoir des cartes de couplage différentes, et chaque dispositif possède certains qubits et coupleurs plus performants que d'autres. Enfin, différents ordinateurs quantiques peuvent avoir des portes natives différentes (des portes que le matériel peut exécuter). La transpilation du circuit réécrit le circuit quantique abstrait en utilisant des portes que l'ordinateur quantique cible peut exécuter et sélectionne la correspondance optimale avec les qubits physiques (entre autres). La transpilation est un sujet riche et complexe. Pour en savoir plus sur la transpilation, consulte la référence API.
# Step 2: Optimize for target hardware
# Transpile the circuit into basis gates executable on the hardware
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
pm = generate_preset_pass_manager(backend=backend, optimization_level=2)
qc_compiled = pm.run(qc)
qc_compiled.draw("mpl", idle_wires=False, fold=-1)
Étape 3 : Exécuter le circuit.
En utilisant la primitive Runtime Sampler, nous allons exécuter le circuit cible.
# Step 3: Execute the target circuit
sampler = Sampler(backend)
job = sampler.run([qc_compiled])
job_id = job.job_id()
print("job id:", job_id)
job id: d13nkhpn2txg008jt0d0
# Check the job status
job.status()
'DONE'
Tu peux aussi vérifier le statut de la tâche depuis ton tableau de bord IBM Quantum®.
# If the Notebook session got disconnected you can also check your job status
# by running the following code
from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService()
job_real = service.job(job.job_id()) # Input your job-id between the quotations
job_real.status()
'DONE'
Si tu vois 'DONE' s'afficher, tu peux obtenir le résultat en exécutant la cellule ci-dessous.
# Execute after 'DONE' is displayed
result_real = job_real.result()
print(result_real[0].data.c.get_counts())
{'001': 992, '110': 430, '011': 579, '010': 605, '111': 402, '000': 925, '100': 57, '101': 106}
Étape 4 : Post-traiter les résultats
# Step 4: Post-process the results
from qiskit.visualization import plot_histogram
plot_histogram(result_real[0].data.c.get_counts())
Tu peux interpréter les résultats ci-dessus directement. Ou, en utilisant marginal_count, tu peux tracer les résultats de Bob sur le qubit 2.
# trace out Bob's results on qubit 2
from qiskit.result import marginal_counts
bobs_qubit = 2
real_counts = result_real[0].data.c.get_counts()
bobs_counts = marginal_counts(real_counts, [bobs_qubit])
plot_histogram(bobs_counts)
Comme on le voit ici, il y a quelques résultats dans lesquels nous avons mesuré . Ceux-ci sont dus au bruit et aux erreurs. En particulier, les circuits dynamiques ont tendance à avoir un taux d'erreur plus élevé en raison de la mesure chronophage au milieu du circuit.
4.5 Points clés sur la téléportation quantique
Nous pouvons transporter un état quantique vers un ami distant en partageant une paire de qubits intriqués (un e-bit).
-
La téléportation quantique peut-elle envoyer l'état quantique plus vite que la lumière ? Non, parce qu'Alice doit communiquer à Bob les résultats de mesure de manière classique.
-
La téléportation quantique contournerait-elle le « théorème de non-clonage », qui interdit la copie d'un état quantique ? Non, parce que l'état quantique original donné à Alice sur l'un de ses qubits a été perdu lors de la mesure. Il s'est effondré en ou .
5. Codage superdense
Pratiquement le même dispositif peut être utilisé à une fin différente. Supposons qu'Alice veuille envoyer à Bob deux bits d'information classique, mais qu'elle n'ait aucun moyen de communication classique avec Bob. Elle partage cependant une paire intriquée avec Bob et est autorisée à envoyer son qubit à l'emplacement de Bob. Remarque le contraste avec le protocole de téléportation quantique. Dans la téléportation, la communication classique était disponible pour les amis, et l'objectif était d'envoyer un état quantique. Ici, la communication classique n'est pas accessible et ils utilisent le transfert d'un qubit pour partager deux bits d'information classique.
5.1 Le protocole du codage superdense
Hypothèse : Alice dispose de deux bits d'information, disons . Alice et Bob partagent une paire intriquée (e-bit), mais ils ne peuvent pas communiquer classiquement.
- Alice effectue l'une des opérations suivantes sur sa partie de l'e-bit.
- Si , elle ne fait rien
- Si , elle applique la porte Z
- Si , elle applique la porte X
- Si , elle applique la porte Z puis la porte X.
- Alice envoie sa partie de l'e-bit à l'emplacement de Bob.
- Bob applique une porte CNOT avec le qubit d'Alice comme contrôle et son qubit comme cible, puis applique la porte H au qubit d'Alice, et mesure les deux qubits. Les états de départ possibles et les résultats des opérations de Bob sont :
Note que le signe négatif de est une phase globale, donc elle n'est pas mesurable.
5.2 Circuit quantique simulant le codage superdense
Sur la base du protocole du codage superdense, tu peux construire le circuit de codage superdense comme ci-dessous. Essaie de changer le message, msg, qu'Alice veut transmettre à Bob.
from qiskit import QuantumCircuit
Les étapes des Qiskit patterns sont identifiées dans les commentaires du code.
# Step 1: Map problem to quantum circuits and operators
# Create 2-qubits circuit
qc = QuantumCircuit(2, 2)
# Eve creates EPR pair and send q0 to Alice and q1 to Bob
qc.h(0)
qc.cx(0, 1)
qc.barrier()
# set message which Alice wants to transform to Bob
msg = "11" # You can change the message
if msg == "00":
pass
elif msg == "10":
qc.x(0)
elif msg == "01":
qc.z(0)
elif msg == "11":
qc.z(0)
qc.x(0)
qc.barrier()
# Bob receives EPR qubit from Alice and performs unitary operations
qc.cx(0, 1)
qc.h(0)
qc.barrier()
# Bob measures q0 and q1
qc.measure(0, 0)
qc.measure(1, 1)
qc.draw(output="mpl")
# We will execute on a simulator first
from qiskit_aer import AerSimulator
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit_ibm_runtime import Sampler
# Define backend
backend = AerSimulator()
shots = 1000
# Transpile to backend
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_qc = pm.run(qc)
# Run the job
sampler = Sampler(mode=backend)
job_sim = sampler.run([isa_qc], shots=shots)
result_sim = job_sim.result()
# Extract counts data
counts = result_sim[0].data.c.get_counts()
print(counts)
{'11': 1000}
# Visualize the results
from qiskit.visualization import plot_histogram
plot_histogram(counts)
Tu peux constater que Bob a bien reçu le message qu'Alice voulait lui envoyer.
Ensuite, essayons avec un vrai ordinateur quantique.
from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService()
backend = service.least_busy(operational=True)
print("The least busy device is ", backend)
The least busy device is <IBMBackend('ibm_brisbane')>
# Step 1 was already completed before the simulator job above.
# Step 2: Optimize for target hardware
# Transpile the circuit into basis gates executable on the hardware
pm = generate_preset_pass_manager(backend=backend, optimization_level=2)
qc_compiled = pm.run(qc)
qc_compiled.draw("mpl", idle_wires=False)
# Step 3:Execute the target circuit
sampler = Sampler(backend)
job = sampler.run([qc_compiled])
job_id = job.job_id()
print("job id:", job_id)
job id: d13nnyq3grvg008j0zag
# Check the job status
job.status()
'DONE'
# If the Notebook session got disconnected you can also check your job status
# by running the following code
# from qiskit_ibm_runtime import QiskitRuntimeService
# service = QiskitRuntimeService()
job = service.job(job_id) # Input your job-id between the quotations
job.status()
'DONE'
# Execute after job has successfully run
real_result = job.result()
print(real_result[0].data.c.get_counts())
{'11': 3942, '01': 107, '10': 41, '00': 6}
# Step 4: post-process the results
from qiskit.visualization import plot_histogram
plot_histogram(real_result[0].data.c.get_counts())
Le résultat est celui que nous attendions. Note que le codage superdense sur un vrai ordinateur quantique a montré moins d'erreurs que dans le cas de la téléportation quantique sur un vrai ordinateur quantique. L'une des raisons pourrait être que la téléportation quantique utilise des circuits dynamiques, et pas le codage superdense. Nous en apprendrons davantage sur les erreurs dans les circuits quantiques dans les leçons suivantes.
6. Résumé
Dans cette session, nous avons implémenté deux protocoles quantiques. Bien que les scénarios impliquant des amis distants pour les deux soient quelque peu éloignés de l'informatique quantique sur un seul QPU, ils ont des applications en informatique quantique et nous aident à mieux comprendre le transfert d'information quantique.
- Téléportation quantique : bien que nous ne puissions pas copier des états quantiques, nous pouvons téléporter des états quantiques inconnus en ayant une intrication partagée.
- Codage superdense quantique : une paire intriquée partagée, et le transfert d'un qubit, permettent la communication de deux bits d'information classique.
# See the version of Qiskit
import qiskit
qiskit.__version__
'2.0.2'