Applicazione di un gate quantico multi qubit a qubit specifici


9

Una matrice controllata non gate si presenta così:

[1000010000010010]

Funziona alla grande quando hai solo due qubit e vuoi usare il primo qubit come controllo e il secondo qubit come input da capovolgere (o meno).

Esiste un metodo per convertire questa matrice da utilizzare, ad esempio, se si dispone di 3 qubit e si desidera utilizzare qubit 1 come controllo e qubit 3 come input che è possibile capovolto?

Pensandoci logicamente, posso trovare questo:

[1000000001000000001000000001000000000100000010000000000100000010]

Esiste un modo migliore, più formale / generalizzato per convertire le porte multi qubit per utilizzare qualsiasi qubit specificato, piuttosto che la prima in un circuito qubit?NN

Risposte:


7

Espandere-n-Swap

Se si desidera applicare un gate a un sottoinsieme dei qubit:

Può essere noioso fare tutte quelle grandi moltiplicazioni di matrici, ma le matrici di scambio sono scarse e l'idea è molto semplice.

I controlli sono più facili

Nel caso di aggiungere controlli a un'operazione (che si applica all'esempio specifico che hai fornito), c'è un trucco più semplice. Espandi semplicemente l'operazione come di consueto, ma poi sostituisci tutte le parti della matrice che corrispondono a input con controllo fallito con quale sarebbe la matrice di identità.

È un po 'più facile tenere traccia di se si introduce un falso "valore di controllo" che sovrascrive il comportamento abituale del prodotto tensorec , in modo che invece di , hai (in altre parole: quando una voce è non affianchi sopra la voce e scala dalla voce; usi invece di ).[c]U=cU[c]U=cIcUUIU

Definire "operazione" di un controllo qubit-must-be-ON come . Una no-op è , e non è un . Quindi l'operazione dalla tua domanda potrebbe essere calcolata in questo modo (assumendo un ordine big-endian):C=[c001]IX

CNOT31=CIX

=[c001][1001][0110]

=[c[1001]0[1001]0[1001]1[1001]][0110]

=[[c00c][0000][0000][1001]][0110]

=[c0000c0000100001][0110]

(nota: andando a usare un singolo zero per significare ambiguamente una matrice zero 2x2 dove conveniente)

=[c[0110]0000c[0110]0000[0110]0000[0110]]

=[[c00c]0000[c00c]0000[0110]0000[0110]]

=[c00000000c00000000c00000000c000000000100000010000000000100000010]

(ora abbiamo finito con i prodotti tensore e non abbiamo più bisogno della )c

[1000000001000000001000000001000000000100000010000000000100000010]

Ha senso?


8

Non utilizzare il metodo di scambio, è molto inefficiente. E la risposta dell'altra persona è specifica per il cancello CNOT e, ad essere sinceri, complica troppo le cose.

Ecco un algoritmo molto semplice che risolve il problema per ogni singolo caso, non solo per la porta CNOT, per eventuali bit arbitrari.

L'algoritmo:

let sys = matrix representing the current state of the system
let n = number of qubits being simulated
let lgm = logic gate matrix of size 2^n by 2^n
let f = our logic gate transformation function
for i = 0 to (2^n) - 1:
    lgm[column = i] = f(i)
sys = sys × lgg

Nei computer classici, c'è qualcosa noto come "decodificatore". Diciamo che ho solo 3 fili, in effetti, 3 bit. Ma voglio controllare 8 fili. Può essere fatto? Sì, perché 3 bit ha 8 diverse possibilità: 000, 001, 010, 011, 100, 101, 110, 111. Quindi possiamo assegnare ogni possibilità a uno dei nostri 8 fili di uscita. Questo si chiama "decodifica".

Se passo il numero 101 e abbiamo 3 bit, conosciamo 101 = 5, quindi imposterò il filo di uscita 5 su un'alta tensione e gli altri 7 fili di uscita saranno 0, che possiamo rappresentare in questo modo: decodifica (101) = [0, 0, 0, 0, 0, 1, 0, 0].

In questo algoritmo, menziono la "funzione di trasformazione" chiamata "f". Per i computer classici, la funzione di trasformazione sta semplicemente rilevando un valore di input e restituendo la versione "decodificata" del valore di output. Quindi se abbiamo 3 bit e l'output è 4, restituiremo [0, 0, 0, 0, 1, 0, 0, 0]. Quindi lo assegniamo come colonna della nostra matrice per quel valore.

Pensiamo alla "decodifica" in termini di qubit. Come possiamo decodificare i qubit | 101>?

Sappiamo che per i nostri vettori di probabilità qubit, | 0> è [1, 0] e | 1> è [0, 1]. I qubit di decodifica possono quindi essere eseguiti con il cosiddetto prodotto Kronecker.

