Aller au contenu principal

Implémentation avec Qiskit

Dans la leçon précédente, nous avons découvert les classes Statevector et Operator de Qiskit, et nous les avons utilisées pour simuler des opérations et des mesures sur des qubits individuels. Dans cette section, nous allons utiliser ces classes pour explorer le comportement de plusieurs qubits.

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit
from qiskit import __version__

print(__version__)
2.1.1

Commençons par importer les classes Statevector et Operator, ainsi que la fonction racine carrée de NumPy. À partir de maintenant, en règle générale, nous prendrons soin d'effectuer tous les imports nécessaires en premier dans chaque leçon.

from qiskit.quantum_info import Statevector, Operator
from numpy import sqrt

Produits tensoriels

La classe Statevector dispose d'une méthode tensor, qui renvoie le produit tensoriel de ce Statevector avec un autre, passé en argument. L'argument est interprété comme le facteur tensoriel de droite.

Par exemple, ci-dessous nous créons deux vecteurs d'état représentant 0\vert 0\rangle et 1,\vert 1\rangle, et utilisons la méthode tensor pour créer un nouveau vecteur, ψ=01.\vert \psi\rangle = \vert 0\rangle \otimes \vert 1\rangle. Remarque : ici, nous utilisons la méthode from_label pour définir les états 0\vert 0\rangle et 1,\vert 1\rangle, plutôt que de les définir nous-mêmes.

zero = Statevector.from_label("0")
one = Statevector.from_label("1")
psi = zero.tensor(one)
display(psi.draw("latex"))

01 |01\rangle

Les autres labels autorisés incluent "+" et "-" pour les états plus et moins, ainsi que "r" et "l" (abréviation de "right" et "left", c'est-à-dire droite et gauche) pour les états

+i=120+i21eti=120i21.\vert {+i} \rangle = \frac{1}{\sqrt{2}} \vert 0 \rangle + \frac{i}{\sqrt{2}} \vert 1 \rangle \qquad\text{et}\qquad \vert {-i} \rangle = \frac{1}{\sqrt{2}} \vert 0 \rangle - \frac{i}{\sqrt{2}} \vert 1 \rangle.

Ici, "+" , "-" ou "right" et "left" proviennent du contexte du spin en mécanique quantique, dans lequel une composante du spin peut pointer vers la gauche ou vers la droite lors d'une expérience ; cela ne fait pas référence au qubit le plus à droite ou le plus à gauche dans des systèmes à plusieurs qubits. Voici un exemple du produit tensoriel de +\vert {+} \rangle et i.\vert {-i} \rangle.

plus = Statevector.from_label("+")
minus_i = Statevector.from_label("l")
phi = plus.tensor(minus_i)
display(phi.draw("latex"))

1200i201+1210i211\frac{1}{2} |00\rangle- \frac{i}{2} |01\rangle+\frac{1}{2} |10\rangle- \frac{i}{2} |11\rangle

Une alternative consiste à utiliser l'opération ^ pour les produits tensoriels, ce qui donne naturellement les mêmes résultats.

display((plus ^ minus_i).draw("latex"))

1200i201+1210i211\frac{1}{2} |00\rangle- \frac{i}{2} |01\rangle+\frac{1}{2} |10\rangle- \frac{i}{2} |11\rangle

La classe Operator dispose également d'une méthode tensor (ainsi qu'une méthode from_label), comme on peut le voir dans les exemples suivants.

