Search
Progetto 3: Progettazione di un serbatoio Markoviano

Progetto 3: Progettazione di un serbatoio Markoviano

Per decenni, il rumore indotto dall’ambiente è stato considerato il nemico per eccellenza delle tecnologie quantistiche. Ciò è dovuto al fatto che molto spesso l’interazione tra un sistema quantistico e l’ambiente circostante porta alla rapida scomparsa delle proprietà quantistiche, in particolare la coerenza e l’entanglement, che svolgono un ruolo fondamentale nel garantire il vantaggio quantistico. Questo punto di vista è cambiato radicalmente non appena i fisici hanno dimostrato che una manipolazione appropriata di un ambiente artificiale (ingegneria dei serbatoi quantistici) avrebbe permesso di orientare il sistema aperto verso, ad esempio, uno stato di entanglement massimo [J. T. Barreiro, et al., Nature 470, 486 (2011), J. T. Barreiro et al., Nat. Phys. 6, 943 (2010)], ribaltando così la prospettiva che considera l’ambiente come un nemico.

Seguendo le linee di J. T. Barreiro, et al., Nature 470, 486 (2011), simuliamo sperimentalmente un’equazione maestra markoviana di semigruppo per un sistema aperto a due qubit avente come stato stazionario asintotico lo stato di Bell $|\psi^- \rangle = \frac{1}{\sqrt{2} }(|01\rangle - |10\rangle)$, dove con $|0\rangle$ e $|1\rangle$ indichiamo la base computazionale di ciascun qubit e utilizziamo la notazione $| 01\rangle = |0\rangle_1 |1\rangle _2$. Ciò ci permette di preparare uno stato di massimo entanglement come risultato della dinamica dissipativa del sistema aperto.

I quattro stati di Bell sono:

\begin{align} |\psi^- \rangle = \frac{1}{\sqrt{2} }(|01\rangle - |10\rangle) \\ |\psi^+ \rangle = \frac{1}{\sqrt{2} }(|01\rangle + |10\rangle) \\ |\phi^- \rangle = \frac{1}{\sqrt{2} }(|00\rangle - |11\rangle) \\ |\phi^+ \rangle = \frac{1}{\sqrt{2} }(|00\rangle + |11\rangle) \end{align}

Ognuno di essi è determinato in modo univoco come un autovettore con autovalori $\pm1$ rispetto a $\sigma_z^{(1)} \otimes \sigma_z^{(2)}$ e $\sigma_x^{(1)}\otimes\sigma_x^{(2)}$, dove $\sigma_x^{(i)}$ e $\sigma_z^{(i)}$, con $i=1,2$, sono gli operatori di Pauli $x$ e $z$ dei qubit 1 e 2.

La dinamica dissipativa che porta due qubit da uno stato iniziale arbitrario allo stato di Bell $|\psi^- \rangle $ è realizzata dalla composizione di due canali che portano gli operatori stabilizzatori $\sigma_z^{(1)} \otimes \sigma_z^{(2)}$ e $\sigma_x^{(1)} \otimes \sigma_x^{(2)}$ dallo spazio dell'autovalore $+1$ a quello dell'autovalore $-1$.

Nello specifico, consideriamo le due famiglie di mappe CPTP parametrizzate da $p$, $\Phi_{zz} \rho_S = E_{1z} \rho_S E_{1z}^{\dagger} + E_{2z} \rho_S E_{2z}^{\dagger} $, con

\begin{equation} \begin{aligned} E_{1z} &=\sqrt{p} \mathbb{I}^{(1)} \otimes \sigma_x^{(2)} \frac{1}{2}\left( \mathbb{I}+ \sigma_z^{(1)} \otimes \sigma_z^{(2)} \right), \\ E_{2z} &= \frac{1}{2} \left( \mathbb{I}-\sigma_z^{(1)}\otimes\sigma_z^{(2)} \right) \\ &+ \sqrt{1-p} \frac{1}{2} \left( \mathbb{I}+ \sigma_z^{(1)}\otimes\sigma_z^{(2)} \right), \end{aligned} \end{equation}

e $\Phi_{xx}\rho_S = E_{1x} \rho_S E_{1x}^{\dagger} + E_{2x} \rho_S E_{2x}^{\dagger} $, dove $E_{1x}$ e $E_{2x}$ hanno la stessa forma di $E_{1z}$ e $E_{2z}$ nelle equazioni, sostituendo $\sigma_x^{(2)}$ con $\sigma_z^{(2)}$ e $\sigma_z^{(1)}\otimes\sigma_z^{(2)}$ con $\sigma_x^{(1)}\otimes\sigma_x^{(2)}$.

