Come programmare un computer quantistico - Parte 2

Navi da battaglia con misure quantistiche

IBM Research https://www.flickr.com/photos/ibm_research_zurich/33072160062/

Questo articolo ha 'Parte 2' nel titolo per una buona ragione. C'è stata una parte 1, in cui abbiamo esaminato le basi della scrittura e dell'esecuzione di programmi quantistici.

Presumo che tu abbia letto almeno la prima metà prima di venire qui.

La maggior parte delle attuali conoscenze di programmazione necessarie per questo tutorial è stata trattata l'ultima volta. Questo articolo si concentrerà principalmente su alcune delle cose che possiamo fare con questi comandi.

Come guardare i qubit

Nei programmi abbiamo variabili. Ad un certo punto dovremo guardarli.

Questo potrebbe essere alla fine del programma quando otteniamo il risultato. Potrebbe anche essere durante il programma, quando utilizziamo la variabile come parte di un'istruzione condizionale. Ad ogni modo, succede molto. E quando si programmano variabili non quantistiche, è un processo abbastanza insignificante.

Questo perché le variabili non quantistiche hanno valori definiti. Guardandoli ci dice, o altre parti del programma, qual è il valore. Nulla della variabile stessa cambierà.

Questo non è vero per le variabili quantistiche, che possono avere valori indefiniti. Possono trovarsi in una cosiddetta sovrapposizione quantistica, che consente loro di contenere contemporaneamente più valori contraddittori.

Quando li guardiamo, devono rinunciare a tutta questa stranezza. Sono costretti a prendere un valore definito e quindi a dirci qual è quel valore. Poiché questo non è solo un processo passivo, deve essere attentamente considerato. E ha bisogno di un nome. Lo chiamiamo misurazione.

In questo articolo esploreremo alcune delle proprietà della misurazione. Lo useremo anche come base di una meccanica di gioco e vedremo esattamente come programmarlo su un computer quantistico. Alla fine avremo una nuova versione di Battleships.

Mappatura del mondo di un qubit

Prima di iniziare davvero a misurare i qubit, dovremmo cercare di capire un po 'di più il loro mondo. Il modo migliore per visualizzare un qubit è usare una sfera. Ogni possibile stato di qubit corrisponde a un punto sulla superficie di questa sfera.

Gli stati 0 e 1 sono completamente diversi, completamente disgiunti. Sono gli opposti l'uno dell'altro. Vivranno quindi su lati opposti della sfera. Di solito scegliamo di mettere 0 al polo nord e 1 a sud.

Scegliamo un punto equidistante tra i due, da qualche parte lungo l'equatore. Può essere ovunque tu voglia. Lo chiameremo +. Perché +? Perchè no?

Anche lo stato + ha un opposto, diverso da quello di 0 rispetto a 1. Vive dalla parte opposta, che sarà anche un punto lungo l'equatore. Chiameremo questo stato -.

Con i punti 0, 1, + e - ora definiti, un'altra coppia di punti richiede la nostra attenzione. Questi sono quelli equidistanti tra 0 e 1 e anche equidistanti tra + e -. Chiameremo questi ↻ e ↺. Perché? Perché una volta ho visto un ragazzo che non scriveva il Codice Da Vinci e mi piaceva.

Ora abbiamo mappato il mondo del qubit con sei punti. Questi non sono assolutamente gli unici che useremo mai. Sono semplicemente i punti di riferimento attraverso i quali navigheremo.

Misurare un qubit

Ogni misurazione è semplicemente noi che chiediamo a un qubit di scegliere tra due punti opposti sulla sfera.

L'esempio classico è per la nostra coppia preferita di stati opposti: 0 e 1. Chiediamo al qubit di scegliere tra i due. Se era già nello stato 0, andrà a 0. Un qubit nello stato 1 fornirà allo stesso modo il risultato 1. Per qualsiasi altro stato, il risultato sarà casuale, con l'opzione più vicina è la più probabile.

Sull'equatore, è una probabilità del 50/50 in entrambi i casi. Quindi se il nostro stato era + o -, e quindi chiediamo se è 0 o 1, dovrà scegliere l'uno o l'altro con uguale probabilità.

La misurazione basata su 0 e 1 ha alcuni nomi. Possiamo chiamarlo una misura 0/1, per ovvi motivi. Si chiama anche una misura di base Z, a causa della relazione speciale che gli stati 0 e 1 hanno con un'operazione chiamata z. Altro su quella storia un'altra volta.

Il prossimo tipo di misurazione più popolare è quello per + e -. Chiamerò questo una misurazione +/-, ma potresti anche vederlo chiamato una misurazione di base X. Funziona allo stesso modo di prima, ma solo per + e - invece di 0 e 1. Quindi, se inizi con un qubit nello stato + e fai questa misura, otterrai il risultato +. Ma se inizi con 0 e fai la stessa domanda, sceglierà in modo casuale.

Abbiamo anche una misurazione per le strane cose della freccia. Questa è chiamata misurazione su base Y. A nessuno piacciono le misurazioni della base Y.

Un po 'è solo un po', anche quando è quantico

La misurazione di oggetti non quantistici è un processo passivo. Ti dice cosa sta facendo l'oggetto, ma non lo cambia in alcun modo. Misurare le cose quantistiche è molto diverso. Le misurazioni quantistiche non cambiano solo la nostra conoscenza delle variabili. Cambiano le variabili stesse.

Supponi di avere un qubit in stato +, quindi chiedi se è 0 o 1. Quando ti dà un risultato casuale, non ti sta solo prendendo in giro. Non ti sta dicendo delle sciocchezze perché hai fatto la domanda sbagliata. Una volta che ti dà un risultato, si attaccherà con esso. Il suo valore cambierà per riflettere la risposta. Se ti dice 0, sarà 0 per sempre (o fino a quando non lo confondi di nuovo, almeno). Si dimenticherà che è mai stato +.

Ciò significa che un qubit può essere sempre e solo sicuro del suo risultato in una singola misurazione. Se sa sicuramente se è 0 o 1, è completamente incerto se è + o - e anche completamente incerto se è ↻ o ↺. Un qubit ha solo una quantità limitata di certezza da aggirare, limitata dal principio di incertezza di Heisenberg.

Ciò significa che abbiamo sempre e solo una possibilità di ottenere informazioni da un qubit. Una volta estratto un singolo risultato binario, tutto il qubit mai conosciuto prima della misurazione viene dimenticato. Ricorda solo il risultato che ci ha dato. E così, nonostante il numero infinito di possibili stati qubit, possiamo estrarre solo un singolo bit di informazioni. Ecco perché la pensiamo come la versione quantistica di un bit, piuttosto che un float quantistico o un vettore quantico 3, ecc.

La meccanica di gioco

Faremo una variante di Battleships in cui ci saranno due tipi di attacco: bombe e siluri. Sarà necessario solo un attacco riuscito per affondare una nave, ma ottenere un attacco riuscito non è sempre così facile. Alcune navi hanno una difesa così grande contro gli aerei che nessuna bomba potrà mai avvicinarsi a loro. Altri sono bravi a respingere i siluri.

Per implementarlo su un normale computer, potremmo definire due variabili booleane per ogni nave. Uno ci direbbe se la nave è immune alle bombe e l'altra ai siluri. Questi possono quindi essere controllati durante gli attacchi per vedere se la nave affonda o no.

Se questa fosse l'implementazione che usiamo, sarebbe teoricamente possibile che una nave sia immune da entrambi i tipi di attacco. Questo sarebbe un design di gioco scadente, dal momento che rende impossibile per un giocatore vincere. Una buona attuazione dovrebbe impedire l'esistenza di navi indistruttibili.

Un modo per evitare di realizzare tali navi è con poche semplici righe di codice. Questo non è proprio il nostro stile, però. Invece, lo ripareremo con la meccanica quantistica!

In particolare, proveremo a spremere questi due booleani in un unico qubit. Dal momento che non si adattano perfettamente, avremo un comportamento quantistico interessante. Ciò aggiungerà un gameplay interessante al gioco, oltre a impedire a qualsiasi nave di essere indistruttibile.

Lo implementeremo associando un attacco bomba a una misura 0/1. Se otteniamo il risultato 1, diciamo che la nave è affondata. Per 0 deduciamo che la nave è immune agli attacchi bomba. Per i siluri invece facciamo una misurazione +/-, con - implicando la distruzione e + implicando l'immunità.