H = Operator.from_label("H")
Id = Operator.from_label("I")
X = Operator.from_label("X")
display(H.tensor(Id).draw("latex"))
display(H.tensor(Id).tensor(X).draw("latex"))
[220220022022220220022022] \begin{bmatrix} \frac{\sqrt{2}}{2} & 0 & \frac{\sqrt{2}}{2} & 0 \\ 0 & \frac{\sqrt{2}}{2} & 0 & \frac{\sqrt{2}}{2} \\ \frac{\sqrt{2}}{2} & 0 & - \frac{\sqrt{2}}{2} & 0 \\ 0 & \frac{\sqrt{2}}{2} & 0 & - \frac{\sqrt{2}}{2} \\ \end{bmatrix} [02200022002200022000000220002200220002200220002200220002200000022000220022000220] \begin{bmatrix} 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 \\ \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 \\ 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} \\ 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 \\ 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 & 0 \\ \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 & 0 & 0 \\ 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} \\ 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 \\ \end{bmatrix}

De même que pour les vecteurs, l'opération ^ est équivalente.

display((H ^ Id ^ X).draw("latex"))
[02200022002200022000000220002200220002200220002200220002200000022000220022000220] \begin{bmatrix} 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 \\ \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 \\ 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} \\ 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 \\ 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 & 0 \\ \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 & 0 & 0 \\ 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} \\ 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 \\ \end{bmatrix}

Les états composés peuvent être fait évoluer à l'aide d'opérations composées, comme on pourrait s'y attendre — tout comme nous l'avons vu pour les systèmes simples dans la leçon précédente. Par exemple, le code suivant calcule l'état (HI)ϕ(H\otimes I)\vert\phi\rangle pour ϕ=+i\vert\phi\rangle = \vert + \rangle \otimes \vert {-i}\rangle (qui a déjà été défini ci-dessus).

display(phi.evolve(H ^ Id).draw("latex"))

22002i201\frac{\sqrt{2}}{2} |00\rangle- \frac{\sqrt{2} i}{2} |01\rangle

Voici du code qui définit une opération CXCX et calcule CXψCX \vert\psi\rangle pour ψ=+0.\vert\psi\rangle = \vert + \rangle \otimes \vert 0 \rangle. Pour être précis, il s'agit d'une opération CXCX pour laquelle le qubit de gauche est le contrôle et le qubit de droite est la cible. Le résultat est l'état de Bell ϕ+.\vert\phi^{+}\rangle.

CX = Operator([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]])
psi = plus.tensor(zero)
display(psi.evolve(CX).draw("latex"))

2200+2211\frac{\sqrt{2}}{2} |00\rangle+\frac{\sqrt{2}}{2} |11\rangle

Mesures partielles

Dans la leçon précédente, nous avons utilisé la méthode measure pour simuler une mesure d'un vecteur d'état quantique. Cette méthode renvoie deux éléments : le résultat de mesure simulé, et le nouveau Statevector compte tenu de cette mesure.

Par défaut, measure mesure tous les qubits du vecteur d'état. On peut également fournir une liste d'entiers en argument, ce qui entraîne la mesure uniquement des indices de qubits spécifiés. Pour illustrer cela, le code ci-dessous crée l'état

w=001+010+1003\vert w\rangle = \frac{\vert 001\rangle + \vert 010\rangle + \vert 100\rangle}{\sqrt{3}}

et mesure le qubit numéro 0, qui est le qubit le plus à droite. (Qiskit numérote les qubits en commençant par 0, de droite à gauche. Nous reviendrons sur cette convention de numérotation dans la prochaine leçon.)

w = Statevector([0, 1, 1, 0, 1, 0, 0, 0] / sqrt(3))
display(w.draw("latex"))

result, state = w.measure([0])
print(f"Measured: {result}\nState after measurement:")
display(state.draw("latex"))

result, state = w.measure([0, 1])
print(f"Measured: {result}\nState after measurement:")
display(state.draw("latex"))

33001+33010+33100\frac{\sqrt{3}}{3} |001\rangle+\frac{\sqrt{3}}{3} |010\rangle+\frac{\sqrt{3}}{3} |100\rangle

Measured: 0
State after measurement:

22010+22100\frac{\sqrt{2}}{2} |010\rangle+\frac{\sqrt{2}}{2} |100\rangle

Measured: 00
State after measurement:

100 |100\rangle