Implementazione con Qiskit
Nella lezione precedente abbiamo dato una prima occhiata alle classi Statevector e Operator di Qiskit, e le abbiamo usate per simulare operazioni e misurazioni su singoli qubit.
In questa sezione useremo queste classi per esplorare il comportamento di più qubit.
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit
from qiskit import __version__
print(__version__)
2.1.1
Inizieremo importando le classi Statevector e Operator, oltre alla funzione radice quadrata di NumPy.
D'ora in avanti, in linea generale, ci occuperemo di tutti gli import necessari all'inizio di ogni lezione.
from qiskit.quantum_info import Statevector, Operator
from numpy import sqrt
Prodotti tensoriali
La classe Statevector dispone di un metodo tensor, che restituisce il prodotto tensoriale di quello Statevector con un altro, fornito come argomento.
L'argomento viene interpretato come il fattore tensoriale a destra.
Ad esempio, qui sotto creiamo due vettori di stato che rappresentano e e usiamo il metodo tensor per creare un nuovo vettore,
Nota che qui stiamo usando il metodo from_label per definire gli stati e anziché definirli manualmente.
zero = Statevector.from_label("0")
one = Statevector.from_label("1")
psi = zero.tensor(one)
display(psi.draw("latex"))
Le altre etichette ammesse includono "+" e "-" per gli stati più e meno, nonché "r" e "l" (abbreviazioni di "right" e "left") per gli stati
Qui "+" , "-" oppure "right" e "left" derivano dal contesto dello spin in meccanica quantistica, in cui una componente dello spin può puntare a sinistra o a destra in un esperimento; non si riferiscono al qubit più a destra o più a sinistra in sistemi a più qubit. Ecco un esempio del prodotto tensoriale di e
plus = Statevector.from_label("+")
minus_i = Statevector.from_label("l")
phi = plus.tensor(minus_i)
display(phi.draw("latex"))
In alternativa, si può usare l'operazione ^ per i prodotti tensoriali, che naturalmente produce gli stessi risultati.
display((plus ^ minus_i).draw("latex"))
Anche la classe Operator dispone di un metodo tensor (e di un metodo from_label), come vediamo negli esempi seguenti.
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"))
Anche in questo caso, come per i vettori, l'operazione ^ è equivalente.
display((H ^ Id ^ X).draw("latex"))
Gli stati composti possono essere evoluti tramite operazioni composte nel modo che ci aspettiamo — proprio come abbiamo visto per i sistemi singoli nella lezione precedente. Ad esempio, il codice seguente calcola lo stato per (già definito sopra).
display(phi.evolve(H ^ Id).draw("latex"))
Ecco del codice che definisce un'operazione e calcola per Per essere precisi, si tratta di un'operazione in cui il qubit a sinistra è il controllo e il qubit a destra è il bersaglio. Il risultato è lo stato di Bell
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"))
Misurazioni parziali
Nella lezione precedente abbiamo usato il metodo measure per simulare la misurazione di un vettore di stato quantistico.
Questo metodo restituisce due elementi: il risultato simulato della misurazione e il nuovo Statevector dato tale risultato.
Per impostazione predefinita, measure misura tutti i qubit nel vettore di stato.
In alternativa, possiamo fornire come argomento una lista di interi, che fa sì che vengano misurati solo i qubit con quegli indici.
Per dimostrarlo, il codice seguente crea lo stato
e misura il qubit numero 0, ovvero il qubit più a destra. (Qiskit numera i qubit partendo da 0, da destra a sinistra. Torneremo su questa convenzione di numerazione nella prossima lezione.)
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"))
Measured: 0
State after measurement:
Measured: 00
State after measurement: