Sari la conținutul principal

Computații clasice pe calculatoare cuantice

Vom îndrepta acum atenția spre implementarea algoritmilor clasici pe calculatoare cuantice. Vom vedea că orice computație care poate fi efectuată cu un circuit Boolean clasic poate fi efectuată și de un circuit cuantic cu un cost computațional asimptotic similar. Mai mult, acest lucru se poate face într-un mod „curat", care va fi descris în curând, și care reprezintă o cerință importantă pentru folosirea acestor computații ca subrutine în cadrul unor computații cuantice mai mari.

Simularea circuitelor Boolean cu circuite cuantice

Circuitele Boolean sunt compuse din porți AND, OR, NOT și FANOUT. Pentru a simula circuitele Boolean cu circuite cuantice, vom începe prin a arăta cum poate fi simulată fiecare dintre aceste patru porți cu porți cuantice. Odată rezolvat acest lucru, conversia unui circuit Boolean dat într-un circuit cuantic este o simplă chestiune de simulare a câte unei porți pe rând. Va fi nevoie doar de porți NOT, porți controlled-NOT și porți Toffoli, care sunt toate operații deterministe, dar și unitare.

Porți Toffoli

Porțile Toffoli pot fi descrise alternativ ca porți controlled-controlled-NOT, a căror acțiune asupra stărilor bazei standard este prezentată în figura de mai jos.

Toffoli gate

Ținând cont că folosim convenția de ordonare a Qiskit, unde qubiții sunt ordonați în ordinea crescătoare a semnificației de sus în jos, reprezentarea matriceală a acestei porți este următoarea.

(1000000001000000001000000000000100001000000001000000001000010000)\begin{pmatrix} 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 & 0 & 0 & 0 & 1 \\ 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 & 1 & 0 & 0 & 0 & 0 \end{pmatrix}

Un alt mod de a gândi porțile Toffoli este că ele sunt în esență porți de interogare pentru funcția AND, în sensul că urmează tiparul văzut în lecția anterioară pentru implementările unitare ale porților de interogare ale unor funcții arbitrare cu intrări și ieșiri de tipul șiruri binare.

Porțile Toffoli nu sunt incluse în setul implicit de porți discutat mai devreme în lecție, dar este posibil să construiești o poartă Toffoli din porțile H,H, T,T, TT^{\dagger} și CNOT după cum urmează.

Quantum circuit for a Toffoli gate

Simularea porților Boolean cu porți Toffoli, controlled-NOT și NOT

O singură poartă Toffoli, folosită împreună cu câteva porți NOT, poate implementa o poartă AND și una OR, iar porțile FANOUT pot fi implementate cu ușurință folosind porți controlled-NOT, după cum sugerează diagramele de mai jos.

Simulating AND and OR gates with Toffoli gates

În toate trei cazurile, qubiții asupra cărora acționează porțile AND, OR și FANOUT intră din stânga ca intrări, iar pentru fiecare este necesar și câte un qubit de spațiu de lucru inițializat la starea zero. Acești qubiți de spațiu de lucru apar în interiorul casetelor care reprezintă implementările porților pentru a sugera că sunt noi și, prin urmare, fac parte din costul acestor implementări.

Pentru porțile AND și OR mai rămân și doi qubiți, pe lângă qubitul de ieșire. De exemplu, în interiorul casetei din diagramă care reprezintă simularea unei porți AND, primii doi qubiți rămân în stările a\vert a\rangle și b.\vert b\rangle. Acești qubiți sunt ilustrați ca rămânând în interiorul casetelor deoarece nu mai sunt necesari și nu fac parte din ieșire. Pot fi ignorați deocamdată, deși vom reveni la ei în curând.

Singura poartă Boolean rămasă, poarta NOT, este inclusă în setul nostru implicit de porți cuantice, deci nu avem nevoie de o simulare pentru aceasta.

Simularea gate cu gate a circuitelor Boolean

Să presupunem acum că avem un circuit Boolean obișnuit numit C,C, compus din porți AND, OR, NOT și FANOUT, cu nn biți de intrare și mm biți de ieșire. Fie t=size(C)t = \operatorname{size}(C) numărul de porți din CC și să numim ff funcția calculată de CC, care are forma

