Aller au contenu principal

Premiers pas avec Qiskit en classe

Pour ce module Qiskit en classe, les étudiants doivent disposer d'un environnement Python fonctionnel avec les packages suivants installés :

  • qiskit v2.1.0 ou plus récent
  • qiskit-ibm-runtime v0.40.1 ou plus récent
  • qiskit-aer v0.17.0 ou plus récent
  • qiskit.visualization
  • numpy
  • pylatexenc

Pour configurer et installer les packages ci-dessus, consulte le guide Installer Qiskit. Pour exécuter des jobs sur de vrais ordinateurs quantiques, les étudiants devront créer un compte IBM Quantum® en suivant les étapes du guide Configurer ton compte IBM Cloud®.

Ce module a été testé et a utilisé 2 secondes de temps QPU sur un processeur Heron v2. Il s'agit d'une estimation uniquement. Ton utilisation réelle peut varier.

# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-aer qiskit-ibm-runtime
# Uncomment and modify this line as needed to install dependencies
#!pip install 'qiskit>=2.1.0' 'qiskit-ibm-runtime>=0.40.1' 'qiskit-aer>=0.17.0' 'numpy' 'pylatexenc'

Introduction

Dans les modules Qiskit en classe, tu auras l'occasion d'utiliser un ordinateur quantique pour explorer divers concepts dans des domaines adjacents à l'informatique quantique, comme la mécanique quantique, l'informatique, la chimie, et bien d'autres. Ce module constitue un prérequis aux autres — il présente les fondamentaux de l'informatique quantique et comment utiliser Qiskit pour exécuter des circuits quantiques.

Nous commencerons par un bref aperçu du fonctionnement d'un ordinateur classique, puis nous te montrerons comment ces concepts sont adaptés au paradigme de l'informatique quantique. Enfin, nous te montrerons comment assembler ces concepts pour construire et exécuter ton premier circuit quantique.

Les ordinateurs classiques

Tu connais probablement les bases du fonctionnement des ordinateurs classiques, mais ici nous allons mettre en évidence quelques caractéristiques clés afin de pouvoir les comparer aux ordinateurs quantiques.

Les unités de base de l'information : les bits

Les ordinateurs classiques traitent de l'information classique, et l'unité fondamentale de l'information classique est le bit. Un seul bit peut stocker la réponse à une question « oui/non ». On représente généralement les deux états binaires d'un bit par « 0 » et « 1 ».

Rappel sur les nombres binaires

Combiner des bits te permet de stocker davantage d'informations. Par exemple, si tu veux stocker un nombre de 0 à 15, tu peux le faire avec quatre bits de la manière suivante :

0 = 00004 = 01008 = 100012 = 1100
1 = 00015 = 01019 = 100113 = 1101
2 = 00106 = 011010 = 101014 = 1110
3 = 00117 = 011111 = 101115 = 1111

En général, pour convertir un nombre binaire de NN bits en un nombre familier en base 10, tu multiplies le bit le moins significatif (le plus à droite) par 20=12^0 = 1, le bit suivant à gauche par 21=22^1 = 2, puis le suivant par 22=42^2 = 4, et ainsi de suite jusqu'au bit le plus significatif (le plus à gauche), que tu multiplies par 2N12^{N-1}.

Ainsi, NN bits peuvent se trouver dans l'un des 2N2^N états possibles différents.

Vérifie ta compréhension

Lis la (les) question(s) ci-dessous, réfléchis à ta réponse, puis clique sur le triangle pour révéler la solution.

De combien de bits as-tu besoin pour représenter le nombre 86 ? Écris la chaîne de bits qui encode ce nombre en binaire.

Réponse :

Rappelle-toi que NN bits te permettent de représenter les nombres 00 à 2N12^N - 1, donc six bits nous amènerait jusqu'à 261=632^6 - 1 = 63. Ce n'est pas tout à fait suffisant. On ajoute un bit supplémentaire pour arriver jusqu'à 271=1272^7 - 1 = 127. Décomposons maintenant 86 en puissances de 2 :

86=64+16+4+2=26×1+25×0+24×1+23×0+22×1+21×1+20×0=1010110\begin{aligned} 86 &= 64 + 16 + 4 + 2 \\ &= 2^6 \times 1 + 2^5 \times 0 + 2^4 \times 1 + 2^3 \times 0 + 2^2 \times 1 + 2^1 \times 1 + 2^0 \times 0 \\ &= 1010110 \end{aligned}

Opérations fondamentales : les portes

Un ordinateur doit pouvoir faire quelque chose avec les bits pour, eh bien, calculer. Les portes binaires sont les opérations qui constituent les blocs de construction fondamentaux de tous les algorithmes et codes plus complexes.

Porte à un seul bit :

NOT

Quand tu n'as qu'un seul bit, il n'y a qu'une seule façon de transformer son état : basculer l'état de 0 à 1 ou de 1 à 0. On appelle cela la porte « NOT ». L'effet de cette porte — et des autres portes dont nous parlerons ci-dessous — peut être représenté dans une « table de vérité », avec des colonnes pour les états d'entrée et de sortie des qubits. La table de vérité de la porte NOT est :

EntréeSortie
01
10

Portes multi-bits :

AND

AND est une porte à deux bits qui prend deux bits en entrée et produit un seul bit en sortie. Elle produit 1 si les deux bits d'entrée sont 1, et 0 sinon :

EntréeSortie
000
010
100
111

OR

OR est une autre porte à deux bits avec un seul bit de sortie. Elle produit 1 si l'un ou l'autre des bits est 1 :

EntréeSortie
000
011
101
111

XOR