Questo metodo rende impossibile per una nave essere assolutamente immune da entrambi i tipi di attacco. Se scopriamo che una nave nemica è immune alle bombe (cioè il suo stato è 0), sappiamo che deve essere completamente incerta sui siluri (il risultato di una misurazione +/-). Dato che un attacco con bombe fallirebbe sicuramente, dovremmo quindi attaccare con i siluri dopo.

Potrebbe quindi risultare che l'attacco siluro fallisce (lo stato diventa + dopo la misurazione +/-). La nave avrebbe deciso che è assolutamente immune da loro, e ogni ulteriore attacco di siluro fallirebbe. Ma non tutta la speranza è persa. Diventando certi dei siluri, è diventato incerto sulle bombe. L'attacco successivo con loro (facendo una misura 0/1) potrebbe portare alla vittoria.

Se l'attacco dinamitardo non riesce, torniamo ai siluri e così via. La tattica migliore è quella di continuare a passare tra i due finché la nave non affonda definitivamente.

Inizieremo le navi come incerte sulla loro immunità ad entrambi gli attacchi. Questo può essere fatto inizializzando il qubit in uno degli stati di base Y. Andiamo per ↻. Questo è in realtà uno stato che abbiamo incontrato nella Parte 1, vale a dire u3 (0,5 * pi, 0,0) 0, quindi sappiamo già come farlo.

Trattare con qubit di breve durata

L'implementazione del gioco su un processore quantistico non sarà facile come potremmo sperare. Daremo uno sguardo a tutti i problemi che ci ostacoleranno e vedremo come aggirarli.

Supponiamo che una nave venga attaccata da una bomba e sopravviva. Quindi nel round successivo viene colpito da un siluro.

Se il gioco fosse eseguito su un normale computer e fosse simulato utilizzando bit normali, implementarlo sarebbe abbastanza semplice. La nave verrebbe inizializzata all'inizio del gioco, quindi attenderà in memoria fino a quando il giocatore non deciderà cosa farne. Una volta che il giocatore invia una bomba, verranno applicate le operazioni corrispondenti per vedere se viene distrutta. Se sopravvive, aspetta di nuovo fino al prossimo attacco.

Questo non funzionerà per noi. I Qubit non possono restare in attesa di scale temporali umane. Pochi secondi sono più che sufficienti per consentire loro di arrestarsi e bruciarsi, almeno con la tecnologia attuale.

L'alternativa è eseguire un nuovo processo quantico ogni volta che viene fatto un attacco. Il primo lavoro verrà inizializzato con lo stato ↻, in modo che i risultati siano casuali sia per una misurazione 0/1 (attacco bomba) sia per una misurazione +/- (attacco siluro). Il risultato della misurazione viene quindi registrato e archiviato nella memoria del normale computer. Quando si verifica l'attacco successivo, viene creato un altro lavoro per vedere cosa succede. Verrà inizializzato con il risultato dell'ultima misurazione e quindi continua.

Fare una misurazione +/-

Finora ho scritto un sacco di parole, ma non una singola riga di codice. Cominciamo ricordando come una misura 0/1 è implementata nel codice QASM.

misura q [0] -> c [0];

Il ruolo di c [0] qui è importante rivisitare. È l'output del processo di misurazione. È il bit normale in cui è memorizzato il risultato della misurazione. Per una misurazione 0/1 il risultato è 0 o 1.

Questo è abbastanza semplice per una misurazione 0/1. Ma ora stiamo esaminando le misurazioni +/-. Come otteniamo le informazioni da una di esse?

Vorremmo comunque memorizzare il risultato in un bit normale c [0]. Dal momento che è un po 'normale, non ha conoscenza degli stati strani + e -. Conosce solo il normale binario. Pertanto, scegliamo di segnalare il risultato + come c [0] = 0 e - come c [0] = 1. Il fatto che questi sembreranno gli stessi dei risultati di una misurazione 0/1 non sarà un problema. Come in qualsiasi programma per computer, dovremmo sapere cosa abbiamo programmato e quindi dovremmo sapere come interpretare i risultati.