f:ΣnΣmf:\Sigma^n\rightarrow\Sigma^m

pentru Σ={0,1}.\Sigma = \{0,1\}.

Acum să ne gândim la ce se întâmplă când parcurgem pe rând porțile AND, OR și FANOUT ale lui C,C, înlocuind fiecare cu simularea corespunzătoare descrisă mai sus, inclusiv adăugând qubiții de spațiu de lucru necesari. Să numim circuitul rezultat RR și să ordonăm qubiții lui RR astfel încât cei nn biți de intrare ai lui CC să corespundă primilor nn qubiți ai lui RR, iar qubiții de spațiu de lucru să fie la sfârșit.

Reversible circuit simulation

Aici, kk este numărul de qubiți de spațiu de lucru necesari — câte unul pentru fiecare poartă AND, OR și FANOUT din CC — și gg este o funcție de forma g:ΣnΣn+kmg:\Sigma^n \rightarrow \Sigma^{n+k-m} care descrie stările qubiților rămași creați de simulările de porți după ce RR este rulat. În figură, qubiții corespunzători ieșirii f(x)f(x) se află sus, iar qubiții rămași care stochează g(x)g(x) se află jos. Putem forța acest lucru dacă dorim, prin rearanjarea qubiților cu porți SWAP, care pot fi implementate cu trei porți controlled-NOT astfel:

Swapping with cNOT gates

Cum vom vedea în secțiunea următoare, nu este cu adevărat esențial să rearanjăm qubiții de ieșire în acest mod, dar este suficient de simplu de făcut dacă alegem să o facem.

Funcția gg care descrie stările clasice ale qubiților rămași este determinată de circuitul C,C, dar de fapt nu trebuie să ne îngrijorăm prea mult în privința ei; nu ne interesează în mod specific în ce stare se află acești qubiți când computația se termină. Litera gg vine după f,f, deci este un nume rezonabil pentru această funcție din acel motiv, dar există un motiv mai bun de a alege numele gg — este prescurtarea pentru gunoi (engl. garbage).

Curățarea gunoiului

Dacă singurul nostru interes este evaluarea funcției ff calculată de un circuit Boolean CC cu un circuit cuantic, nu trebuie să mergem mai departe decât simularea gate cu gate tocmai descrisă. Aceasta înseamnă că, pe lângă ieșirea funcției, vom mai avea o grămadă de gunoi rămas.

Totuși, asta nu este suficient dacă vrem să efectuăm computații clasice ca subrutine în cadrul unor computații cuantice mai mari, deoarece acei qubiți de gunoi vor cauza probleme. Fenomenul de interferență este extrem de important pentru algoritmii cuantici, iar qubiții de gunoi pot distruge tiparele de interferență necesare pentru ca algoritmii cuantici să funcționeze.

Din fericire, curățarea gunoiului, ca să spunem așa, nu este dificilă. Cheia este să folosim faptul că, deoarece RR este un circuit cuantic, îl putem rula în sens invers, înlocuind pur și simplu fiecare poartă cu inversa sa și aplicându-le în ordine inversă, obținând astfel un circuit cuantic pentru operația R.R^{\dagger}. Porțile Toffoli, porțile CNOT și porțile NOT sunt de fapt propriile lor inverse, deci rularea lui RR în sens invers este cu adevărat doar o chestiune de aplicare a porților în ordine inversă — dar mai general, orice circuit cuantic poate fi inversat după cum tocmai am descris.

Mai concret, ce putem face este să adăugăm mm qubiți în plus (amintind că funcția ff are mm biți de ieșire), să folosim porți CNOT pentru a copia ieșirea lui RR pe acești qubiți și să inversăm RR pentru a curăța gunoiul. Figura de mai jos ilustrează circuitul rezultat și descrie acțiunea sa asupra stărilor bazei standard.

Garbage-free computation

Dacă punem o casetă în jurul întregului circuit și îl numim QQ, arată astfel:

Simulation as a query gate

Dat fiind că CC are tt porți, circuitul QQ va avea O(t)O(t) porți.

