Synthétiser des opérations unitaires
Versions des packages
Le code de cette page a été développé avec les prérequis suivants. Nous recommandons d'utiliser ces versions ou des versions plus récentes.
qiskit[all]~=2.3.0
Une opération unitaire décrit un changement préservant la norme d'un système quantique. Pour qubits, ce changement est décrit par une matrice complexe de dimension , notée , dont l'adjoint est égal à l'inverse, c'est-à-dire .
La synthèse d'opérations unitaires spécifiques en un ensemble de portes quantiques est une tâche fondamentale utilisée, par exemple, dans la conception et l'application d'algorithmes quantiques ou dans la compilation de circuits quantiques.
Bien qu'une synthèse efficace soit possible pour certaines classes d'unitaires — comme ceux composés de portes Clifford ou ayant une structure de produit tensoriel — la plupart des unitaires n'appartiennent pas à ces catégories. Pour les matrices unitaires générales, la synthèse est une tâche complexe dont le coût de calcul croît exponentiellement avec le nombre de qubits. Par conséquent, si tu connais une décomposition efficace pour l'unitaire que tu souhaites implémenter, elle sera probablement meilleure qu'une synthèse générale.
Si aucune décomposition n'est disponible, le SDK Qiskit te fournit les outils nécessaires pour en trouver une. Cependant, note que cela génère généralement des circuits profonds qui peuvent ne pas convenir à l'exécution sur des ordinateurs quantiques bruités.
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit
import numpy as np
from qiskit import QuantumCircuit
U = 0.5 * np.array(
[[1, 1, 1, 1], [-1, 1, -1, 1], [-1, -1, 1, 1], [-1, 1, 1, -1]]
)
circuit = QuantumCircuit(2)
circuit.unitary(U, circuit.qubits)
<qiskit.circuit.instructionset.InstructionSet at 0x7fedb83e7a90>
Re-synthèse pour l'optimisation de circuits
Il est parfois utile de re-synthétiser une longue série de portes à un et deux qubits, si la longueur peut être réduite. Par exemple, le circuit suivant utilise trois portes à deux qubits.
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
qreg_q = QuantumRegister(2, "q")
creg_c = ClassicalRegister(4, "c")
circuit = QuantumCircuit(qreg_q, creg_c)
circuit.h(qreg_q[0])
circuit.cx(qreg_q[0], qreg_q[1])
circuit.sx(qreg_q[1])
circuit.cz(qreg_q[0], qreg_q[1])
circuit.x(qreg_q[1])
circuit.x(qreg_q[0])
circuit.cx(qreg_q[0], qreg_q[1])
circuit.h(qreg_q[0])
circuit.draw("mpl")
Cependant, après re-synthèse avec le code suivant, il ne nécessite plus qu'une seule porte CX. (Ici, nous utilisons la méthode QuantumCircuit.decompose() pour mieux visualiser les portes utilisées lors de la re-synthèse de l'unitaire.)
from qiskit.quantum_info import Operator
# compute unitary matrix of circuit
U = Operator(circuit)
# re-synthesize
better_circuit = QuantumCircuit(2)
better_circuit.unitary(U, range(2))
better_circuit.decompose().draw()
global phase: 6.2071
┌───────────────┐ ┌────────────────┐
q_0: ─┤ U(π/2,π/2,-π) ├────■────┤ U(π/2,-π,-π/2) ├─
┌┴───────────────┴─┐┌─┴─┐┌─┴────────────────┴┐
q_1: ┤ U(1.7229,π/2,-π) ├┤ X ├┤ U(π/2,0.15207,-π) ├
└──────────────────┘└───┘└───────────────────┘
La fonction transpile de Qiskit effectue automatiquement cette re-synthèse pour un niveau d'optimisation suffisamment élevé.
Prochaines étapes
- Consulte un exemple de décomposition de circuit dans le tutoriel Algorithme de Grover.
- Pour plus d'informations sur le transpiler Qiskit, visite la section Transpile.