Ora sappiamo come ottenere i risultati da una misurazione +/-. Ma non abbiamo ancora scoperto come farlo effettivamente. Questo perché dobbiamo essere furtivi al riguardo. Dobbiamo hackerare il processo che esegue misurazioni 0/1 e invece ha fatto un +/-.

La chiave del nostro hack è un'operazione chiamata Hadamard. Applicando questo a un qubit q [0] nel codice QASM è simile al seguente.

hq [0];

Il comando che usiamo in Python per aggiungere questa linea a un file QASM chiamato gridScript è

gridScript.h (q [0])

L'effetto di Hadamard è di scambiare gli stati di base Z con quelli di base X e viceversa. È una rotazione della Sfera che sposta le svolte di uno stato di qubit 0 in un + e + in 0. Analogamente, 1 viene ruotato in - e viceversa.

Ciò significa che quella storia che possiamo raccontare di un qubit in termini di 0 e 1 prima dell'Hadamard, dobbiamo raccontarla con + e - dopo. E qualsiasi storia di + e - diventa una di 0 e 1.

Questo è esattamente ciò di cui abbiamo bisogno. Significa che una misurazione +/- su un qubit q [0] può essere eseguita con il seguente codice QASM.

hq [0]; misura q [0] -> c [0]; hq [0];

Per capire perché funziona, passiamo ad alcuni esempi. Il qubit q [0] inizierà di nuovo appena dichiarato in ciascuno, e quindi sarà nel suo valore iniziale predefinito di 0.

Esempio zero:

misura q [0] -> c [0];

Il qubit inizia nello stato 0. Viene chiesto se è 0 o 1 e dice a c [0] la risposta. Il risultato sarà sempre c [0] = 0.

Esempio uno:

xq [0];
misura q [0] -> c [0];

Il qubit inizia nello stato 0 e quindi viene ruotato su 1. Viene quindi chiesto se è 0 o 1. Risponde sempre 1.

Esempio +:

hq [0];
misura q [0] -> c [0];

Il qubit inizia nello stato 0 e viene immediatamente ruotato su +. Viene quindi chiesto se il suo stato è 0 o 1. Seleziona casualmente l'uno o l'altro e il suo stato viene aggiornato con la risposta.

Ora abbiamo fatto alcuni esempi banali, facciamo qualcosa di più complesso.

Esempio ++:

hq [0];
hq [0]; misura q [0] -> c [0]; hq [0];

Il qubit inizia nello stato 0 e quindi viene ruotato su +. Successivamente, ci sono due modi equivalenti per continuare la storia.

Si deve dire che le tre linee finali effettuano collettivamente una misurazione +/-. Chiedono al qubit se è + o -. Per + restituiscono il risultato c [0] = 0, e per - restituiscono c [0] = 1. Poiché il qubit va nella misura con stato + in questo esempio, viene sempre misurato come +. Esce quindi dalla misura ancora in questo stato.

Per l'altra storia, esaminiamo gli effetti delle linee uno a uno. Il secondo Hadamard annulla l'effetto del primo, quindi ruota il qubit di nuovo sullo stato 0. Viene quindi chiesto se il suo stato è 0 o 1, e quindi risponde sempre 0. Un ulteriore Hadamard lo ruota di nuovo su +.

Entrambe le storie concordano sugli effetti osservabili. Sono d'accordo che l'output c [0] sarà sempre 0 e concordano che lo stato del qubit alla fine sarà +. Non sono d'accordo su come sia successo. Entrambe le interpretazioni sono ugualmente valide.

Se vuoi un po 'di gergo per cercare cose su Wikipedia, questi sono esempi delle immagini della meccanica quantistica di Schrödinger e Heisenberg.

Esempio +1:

xq [0];
hq [0]; misura q [0] -> c [0]; hq [0];

Ecco un altro esempio per il quale abbiamo due storie equivalenti. Possiamo dire che q [0] inizia come 0 e quindi viene ruotato su 1. Questo viene quindi ruotato di t0 - prima di passare attraverso una misurazione 0/1. Decide in modo casuale l'uno o l'altro, fornisce l'output c [0] = 0 o c [0] = 1 e lo stato viene aggiornato di conseguenza. Se ha deciso 0, l'Hadamard finale lo ruota su +. Altrimenti finirà con -.