XOR signifie « OU exclusif » et ressemble à la porte OR, mais produit 1 si un seul des bits d'entrée est 1. Il produit 0 si les deux sont à 1 ou les deux à 0 :

EntréeSortie
000
011
101
110

Mesures :

En général, lorsqu'on apprend l'informatique classique, on accorde peu d'attention au processus de lecture de l'état des bits. C'est parce que ce n'est pas très complexe d'un point de vue conceptuel. Tu peux mesurer les bits à n'importe quel moment avant, pendant ou après un calcul, et cela n'affecte pas le résultat. Ce n'est pas le cas en informatique quantique, comme nous allons le voir ci-dessous.

Circuits :

En combinant les portes ci-dessus, tu peux effectuer n'importe quelle opération sur un ordinateur. Prenons un exemple simple : en utilisant les portes AND et XOR, tu peux construire le circuit demi-additionneur, qui calcule la somme de deux bits. Ceci est représenté dans un schéma de circuit logique, où les fils représentent les bits et les portes opérant sur les bits sont montrées comme des symboles sur les fils correspondants :

Schéma du circuit classique pour le circuit demi-additionneur. Une porte XOR génère le bit de somme (Sum) et une porte AND génère le bit de retenue (Carry).

Ainsi, les deux bits sont copiés et passés à la fois dans une porte AND et une porte XOR. Le résultat de la porte XOR est le « bit de somme » (S), qui reste dans la position des unités du nombre binaire, et le résultat de la porte AND est le « bit de retenue » (C), qui est la valeur du chiffre suivant le plus significatif dans le nombre binaire. Voici la table de vérité :

AABBSomme (ABA \oplus B)Retenue (ABA \wedge B)
0000
0110
1010
1101

Vérifie ta compréhension

Lis la (les) question(s) ci-dessous, réfléchis à ta réponse, puis clique sur le triangle pour révéler la solution.

Vérifie que la table de vérité ci-dessus donne la solution correcte pour un circuit additionneur. C'est-à-dire que pour chacune des quatre options de A et B, vérifie que A+B=S+2×CA+B=S+2 \times C.

Réponse :

0+0=0+0=0 0+1=1+0=1 1+0=1+0=1 1+1=0+2=2 \begin{aligned} 0+0 &= 0+0 = 0 ~\checkmark \\ 0+1 &= 1+0 = 1 ~\checkmark \\ 1+0 &= 1+0 = 1 ~\checkmark \\ 1+1 &= 0+2 = 2 ~\checkmark \\ \end{aligned}

Les ordinateurs quantiques

Bits \rightarrow qubits

Tout comme les bits sont les unités fondamentales de l'information classique, les bits quantiques, ou « qubits », sont les unités fondamentales de l'information quantique. Comme le bit classique, l'état d'un qubit peut être 0 ou 1, ce qu'on note généralement 0\vert 0\rangle et 1\vert 1\rangle. Mais contrairement au bit classique, un bit quantique peut aussi être dans une superposition à la fois de l'état 0\vert 0\rangle et de l'état 1\vert 1\rangle en même temps. En général, un qubit peut être dans n'importe quel état ψ\vert \psi\rangle de la forme :

ψ=c00+c11\vert \psi\rangle = c_0 \vert 0\rangle + c_1 \vert 1\rangle

c0c_0 et c1c_1 sont des amplitudes complexes avec c02+c12=1\vert c_0 \vert ^2+\vert c_1\vert ^2=1.

La phase quantique

Comme c0c_0 et c1c_1 sont complexes, chacun peut s'écrire ci=cieiϕic_i = \vert c_i\vert e^{i\phi_i}ϕi\phi_i est appelé la phase. Si on multiplie l'état entier par le même facteur de phase global, rien ne change physiquement — on appelle cela une phase globale, et elle n'a pas de conséquences observables.

Pour cette raison, il est conventionnel de « factoriser » eiϕ0e^{i\phi_0}, ce qui donne :

ψ=c00+c1eiϕ1\vert \psi\rangle = \vert c_0\vert \vert 0\rangle + \vert c_1\vert e^{i\phi}\vert 1\rangle

ϕ=ϕ1ϕ0\phi = \phi_1-\phi_0 est la phase relative de l'état quantique, qui a des conséquences observables.

Cette phase joue un rôle très important en informatique quantique, et tu exploreras ses diverses conséquences dans les modules Qiskit en classe suivants.

Plusieurs qubits

Alors que l'état de plusieurs bits pouvait simplement s'exprimer comme une chaîne de 0 et de 1, l'état de plusieurs qubits devient un peu plus complexe en raison des principes de superposition et d'intrication.

Rappelle-toi que NN bits pouvaient être dans l'un des 2N2^N états possibles allant des nombres binaires 000...000 à 111...111. Mais maintenant, grâce au principe de superposition, NN qubits peuvent être dans une superposition de tous ces états à la fois !

Ceci peut s'exprimer comme

ψN=i=02N1cii\psi_N = \sum_{i=0}^{2^N-1} c_i \vert i\rangle

où, comme dans le cas classique, l'état i\vert i\rangle correspond à l'état où chaque qubit est dans la bonne combinaison de 0 et de 1 pour donner le nombre binaire ii. Ces états sont connus sous le nom d'« états de base computationnels » du système quantique. Par exemple, un état à trois qubits peut s'écrire comme une superposition de ses huit états de base computationnels :

ψ3=c0000+c1001+c2010+c3011+c4100+c5101+c6110+c7111\psi_3 = c_0 \vert 000\rangle + c_1 \vert 001\rangle + c_2 \vert 010\rangle + c_3 \vert 011\rangle + c_4 \vert 100\rangle + c_5 \vert 101\rangle + c_6 \vert 110\rangle + c_7 \vert 111\rangle

Chaque qubit dans le système est désigné par un indice 00 à N1N-1. La convention est de lire les états des qubits de droite à gauche, de sorte que l'état du qubit 00 est le plus à droite et l'état du qubit N1N-1 est le plus à gauche. Cette notation est appelée « little-endian », et elle peut sembler contre-intuitive au premier abord, puisque nous avons l'habitude de lire de gauche à droite.

Vérifie ta compréhension

Lis la (les) question(s) ci-dessous, réfléchis à ta réponse, puis clique sur le triangle pour révéler la solution.

À première vue, il peut sembler contre-intuitif d'ordonner les qubits de droite à gauche comme dans la notation little-endian, mais c'est en fait une chose très logique à faire ! Explique pourquoi. (Rappelle-toi notre discussion ci-dessus sur la conversion binaire en base 10.)

Réponse :

Si on ordonne les qubits de droite à gauche, de sorte que le qubit 0 soit le plus à droite et le qubit N-1 le plus à gauche, il est logique d'associer le qubit 00 au bit le moins significatif, qui est multiplié par 202^0, et le qubit N1N-1 au bit le plus significatif, qui est multiplié par 2N12^{N-1}.

Intrication

Comme nous l'avons mentionné plus tôt, une autre caractéristique clé des qubits est qu'ils peuvent être intriqués les uns avec les autres. Prenons l'exemple d'un état à deux qubits, où c0=c3=12c_0 = c_3 = \frac{1}{\sqrt{2}} et c1=c2=0c_1 = c_2 = 0 :

ψ=12(00+11)\vert \psi\rangle = \frac{1}{\sqrt{2}}(\vert 00\rangle + \vert 11\rangle)

Ainsi, l'état du qubit 0 peut être soit 0\vert 0\rangle soit 1\vert 1\rangle avec une probabilité égale, de même pour l'état du qubit 1. Mais ces probabilités ne sont plus indépendantes l'une de l'autre. Si on trouve que l'état du qubit 0 est 0\vert 0\rangle, alors on sait que le qubit 1 sera aussi dans 0\vert 0\rangle. Cela est vrai quelle que soit la distance qui les sépare, c'est pourquoi l'acte de mesurer un état intriqué est parfois appelé « action fantôme à distance ».

L'intrication peut aussi prendre d'autres formes. Par exemple, l'état

ψ=12(01+10)\vert \psi\rangle = \frac{1}{\sqrt{2}}(\vert 01\rangle + \vert 10\rangle)

produit des résultats opposés à chaque fois : si un qubit est mesuré 0\vert 0\rangle, l'autre est garanti d'être trouvé dans l'état 1\vert 1\rangle.

Vérifie ta compréhension

Lis la (les) question(s) ci-dessous, réfléchis à ta réponse, puis clique sur le triangle pour révéler la solution.

L'état ψ=11\vert \psi\rangle = \vert 11\rangle est-il intriqué ? Pourquoi ou pourquoi pas ?

Réponse :

Il n'est pas intriqué. Bien que les résultats soient toujours les mêmes lorsqu'on mesure les deux qubits, c'est uniquement parce que chaque qubit est toujours fixé dans l'état 1\vert 1\rangle. Le résultat de la mesure d'un qubit ne dépend pas réellement de l'autre — les deux sont simplement toujours 1\vert 1\rangle.

En général, si tu peux décrire l'état de chaque qubit séparément et les multiplier ensemble comme ceci :

ψ=ψ1ψ0\vert \psi\rangle = \vert \psi_1\rangle \vert \psi_0\rangle

Alors c'est un « état produit » et il n'est pas intriqué.

Notation vectorielle

Il est souvent utile d'utiliser des vecteurs et des matrices pour voir comment l'état quantique se transforme sous différentes opérations. Dans cette représentation, nos états quantiques seront des vecteurs, et nos portes quantiques (abordées dans la section suivante) seront des matrices qui transforment les vecteurs.

Pour un seul qubit, les formes vectorielles des états sont choisies comme : 0=(10)\vert 0\rangle = \begin{pmatrix}1 \\ 0\end{pmatrix} 1=(01)\vert 1\rangle = \begin{pmatrix}0 \\ 1\end{pmatrix} Ainsi, un état arbitraire ψ=a0+b1\vert \psi\rangle = a\vert 0\rangle+b\vert 1\rangle peut s'écrire comme ψ=(ab)\vert \psi\rangle =\begin{pmatrix}a \\ b\end{pmatrix}

Pour un état général à nn qubits, nous aurons besoin d'un vecteur de dimension 2n2^n, avec les états de base ordonnés comme on pourrait s'y attendre, par valeur binaire croissante :

0000=(1000),0001=1110=(0010),1111=(0001)\vert 0 \dots 000\rangle = \begin{pmatrix}1 \\ 0 \\ 0 \\ \vdots \\ 0\end{pmatrix}, \vert 0 \dots 001 \rangle = \vert 1 \dots 110\rangle = \begin{pmatrix}0 \\ \vdots \\ 0 \\ 1 \\ 0\end{pmatrix}, \vert 1 \dots 111 \rangle = \begin{pmatrix}0 \\ \vdots \\ 0 \\ 0\\ 1\end{pmatrix}

Avec ce choix de notation vectorielle à l'esprit, nous pouvons introduire les portes quantiques nécessaires, leurs effets sur les états quantiques, et leurs formes matricielles.

Vérifie ta compréhension

Lis la (les) question(s) ci-dessous, réfléchis à ta réponse, puis clique sur le triangle pour révéler la solution.

Il y a quatre états de base computationnels pour un système à deux qubits. Écris chacun d'eux en notation ket et en notation vectorielle.

Réponse :