Cambiando il parametro $0 \le p \le 1$ simuliamo tipi diversi di dinamiche di sistemi quantistici aperti. Per $p\ll1$, l'applicazione ripetuta di, ad esempio, $\Phi_{zz}$ genera un'equazione maestra di Lindblad con operatore di salto $V=\frac{1}{2} \mathbb{I}^{(1)}\otimes\sigma_x^{(2)}\left( \mathbb{I}+ \sigma_z^{(1)} \otimes \sigma_z^{(2)} \right)$. Per $p=1$, la mappa $\Phi_{xx} \circ \Phi_{zz}$ genera $|\psi_- \rangle $ per ogni stato iniziale.

Implementazione del circuito

In J. T. Barreiro, et al., Nature 470, 486 (2011), gli autori presentano i circuiti per l’implementazione del pompaggio dello stato di Bell. Tuttavia, questi sono composti da porte tipiche della piattaforma a ioni intrappolati utilizzata in quel lavoro, pertanto la loro implementazione diretta sui dispositivi quantistici di IBM comporterebbe circuiti di lunghezza eccessiva. Proponiamo quindi una serie diversa di circuiti che seguono gli stessi principi di funzionamento di base, ma sono stati progettati specificatamente tenendo conto delle caratteristiche dei dispositivi IBM.

I circuiti di pompaggio sono composti da quattro parti:

  1. L'informazione relativa allo stato del sistema (ovvero se il sistema si trova nello spazio dell'autovalore $+1$ o $-1$ degli operatori stabilizzatori) viene mappate in un qubit ausiliare.

  2. Lo stato del sistema viene modificato in base allo stato del qubit ausiliare.

  3. Il circuito di mappatura viene invertito.

  4. A questo punto, il sistema è stato pompato, ma se l’ausiliare deve essere riutilizzato per un nuovo ciclo di pompaggio, deve essere resettato: questa è la quarta fase.

Seguiamo queste stesse linee guida, progettando circuiti che eseguono questi stessi passaggi riducendo al minimo il numero di porte coinvolte. Prima di illustrare i circuiti risultanti, precisiamo che, poiché non tutti i dispositivi IBM sono dotati dell’operazione di reset (che in ogni caso è piuttosto rumorosa), dobbiamo utilizzare un ausiliare diverso per ogni pompaggio.

Il modo in cui mappiamo le informazioni dello spazio degli autovalori su un ausiliare consiste nell’applicare innanzitutto un gate CNOT tra i qubit del sistema. Supponiamo che i qubit $s_1$ e $s_2$ si trovino inizialmente in uno stato di Bell, ad esempio $| \phi^{\pm} \rangle = (| 00 \rangle \pm | 11 \rangle)/\sqrt{2}$. Un gate CNOT controllato da $s_1$ trasforma lo stato in $|\pm\rangle|0\rangle$. Invece $| \psi^{\pm} \rangle$ verrebbe trasformato in $|\pm\rangle|1\rangle$. Pertanto, si osserva che l’informazione relativa allo spazio degli autovalori di $\sigma_x^{(1)}\otimes\sigma_x^{(2)}$ (ovvero il segno) è contenuta nello stato di $s_1$ dopo la trasformazione, mentre quella corrispondente a $\sigma_z^{(1)}\otimes\sigma_z^{(2)}$ si trova nel qubit $s_2$.

Consideriamo ora il circuito che implementa la pompa $\sigma_z^{(1)}\otimes\sigma_z^{(2)}$:

from qiskit import QuantumRegister, QuantumCircuit
import numpy as np
#######################
#       pompa ZZ      #
#######################

# Quantum register
q = QuantumRegister(3, name='q')

# Quantum circuit  
zz = QuantumCircuit(q)

# pompa ZZ che agisce sui qubit di sistema
## Qubit identification
system = [2, 1]
a_zz = 0

## Definiamo l'efficienza della pompa 
## e la rotazione corrispondente
p = 0.5
theta = 2 * np.arcsin(np.sqrt(p))

## Costruiamo il circuito
### Mappiamo le informazioni sull'ausiliare
zz.cx(q[system[0]], q[system[1]])
zz.x(q[a_zz])
zz.cx(q[system[1]], q[a_zz])
    
