Toric code
Teraz omówimy konkretny CSS code znany jako toric code, odkryty przez Aleksieja Kitajewa w 1997 roku. W rzeczywistości toric code to nie jeden kod, lecz rodzina kodów — po jednym dla każdej dodatniej liczby całkowitej począwszy od 2. Kody te mają kilka kluczowych właściwości:
-
Generatory Stabilizer mają niską wagę, a w szczególności wszystkie mają wagę 4. W nomenklaturze teorii kodowania toric code jest przykładem kwantowego kodu kontroli parzystości o niskiej gęstości, czyli kwantowego kodu LDPC (gdzie niska oznacza w tym przypadku 4). Jest to wygodne, ponieważ każdy pomiar generatora Stabilizer nie musi angażować zbyt wielu qubitów.
-
Toric code ma geometryczną lokalność. Oznacza to, że generatory Stabilizer nie tylko mają niską wagę, ale można też rozmieścić kubity przestrzennie tak, by każdy pomiar generatora Stabilizer angażował wyłącznie kubity leżące blisko siebie. W zasadzie sprawia to, że takie pomiary są łatwiejsze do wykonania niż gdyby dotyczyły qubitów oddalonych przestrzennie.
-
Kolejne elementy rodziny toric code mają coraz większy dystans i mogą tolerować stosunkowo wysoką stopę błędów.
Opis toric code
Niech będzie dodatnią liczbą całkowitą i rozważmy lattice z tzw. periodycznymi brzegami. Na przykład poniższy rysunek przedstawia lattice dla
Zwróć uwagę, że linie po prawej stronie i na dole są liniami przerywanymi. Wskazuje to, że przerywana linia po prawej jest tą samą linią co linia po lewej stronie, i analogicznie przerywana linia na dole jest tą samą linią co linia na samej górze.
Fizyczna realizacja takiej konfiguracji wymaga trzech wymiarów. Możemy na przykład uformować lattice w cylinder, dopasowując najpierw lewą i prawą krawędź, a następnie wygiąć cylinder tak, by okręgi na końcach — które były górną i dolną krawędzią lattice — spotkały się. Możemy też najpierw dopasować górę i dół, a potem boki; działa to w obie strony i dla celów tego omówienia nie ma znaczenia, którą kolejność wybierzemy.
Otrzymujemy w ten sposób torus — czyli, innymi słowy, pączek (choć może lepszym obrazem jest dętka, bo to nie jest bryła: lattice staje się jedynie powierzchnią torusa). Stąd pochodzi nazwa „toric code".
Sposób, w jaki można „poruszać się" po takim torusie między sąsiednimi punktami lattice, będzie prawdopodobnie znajomy osobom, które grały w stare gry wideo, gdzie wyjście poza górną krawędź ekranu powodowało pojawienie się na dole, i podobnie po lewej i prawej stronie. Właśnie tak będziemy patrzeć na tę lattice z periodycznymi brzegami, bez odnoszenia się wprost do torusa w trójwymiarowej przestrzeni.
Następnie kubity rozmieszczamy na krawędziach tej lattice, jak pokazuje poniższy rysunek, gdzie kubity oznaczono wypełnionymi niebieskimi kółkami.
Zwróć uwagę, że kubity umieszczone na liniach przerywanych nie są wypełnione, bo są już reprezentowane na najwyższej i skrajnie lewej linii lattice. Łącznie jest qubitów: qubitów na poziomych liniach i qubitów na pionowych liniach.
Aby opisać sam toric code, pozostaje opisać generatory Stabilizer:
-
Dla każdej płytki (plaquette) utworzonej przez linie w lattice istnieje jeden generator Stabilizer , uzyskany przez tensoring macierzy na czterech qubitach stykających się z tą płytką oraz macierzy identyczności na wszystkich pozostałych qubitach.
-
Dla każdego vertex (wierzchołka) utworzonego przez linie w lattice istnieje jeden generator Stabilizer , uzyskany przez tensoring macierzy na czterech qubitach sąsiadujących z tym vertex oraz macierzy identyczności na wszystkich pozostałych qubitach.
W obu przypadkach otrzymujemy operację Pauli o wadze 4. Poszczególne generatory Stabilizer możemy zilustrować następująco.
Poniżej znajduje się ilustracja przedstawiająca kilka przykładów generatorów Stabilizer w kontekście samej lattice. Zwróć uwagę, że uwzględniono generatory Stabilizer owijające się wokół periodycznych brzegów. Takie generatory nie są wyjątkowe ani w żaden sposób wyróżnione spośród tych, które się nie owijają.
Aby kod był poprawnym kodem Stabilizer, generatory Stabilizer muszą komutować. Jak zwykle, wszystkie generatory Stabilizer komutują ze sobą nawzajem, ponieważ komutuje samo ze sobą, a identyczność komutuje ze wszystkim — i analogicznie dla generatorów Stabilizer . Generatory Stabilizer i wyraźnie komutują, gdy działają nietrywialnie na rozłącznych zbiorach qubitów, jak w przykładach z poprzedniego rysunku. Pozostała możliwość to sytuacja, gdy generator Stabilizer i generator Stabilizer nakładają się na qubitach, na których działają nietrywialnie — gdy tak się zdarza, generatory zawsze nakładają się na dokładnie dwóch qubitach, jak na kolejnym rysunku.
W konsekwencji dwa takie generatory Stabilizer komutują, tak jak komutują i . Wszystkie generatory Stabilizer komutują więc ze sobą nawzajem.
Drugi wymagany warunek dla generatorów Stabilizer kodu Stabilizer to to, że tworzą one minimalny zbiór generujący. Ten warunek w rzeczywistości nie jest spełniony przez ten zbiór: jeśli pomnożymy wszystkie generatory Stabilizer razem, otrzymamy operację identyczności, i podobnie dla generatorów Stabilizer . Zatem każdy z generatorów Stabilizer można wyrazić jako iloczyn wszystkich pozostałych, i analogicznie każdy z generatorów Stabilizer można wyrazić jako iloczyn pozostałych generatorów Stabilizer . Jeśli jednak usuniemy po jednym generatorze Stabilizer każdego typu, uzyskamy minimalny zbiór generujący.
Dla jasności: w praktyce zależy nam w równym stopniu na wszystkich generatorach Stabilizer i w ściśle operacyjnym sensie nie ma potrzeby wybierania jednego generatora Stabilizer każdego typu do usunięcia. Jednak na potrzeby analizy kodu — a w szczególności zliczania generatorów — możemy wyobrazić sobie, że jeden generator Stabilizer każdego typu został usunięty, uzyskując minimalny zbiór generujący, mając na uwadze, że wyniki tych usuniętych generatorów (traktowanych jako obserwable) zawsze możemy wywnioskować z wyników wszystkich pozostałych obserwabli generatorów Stabilizer tego samego typu.
Pozostaje generatorów Stabilizer każdego typu, czyli łącznie w (hipotetycznym) minimalnym zbiorze generującym. Biorąc pod uwagę, że łączna liczba qubitów wynosi , toric code koduje kubity.
Ostatni wymagany warunek dla generatorów Stabilizer to istnienie co najmniej jednego wektora stanu kwantowego unieruchomionego przez wszystkie generatory Stabilizer. Przekonamy się, że tak jest, kontynuując analizę kodu — można też uzasadnić, że nie ma możliwości wygenerowania razy identyczności na wszystkich qubitach z tych generatorów Stabilizer.
Wykrywanie błędów
Kod toryczny ma prostą i elegancką definicję, jednak jego właściwości korekcji błędów kwantowych mogą nie być od razu oczywiste. Jak się okazuje, to naprawdę niesamowity kod! Żeby zrozumieć, dlaczego i jak działa, zacznijmy od przyjrzenia się różnym błędom i generowanym przez nie syndrome'om.
Kod toryczny jest kodem CSS, ponieważ wszystkie nasze generatory Stabilizer są albo generatorami Stabilizer , albo generatorami Stabilizer . Oznacza to, że błędy i błędy można wykrywać (i ewentualnie korygować) niezależnie. W rzeczywistości między generatorami Stabilizer i istnieje prosta symetria, która pozwala nam analizować błędy i błędy w zasadniczo ten sam sposób. Skupimy się więc na błędach , które są potencjalnie wykrywane przez generatory Stabilizer — ale całą poniższą dyskusję można bezpośrednio przenieść z błędów na błędy , które analogicznie są wykrywane przez generatory Stabilizer .
Poniższy diagram przedstawia efekt błędu na jednym qubicie. Zakładamy, że nasze kubitów znajdowało się wcześniej w stanie należącym do przestrzeni kodowej kodu torycznego, co powoduje, że wszystkie pomiary generatorów Stabilizer dają wynik Generatory Stabilizer wykrywają błędy , a każdemu kafeltowi na rysunku odpowiada jeden taki generator Stabilizer — wynik pomiaru odpowiedniego generatora Stabilizer możemy więc zaznaczyć kolorem tego kafla: wyniki oznaczone są białymi kafelkami, a wyniki — szarymi kafelkami. Jeśli na jednym z kubitów wystąpi błąd bit-flip, efektem jest to, że pomiary generatorów Stabilizer odpowiadających dwóm kafelkom stykającym się z dotkniętym kubitem zaczynają dawać wynik
Jest to intuicyjne, gdy rozważymy generatory Stabilizer i ich zachowanie. W istocie każdy generator Stabilizer mierzy parzystość czterech kubitów stykających się z odpowiednim kafelkiem (względem bazy standardowej). Wynik nie oznacza więc, że na tych czterech kubitach nie wystąpiły żadne błędy — wskazuje jedynie, że na tych kubitach wystąpiła parzysta liczba błędów , natomiast wynik oznacza, że wystąpiła nieparzysta liczba błędów . Pojedynczy błąd odwraca zatem parzystość czterech bitów na obu stykających się z nim kafelkach, powodując, że pomiary generatorów Stabilizer dają wynik
Teraz wprowadźmy wiele błędów , żeby zobaczyć, co się stanie. Rozważymy w szczególności łańcuch sąsiadujących błędów , gdzie dwa błędy są sąsiadujące, jeśli dotyczą kubitów stykających się z tym samym kafelkiem.
Dwa generatory Stabilizer na końcach łańcucha dają w tym przypadku wynik , ponieważ na dwóch odpowiadających im kafelkach wystąpiła nieparzysta liczba błędów . Wszystkie pozostałe generatory Stabilizer dają natomiast wynik — w tym te stykające się z łańcuchem, lecz nie będące jego końcami — ponieważ na kubitach stykających się z odpowiadającymi im kafelkami wystąpiła parzysta liczba błędów .
Tak więc, dopóki mamy łańcuch błędów z końcami, kod toryczny wykryje, że wystąpiły błędy, co objawi się wynikami w pomiarach generatorów Stabilizer odpowiadających końcom łańcucha. Zwróć uwagę, że rzeczywisty łańcuch błędów nie jest ujawniany — widoczne są tylko końce! To nie problem — w następnym podrozdziale zobaczymy, że nie musimy wiedzieć dokładnie, które kubity zostały dotknięte błędami , żeby je skorygować. (Kod toryczny jest przykładem wysoce zdegenerowanego kodu w tym sensie, że na ogół nie identyfikuje jednoznacznie korygowanych błędów.)
Możliwe jest jednak, że łańcuch sąsiadujących błędów nie ma końców — tzn. łańcuch błędów może tworzyć zamkniętą pętlę, jak na poniższym rysunku.
W takim przypadku na każdym kafelku wystąpiła parzysta liczba błędów , więc każdy pomiar generatora Stabilizer daje wynik . Zamknięte pętle sąsiadujących błędów nie są więc wykrywane przez kod.
Mogłoby się to wydawać rozczarowujące, bo do utworzenia zamkniętej pętli wystarczą zaledwie cztery błędy (a liczymy na coś znacznie lepszego niż kod o odległości 4). Jednak zamknięta pętla błędów w postaci pokazanej na poprzednim rysunku nie jest w rzeczywistości błędem — bo jest ona elementem Stabilizer! Przypomnij sobie, że oprócz generatorów Stabilizer mamy też generator Stabilizer dla każdego vertex w kratowinach. A mnożąc sąsiadujące generatory Stabilizer , uzyskujemy zamknięte pętle operacji . Na przykład zamkniętą pętlę z poprzedniego rysunku można uzyskać, mnożąc generatory Stabilizer wskazane na poniższym rysunku.
To jednak nie jedyny typ zamkniętej pętli błędów , jaki możemy mieć — i nie jest tak, że każda zamknięta pętla błędów należy do Stabilizer. W szczególności różne typy pętli można scharakteryzować następująco.
-
Zamknięte pętle błędów z parzystą liczbą błędów na każdej poziomej linii i każdej pionowej linii kubitów. (Powyższy przykład należy do tej kategorii.) Pętle tej postaci są zawsze zawarte w Stabilizer, ponieważ można je efektywnie skurczyć do zera przez mnożenie przez generatory Stabilizer .
-
Zamknięte pętle błędów z nieparzystą liczbą błędów na co najmniej jednej poziomej lub co najmniej jednej pionowej linii kubitów. Pętle tej postaci nigdy nie są zawarte w Stabilizer i dlatego reprezentują nietrywialny błędy niezauważane przez kod.
Przykład zamkniętej pętli błędów należącej do drugiej kategorii pokazano na poniższym diagramie.
Taki łańcuch błędów nie jest zawarty w Stabilizer, ponieważ każdy generator Stabilizer umieszcza parzystą liczbę operacji na każdej poziomej linii i każdej pionowej linii kubitów. Jest to więc rzeczywisty przykład nietrywialnego błędu, którego kod nie wykrywa.
Kluczem jest to, że jedynym sposobem na utworzenie pętli drugiego rodzaju jest okrążenie torusa — albo dookoła dziury pośrodku torusa, albo przez nią, albo w obu kierunkach. Intuicyjnie mówiąc, łańcucha błędów takiego jak ten nie można skurczyć do zera przez mnożenie przez generatory Stabilizer , ponieważ topologia torusa na to nie pozwala. Z tego powodu kod toryczny jest czasami klasyfikowany jako topologiczny kwantowy kod korekcji błędów. Minimalna długość takiej pętli to , i właśnie taka jest odległość kodu torycznego: każda zamknięta pętla błędów o długości mniejszej niż musi należeć do pierwszej kategorii, a więc jest zawarta w Stabilizer; natomiast każdy łańcuch błędów z końcami jest wykrywany przez kod.
Ponieważ kod toryczny używa kubitów do zakodowania kubitów i ma odległość , jest to kod Stabilizer .
Korekcja błędów
Omówiliśmy wykrywanie błędów w kodzie torycznym, a teraz krótko porozmawiamy o tym, jak korygować błędy. Kod toryczny jest kodem CSS, więc błędy i można wykrywać i korygować niezależnie. Skupiając się nadal na generatorach Stabilizer , które wykrywają błędy , rozważmy, jak można skorygować łańcuch błędów . (Błędy koryguje się w symetryczny sposób.)
Jeśli podczas pomiaru generatorów Stabilizer pojawi się syndrome różny od syndrome , wyniki ujawniają końce jednego lub więcej łańcuchów błędów . Możemy spróbować skorygować te błędy, parując wyniki i tworząc łańcuch korekcji między nimi. Przy tym sensownie jest wybierać najkrótsze ścieżki, wzdłuż których wykonywane są korekty.
Rozważmy na przykład poniższy diagram, który przedstawia syndrome z dwoma wynikami oznaczonymi szarymi kafelkami, spowodowany łańcuchem błędów zilustrowanym magentową linią i kółkami. Jak już zauważyliśmy, sam łańcuch nie jest ujawniany przez syndrome — widoczne są tylko jego końce.
Żeby spróbować skorygować ten łańcuch błędów, wybieramy najkrótszą ścieżkę między wynikami pomiaru i stosujemy bramki jako korekty do kubitów wzdłuż tej ścieżki (zaznaczonych na żółto na rysunku). Choć korekty mogą nie odpowiadać dokładnie rzeczywistemu łańcuchowi błędów, błędy i korekty razem tworzą zamkniętą pętlę operacji zawartą w Stabilizer kodu. Korekta jest więc w tej sytuacji skuteczna, ponieważ łączny efekt błędów i korekcji to brak jakiegokolwiek działania na zakodowanym stanie.
Ta strategia nie zawsze będzie skuteczna. Na przykład inne wytłumaczenie tego samego syndrome co na poprzednim rysunku pokazano na poniższym rysunku.
Tym razem ten sam łańcuch korekcji co poprzednio nie koryguje tego łańcucha błędów, ponieważ łączny efekt błędów i korekcji to zamknięta pętla operacji owijająca się wokół torusa, która ma nietrywialny wpływ na przestrzeń kodową. Nie ma więc gwarancji, że opisana strategia wybierania najkrótszej ścieżki korekcji między dwoma wynikami pomiaru syndrome prawidłowo skoryguje błąd, który wywołał ten syndrome.
Być może bardziej prawdopodobne, w zależności od modelu szumu, jest zmierzenie syndrome z więcej niż dwoma wpisami , jak sugeruje poniższy rysunek.
W takim przypadku znane są różne strategie korekcji. Jedną naturalną strategią jest próba parowania wyników pomiaru i wykonywanie korekcji wzdłuż najkrótszych ścieżek łączących pary, co wskazano na rysunku kolorem żółtym. W szczególności można obliczyć minimalne doskonałe dopasowanie wagowe między wynikami pomiaru , a następnie połączyć pary najkrótszymi ścieżkami korekcji . Obliczenie minimalnego doskonałego dopasowania wagowego można wykonać efektywnie klasycznym algorytmem zwanym algorytmem blossom, odkrytym przez Edmondsa w latach 60. XX wieku.
To podejście na ogół nie jest optymalne dla najczęściej badanych modeli szumu, ale na podstawie symulacji numerycznych działa bardzo dobrze w praktyce poniżej wskaźnika szumu wynoszącego około 10%, przy założeniu niezależnych błędów Pauli, gdzie i są jednakowo prawdopodobne.