00=(1000),01=(0100),,10=(0010),11=(0001)\vert 00\rangle = \begin{pmatrix}1 \\ 0 \\ 0 \\ 0\end{pmatrix}, \vert 01 \rangle = \begin{pmatrix}0 \\ 1 \\ 0 \\ 0\end{pmatrix}, \dots, \vert 10\rangle = \begin{pmatrix}0 \\ 0 \\ 1 \\ 0\end{pmatrix}, \vert 11 \rangle = \begin{pmatrix}0 \\ 0 \\ 0\\ 1\end{pmatrix}

Portes \rightarrow portes quantiques

Tout comme les portes classiques telles que NOT, AND, OR et XOR peuvent être combinées pour construire des circuits classiques arbitraires, les portes quantiques jouent le même rôle en informatique quantique. Parce que les qubits possèdent des caractéristiques quantiques supplémentaires, les portes quantiques sont en conséquence plus riches. Bien qu'on puisse encore décrire leur action sur les états de base 0|0\rangle et 1|1\rangle avec une table de vérité, cela ne capture pas toute la réalité. Pour les portes quantiques, il est souvent plus naturel d'utiliser une représentation matricielle, car elles agissent aussi sur les superpositions d'états de base.

Ci-dessous, nous présenterons les portes quantiques les plus courantes et comment elles transforment les qubits avec lesquels elles interagissent. Le cas échéant, nous les relierons aux portes classiques familières.

Portes à un seul qubit

Porte XX : C'est l'équivalent quantique d'une opération NOT. Sa table de vérité ressemble exactement à la porte NOT classique :

EntréeSortie
0\vert 0\rangle1\vert 1\rangle
1\vert 1\rangle0\vert 0\rangle

Et la représentation matricielle :

X=(0110)X=\begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix}

Dans Qiskit, créer un circuit avec une porte XX ressemble à ceci :

from qiskit import QuantumCircuit

qc = QuantumCircuit(1)
qc.x(0)
qc.draw("mpl")

Sortie de la cellule de code précédente

Dans ce schéma de circuit très simple, le qubit est représenté par un fil, la ligne noire horizontale, et la porte apparaît comme une boîte sur ce fil.

Porte de Hadamard : Crée un état de superposition. Table de vérité :

EntréeSortie
0\vert 0\rangle12(0+1)\frac{1}{\sqrt{2}}\left(\vert 0\rangle+\vert 1\rangle\right)
1\vert 1\rangle12(01)\frac{1}{\sqrt{2}}\left(\vert 0\rangle-\vert 1\rangle\right)

Représentation matricielle : H=12(1111)H=\frac{1}{\sqrt{2}}\begin{pmatrix} 1 & 1 \\ 1 & -1 \end{pmatrix}

Un circuit avec une porte de Hadamard se crée comme suit :

from qiskit import QuantumCircuit

qc = QuantumCircuit(1)
qc.h(0)
qc.draw("mpl")

Sortie de la cellule de code précédente

Porte ZZ : Ajoute un déphasage de Δϕ=π\Delta \phi = \pi à l'état 1|1\rangle :

EntréeSortie
0\vert 0\rangle0\vert 0\rangle
1\vert 1\rangle1-\vert 1\rangle

Z=(1001)Z=\begin{pmatrix} 1 & 0 \\ 0 & -1 \end{pmatrix}

Dans Qiskit, créer un circuit avec une porte ZZ ressemble à ceci :

qc = QuantumCircuit(1)
qc.z(0)
qc.draw("mpl")

Sortie de la cellule de code précédente

Porte TT : Ajoute un déphasage de Δϕ=π/4\Delta \phi = \pi/4 à l'état 1|1\rangle :

EntréeSortie
0\vert 0\rangle0\vert 0\rangle
1\vert 1\rangleeiπ/41e^{i\pi/4}\vert 1\rangle

T=(100eiπ/4)T=\begin{pmatrix} 1 & 0 \\ 0 & e^{i\pi/4} \end{pmatrix}

Dans Qiskit, créer un circuit avec une porte TT ressemble à ceci :

qc = QuantumCircuit(1)
qc.t(0)
qc.draw("mpl")

Sortie de la cellule de code précédente

Portes multi-qubits

Les portes à deux qubits peuvent ressembler aux portes classiques à deux bits, mais avec une mise en garde importante : toutes les portes quantiques doivent être réversibles. En termes d'algèbre linéaire, cela signifie qu'elles sont représentées par des matrices unitaires. Ainsi, deux qubits en entrée sont toujours associés à deux qubits en sortie, et l'opération peut, en principe, être annulée. Cela contraste avec les portes classiques vues ci-dessus comme AND ou OR, qui perdent de l'information et sont irréversibles — à partir d'une sortie, tu ne peux pas déterminer de façon unique l'entrée.

Porte CNOT (Controlled-NOT) : Les deux qubits en entrée sont appelés les qubits « contrôle » et « cible ». Le qubit contrôle reste inchangé, mais son état dicte ce qui arrive au qubit cible. Si le qubit contrôle est dans l'état 1\vert 1\rangle, alors une porte XX est appliquée à la cible ; si l'état du qubit contrôle est 0\vert 0\rangle, aucun changement n'est effectué. Dans la notation ci-dessous, suppose que le qubit AA (le qubit le plus à droite) est le contrôle, et le qubit BB (le plus à gauche) est la cible. La notation utilisée est CNOT(qcontrol,qtarget)BA.CNOT(q_{control},q_{target})\vert BA\rangle.

CNOT(A,B)BAinput=BAoutputCNOT(A,B)\vert BA\rangle_{input} = \vert BA\rangle_{output}