Dacă ignorăm cei kk qubiți suplimentari de spațiu de lucru, avem un circuit QQ care funcționează exact ca o poartă de interogare pentru funcția f.f. Dacă vrem pur și simplu să calculăm funcția ff pe un șir x,x, putem seta y=0my = 0^m și valoarea rezultată f(x)f(x) va apărea pe ultimii mm qubiți — sau putem alimenta o stare diferită în ultimii mm qubiți dacă dorim (poate pentru a utiliza un phase kickback, ca în algoritmul lui Deutsch sau al lui Deutsch-Jozsa).

Aceasta înseamnă că pentru orice algoritm de interogare, dacă avem un circuit Boolean care calculează funcția de intrare, putem înlocui fiecare poartă de interogare cu o implementare ca circuit a acesteia, și algoritmul de interogare va funcționa corect.

Rețineți că qubiții de spațiu de lucru sunt necesari pentru ca acest proces să funcționeze, dar sunt readuși la stările lor inițiale odată ce circuitul combinat este executat. Asta permite ca acești qubiți să fie folosiți din nou ca qubiți de spațiu de lucru în alte scopuri. Există și strategii cunoscute pentru a reduce numărul de qubiți de spațiu de lucru necesari (care vin cu un cost de mărire a circuitelor), dar nu vom discuta acele strategii aici.

Implementarea funcțiilor inversabile

Construcția tocmai descrisă ne permite să simulăm orice circuit Boolean cu un circuit cuantic fără gunoi. Dacă CC este un circuit Boolean care implementează o funcție f:ΣnΣm,f:\Sigma^n \rightarrow \Sigma^m, atunci obținem un circuit cuantic QQ care operează astfel pe stările bazei standard.

Q(y0kx)=yf(x)0kxQ \bigl( \vert y \rangle \vert 0^k \rangle \vert x\rangle\bigr) = \vert y \oplus f(x) \rangle \vert 0^k \rangle \vert x\rangle

Numărul kk indică câți qubiți de spațiu de lucru sunt necesari în total. Asta este suficient pentru scopurile acestui curs, dar este posibil să duci această metodologie cu un pas mai departe când funcția ff în sine este inversabilă.

Mai precis, să presupunem că funcția ff are forma f:ΣnΣnf:\Sigma^n \rightarrow \Sigma^n și că există o funcție f1f^{-1} astfel încât f1(f(x))=xf^{-1}(f(x)) = x pentru orice xΣnx\in\Sigma^n (care este în mod necesar unică atunci când există). Aceasta înseamnă că operația care transformă x\vert x \rangle în f(x)\vert f(x) \rangle pentru orice xΣnx\in\Sigma^n este unitară, deci am putea spera să construim un circuit cuantic care implementează operația unitară definită de

Ux=f(x)U \vert x \rangle = \vert f(x) \rangle

pentru orice xΣn.x\in\Sigma^n.

Pentru a fi clar, faptul că aceasta este o operație unitară depinde de ff a fi inversabilă — nu este unitară când ff nu este inversabilă. Ignorând qubiții de spațiu de lucru, UU este diferit de operația pe care o implementează circuitul QQ deoarece nu păstrăm o copie a intrării și nu aplicăm XOR cu un șir arbitrar, ci înlocuim xx cu f(x).f(x).

Întrebarea este: când ff este inversabilă, putem face asta?

Răspunsul este da, cu condiția să avem voie să folosim qubiți de spațiu de lucru și, pe lângă un circuit Boolean care calculează f,f, să avem și unul care calculează f1.f^{-1}. Deci, aceasta nu este o scurtătură pentru inversarea computațională a funcțiilor când nu știm deja cum să facem asta! Diagrama de mai jos ilustrează cum se poate realiza prin compunerea a două circuite cuantice, QfQ_f și Qf1,Q_{f^{-1}}, obținute individual pentru funcțiile ff și f1f^{-1} prin metoda descrisă mai sus, împreună cu nn porți swap, luând kk ca maximul numărului de qubiți de spațiu de lucru necesari de QfQ_f și Qf1.Q_{f^{-1}}.

Simulation of an invertible function