### Rotazione condizionata
zz.cu(theta, 0.0, 0.0, 0, q[a_zz], q[system[1]])
    
### Mapping inverso
zz.cx(q[system[1]], q[a_zz])
zz.cx(q[system[0]], q[system[1]])

# Disegnamo il circuito
zz.draw(output='mpl')

Per mappare le informazioni dello spazio degli autovalori nell’ausiliare ambientale $a_\textrm{ZZ}$, applichiamo un CNOT controllato dal qubit $s_2$. Dopo questi due gate (e considerando che lo stato iniziale dell’ausiliare è $|1\rangle$), $a_\textrm{ZZ}$ si troverà nello stato $|1\rangle$ se lo stato iniziale del sistema è $| \phi^{\pm} \rangle$ e in $|0\rangle$ se è $| \psi^{\pm} \rangle$. Pertanto, il gate di rotazione condizionale agisce solo nel primo caso, mentre non modifica lo stato nel secondo. L’angolo della rotazione controllata, a sua volta, determina l’efficienza della pompa $p$ tramite la relazione $\theta = 2 \arcsin{\sqrt{p} }$. Infine, gli ultimi due gate CNOT si limitano a invertire la parte di mappatura del circuito.

Il principio di funzionamento della pompa $\sigma_x^{(1)}\otimes\sigma_x^{(2)}$ è essenzialmente lo stesso. Tuttavia, è necessario aggiungere un gate di Hadamard supplementare per trasformare lo stato di $s_1$ prima di mappare l’informazione sull’ausiliare $a_\textrm{XX}$:

#######################
#       pompa XX      #
#######################

# Quantum register
q = QuantumRegister(4, name='q')

# Quantum circuit  
xx = QuantumCircuit(q)

# pompa XX che agisce sui qubit di sistema
## Qubit identification
system = [1, 0]
a_xx = 3

## Definiamo l'efficienza della pompa 
## e la rotazione corrispondente
p = 0.5
theta = 2 * np.arcsin(np.sqrt(p))

## Costruiamo il circuito
### Mappiamo le informazioni sull'ausiliare
xx.cx(q[system[0]], q[system[1]])
xx.h(q[system[0]])
xx.x(q[a_xx])
xx.cx(q[system[0]], q[a_xx])
    
### Rotazione condizionata
xx.cu(theta, 0.0, 0.0, 0, q[a_xx], q[system[0]])
    
### Mapping inverso
xx.cx(q[system[0]], q[a_xx])
xx.h(q[system[0]])
xx.cx(q[system[0]], q[system[1]])

# Disegnamo il circuito
xx.draw(output='mpl')

Per quanto riguarda la pompa composita, possiamo semplicemente concatenare i due circuiti. Si noti che nella concatenazione diretta ci sarebbero due CNOT consecutivi tra i qubit del sistema, che possono essere rimossi.

###########################
#       pompe ZZ-XX       #
###########################

# Quantum register
q = QuantumRegister(5, name='q')

# Quantum circuit  
zz_xx = QuantumCircuit(q)

# pompe ZZ e XX che agiscono sui qubit di sistema
## Qubit identification
system = [2, 1]
a_zz = 0
a_xx = 4

## Definiamo l'efficienza della pompa 
## e la rotazione corrispondente
p = 0.5
theta = 2 * np.arcsin(np.sqrt(p))


## Costruiamo il circuito
## pompa ZZ 
### Mappiamo le informazioni sull'ausiliare
zz_xx.cx(q[system[0]], q[system[1]])
zz_xx.x(q[a_zz])
zz_xx.cx(q[system[1]], q[a_zz])
    
### Rotazione condizionata
zz_xx.cu(theta, 0.0, 0.0, 0, q[a_zz], q[system[1]])
    
### Mapping inverso
zz_xx.cx(q[system[1]], q[a_zz])
#zz_xx.cx(q[system[0]], q[system[1]])

## pompa XX
### Mappiamo le informazioni sull'ausiliare
#zz_xx.cx(q[system[0]], q[system[1]])
zz_xx.h(q[system[0]])
zz_xx.x(q[a_xx])
zz_xx.cx(q[system[0]], q[a_xx])
    
### Rotazione condizionata
zz_xx.cu(theta, 0.0, 0.0, 0, q[a_xx], q[system[0]])
    