EntréeSortie
00\vert 00\rangle00\vert 00\rangle
01\vert 01\rangle11\vert 11\rangle
10\vert 10\rangle10\vert 10\rangle
11\vert 11\rangle01\vert 01\rangle

Donc la matrice représentant cette action est :

CNOT=(1000000100100100)CNOT=\begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0\end{pmatrix}

qc = QuantumCircuit(2)
qc.cx(0, 1)
qc.draw("mpl")

Sortie de la cellule de code précédente

C'est le premier schéma de circuit que nous voyons avec deux qubits, représentés par les deux fils. La porte CNOT est implémentée entre les deux qubits, avec q0q_0 comme contrôle et q1q_1 comme cible.

Vérifie ta compréhension

Lis la (les) question(s) ci-dessous, réfléchis à ta réponse, puis clique sur le triangle pour révéler la solution.

La plupart des portes ont la même forme matricielle dans Qiskit qu'ailleurs. Mais la porte CNOT agit sur deux qubits, et donc les conventions d'ordonnancement des qubits deviennent soudainement un problème. Les textes qui ordonnent les qubits q0,q1,...\vert q_0,q_1,...\rangle afficheront une forme matricielle différente pour leurs portes CNOT. Vérifie par multiplication matricielle explicite que la matrice CNOT ci-dessus a l'action correcte sur l'état 01.\vert 01\rangle.

Réponse :

CNOT01=(1000000100100100)(0100)=(0001)=11CNOT\vert 01\rangle =\begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0\end{pmatrix}\begin{pmatrix}0 \\ 1 \\ 0 \\0\end{pmatrix} = \begin{pmatrix}0 \\ 0 \\ 0 \\1\end{pmatrix} = \vert 11\rangle

Porte SWAP : Cette porte échange les états de deux qubits. Table de vérité :

EntréeSortie
00\vert 00\rangle00\vert 00\rangle
01\vert 01\rangle10\vert 10\rangle
10\vert 10\rangle01\vert 01\rangle
11\vert 11\rangle11\vert 11\rangle

Donc la matrice représentant cette action est :

SWAP=(1000001001000001)SWAP=\begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1\end{pmatrix}

qc = QuantumCircuit(2)
qc.swap(0, 1)
qc.draw("mpl")

Sortie de la cellule de code précédente

La porte SWAP peut en fait être construite à partir de trois CNOTs. Pour voir comment, on peut decompose() la porte avec Qiskit :

qc = QuantumCircuit(2)
qc.swap(0, 1)
qc.decompose().draw("mpl")

Sortie de la cellule de code précédente

Ici, nous voyons pour la première fois comment plusieurs portes sont affichées dans un schéma de circuit. On le lit de gauche à droite, donc la porte la plus à gauche est appliquée en premier.

Vérifie ta compréhension

Lis la (les) question(s) ci-dessous, réfléchis à ta réponse, puis clique sur le triangle pour révéler la solution.

Vérifie que la combinaison de CNOTs ci-dessus donne une porte SWAP. Tu peux le faire par multiplication matricielle ou toute autre méthode.

Réponse :

Par multiplication matricielle :

(1000000100100100)(1000010000010010)(1000000100100100)=(1000001001000001)=SWAP \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0\end{pmatrix} \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0\end{pmatrix} \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0\end{pmatrix} = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1\end{pmatrix} = SWAP ~\checkmark

En utilisant une table de vérité pour voir comment les états changent avec chaque CNOT. Dans la dernière colonne, les états doivent être équivalents à la colonne « sortie » de la table de vérité SWAP :

EntréeCNOT(A,B)CNOT(B,A)CNOT(A,B)
00\vert 00\rangle00\vert 00\rangle00\vert 00\rangle00\vert 00\rangle \checkmark
01\vert 01\rangle11\vert 11\rangle10\vert 10\rangle10\vert 10\rangle \checkmark
10\vert 10\rangle10\vert 10\rangle11\vert 11\rangle01\vert 01\rangle \checkmark
11\vert 11\rangle01\vert 01\rangle01\vert 01\rangle11\vert 11\rangle \checkmark

Porte de Toffoli (ou « controlled-controlled-NOT » (CCNOT)) : C'est une porte à trois qubits. Le nom « controlled-controlled-NOT » t'indique peut-être déjà comment il fonctionne : il y a deux qubits de contrôle et un qubit cible, et l'état du qubit cible est basculé uniquement si les deux qubits de contrôle sont dans l'état 1\vert 1\rangle. Nous conservons la convention d'ordonnancement utilisée avec le CNOT :

CCNOT(ControlA,ControlB,TargetC)CBACCNOT(Control A, Control B, Target C)\vert CBA\rangle

Donc la table de vérité est :

EntréeSortie
000\vert 000\rangle000\vert 000\rangle
001\vert 001\rangle001\vert 001\rangle
010\vert 010\rangle010\vert 010\rangle
011\vert 011\rangle111\vert 111\rangle
100\vert 100\rangle100\vert 100\rangle
101\vert 101\rangle101\vert 101\rangle
110\vert 110\rangle110\vert 110\rangle
111\vert 111\rangle011\vert 011\rangle

Et la matrice représentant cette action est :