In alternativa, potremmo dire che dopo essere stato ruotato su 1, il qubit passa attraverso una misurazione +/-. Decide in modo casuale tra queste due opzioni, fornendo l'output c [0] = 0 per + e c [0] = 0 per -. Lo stato viene aggiornato di conseguenza, finendo nello stato + o -.

Ancora una volta, queste due storie sono ugualmente valide e concordano su tutti gli effetti osservabili. Se vogliamo pensare alle tre linee

hq [0]; misura q [0] -> c [0]; hq [0];

come misura +/-, siamo liberi di farlo. Se vogliamo pensarlo come un Hadamard seguito da una misurazione 0/1 seguita da un Hadamard, va bene lo stesso.

C'è una cosa importante da notare prima di andare avanti. L'API di IBM al momento non ci consente di fare nulla su un qubit dopo averlo misurato. Questa non è una regola generale per i computer quantistici. Di solito ci aspetteremmo di essere in grado di continuare a misurare e manipolare i qubit per tutto il tempo che vorremmo. Ma non possiamo farlo al momento.

Questo non ci pone alcun problema. Dal momento che i qubit non possono sedersi mentre i giocatori effettuano comunque delle scelte, dobbiamo già ricreare completamente lo stato dopo ogni round di misurazione. Il secondo Hadamard si presenterà effettivamente nel prossimo lavoro, agendo sulla versione reincarnata dello stato.

Tutte le altre possibili misurazioni possono essere raggiunte da hack simili. Dobbiamo solo eseguire alcune operazioni in anticipo per individuare la nostra misurazione alternativa e quindi (se l'API lo consente) fare le operazioni opposte subito dopo.

Gestire gli errori

L'attuale tecnologia quantistica non è perfetta. I qubit non fanno sempre ciò che dovrebbero. Se il tuo qubit è 0 e fai una misura 0/1, il risultato dovrebbe essere sempre 0. Sempre. Ma con gli attuali dispositivi quantistici, c'è la possibilità che sia 1. Potrebbe essere perché un'operazione x si è intrufolata mentre non stavamo guardando. Potrebbe essere perché la misurazione ci sta mentendo. Eventi come questi sono rari, ma accadono.

Esistono due modi in cui possiamo gestire gli errori. Uno è di ignorarli. Possiamo scriverli nella narrazione del gioco. Ci sono grandi tempeste sul mare. Questi a volte portano una nave a essere distrutta da un attacco anche se è immune. O sopravvivere a un attacco che avrebbe dovuto distruggerlo.

Il secondo modo di gestire gli errori è provare a rimuovere i loro effetti. Se fossero disponibili molti qubit, potremmo farlo con la correzione dell'errore quantistico. Purtroppo mancano ancora alcuni anni.

Invece faremo alcune statistiche. Per questo abbiamo bisogno di probabilità, che otteniamo eseguendo ogni lavoro molte volte e vedendo con quale frequenza si presentano tutti i possibili risultati.

Nel caso silenzioso, le probabilità sarebbero tutte dello 0%, 100% o 50%. Un risultato è impossibile (come ottenere un 1 se lo stato è 0), certo (come ottenere un + se lo stato è +) o completamente casuale (come ottenere uno 0 quando lo stato è +).

Il rumore li rovinerà un po '. Quando eseguiamo una misurazione 0/1 di uno 0, potremmo scoprire che il risultato 0 si verifica solo il 98% delle volte, con il 2% che va invece per 1. Per correggere ciò faremo qualcosa di abbastanza arbitrario. Decideremo che nulla con una probabilità inferiore al 5% non dovrebbe mai accadere. Qualunque cosa con una probabilità superiore al 95% avrebbe dovuto essere certa.

Mettere tutto insieme

Questo articolo ha trattato i grandi tratti della meccanica di gioco per questa versione di Battleships e come implementarlo con un computer quantistico. Piuttosto che passare attraverso tutti i dettagli chiacchieroni qui, lo lascerò per i commenti nel codice sorgente reale.

Se c'è qualcosa che pensi abbia bisogno di ulteriori spiegazioni, sentiti libero di farmelo sapere.