Quindi se convertiamo ogni bit nell'equivalente del vettore di probabilità e prendiamo il prodotto Kronecker di tutti loro, otteniamo ...

|101> = |1> ⊗ |0> ⊗ |1> = [0, 1] ⊗ [1, 0] ⊗ [0, 1] = [0, 0, 0, 0, 0, 1, 0, 0]

Ecco come vorremmo decodificare i qubit. Questo algoritmo può essere applicato allo stesso qubit usando questo.

Proviamo questo algoritmo su un problema più semplice.

Supponiamo di avere un sistema con solo 2 qubit. Se vogliamo applicare il gate Hadamard a solo 1 qubit, possiamo generare un gate logico per entrambi i qubit che applica il gate Hadamard solo a un singolo qubit. Supponiamo che il singolo qubit a cui vogliamo applicarlo sia il nostro qubit più significativo e il meno significativo non sarà interessato.

Vogliamo una funzione di trasformazione che per ciascuno dei nostri possibili input, produca l'output corretto. Abbiamo due qubit, questo significa che ci sono quattro possibili output.

f(|00>) = ?
f(|01>) = ?
f(|10>) = ?
f(|11>) = ?

Sappiamo che il qubit meno significativo non sarà interessato, quindi possiamo riempirlo.

f(|00>) = ? ⊗ |0>
f(|01>) = ? ⊗ |1>
f(|10>) = ? ⊗ |0>
f(|11>) = ? ⊗ |1>

Sappiamo anche cosa fa l'Hadamard con un qubit, in modo tale che:

H(|0>) = 1/sqrt(2)|0> + 1/sqrt(2)|1>
H(|1>) = 1/sqrt(2)|0> - 1/sqrt(2)|1>

Quindi la nostra funzione di trasformazione è semplicemente:

f(|00>) = (1/sqrt(2)|0> + 1/sqrt(2)|1>) ⊗ |0>
f(|01>) = (1/sqrt(2)|0> + 1/sqrt(2)|1>) ⊗ |1>
f(|10>) = (1/sqrt(2)|0> - 1/sqrt(2)|1>) ⊗ |0>
f(|11>) = (1/sqrt(2)|0> - 1/sqrt(2)|1>) ⊗ |1>

Espandilo nel nostro modulo vettoriale di probabilità normalizzato ...

f(|00>) = [ 1/sqrt(2), 1/sqrt(2) ] ⊗ [ 1, 0 ]
f(|01>) = [ 1/sqrt(2), 1/sqrt(2) ] ⊗ [ 0, 1 ]
f(|10>) = [ 1/sqrt(2), -1/sqrt(2) ] ⊗ [ 1, 0 ]
f(|11>) = [ 1/sqrt(2), -1/sqrt(2) ] ⊗ [ 0, 1 ]

Ora risolviamo davvero questo ...

f(|00>) = [ 1/sqrt(2), 0, 1/sqrt(2), 0 ]
f(|01>) = [ 0, 1/sqrt(2), 0, 1/sqrt(2) ]
f(|10>) = [ 1/sqrt(2), 0, -1/sqrt(2), 0 ]
f(|11>) = [ 0, 1/sqrt(2), 0, -1/sqrt(2) ]

Questa è la nostra funzione di trasformazione.

La nostra matrice di gate logici, "lgm", ha dimensioni 2 ^ n per 2 ^ n dove n = numero di qubit da simulare, quindi in questo caso è 2 ^ 2 per 2 ^ 2 o 4x4. Il nostro algoritmo ci dice che per ogni colonna i, impostare la colonna uguale a f (i). Abbiamo definito la nostra funzione di trasformazione delle probabilità, in modo da poter compilare facilmente queste colonne.

lgm = 
    |00>       |01>        |10>        |11>
[ 1/sqrt(2),         0,  1/sqrt(2),          0 ] 
[         0, 1/sqrt(2),          0,  1/sqrt(2) ]
[ 1/sqrt(2),         0, -1/sqrt(2),          0 ]
[         0, 1/sqrt(2),          0, -1/sqrt(2) ]

Ora il passo finale nel nostro algoritmo è semplicemente la moltiplicazione della matrice che rappresenta l'intero sistema quantistico, sys, per questa porta logica, lgm.

E questo fa quello che vogliamo. Applicherà il gate hadamard solo al maggior qubit e lascerà solo il qubit meno significativo. Se non mi credi, puoi provarlo tu stesso e vedere che funziona.

Il motivo per cui è così potente è perché si applica a tutti i casi.

Proviamo questo algoritmo sul tuo problema.