CCNOT=(1000000001000000001000000000000100001000000001000000001000010000)CCNOT=\begin{pmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\ 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\end{pmatrix}
qc = QuantumCircuit(3)
qc.ccx(0, 1, 2)
qc.draw("mpl")

Sortie de la cellule de code précédente

La porte de Toffoli peut elle aussi être décomposée en CNOTs, ainsi que d'autres portes. Cependant, c'est significativement plus complexe que la décomposition de la porte SWAP, donc ce sera laissé comme exercice optionnel à la fin du module pour explorer et vérifier cette décomposition.

Mesures

Les mesures jouent un rôle spécial en informatique quantique — un rôle sans analogue dans l'informatique classique. Alors qu'en informatique classique, tu peux vérifier tes bits à n'importe quel moment de ton choix durant un algorithme, en informatique quantique, tu dois être très sélectif sur le moment où tu regardes tes qubits, car la mesure effondre leur état et détruit la superposition qui confère aux qubits leur complexité computationnelle.

En particulier, étant donné un état quantique à NN bits ψ=i=02N1cii\vert \psi\rangle = \sum_{i=0}^{2^N-1} c_i \vert i\rangle, une mesure va effondrer l'état vers l'une des fonctions de base i\vert i\rangle avec une probabilité égale à ci2\vert c_i\vert ^2.

Mais cet effet destructeur d'une mesure n'est pas toujours un obstacle. C'est en fait une ressource clé dans certains algorithmes et protocoles, comme la téléportation quantique et la distribution de clés quantiques.

Dans Qiskit, quand une mesure est effectuée, elle est envoyée dans un registre classique où elle est stockée comme un bit classique. Créer un circuit avec une mesure ressemble à ceci :

qc = QuantumCircuit(
1, 1
) # the second number is the number of classical bits in the circuit
qc.measure(0, 0)
qc.draw("mpl")

Sortie de la cellule de code précédente

Circuits

Maintenant que nous savons comment fonctionnent les qubits, les portes et les mesures, construisons et exécutons notre propre circuit quantique ! Pour cela, nous devons te présenter un flux de travail utile appelé les patterns Qiskit.

Le framework des patterns Qiskit

Le framework des patterns Qiskit est une procédure générale pour aborder et résoudre des problèmes avec un ordinateur quantique. Il se compose de quatre étapes :

  1. Correspondance : associer notre problème à des circuits et des opérateurs quantiques
  2. Optimisation : optimiser le circuit pour le matériel cible
  3. Exécution : exécuter sur le matériel cible
  4. Post-traitement : post-traiter nos résultats

Pour illustrer ces étapes, nous allons implémenter une version quantique du circuit demi-additionneur discuté ci-dessus.

1. Mapping

Le circuit additionneur classique utilise une porte XOR et une porte AND pour calculer respectivement les bits de somme et de retenue. Nous pouvons adapter ces portes au contexte quantique pour créer le demi-additionneur quantique. D'abord, en se souvenant que les portes quantiques sont réversibles, nous ne pouvons pas simplement écraser les entrées. Au lieu de cela, nous introduisons deux qubits auxiliaires initialisés à 0\vert 0\rangle pour stocker les sorties de somme et de retenue. Ainsi, notre état quantique complet sera composé des qubits AA et BB, et des qubits de somme et de retenue, que nous noterons SS et CC :

ψ=CSBA\vert \psi\rangle = \vert C S B A\rangle

Maintenant, nous avons besoin de portes quantiques qui accomplissent ce que faisaient les portes XOR et AND dans le circuit classique.

Somme :

Pour le XOR, nous appliquons deux CNOTs, chacun avec les qubits de contrôle AA et BB et le qubit cible SS pour les deux. Si AA et BB sont différents, alors l'une des portes CNOT basculera SS dans l'état 1\vert 1\rangle. Si AA et BB sont tous les deux 0\vert 0\rangle, alors rien n'arrive à SS et il reste dans l'état 0\vert 0\rangle. Si AA et BB sont tous les deux 1\vert 1\rangle, alors l'état de SS basculera deux fois, le ramenant à l'état 0\vert 0\rangle.

Retenue :

Pour le bit de retenue, nous avons besoin de quelque chose qui fonctionne comme la porte AND classique.

Vérifie ta compréhension

Lis la (les) question(s) ci-dessous, réfléchis à ta réponse, puis clique sur le triangle pour révéler la solution.

Parcours les portes que nous avons abordées pour voir si tu peux deviner quelle porte quantique nous utiliserons à la place de la porte AND classique :

Réponse :

C'est la porte de Toffoli ! Rappelle-toi que la porte de Toffoli, ou controlled-controlled-NOT, bascule l'état cible si et seulement si le qubit de contrôle 0 ET le qubit de contrôle 1 sont tous les deux 1\vert 1\rangle. Donc, si le qubit cible commence dans l'état 0\vert 0\rangle, alors elle a la même action que la porte AND.

Nous avons donc maintenant tous les ingrédients dont nous avons besoin pour construire le circuit quantique :

# qubits: a, b, sum, carry
qc = QuantumCircuit(4)

# Choose values for A and B:
a = 0
b = 0

# Prepare A and B qubits according to selected values:
if a:
qc.x(0)
if b:
qc.x(1)

# XOR (sum) into qubit 2
qc.cx(0, 2)
qc.cx(1, 2)

# AND (carry) into qubit 3
qc.ccx(0, 1, 3) # a AND b

# measure
qc.measure_all()

qc.draw("mpl")

Sortie de la cellule de code précédente

Ci-dessus se trouve le schéma de circuit pour le circuit demi-additionneur quantique. Comme mentionné précédemment, les fils représentent les qubits 00 à 33 ordonnés de haut en bas, et le registre de bits classiques est le fil double ligné en bas. Ensuite, en lisant de gauche à droite, nous voyons comment les portes sont appliquées à chaque qubit en observant où les boîtes apparaissent sur les fils correspondants. Enfin, les mesures sont montrées à la fin. Les mesures effondrent les états des qubits vers des valeurs définies 00 ou 11, et les résultats sont envoyés à un registre classique.

Une subtilité : bien que le schéma de circuit soit dessiné de gauche à droite, quand on écrit l'expression matricielle correspondante, on doit la lire de droite à gauche. C'est parce qu'en multiplication matricielle, l'opérateur le plus proche du vecteur d'état agit en premier. Donc, par exemple, le circuit ci-dessus (en ignorant les mesures) s'écrirait comme :

CCNOT(q0,q1,q3)CNOT(q1,q2)CNOT(q0,q2)q3q2q1q0CCNOT(q_0,q_1,q_3)CNOT(q_1, q_2)CNOT(q_0,q_2)\vert q_3 q_2 q_1 q_0\rangle

2. Optimizing :

Ensuite, nous devons optimiser le circuit pour l'exécuter sur le matériel quantique. Cette optimisation est accomplie grâce au transpiler, qui traduit le circuit abstrait montré ci-dessus en instructions que l'ordinateur quantique comprendra. Il assigne les qubits logiques ci-dessus à de vrais qubits physiques sur le processeur et réécrit les portes en termes de son propre ensemble natif de portes optimisées pour fonctionner sur l'ordinateur quantique. Enfin, le transpiler implémente également quelque chose appelé « suppression et mitigation d'erreurs » pour essayer de minimiser l'effet des erreurs sur le résultat. Ce n'est pas si important pour notre circuit très simple, mais si tu continues ton parcours en informatique quantique en exécutant des circuits plus complexes, tu verras bientôt la valeur de la suppression et de la mitigation d'erreurs. Si tu veux en savoir plus, consulte le cours d'Olivia Lane, L'informatique quantique en pratique.

D'abord, nous chargeons les packages nécessaires pour communiquer avec les ordinateurs quantiques IBM® et nous sélectionnons un backend sur lequel exécuter. Nous pouvons choisir le backend le moins occupé, ou sélectionner un backend spécifique dont nous connaissons les propriétés.

Il y a du code ci-dessous pour sauvegarder tes identifiants lors de la première utilisation. Assure-toi de supprimer ces informations du notebook après les avoir sauvegardées dans ton environnement, afin que tes identifiants ne soient pas accidentellement partagés lorsque tu partages le notebook. Consulte Configurer ton compte IBM Cloud et Initialiser le service dans un environnement non fiable pour plus d'informations.

# Load the Qiskit Runtime service
from qiskit_ibm_runtime import QiskitRuntimeService

# Load the Qiskit Runtime service

# Syntax for first saving your token. Delete these lines after saving your credentials.
# QiskitRuntimeService.save_account(channel='ibm_quantum_platform', instance = '<YOUR_IBM_INSTANCE_CRN>', token='<YOUR-API_KEY>', overwrite=True, set_as_default=True)
# service = QiskitRuntimeService(channel='ibm_quantum_platform')

# Load saved credentials
service = QiskitRuntimeService()

# Use the least busy backend, or uncomment the loading of a specific backend like "ibm_brisbane".
backend = service.least_busy(operational=True, simulator=False, min_num_qubits=127)
# backend = service.backend("ibm_brisbane")
print(backend.name)
ibm_fez

Maintenant, nous utilisons le transpiler pour optimiser le circuit. Nous pouvons choisir le niveau d'optimisation de 0 (aucune optimisation) à 3 (optimisation maximale). Pour voir ce que chaque niveau implique, consulte le guide Définir le niveau d'optimisation du transpiler. Le circuit résultant aura l'air significativement différent du circuit logique que nous avons créé lors de l'étape de mapping.

# Transpile the circuit and optimize for running on the quantum computer selected
# Step 2: Transpile
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager

target = backend.target
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)