### Mapping inverso
zz_xx.cx(q[system[0]], q[a_xx])
zz_xx.h(q[system[0]])
zz_xx.cx(q[system[0]], q[system[1]])

# Disegnamo il circuito
zz_xx.draw(output='mpl')

L'obiettivo generale di questo progetto è quello di utilizzare questi circuiti per far passare lo stato del sistema da uno stato massimamente misto a $|\psi^-\rangle$. In questo progetto non ricorreremo alla ricostruzione tomografica dello stato a due qubit; misureremo invece le popolazioni dei quattro stati di Bell cambiando base.

Attività 1 (1 punto)

Scrivi tre funzioni, una per ciascun canale (ZZ, XX e la loro composizione), che restituiscano un circuito quantistico che implementi il canale sui qubit del sistema per un dato valore del parametro di efficienza $p$ (nella mappa di composizione, imponi efficienze uguali per entrambi). I circuiti devono includere la misura dei qubit del sistema nella base di Bell applicando un CNOT e un Hadamard ai qubit pertinenti. Suggerimento: rimuovi i gate CNOT consecutivi (e quelli su un singolo qubit) che danno come risultato l’identità.

Trova la struttura suggerita per le funzioni riportate di seguito.

def zz_pump(q, c, p, system, ancilla):
    """Dà come risultato un QuantumCircuit che implementa il canale della pompa ZZ sui qubit di sistema
    
    Args:
        q (QuantumRegister): il registro da usare per il circuito
        c (ClassicalRegister): il registro da usare per la misura dei qubit di sistema
        p (float): l'efficienza del canale, fra 0 e 1
        system (list): lista di indici per i qubit di sistema
        ancilla (int): indice del qubit ausiliare
    
    Returns:
        Un oggetto QuantumCircuit
    """
def xx_pump(q, c, p, system, ancilla):
    """Dà come risultato un QuantumCircuit che implementa il canale della pompa ZZ sui qubit di sistema
    
    Args:
        q (QuantumRegister): il registro da usare per il circuito
        c (ClassicalRegister): il registro da usare per la misura dei qubit di sistema
        p (float): l'efficienza del canale, fra 0 e 1
        system (list): lista di indici per i qubit di sistema
        ancilla (int): indice del qubit ausiliare
    
    Returns:
        Un oggetto QuantumCircuit
    """
def zz_xx_pump(q, c, p, system, ancillae):
    """Dà come risultato un QuantumCircuit che implementa il canale composto sui qubit di sistema
    
    Args:
        q (QuantumRegister): il registro da usare per il circuito
        c (ClassicalRegister): il registro da usare per la misura dei qubit di sistema
        p (float): l'efficienza del canale, fra 0 e 1
        system (list): lista di indici per i qubit di sistema
        ancilla (int): indice del qubit ausiliare
    
    Returns:
        Un oggetto QuantumCircuit
    """

Attività 2 (3 punti)

Dobbiamo impostare inizialmente il sistema a due qubit nello stato massimamente misto $\rho = I_4/4$, dove $I_4$ è la matrice identità $4\times4$. In linea di principio, ciò potrebbe essere ottenuto facendo entanglement del sistema con altri qubit ausiliari, ma ciò richiederebbe due qubit aggiuntivi nella nostra simulazione. Possiamo invece creare una miscela statistica adeguata. Ciò significa che possiamo ottenere $\rho$ mescolando quattro stati inizialmente puri, ad esempio gli stati della base computazionale a due qubit.

Per ciascuno stato iniziale dei qubit $|00\rangle$, $|01\rangle$, $|10\rangle$ e $|11\rangle$, applica i tre canali per diversi valori di $p \in [0,1]$ e salva le popolazioni di Bell risultanti per il compito successivo.

Attività 3 (3 punti)

Per simulare infine l'effetto dei diversi canali sullo stato massimamente misto, calcola la media di tutti i risultati relativi ai quattro stati iniziali utilizzando un simulatore privo di rumore. Rappresenta graficamente i risultati in funzione dell'efficienza del canale $p$.

Attività 4 (3p)

Esegui i circuiti su un simulatore con rumore (ad esempio FakePerth) con mitigazione dell'errore di lettura e traccia i risultati. Per la mitigazione dell'errore di lettura puoi, ad esempio, utilizzare LocalReadoutError e applicare l'oggetto mitigatore ai risultati.

Attività opzionale

Esegui i circuiti su IBM Quantum con mitigazione del rumore e rappresenta graficamente i risultati.