Immagina di avere un sistema a 3 qubit e vogliamo applicare un gate CNOT a qubit [0] e qubit [2]. Se cerchi la matrice CNOT su Wikipedia, quella matrice si applica solo a un sistema a 2 qubit. Una soluzione ingenua sarebbe quella di aggiungere ad essa matrici di identità usando il prodotto Kronecker per farlo funzionare su sistemi con tre qubit. Ma questo non riesce qui: qubit [0] e qubit [2] non sono adiacenti, quindi semplicemente aggiungere matrici di identità non funzionerà.

Abbiamo potuto scambiare qubit [0] con qubit [1], applicare il cancello CNOT, poi scambiare indietro. Ma è lento. Invece, potremmo semplicemente generare un gate CNOT non adiacente per il nostro problema usando l'algoritmo sopra.

Dobbiamo prima trovare una funzione di trasformazione per ogni caso.

f(|000>) = |0> ⊗ |0> ⊗ |0>
f(|001>) = |0> ⊗ |0> ⊗ |1>
f(|010>) = |0> ⊗ |1> ⊗ |0>
f(|011>) = |0> ⊗ |1> ⊗ |1>
f(|100>) = |1> ⊗ |0> ⊗ |1>
f(|101>) = |1> ⊗ |0> ⊗ |0>
f(|110>) = |1> ⊗ |1> ⊗ |1>
f(|111>) = |1> ⊗ |1> ⊗ |0>

Se capisci la porta CNOT, puoi capire perché questa è la nostra funzione. Pensa a questo come a una tabella di verità. Poiché il nostro qubit di controllo è il qubit più significativo, qubit [2], solo quando quel qubit è | 1> verrà annullato il qubit meno significativo, qubit [0].

Espandilo nel nostro modulo vettoriale di probabilità normalizzato ...

f(|000>) = [ 1, 0 ] ⊗ [ 1, 0 ] ⊗ [ 1, 0 ]
f(|001>) = [ 1, 0 ] ⊗ [ 1, 0 ] ⊗ [ 0, 1 ]
f(|010>) = [ 1, 0 ] ⊗ [ 0, 1 ] ⊗ [ 1, 0 ]
f(|011>) = [ 1, 0 ] ⊗ [ 0, 1 ] ⊗ [ 0, 1 ]
f(|100>) = [ 0, 1 ] ⊗ [ 1, 0 ] ⊗ [ 0, 1 ]
f(|101>) = [ 0, 1 ] ⊗ [ 1, 0 ] ⊗ [ 1, 0 ]
f(|110>) = [ 0, 1 ] ⊗ [ 0, 1 ] ⊗ [ 0, 1 ]
f(|111>) = [ 0, 1 ] ⊗ [ 0, 1 ] ⊗ [ 1, 0 ]

Ora risolviamo davvero questo ...

f(|000>) = [ 1, 0, 0, 0, 0, 0, 0, 0 ]
f(|001>) = [ 0, 1, 0, 0, 0, 0, 0, 0 ]
f(|010>) = [ 0, 0, 1, 0, 0, 0, 0, 0 ]
f(|011>) = [ 0, 0, 0, 1, 0, 0, 0, 0 ]
f(|100>) = [ 0, 0, 0, 0, 0, 1, 0, 0 ]
f(|101>) = [ 0, 0, 0, 0, 1, 0, 0, 0 ]
f(|110>) = [ 0, 0, 0, 0, 0, 0, 0, 1 ]
f(|111>) = [ 0, 0, 0, 0, 0, 0, 1, 0 ]

Rendiamo queste le colonne della nostra matrice LGG.

lgm =
[ 1, 0, 0, 0, 0, 0, 0, 0 ]
[ 0, 1, 0, 0, 0, 0, 0, 0 ]
[ 0, 0, 1, 0, 0, 0, 0, 0 ]
[ 0, 0, 0, 1, 0, 0, 0, 0 ]
[ 0, 0, 0, 0, 0, 1, 0, 0 ]
[ 0, 0, 0, 0, 1, 0, 0, 0 ]
[ 0, 0, 0, 0, 0, 0, 0, 1 ]
[ 0, 0, 0, 0, 0, 0, 1, 0 ]

Ora se la matrice si moltiplica la nostra intera matrice di sistema, sys, per la nostra matrice di gate logici, lgm, il nostro risultato sarà l'effetto dell'applicazione del gate CNOT a qubit [2] e qubit [0] dove qubit [2] è il controllo qubit.


Grazie per aver incluso un esempio alla fine; è stato molto utile. Potresti fornire anche una definizione del prodotto Kronecker? (Penso anche che potresti averlo scritto erroneamente come "Kornecker" una volta.)
Pro Q

1
Lo consiglio per il prodotto Kronecker: youtube.com/watch?v=e1UJXvu8VZk
Amelia Hartman
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.