qc_isa.draw("mpl")

Sortie de la cellule de code précédente

Un « Sampler » est une primitive conçue pour échantillonner les états possibles résultant d'un circuit quantique, et collecter des statistiques sur quels états pourraient être mesurés et avec quelle probabilité. Nous importons ici le Sampler Qiskit Runtime :

# Load the Runtime primitive and session
from qiskit_ibm_runtime import SamplerV2 as Sampler

sampler = Sampler(mode=backend)

Si tu as épuisé ton temps alloué sur de vrais ordinateurs quantiques ou si tu n'as pas de connexion Internet, tu préféreras peut-être utiliser un simulateur. Pour ce faire, exécute la cellule ci-dessous et décommente la ligne associée dans l'étape « Execute ».

# Load the backend sampler
from qiskit.primitives import BackendSamplerV2

# Load the Aer simulator and generate a noise model based on the currently-selected backend.
from qiskit_aer import AerSimulator
from qiskit_aer.noise import NoiseModel

noise_model = NoiseModel.from_backend(backend)

# Define a simulator using Aer, and use it in Sampler.
backend_sim = AerSimulator(noise_model=noise_model)
sampler_sim = BackendSamplerV2(backend=backend_sim)

# Alternatively, load a fake backend with generic properties and define a simulator.
# backend_gen = GenericBackendV2(num_qubits=18)
# sampler_gen = BackendSamplerV2(backend=backend_gen)

3. Executing

Après avoir préparé le circuit, nous pouvons maintenant l'exécuter sur l'ordinateur quantique !

job = sampler.run([qc_isa], shots=100)
# job = sampler_sim.run([qc_isa]) # uncomment if you want to run on a simulator
res = job.result()
counts = res[0].data.meas.get_counts()

4. Post-processing

Nous sommes maintenant prêts à visualiser nos résultats ! Nous allons afficher un histogramme des 100 échantillons du circuit.

from qiskit.visualization import plot_histogram

print("counts = ", counts)
plot_histogram(counts)
counts =  {'0000': 90, '0100': 4, '1100': 3, '0010': 3}

Sortie de la cellule de code précédente

