Note
Cette page a été générée à partir de tutorials/circuits/01_circuit_basics.ipynb.
Principes de base des circuits¶
Ici, nous vous présentons une vue d’ensemble de l’utilisation de Qiskit. Le package fondamental de Qiskit est Terra qui fournit les éléments de base nécessaires à la programmation des ordinateurs quantiques. L’unité fondamentale de Qiskit est le circuit quantique. Un workflow de base en utilisant Qiskit se compose de deux étapes : Build et Execute. Build vous permet de construire différents circuits quantiques qui représentent le problème que vous êtes en train de résoudre, et Execute qui vous permet de les exécuter sur différents backends. Après que les travaux ont été exécutés, les données sont collectées et traitées en fonction du résultat souhaité.
[1]:
import numpy as np
from qiskit import QuantumCircuit
Construction du circuit¶
L’élément de base dont vous aurez besoin pour un premier programme est le QuantumCircuit (circuit quantique). Nous commençons par créer un QuantumCircuit
constitué de 3 qubits.
[2]:
# Create a Quantum Circuit acting on a quantum register of three qubits
circ = QuantumCircuit(3)
Après avoir créé le circuit avec ses registres, vous pouvez ajouter les portes (« opérations ») pour manipuler les registres. En parcourant les tutoriels vous trouverez davantage de portes et de circuits ; ci-dessous un exemple de circuit quantique qui crée un état GHZ avec 3 qubits
Pour créer un tel état, nous démarrons avec un registre quantique de 3 qubits. Par défaut, chaque qubit du registre est initialisé à \(|0\rangle\). Pour créer l’état GHZ, on applique les portes suivantes: - Une porte Hadamard \(H\) sur le qubit 0, qui le place dans un état de superposition \(\left(|0\rangle+|1\rangle\right)/\sqrt{2}\). - Une opération « controlled-Not » (NON-contrôlé ou C-not) (\(C_{X}\)) entre le qubit 0 et le qubit 1. - Une opération « controlled-Not » (C-not) entre le qubit 0 et le qubit 2.
Dans un calculateur quantique parfait, l’état produit en lançant ce circuit serait l’état GHZ ci-dessus.
Dans Qiskit, les opérations peuvent être ajoutées au circuit une par une, comme montré ci-dessous.
[3]:
# Add a H gate on qubit 0, putting this qubit in superposition.
circ.h(0)
# Add a CX (CNOT) gate on control qubit 0 and target qubit 1, putting
# the qubits in a Bell state.
circ.cx(0, 1)
# Add a CX (CNOT) gate on control qubit 0 and target qubit 2, putting
# the qubits in a GHZ state.
circ.cx(0, 2)
[3]:
<qiskit.circuit.instructionset.InstructionSet at 0x7f7c92288310>
Visualisation du circuit¶
Vous pouvez visualiser le circuit en utilisant Qiskit QuantumCircuit.draw()
, qui dessinera le circuit de la façon dont on le voit dans de nombreux ouvrages.
[4]:
circ.draw('mpl')
[4]:
Dans le circuit, les qubits sont mis dans un ordre où le qubit 0 sera en haut et le qubit 2 en bas. Le circuit est lu de gauche à droite (ce qui signifie que les portes appliquées en premiers sont celles de gauche et ainsi de suite).
Lorsqu’on représente l’état d’un système à plusieurs qubits, l’ordre des produits tensoriels utilisé dans Qiskit est différent de celui de la plupart des manuels de physique. Supposons qu’il y a \(n\) qubits, et que le qubit \(j\) est étiqueté comme \(Q_{j}\). Qiskit utilise un ordre dans lequel le qubit :math:` n^{ mathrm{th}} ` est sur le côté gauche du produit tensoriel, de sorte que les vecteurs de base sont marqués comme :math:` Q_{n-1}otimes cdots otimes Q_1otimes Q_0 `.
Par exemple, si le qubit zéro est dans l’état 0, le qubit 1 est dans l’état 0, le qubit 2 dans l’état 1, Qiskit représentera cet état par \(|100\rangle\), tandis que de nombreux manuels de physiques l’auraient représenté par \(|001\rangle\).
Cette différence d’affichage affecte la façon dont les opérations multi-qubits sont représentées en tant que matrices. Par exemple, Qiskit représente une opération Control-X (\(C_{X}\)) avec un qubit 0 étant le qubit de contrôle et un qubit 1 qui est la cible par
Simulation des circuits¶
Pour simuler un circuit, nous utilisons le module quant_info de Qiskit. Ce simulateur renvoie l’état quantique, qui est un vecteur complexe de dimension \(2^n\), où \(n\) est le nombre de qubits (alors soyez prudent en utilisant ceci car il va rapidement devenir trop grand pour s’exécuter sur votre machine).
Il y a deux étapes pour le simulateur. La premières consiste à définir l’état d’entrée et la seconde à faire évoluer cet état au travers du circuit quantique.
[5]:
from qiskit.quantum_info import Statevector
# Set the intial state of the simulator to the ground state using from_int
state = Statevector.from_int(0, 2**3)
# Evolve the state by the quantum circuit
state = state.evolve(circ)
#draw using latex
state.draw('latex')
[5]:
[6]:
from qiskit.visualization import array_to_latex
#Alternative way of representing in latex
array_to_latex(state)
[6]:
Qiskit fournit aussi une boite à outil de visualisation qui permet d’afficher ces résultats.
Ci-dessous, nous utilisons la fonction de visualisation pour afficher les points correspondants aux composantes réelles et imaginaires de la matrice densité \(\rho\).
[7]:
state.draw('qsphere')
[7]:
[8]:
state.draw('hinton')
[8]:
Représentation unitaire d’un circuit¶
Le module quant_info de Qiskit a également une méthode d’opérateur qui peut être utilisée pour faire un opérateur unitaire pour le circuit. Ceci calcule la matrice \(2^n \times 2^n\) représentant le circuit quantique.
[9]:
from qiskit.quantum_info import Operator
U = Operator(circ)
# Show the results
U.data
[9]:
array([[ 0.70710678+0.j, 0.70710678+0.j, 0. +0.j,
0. +0.j, 0. +0.j, 0. +0.j,
0. +0.j, 0. +0.j],
[ 0. +0.j, 0. +0.j, 0. +0.j,
0. +0.j, 0. +0.j, 0. +0.j,
0.70710678+0.j, -0.70710678+0.j],
[ 0. +0.j, 0. +0.j, 0.70710678+0.j,
0.70710678+0.j, 0. +0.j, 0. +0.j,
0. +0.j, 0. +0.j],
[ 0. +0.j, 0. +0.j, 0. +0.j,
0. +0.j, 0.70710678+0.j, -0.70710678+0.j,
0. +0.j, 0. +0.j],
[ 0. +0.j, 0. +0.j, 0. +0.j,
0. +0.j, 0.70710678+0.j, 0.70710678+0.j,
0. +0.j, 0. +0.j],
[ 0. +0.j, 0. +0.j, 0.70710678+0.j,
-0.70710678+0.j, 0. +0.j, 0. +0.j,
0. +0.j, 0. +0.j],
[ 0. +0.j, 0. +0.j, 0. +0.j,
0. +0.j, 0. +0.j, 0. +0.j,
0.70710678+0.j, 0.70710678+0.j],
[ 0.70710678+0.j, -0.70710678+0.j, 0. +0.j,
0. +0.j, 0. +0.j, 0. +0.j,
0. +0.j, 0. +0.j]])
Backend OpenQASM¶
Les simulateurs précédents sont utiles car ils fournissent une information sur l’état de sortie d’un circuit idéal et la représentation matricielle de ce circuit. Toutefois, une expérience réelle se termine par la mesure de chaque qubit (habituellement sur la ba se de calcul \(|0\rangle, |1\rangle\)). Sans mesure, on ne peut pas récupérer d’information à propos de l’état. Mais la mesure provoque l’effrondrement du système quantique en un système de bits classiques.
Par exemple, supposons que nous fassions des mesures indépendantes sur chaque qubit de l’état GHZ à trois qubits
et notons \(xyz\) la chaîne de bits résultante. Rappelons que, dans la convention de nommage des qubits utilisée par Qiskit, \(x\) correspond à la sortie du qubit 2, \(y\) à la sortie du qubit 1 et \(z\) à la sortie du qubit 0.
Note: Cette représentation de la chaîne de bits place le bit le plus significatif (MSB) à gauche, et le bit le moins significatif (LSB) sur la droite. Il s’agit de l’ordre standard des bits binaires. Nous commandons les qubits de la même façon (le qubit représentant le MSB a l’index 0), c’est pourquoi Qiskit utilise un ordre de produit tensoriel non standard.
Rappelons que la probabilité d’obtenir un résultat \(xyz\) est définie par
et ainsi les probabilités d’obtenir 000 ou 111 à partir de l’état GHZ sont toutes les deux 1/2.
Pour simuler un circuit qui inclut la mesure, nous avons besoin d’ajouter les mesures aux circuits précédents et d’utiliser un environnement Aer différent.
[10]:
# Create a Quantum Circuit
meas = QuantumCircuit(3, 3)
meas.barrier(range(3))
# map the quantum measurement to the classical bits
meas.measure(range(3), range(3))
# The Qiskit circuit object supports composition.
# Here the meas has to be first and front=True (putting it before)
# as compose must put a smaller circuit into a larger one.
qc = meas.compose(circ, range(3), front=True)
#drawing the circuit
qc.draw('mpl')
[10]:
Ce circuit ajoute un registre classique, et 3 mesures qui sont utilisés pour faire correspondre la mesure de chaque qubit à son bit classique.
Pour simuler ce circuit, nous utilisons qasm_simulator
de Qiskit Aer. Chaque exécution (« tir » ou « shot » en anglais) de ce circuit aboutira soit à une séquence 000, soit à 111. Pour obtenir une statistique de la distribution des résultats (par exemple, estimer \(\mathrm{Pr}(000)\)), nous devrons exécuter le circuit plusieurs fois. Le nombre de fois où le circuit sera testé peut être spécifié dans la fonction execute
par le mot-clé shots
.
[11]:
# Adding the transpiler to reduce the circuit to QASM instructions
# supported by the backend
from qiskit import transpile
# Use AerSimulator
from qiskit_aer import AerSimulator
backend = AerSimulator()
# First we have to transpile the quantum circuit
# to the low-level QASM instructions used by the
# backend
qc_compiled = transpile(qc, backend)
# Execute the circuit on the qasm simulator.
# We've set the number of repeats of the circuit
# to be 1024, which is the default.
job_sim = backend.run(qc_compiled, shots=1024)
# Grab the results from the job.
result_sim = job_sim.result()
Une fois que vous avez un objet résultat, vous pouvez obtenir le comptage (counts) par la fonction get_counts(circuit)
. Cela vous donne le résultat sous forme d’agrégats binaires du circuit testé.
[12]:
counts = result_sim.get_counts(qc_compiled)
print(counts)
{'111': 522, '000': 502}
Approximativement 50% du temps, le résultat sera 000. Qiskit fournit également une fonction plot_histogram
qui vous permet de visualiser le résultat.
[13]:
from qiskit.visualization import plot_histogram
plot_histogram(counts)
[13]:
Les probabilités estimées des résultats \(\mathrm{Pr}(000)\) et \(\mathrm{Pr}(111) sont calculées en prenant l'agrégat comptage (counts) et en le divisant par le nombres de "tirs" (le nombre de répétitions de l'execution du circuit). Essayez de modifier la valeur du mot-clé \) dans la fonction execute
et voyez comment cela affecte la probabilité estimée.
[14]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright
Version Information
Qiskit Software | Version |
---|---|
Qiskit | 0.26.2 |
Terra | 0.17.4 |
Aer | 0.8.2 |
Ignis | 0.6.0 |
Aqua | 0.9.1 |
IBM Q Provider | 0.13.1 |
System information | |
Python | 3.8.5 (default, Sep 4 2020, 07:30:14) [GCC 7.3.0] |
OS | Linux |
CPUs | 2 |
Memory (Gb) | 7.523967742919922 |
Fri Jun 04 17:48:05 2021 IST |
This code is a part of Qiskit
© Copyright IBM 2017, 2021.
This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.