Vai al contenuto principale

Specificare gli osservabili nella base di Pauli

Versioni dei pacchetti

Il codice in questa pagina è stato sviluppato usando i seguenti requisiti. Si raccomanda di usare queste versioni o versioni più recenti.

qiskit[all]~=2.3.0

In meccanica quantistica, gli osservabili corrispondono a proprietà fisiche che possono essere misurate. Considerando un sistema di spin, ad esempio, potresti essere interessato a misurare l'energia del sistema o a ottenere informazioni sull'allineamento degli spin, come la magnetizzazione o le correlazioni tra spin.

Per misurare un osservabile OO a nn qubit su un computer quantistico, devi rappresentarlo come una somma di prodotti tensoriali di operatori di Pauli, ovvero

O=∑k=1KαkPk,  Pk∈{I,X,Y,Z}⊗n,  αk∈R,O = \sum_{k=1}^K \alpha_k P_k,~~ P_k \in \{I, X, Y, Z\}^{\otimes n},~~ \alpha_k \in \mathbb{R},

dove

I=(1001)  X=(0110)  Y=(0−ii0)  Z=(100−1)I = \begin{pmatrix} 1 & 0 \\ 0 & 1 \end{pmatrix} ~~ X = \begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix} ~~ Y = \begin{pmatrix} 0 & -i \\ i & 0 \end{pmatrix} ~~ Z = \begin{pmatrix} 1 & 0 \\ 0 & -1 \end{pmatrix}

e si sfrutta il fatto che un osservabile è hermitiano, ovvero O†=OO^\dagger = O. Se OO non è hermitiano può comunque essere decomposto come somma di operatori di Pauli, ma il coefficiente αk\alpha_k diventa complesso.

In molti casi, l'osservabile è naturalmente specificato in questa rappresentazione dopo aver mappato il sistema di interesse sui qubit. Ad esempio, un sistema spin-1/2 può essere mappato su un hamiltoniano di Ising

H=∑⟨i,j⟩ZiZj−∑i=1nXi,H = \sum_{\langle i, j\rangle} Z_i Z_j - \sum_{i=1}^n X_i,

dove gli indici ⟨i,j⟩\langle i, j\rangle scorrono sugli spin interagenti e gli spin sono soggetti a un campo trasversale in XX. L'indice in pedice indica su quale qubit agisce l'operatore di Pauli, ovvero XiX_i applica un operatore XX al qubit ii lasciando invariati gli altri.

Nel Qiskit SDK, questo hamiltoniano può essere costruito con il seguente codice.

# 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])

Se volessimo misurare l'energia, l'osservabile è l'hamiltoniano stesso. In alternativa, potremmo essere interessati a misurare proprietà del sistema come la magnetizzazione media, contando il numero di spin allineati nella direzione ZZ con l'osservabile

O=1n∑i=1ZiO = \frac{1}{n} \sum_{i=1} Z_i

Per gli osservabili non espressi in termini di operatori di Pauli ma in forma matriciale, occorre prima riformularli nella base di Pauli per poterli valutare su un computer quantistico. Siamo sempre in grado di trovare tale rappresentazione poiché le matrici di Pauli formano una base per le matrici hermitiane 2n×2n2^n \times 2^n. Espandiamo l'osservabile OO come

O=∑P∈{I,X,Y,Z}⊗nTr(OP)P,O = \sum_{P \in \{I, X, Y, Z\}^{\otimes n}} \mathrm{Tr}(O P) P,

dove la somma scorre su tutti i possibili termini di Pauli a nn qubit e Tr(⋅)\mathrm{Tr}(\cdot) è la traccia di una matrice, che funge da prodotto interno. Puoi implementare questa decomposizione da una matrice a termini di Pauli usando il metodo SparsePauliOp.from_operator, come segue:

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])

Questo significa che la matrice può essere scritta come termini di Pauli: O=−Z1+0.5X2+Y2Y1O = -Z_1 + 0.5 X_2 + Y_2 Y_1.

nota

Ricorda che l'ordine del prodotto tensoriale mappa ai qubit come qn⊗qn−1⊗⋯⊗q1q_n \otimes q_{n-1} \otimes \cdots \otimes q_1.

nota

Se l'osservabile è hermitiano (ovvero O†=OO^\dagger = O), i coefficienti di Pauli sono numeri reali. Possiamo tuttavia decomporre anche qualsiasi altra matrice complessa in termini di Pauli, se ammettiamo coefficienti a valori complessi.

Misurare nelle basi di Pauli​

Una misurazione proietta lo stato del qubit sulla base computazionale {∣0⟩,∣1⟩}\{|0\rangle, |1\rangle\}. Ciò implica che puoi misurare solo osservabili che sono diagonali in questa base, come i termini di Pauli composti unicamente da II e ZZ. Misurare termini di Pauli arbitrari richiede quindi un cambio di base per diagonalizzarli. Per farlo, applica le seguenti trasformazioni:

X→Z=HXHY→Z=HS†YSH,\begin{aligned} X &\rightarrow Z = H X H \\ Y &\rightarrow Z = H S^\dagger Y S H, \end{aligned}

dove HH è il gate di Hadamard e S=ZS = \sqrt{Z} è talvolta chiamato gate di fase. Se stai usando un Estimator per calcolare i valori di aspettazione, le trasformazioni di base vengono eseguite automaticamente.

Di seguito è riportato un esempio che mostra come preparare un circuito quantistico e misurare manualmente il qubit 0 nella base X, il qubit 1 nella base Y e il qubit 2 nella base Z. Applichiamo le trasformazioni mostrate nell'equazione precedente e otteniamo il seguente circuito:

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")

Output della cella di codice precedente

Passi successivi​

Raccomandazioni