L'histogramme ci-dessus montre les résultats de mesure des quatre qubits à la fin du circuit. Un ordinateur quantique idéal sans bruit aurait mesuré les qubits avec les mêmes valeurs à chaque fois, mais en réalité, le bruit va faire en sorte que certaines des exécutions produisent des erreurs.

Vérifie ta compréhension

Lis la (les) question(s) ci-dessous, réfléchis à ta réponse, puis clique sur le triangle pour révéler la solution.

En utilisant la chaîne de bits avec le plus grand nombre de comptages comme valeurs pour AA, BB, SS et CC, vérifie que le circuit additionneur quantique a fonctionné.

Réponse :

Nous devons vérifier que A+B=S+2×CA+B = S+2 \times C. Rappelle-toi que l'ordre de la chaîne de bits suit la notation little-endian, donc elle se lit CSBA.

D'après l'histogramme ci-dessus, nous voyons que la chaîne de bits 0000 est la dominante.

0+0=0+0×2=0 0 + 0 = 0 + 0 \times 2 = 0 ~\checkmark

Reviens en arrière et change les valeurs de AA et BB à A=1A=1 et B=1B=1, puis repasse par les étapes des patterns Qiskit pour réexécuter le circuit. Vérifie que le circuit additionneur a fonctionné à nouveau.

Réponse :

Tu devrais obtenir un histogramme avec la chaîne de bits dominante étant 1011 :

1+1=0+1×2=2 1 + 1 = 0 + 1 \times 2 = 2 ~\checkmark

L'une des fonctionnalités supplémentaires du demi-additionneur quantique par rapport au demi-additionneur classique est qu'il peut fonctionner avec des entrées quantiques. C'est-à-dire qu'il peut « additionner » les qubits AA et BB même s'ils sont dans des états de superposition. Dans la section Questions Défi ci-dessous, tu seras invité à préparer les qubits en superpositions et à voir ce qui se passe !

Conclusion

Ce module a été conçu pour te donner une solide compréhension fondamentale des principes de base de l'informatique quantique en la comparant à l'informatique classique. Nous avons examiné le circuit demi-additionneur classique, puis t'avons montré comment adapter le circuit pour fonctionner avec des qubits sur un ordinateur quantique. Tu es maintenant prêt à explorer les autres modules Qiskit en classe !

Concepts clés :

  • Contrairement aux bits classiques qui ne peuvent prendre que les valeurs 0 et 1, les qubits peuvent aussi être dans des états de superposition à la fois de 0 et de 1.
  • Plusieurs qubits peuvent être dans une superposition sur les chaînes de bits classiquement autorisées, appelées états de base computationnels.
  • Plusieurs qubits peuvent être intriqués de sorte que l'état de l'un dépende de l'état de l'autre.
  • La convention Qiskit est d'utiliser la notation little-endian, qui place le qubit le moins significatif, q0q_0, dans la position la plus à droite et le qubit le plus significatif, qNq_N, le plus à gauche.
  • Les portes quantiques sont des opérations réversibles représentées par des matrices unitaires qui agissent sur les vecteurs d'état quantiques. Dans cette notation, la matrice la plus proche du vecteur (la plus à droite) agit en premier.
  • Les mesures effondrent un état de superposition quantique vers l'un de ses états classiquement autorisés, avec une probabilité égale au carré de l'amplitude de l'état de base computationnel correspondant dans la superposition.
  • Les circuits quantiques sont souvent représentés à l'aide de schémas de circuits quantiques, où les qubits sont représentés par des fils horizontaux, et les portes quantiques apparaissent le long de ces fils de gauche à droite.
  • Pour exécuter un circuit quantique, nous utilisons les quatre étapes du flux de travail des patterns Qiskit : Map, Optimize, Execute, Post-process.

Questions

Questions Vrai/Faux

  1. Un seul bit dans un ordinateur classique peut seulement contenir la valeur 0 ou 1.

  2. L'intrication signifie que l'état d'un qubit est indépendant de l'état d'un autre.

  3. Les portes quantiques sont généralement des opérations irréversibles.

  4. La convention Qiskit place le qubit le moins significatif, q0q_0, dans la position la plus à gauche.

  5. Mesurer un état quantique donne toujours exactement le même résultat si on le répète plusieurs fois.

  6. La porte de Hadamard crée une superposition dans un seul qubit.

  7. Les circuits quantiques peuvent inclure des opérations de mesure qui effondrent l'état de superposition vers l'un des états classiquement autorisés.

  8. Le nombre d'états classiques possibles pour NN bits est 2N2N.

  9. Les probabilités de résultat pour les mesures quantiques sont données par les amplitudes au carré des états de base classiquement mesurables.

Questions à réponse courte

  1. Quelles sont certaines des différences principales entre un bit et un qubit ?

  2. Que se passe-t-il pour un état quantique lorsqu'il est mesuré ?

  3. Pourquoi utilise-t-on la notation little-endian dans Qiskit ?

  4. Quelles sont les quatre étapes du flux de travail des patterns Qiskit ?

Questions Défi :

  1. Dans le module, nous n'avons utilisé l'additionneur qu'avec des états classiquement autorisés pour AA et BB. Mais nous pouvons aussi préparer AA et BB en superpositions ! Modifie le code pour préparer chaque qubit dans une superposition égale de 0 et 1, puis exécute le nouveau circuit et obtiens un nouvel histogramme. Que vois-tu ? Explique ce qui se passe.

  2. Décomposition de la porte de Toffoli. Utilise decompose() pour montrer comment la porte de Toffoli est décomposée en portes à un et deux qubits, puis vérifie cette construction par multiplication matricielle. Garde à l'esprit que bien que les schémas de circuits se lisent de gauche à droite, les matrices sont appliquées aux états quantiques de droite à gauche !