Spécifier des observables dans la base de Pauli
Versions des packages
Le code de cette page a été développé avec les dépendances suivantes. Nous recommandons d'utiliser ces versions ou des versions plus récentes.
qiskit[all]~=2.3.0
En mécanique quantique, les observables correspondent à des propriétés physiques mesurables. Lorsqu'on considère un système de spins, par exemple, on peut être intéressé par la mesure de l'énergie du système ou par l'obtention d'informations sur l'alignement des spins, comme la magnétisation ou les corrélations entre spins.
Pour mesurer une observable -qubit sur un ordinateur quantique, tu dois la représenter comme une somme de produits tensoriels d'opérateurs de Pauli, c'est-à-dire
où
et on utilise le fait qu'une observable est hermitienne, c'est-à-dire . Si n'est pas hermitienne, elle peut quand même être décomposée en somme de Paulis, mais le coefficient devient complexe.
Dans de nombreux cas, l'observable est naturellement spécifiée dans cette représentation après avoir mappé le système d'intérêt aux qubits. Par exemple, un système de spin-1/2 peut être mappé à un hamiltonien d'Ising
où les indices parcourent les spins en interaction et les spins sont soumis à un champ transversal en . L'indice en indice inférieur indique sur quel qubit l'opérateur de Pauli agit, c'est-à-dire que applique un opérateur sur le qubit et laisse les autres inchangés.
Dans le SDK Qiskit, cet hamiltonien peut être construit avec le code suivant.
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit
from qiskit.quantum_info import SparsePauliOp
# define the number of qubits
n = 12
# define the single Pauli terms as ("Paulis", [indices], coefficient)
interactions = [
("ZZ", [i, i + 1], 1) for i in range(n - 1)
] # we assume spins on a 1D line
field = [("X", [i], -1) for i in range(n)]
# build the operator
hamiltonian = SparsePauliOp.from_sparse_list(
interactions + field, num_qubits=n
)
print(hamiltonian)
SparsePauliOp(['IIIIIIIIIIZZ', 'IIIIIIIIIZZI', 'IIIIIIIIZZII', 'IIIIIIIZZIII', 'IIIIIIZZIIII', 'IIIIIZZIIIII', 'IIIIZZIIIIII', 'IIIZZIIIIIII', 'IIZZIIIIIIII', 'IZZIIIIIIIII', 'ZZIIIIIIIIII', 'IIIIIIIIIIIX', 'IIIIIIIIIIXI', 'IIIIIIIIIXII', 'IIIIIIIIXIII', 'IIIIIIIXIIII', 'IIIIIIXIIIII', 'IIIIIXIIIIII', 'IIIIXIIIIIII', 'IIIXIIIIIIII', 'IIXIIIIIIIII', 'IXIIIIIIIIII', 'XIIIIIIIIIII'],
coeffs=[ 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j,
1.+0.j, 1.+0.j, 1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j,
-1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j])
Si on souhaite mesurer l'énergie, l'observable est l'hamiltonien lui-même. Sinon, on peut être intéressé par la mesure des propriétés du système, comme la magnétisation moyenne, en comptant le nombre de spins alignés dans la direction avec l'observable
Pour les observables qui ne sont pas données en termes d'opérateurs de Pauli mais sous forme matricielle, il faut d'abord les reformuler dans la base de Pauli afin de les évaluer sur un ordinateur quantique. On peut toujours trouver une telle représentation, car les matrices de Pauli forment une base pour les matrices hermitiennes . On développe l'observable comme suit :
où la somme parcourt tous les termes de Pauli -qubit possibles et est la trace d'une matrice, qui joue le rôle de produit scalaire.
Tu peux implémenter cette décomposition d'une matrice en termes de Pauli en utilisant la méthode SparsePauliOp.from_operator, comme ceci :
import numpy as np
from qiskit.quantum_info import SparsePauliOp
matrix = np.array(
[[-1, 0, 0.5, -1], [0, 1, 1, 0.5], [0.5, 1, -1, 0], [-1, 0.5, 0, 1]]
)
observable = SparsePauliOp.from_operator(matrix)
print(observable)
SparsePauliOp(['IZ', 'XI', 'YY'],
coeffs=[-1. +0.j, 0.5+0.j, 1. -0.j])
Cela signifie que la matrice peut s'écrire en termes de Pauli comme .
Rappelle-toi que l'ordre du produit tensoriel correspond aux qubits selon .
Si l'observable est hermitienne (c'est-à-dire ), les coefficients de Pauli sont des nombres réels. On peut cependant aussi décomposer n'importe quelle autre matrice complexe en termes de Paulis, si l'on autorise des coefficients à valeurs complexes.
Mesurer dans les bases de Pauli
Une mesure projette l'état d'un qubit sur la base computationnelle . Cela implique que tu peux uniquement mesurer des observables qui sont diagonales dans cette base, comme les Paulis composés uniquement de termes et . Mesurer des termes de Pauli arbitraires nécessite donc un changement de base pour les diagonaliser. Pour ce faire, effectue les transformations suivantes :
où est la porte Hadamard et est parfois appelée la porte de phase. Si tu utilises un Estimator pour calculer des valeurs d'espérance, les transformations de base sont effectuées automatiquement.
Voici un exemple illustrant comment préparer un circuit quantique et mesurer manuellement le qubit 0 dans la base X, le qubit 1 dans la base Y et le qubit 2 dans la base Z. On applique les transformations montrées dans l'équation précédente et on obtient le circuit suivant :
from qiskit.circuit import QuantumCircuit
# create a circuit, where we would like to measure
# q0 in the X basis, q1 in the Y basis and q2 in the Z basis
circuit = QuantumCircuit(3)
circuit.ry(0.8, 0)
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.barrier()
# diagonalize X with the Hadamard gate
circuit.h(0)
# diagonalize Y with Hadamard as S^\dagger
circuit.sdg(1)
circuit.h(1)
# the Z basis is the default, no action required here
# measure all qubits
circuit.measure_all()
circuit.draw("mpl")
Étapes suivantes
- Consulte la référence de l'API SparsePauliOp.