[PYTHON] Grundlagen der Quanteninformationstheorie: Topologische Oberflächencodes

\def\bra#1{\mathinner{\left\langle{#1}\right|}} \def\ket#1{\mathinner{\left|{#1}\right\rangle}} \def\braket#1#2{\mathinner{\left\langle{#1}\middle|#2\right\rangle}}

Einführung

Um eine fehlertolerante Quantenberechnung zu realisieren, beträgt die Fehlerrate jedes Teils etwa 10 ^ {-4} = 0,01 % $ oder weniger, und die Konfiguration des verketteten Codes (basierend auf dem Steane-Code) beträgt 7 $. Ich sprach über die Notwendigkeit vieler Quantenbits letztes Mal. Dies macht viele Menschen hoffnungslos, aber der hier beschriebene "topologische Oberflächencode" sollte Ihnen das Licht der Hoffnung geben.

Lassen Sie mich zunächst sagen, was ich in den folgenden Abschnitten zu erklären versuche. Zunächst werden in der "theoretischen Erklärung" der Codezustand des topologischen Oberflächencodes (im Folgenden als "Oberflächencode" bezeichnet) und die Konstruktion der logischen Grundoperation beschrieben, und dann wird eine Fehlerkorrektur gut durchgeführt. Ich werde erklären, was Sie tun können. In "Operation Check" funktioniert eine Reihe von Abläufen zum Erstellen eines Codezustands, Hinzufügen von Rauschen und Korrigieren von Fehlern mithilfe des Quantenberechnungssimulators qlazy korrekt. Stelle sicher das.

Die folgenden Dokumente wurden als Referenz verwendet.

  1. Koshiba, Morimae, Fujii "Quantenberechnung basierend auf Beobachtung" Corona (2017)
  2. Keio University "Quantum Computer Class # 14 Geometric Code"
  3. K.Fujii,"Quantum Computation with Topological Codes - from qubit to topological fault-tolerance",arXiv:1504.01444v1 [quant-ph] 7 Apr 2015
  4. [Quantum Computer Error Correction Technology](https://www.google.com/url?sa=t&source=web&rct=j&url=https://ipsj.ixsq.nii.ac.jp/ej/%3Faction% 3Drepository_uri% 26item_id% 3D101754% 26file_id% 3D1% 26file_no% 3D1 & ved = 2ahUKEwist9m8zuPqAhVKfd4KHaXEBg8QFjAAegQIBBAB & usg = AOvVaw0ayU0bWT63PaMKX

Erklärung der Theorie

Definition des Oberflächencodes

Gesichtsoperator und Scheitelpunktoperator

Ein Oberflächencode ist ein Fehlerkorrekturcode, der vom Generator einer Gruppe von Stabilisatoren definiert wird, die regelmäßig in einer Ebene definiert werden, in der Quantenbits regelmäßig angeordnet sind. Betrachten Sie beispielsweise ein zweidimensionales Gitter von $ n \ mal n $ und platzieren Sie ein Quantenbit in der Mitte dieser Seite (links in der Abbildung unten). Und es wird angenommen, dass die periodische Randbedingung erfüllt ist. Angenommen, die Ober- und Unterseite sind gleich und die linke und rechte Seite sind gleich. Nachdem Sie die Oberseite und die Unterseite zu einem Zylinder zusammengerollt haben, drehen Sie die beiden Kreise an beiden Enden des Zylinders um und kleben Sie sie zusammen, um eine Donutform = Torus zu erhalten, aber ein solches Bild ist. Da es schwierig ist, ein dreidimensionales Objekt zu veranschaulichen, werde ich es anhand eines Gitters erklären, das in einer Ebene darunter dargestellt ist. In meinen Augen ist es jedoch eine Entwicklung eines Torus.

fig1.png

Sie benötigen einen Generator, um einen Stabilisatorcode zu erstellen. Wir definieren also zwei Quellen in diesem Raster. Einer ist der "Plakettenoperator" und der andere ist der "Sternoperator" (rechts in der Abbildung oben).

Der Gesichtsoperator $ A_m $ ist für jedes Gesicht $ f_m $ im Raster wie folgt definiert.

A_m = \prod_{i \in \partial f_m} Z_i  \tag{1}

Hier repräsentiert $ \ partiell f_m $ die vier Seiten, die der Grenze der $ m $ -ten Fläche $ f_m $ entsprechen, und $ Z_i $ ist das Pauli $ Z $ für das auf der $ i $ -ten Seite platzierte Quantenbit. Es ist ein Operator. Wie auf der rechten Seite der obigen Abbildung gezeigt, können Sie sich ein Quadrat vorstellen, das jede Oberfläche umgibt. Dies ist über das gesamte Gitter verteilt.

Andererseits ist der Scheitelpunktoperator für jeden Scheitelpunkt $ v_k $ im Gitter wie folgt definiert.

B_k = \prod_{j \in \delta v_k} X_j  \tag{2}

Hier repräsentiert $ \ delta v_k $ die vier Seiten, die mit dem $ k $ -ten Scheitelpunkt $ v_k $ verbunden sind, und $ X_j $ ist das Pauli $ X für die auf der $ j $ -ten Seite platzierten Quantenbits. Der $ -Operator. Wie auf der rechten Seite der obigen Abbildung gezeigt, können Sie es sich als Kreuzzeichen vorstellen, das auf jedem Scheitelpunkt zentriert ist. Dies ist nach wie vor auch über das gesamte Raster verteilt. Die Oberflächenoperatoren und die Scheitelpunktoperatoren sind austauschbar, und wenn sich der Scheitelpunktoperator und der Oberflächenoperator überlappen, teilen sie sich immer zwei Quantenbits, sodass sie austauschbar sind ($ X_ {i} X_ {j). } $ Und $ Z_ {i} Z_ {j} $ sind austauschbar). Daher haben wir jetzt eine mögliche Quelle definiert.

Nun, hier ist das Problem. Wie viele Quantenbits (Seiten), Flächenoperatoren und Scheitelpunktoperatoren befinden sich in diesem zweidimensionalen $ n \ times n $ -Gitter? Unter Berücksichtigung der periodischen Randbedingung beträgt die Anzahl der Quantenbits (Seiten) $ 2n ^ 2 $, die Anzahl der Flächenoperatoren (Flächen) $ n ^ 2 $ und die Anzahl der Scheitelpunktoperatoren (Scheitelpunkte) $. Sie können sehen, dass es n ^ 2 $ Stücke gibt. Es gibt $ 2n ^ 2 $ Generatoren, die austauschbar sind, aber nicht alle unabhängig sind. Alle Produkte von Gesichtsoperatoren sind Gleichheitsoperatoren $ I $, und alle Produkte von Scheitelpunktoperatoren sind auch Gleichheitsoperatoren $ I $ [^ 1]. Da es zwei Randbedingungen gibt, beträgt die Anzahl der unabhängigen Generatoren $ 2n ^ 2-2 $. Da die Anzahl der Quantenbits (Seiten) $ 2n ^ 2 $ betrug, beträgt die Anzahl der logischen Bits, die in diesem Codebereich beschrieben werden können, $ 2n ^ {2} - (2n ^ {2} -2) = 2 $ Es wird ein Individuum sein.

[^ 1]: Ist das okay? Oberflächenoperatoren sind lückenlos auf dem Torus verteilt. Wenn Sie alle Gesichtsoperatoren erfassen, wird der jeder Seite entsprechende $ Z $ -Operator immer zweimal angezeigt, sodass das Produkt der Gleichheitsoperator $ I $ ist. In ähnlicher Weise sind die Scheitelpunktoperatoren ohne Lücken auf dem Torus verteilt. Wenn alle Scheitelpunktoperatoren erfasst sind, wird der jeder Seite entsprechende $ X $ -Operator immer zweimal angezeigt, sodass das Produkt der Gleichheitsoperator $ I $ ist.

Doppelgitter

Das in der obigen Abbildung gezeigte Gitter hat Seiten, die die Eckpunkte verbinden, aber Sie können sich ein anderes Gitter vorstellen, das die Flächen verbindet. Mit anderen Worten, es ist ein Gitter, das sie mit einem Scheitelpunkt in der Mitte der Oberfläche verbindet (in der folgenden Abbildung links durch eine gestrichelte Linie dargestellt). Ein solches Gitter wird als "Doppelgitter" bezeichnet.

fig2.png

Wenn Sie dieses duale Raster verwenden, um Flächen- und Scheitelpunktoperatoren darzustellen, passiert etwas Seltsames (oder besser gesagt, Sie werden es für einen Moment verstehen). Die Form des Gesichtsoperators wird zu einem Kreuz, die Form des Scheitelpunktoperators wird zu einem Viereck und das Bild der Figur wird umgekehrt (rechts in der obigen Figur).

Da die Flächen, Seiten und Eckpunkte des ursprünglichen Gitters die Eckpunkte, Seiten und Flächen im Doppelgitter sind, können die Generatoren $ A_m und B_k $ in den Worten des Doppelgitters wie folgt umgeschrieben werden. Ich werde.

A_m = \prod_{i \in \delta \bar{v}_m} Z_i  \tag{3}
B_k = \prod_{j \in \partial \bar{f}_k} X_j  \tag{4}

Hier ist $ \ bar {v} _m $ der Scheitelpunkt, wenn die Fläche $ f_m $ durch das Doppelgitter dargestellt wird, und $ \ bar {f} _k $ ist die Ebene, wenn der Scheitelpunkt $ v_k $ durch das Doppelgitter dargestellt wird ( Von nun an werde ich einen Balken über dem Symbol hinzufügen, um deutlich anzuzeigen, dass es sich um eine Entität auf einem Doppelgitter handelt. Sie werden in einer späteren Erklärung sehen, warum wir so etwas hier vorgestellt haben. Denken Sie also bitte daran [^ 2].

[^ 2]: Um diese Zeit wird es in Referenz 3 allgemein als algebraische Topologie unter Verwendung eines Kettenkomplexes beschrieben. Ich werde. Es ist interessant, dass Oberflächencodes auf verschiedenen Arten von Gittern außer quadratischen Gittern berücksichtigt werden können, aber sie werden lang sein, daher werde ich sie in diesem Artikel weglassen.

Offensichtliche Schleife

Nachdem die Quelle definiert wurde, betrachten wir, welche Eigenschaften die auf dem Gitter = Torus definierte Schleife in Bezug auf den Operator hat. Betrachten Sie zunächst die Grenze $ \ partielles D $ der Ebene $ D $ im Raster (siehe Abbildung unten).

fig3.png

Eine solche Schleife wird als "Trivialschleife" bezeichnet [^ 3]. Wenn wir das Produkt der $ Z $ -Operatoren auf jeder Seite der Schleife als $ Z (\ partielles D) $ schreiben,

[^ 3]: Eine Schleife, die durch kontinuierliche Verformung zu einem Punkt zusammengezogen werden kann, wird als "triviale Schleife" bezeichnet.

Z(\partial D) = \prod_{m,f_m \in D} A_{m}  \tag{5}

Ist festgelegt. Die rechte Seite ist das Produkt aller Gesichtsoperatoren, aus denen das Gesicht $ D $ besteht. Können Sie das sehen? Zwei benachbarte Gesichtsoperatoren teilen sich einen $ Z $ -Operator. Wenn Sie also das Produkt der beiden nehmen, ist die gemeinsame Seite $ I $. Wenn alle in $ D $ enthaltenen Gesichtsoperatoren multipliziert werden, werden alle Seiten außer der Grenze von $ D $ zu $ I $, und nur der Operator $ Z $ über der Grenze $ \ partieller D $ bleibt übrig. Es wird sein. Wie aus Gleichung (5) hervorgeht, ist dieser Operator $ Z (\ partielles D) $ mit allen Quellen austauschbar und ein Element der Stabilisatorgruppe ($ A_ {m} $). Weil es ein Produkt ist).

Betrachten Sie als nächstes die Grenze $ \ partiell \ bar {D} $ der Ebene $ \ bar {D} $, die auf dem Doppelgitter definiert ist (siehe Abbildung unten).

fig4.png

Wenn wir $ X (\ partielle \ bar {D}) $ als Produkt der $ X $ -Operatoren schreiben, die auf jeder Seite der Schleife im dualen Gitter platziert sind,

X(\partial \bar{D}) = \prod_{k,\bar{f}_k \in \bar{D}} B_{k}  \tag{6}

Ist festgelegt. Wenn Sie wie zuvor das Produkt aller Oberflächenoperatoren verwenden, aus denen die Oberfläche besteht (diejenigen, die im ursprünglichen Raster Scheitelpunktoperatoren waren), bleibt nur der Operator $ X $ an der Grenze übrig. Wie aus Gleichung (6) hervorgeht, ist dieser Operator $ X (\ partielle \ bar {D})) $ auch mit allen Quellen austauschbar und ein Element der Stabilisatoren.

Das Produkt der $ Z $ -Operatoren, die auf der offensichtlichen Schleife des ursprünglichen Gitters platziert sind, und das Produkt der $ X $ -Operatoren, die auf der offensichtlichen Schleife des Doppelgitters platziert sind, sind Elemente der Stabilisatoren. Auch wenn dies auf den codierten Zustand angewendet wird, ändert sich der codierte Zustand nicht.

Nicht triviale Schleife

Schauen wir uns als nächstes die Eigenschaften der Operatoren $ Z $ und $ X $ an, die über der nicht trivialen Schleife = nicht triviale Schleife platziert sind.

fig5.png

In der obigen Abbildung gibt es eine gerade Linie mit der Bezeichnung $ l_1 $, eine Schleife, die sich unter periodischen Randbedingungen um den Torus wickelt. Obwohl es sich um eine Schleife handelt, handelt es sich um eine nicht triviale Schleife, da sie durch kontinuierliche Verformung nicht auf einen Punkt zusammengezogen werden kann. Der $ Z $ -Operator ist auf jeder Seite aufgereiht und das Produkt wird genommen.

\tilde{Z}_1 = Z(l_1)  \tag{7}

Ich werde schreiben. Dann sind dieser Bediener und die Generatoren austauschbar. Natürlich enthält der Gesichtsoperator nur den Operator $ Z $, und der Scheitelpunktoperator hat immer zwei Seiten, die sich mit $ l_1 $ überlappen, sodass er austauschbar ist [^ 4]. Es ist austauschbar, aber es ist kein Element der Stabilisatoren. Mit anderen Worten, es kann nicht in Form des Ursprungsprodukts ausgedrückt werden. Wenn Sie denken, dass es eine Lüge ist, geben Sie bitte Ihr Bestes. Angenommen, Sie möchten ein Produkt der auf $ l_1 $ ausgerichteten $ Z $ -Operatoren erstellen, sodass Sie die Gesichtsoperatoren neben $ l_1 $ ausrichten. Das Produkt davon ist jedoch $ Z (l_1) $ und eine weitere nicht triviale Schleife von $ Z $ -Operatoren.

[^ 4]: In der Abbildung wird $ l_1 $ durch eine gerade Linie dargestellt, aber selbst wenn es sich um eine Schleife handelt, die keine gerade Linie ist, gibt es immer zwei Seiten, die den Scheitelpunktoperator überlappen. Sie können es verstehen, indem Sie ein Diagramm zeichnen und etwa eine Minute darüber nachdenken.

Was ist ein Operator, der mit allen Quellen austauschbar ist und kein Element der Stabilisatoren ist? Die Antwort ist ein logischer Operator. Hmm? Es mag geworden sein, also werde ich es vorerst erklären. Stabilisatorgruppe $ S $ mit einem unabhängigen Generator,

S = < g_1, g_2, \cdots g_{n-k} >  \tag{8}

Schreiben Sie als und setzen Sie den Stabilisatorstatus auf $ \ ket {\ psi} $. Bringen Sie alle Generatoren $ g_i $ und den austauschbaren Operator $ g \ notin S $ ein.

g \ket{\psi} = g g_{i} \ket{\psi} = g_{i} g \ket{\psi}  \tag{9}

Ist wahr, also ist $ g \ ket {\ psi} $ der Zustand (simultaner Eigenzustand) im Produktraum der Eigenräume, der dem Eigenwert $ + 1 $ von $ g_i $ entspricht. Das heißt, der Status im Codebereich. $ G \ ket {\ psi} = \ ket {\ psi} $ gilt jedoch nicht (weil $ g \ notin S $). Daher ist $ g $ ein Operator, der nur den logischen Zustand ändert, ohne aus dem Codebereich herauszustehen, dh ein logischer Operator.

Angenommen, $ \ tilde {Z} _1 $, definiert in Gleichung (7), ist der logische $ Z $ -Operator für das erste logische Bit [^ 5].

[^ 5]: Ich habe $ l_1 $ verwendet, um den $ Z $ -Operator für das erste logische Bit zu definieren, aber es kann eine nicht triviale Schleife (nicht unbedingt eine gerade Linie) sein, die vertikal verläuft. Sie können alles verwenden.

Wie definieren Sie den Operator $ X $ für das erste logische Bit?

\tilde{X}_1 = X(\bar{l}_1)  \tag{10}

Dann ist es möglich, $ \ tilde {X} _1 \ tilde {Z} _1 \ tilde {X} _1 = - \ tilde {Z} _1 $ zu erfüllen, was mit allen Generatoren austauschbar ist. Es ist in Ordnung.

Außerdem der $ Z $ -Operator für das zweite logische Bit

\tilde{Z}_2 = Z(l_2)  \tag{11}

Du kannst es schaffen. Da ich beim Definieren von $ \ tilde {Z} _1 $ eine nicht triviale Schleife verwendet habe, die sich vertikal dreht, verwende ich eine nicht triviale Schleife, die sich horizontal dreht [^ 6].

[^ 6]: Wenn Sie eine nicht triviale Schleife verwenden, die in vertikaler Richtung verläuft, handelt es sich um eine logische Operation, die den gleichen Effekt wie $ \ tilde {Z} _1 $ hat. Sie müssen daher eine Schleife verwenden, die sich topologisch unterscheidet.

Der $ X $ -Operator für das zweite logische Bit kann mit allen Quellen austauschbar und mit $ \ tilde {Z} _2 $ gegenkommutierbar sein.

\tilde{X}_2 = X(\bar{l}_2)  \tag{12}

Du kannst es schaffen. Jetzt haben Sie alle grundlegenden logischen Operatoren. Auch hier sind die vier oben gezeigten Schleifen nur ein Beispiel. Wenn Sie topologisch getrennte nicht triviale Schleifen bereitstellen, eine für das ursprüngliche Gitter und eine für das duale Gitter, können Sie die Operatoren $ Z $ und $ X $ für die beiden logischen Bits definieren [^ 7].

Fehler Korrektur

Nachdem wir den Codebereich und die grundlegenden logischen Operatoren definiert haben, wollen wir sehen, wie mit diesem Code eine Fehlerkorrektur erreicht werden kann.

Bitinversionsfehler

Schauen wir uns zunächst an, wie das Fehlerbit identifiziert werden kann, wenn in einem Bit ein Bitinversionsfehler auftritt. Angenommen, ein Bitinversionsfehler tritt im Bit mit der Nummer 4 in der folgenden Abbildung auf.

fig6.png

In diesem Fall, wenn alle Generatoren gemessen werden, entsprechen die Oberflächenoperatoren $ Z_ {1} Z_ {2} Z_ {3} Z_ {4} $ und $ Z_ {4} $ f_1 $ und $ f_2 $ in der obigen Abbildung. Nur Z_ {5} Z_ {6} Z_ {7} $ gibt den gemessenen Wert $ -1 $ aus. Wenn der ursprüngliche logische Status $ \ ket {\ psi_ {L}} $ ist

\begin{align}
Z_{1} Z_{2} Z_{3} Z_{4} (X_{4} \ket{\psi_{L}}) &= - X_{4} (Z_{1} Z_{2} Z_{3} Z_{4} \ket{\psi_{L}}) = -X_{4} \ket{\psi_{L}} \\
Z_{4} Z_{5} Z_{6} Z_{7} (X_{4} \ket{\psi_{L}}) &= - X_{4} (Z_{4} Z_{5} Z_{6} Z_{7} \ket{\psi_{L}}) = -X_{4} \ket{\psi_{L}} \tag{13}
\end{align}

Daraus können wir ersehen, dass der gemessene Wert eine Wahrscheinlichkeit von $ 100 % $ hat und $ -1 $ beträgt. Wenn also der Oberflächenoperator derjenige ist, der das Syndrom jedes Generators misst und $ -1 $ ergibt, bedeutet dies, dass ein Bitinversionsfehler aufgetreten ist und an diesem Ort die Oberflächenoperatoren miteinander in Kontakt stehen. Kann identifiziert werden als. Sie können zum ursprünglichen Zustand zurückkehren, indem Sie die Bitinversion für das angegebene Bit erneut durchführen.

Was aber, wenn zwei oder mehr Bits einen Bitinversionsfehler aufweisen? Stellen Sie sich zum Beispiel den Fall vor, in dem die drei blau dargestellten Bits einen Fehler aufweisen, wie in der folgenden Abbildung links dargestellt.

fig7.png

Nur Oberflächenoperatoren, die der Oberfläche $ f_2 $ und der Oberfläche $ f_7 $ entsprechen, messen den Ursprung und geben $ -1 $ aus. Ein Fehler ist auch in den Bits aufgetreten, aus denen die Oberfläche $ f_4 $ und die Oberfläche $ f_5 $ bestehen. Da die Bits jedoch für jedes der beiden Bits gleichzeitig invertiert werden, beträgt der gemessene Wert $ + 1 $. Wenn es einen Fehler in den Bits gibt, die zu den benachbarten Flächen gehören, sieht es in einem Doppelgitter wie eine verbundene Kette aus, daher wird es als "Fehlerkette" bezeichnet (dargestellt durch die blaue Linie). Nur der Oberflächenoperator, der dem Endpunkt dieser Kette entspricht, reagiert auf die Syndrommessung (gemessener Wert ist $ -1 $, der mit hellblau gefüllt ist). Wir müssen irgendwie die gesamte Fehlerkette aus diesen Endpunktinformationen wiederherstellen und den Fehler korrigieren. Sogenanntes schlechtes Einstellungsproblem? Selbst wenn Sie Ihr Bestes geben, ist dies eine Methode, die nur wahrscheinlich erfolgreich ist, oder? Es kann eine Atmosphäre geworden sein. Aber mach dir keine Sorgen. Ich denke, hier ist der Oberflächencode sehr unberechenbar, aber tatsächlich ist es in Ordnung, wenn die Fehlerkettenschätzung bis zu einem gewissen Grad nicht stimmt. Ich werde erklären, warum es in Ordnung ist.

Schauen Sie rechts in der obigen Abbildung. Angenommen, die tatsächliche Fehlerkette ist $ \ bar {c} $ (dargestellt durch die blaue Linie). Angenommen, die geschätzte Fehlerkette ist $ \ bar {r} $ (angezeigt durch die rote Linie). Zu diesem Zeitpunkt ist der tatsächliche Fehler $ X (\ bar {c}) $, aber der geschätzte Fehler ist $ X (\ bar {r}) $. Wie Sie der Abbildung entnehmen können, sind $ X (\ bar {c}) $ und $ X (\ bar {r}) $ die Produkte der Scheitelpunktoperatoren $ B_2, B_4, B_5 $ (der hellorange gefüllte Teil). Sie können durch Berechnung zueinander migrieren. Mit anderen Worten

X(\bar{c}) = B_{2} B_{4} B_{5} X(\bar{r})  \tag{14}

ist. Selbst wenn Sie der Meinung sind, dass der Fehler $ X (\ bar {r}) $ ist, führen Sie die Wiederherstellungsverarbeitung durch.

\begin{align}
X(\bar{r}) X(\bar{c}) \ket{\psi_{L}} &= X(\bar{r}) B_{2} B_{4} B_{5} X(\bar{r}) \ket{\psi_{L}} \\
&= X(\bar{r}) X(\bar{r}) B_{2} B_{4} B_{5} \ket{\psi_{L}} \\
&= B_{2} B_{4} B_{5} \ket{\psi_{L}} = \ket{\psi_{L}} \tag{15}
\end{align}

Immerhin ist es in seinen ursprünglichen Zustand zurückgekehrt [^ 8]. Wenn daher die wahre Fehlerkette und die Fehlerkette, die durch kontinuierliche Transformation übertragen werden können, wie in der obigen Abbildung rechts gezeigt geschätzt werden können, kann der ursprüngliche Codezustand problemlos wiederhergestellt werden.

[^ 8]: $ X (\ bar {r} + \ bar {c}) $ hat keine Auswirkung auf den Vorzeichenstatus, da $ \ bar {r} + \ bar {c} $ eine selbsterklärende Schleife ist Es ist auch gut zu verstehen, dass es keine Auswirkungen hat.

Wenn die Fehlerkette jedoch so geschätzt wird, dass sie nicht kontinuierlich von der tatsächlichen Fehlerkette verformt werden kann, wie in der folgenden Abbildung gezeigt, schlägt der Wiederherstellungsprozess fehl.

fig8.png

Phaseninversionsfehler

Betrachten Sie als nächstes den Fall, in dem ein Phaseninversionsfehler in einem Bit auftritt. Angenommen, im 4. Bit tritt ein Phaseninversionsfehler auf, wie in der folgenden Abbildung gezeigt.

fig9.png

In diesem Fall, wenn alle Generatoren gemessen werden, entsprechen die Scheitelpunktoperatoren $ X_ {1} X_ {3} X_ {4} X_ {6} $ und $ X_ {2} $ v_1 $ und $ v_2 $ in der obigen Abbildung. Nur X_ {4} X_ {5} X_ {7} $ gibt den gemessenen Wert $ -1 $ aus. Wenn der ursprüngliche logische Status $ \ ket {\ psi_ {L}} $ ist

\begin{align}
X_{1} X_{3} X_{4} X_{6} (Z_{4} \ket{\psi_{L}}) &= - Z_{4} (X_{1} X_{3} X_{4} X_{6} \ket{\psi_{L}}) = -Z_{4} \ket{\psi_{L}} \\
X_{2} X_{4} X_{5} X_{7} (Z_{4} \ket{\psi_{L}}) &= - Z_{4} (X_{2} X_{4} X_{5} X_{7} \ket{\psi_{L}}) = -Z_{4} \ket{\psi_{L}} \tag{16}
\end{align}

Daraus können wir ersehen, dass der gemessene Wert eine Wahrscheinlichkeit von $ 100 % $ hat und $ -1 $ beträgt. Wenn der Scheitelpunktoperator derjenige ist, der das Syndrom jedes Generators misst und $ -1 $ ergibt, bedeutet dies, dass ein Phaseninversionsfehler aufgetreten ist und an diesem Ort die Scheitelpunktoperatoren miteinander in Kontakt stehen. Kann identifiziert werden als. Der ursprüngliche Zustand kann wiederhergestellt werden, indem die Phaseninversion für das angegebene Bit erneut durchgeführt wird.

Was aber, wenn zwei oder mehr Bits einen Phaseninversionsfehler aufweisen? Stellen Sie sich zum Beispiel den Fall vor, in dem die drei blau dargestellten Bits einen Fehler aufweisen, wie in der folgenden Abbildung links dargestellt.

fig10.png

Nur die Scheitelpunktoperatoren, die dem Scheitelpunkt $ v_3 $ und dem Scheitelpunkt $ v_4 $ entsprechen, messen den Ursprung und geben $ -1 $ aus (der hellblau ausgefüllte Teil). In den Bits, aus denen der Scheitelpunkt $ v_2 $ und der Scheitelpunkt $ v_5 $ bestehen, ist ein Fehler aufgetreten. Da jedoch die Phase für jedes der beiden Bits gleichzeitig invertiert wird, beträgt der gemessene Wert $ + 1 $. In diesem Fall müssen Sie die Fehlerkette schätzen, die die Eckpunkte $ v_3, v_2, v_5, v_4 $ verbindet. Wenn jedoch wie zuvor die geschätzte Fehlerkette $ r $ kontinuierlich von der wahren Fehlerkette $ c $ transformiert werden kann, wird $ Z (r) $ angewendet, das basierend auf der geschätzten erstellt wurde. Auf diese Weise können Sie den ursprünglichen logischen Status wiederherstellen. Die Wiederherstellung schlägt fehl, wenn die geschätzte Kette nicht kontinuierlich von der realen Kette verformt werden kann.

Fehlerkettenschätzung

Wie wir gerade gesehen haben, kann die Fehlerkorrektur wiederhergestellt werden, auch wenn die Schätzung der Fehlerkette geringfügig abweicht. Wenn die geschätzte Fehlerkette jedoch aufgrund der tatsächlichen Fehlerkette und der kontinuierlichen Verformung nicht migriert werden kann, schlägt die Fehlerkorrektur fehl. .. Ich möchte Fehler so weit wie möglich vermeiden, aber lassen Sie uns darüber nachdenken, wie wir sie am besten einschätzen können.

Angenommen, ein Bitinversionsfehler $ X (\ bar {c}) $ tritt in der Fehlerkette $ \ bar {c} $ auf (dasselbe Argument gilt für den Phaseninversionsfehler, also hier der Bitinversionsfehler Denken Sie nur an). Hier ist die Fehlerkette $ \ bar {c} $ nicht unbedingt eine einzelne Kette. Stellen Sie sich vor, dass mehrere Ketten zu $ \ bar {c} $ zusammengefasst sind (blaue Linie in der folgenden Abbildung).

Die Wahrscheinlichkeit eines solchen Fehlers $ p (\ bar {c}) $ ist

p(\bar{c}) = (1-p)^{|E|} \prod_{i \in E} \Bigl(\frac{p}{1-p} \Bigr)^{z_i}  \tag{17}

Kann ausgedrückt werden als. Hier,|E|Ist die Gesamtzahl der Seiten,z_iIstiDie zweite Seite ist\bar{c}Wenn in enthalten1, Wenn nicht0Es ist ein Binärwert, der den Wert annimmt[1]

Die plausibelste Fehlerkette ist $ \ partiell \ bar {c} $, wenn die Syndrommessung zum Endpunkt $ \ bar {c} $ Grenze $ \ partiell \ bar {c} $ führt. Mit $ \ bar {c} ^ {\ prime} $ wird die bedingte Wahrscheinlichkeit $ p (\ bar {c} ^ {\ prime} | \ partielle \ bar {c}) $ unter der Bedingung maximiert, dass Es scheint gut zu denken, dass es das gibt. Mit anderen Worten

\bar{r} = \arg \max_{\bar{c}^{\prime}} p(\bar{c}^{\prime}|\partial \bar{c})  \tag{18}

Es scheint gut, die Fehlerkette durch zu schätzen. Wo $ p (\ bar {c} ^ {\ prime} | \ teilweise \ bar {c}) $ ist

p(\bar{c}^{\prime}|\partial \bar{c}) \propto (1-p)^{|E|} \prod_{i \in E} \Bigl( \frac{p}{1-p} \Bigr)^{z_{i}^{\prime}} \Bigr|_{\partial \bar{c}^{\prime} = \partial \bar{c}}  \tag{19}

Kann ausgedrückt werden als. Zu diesem Zeitpunkt nimmt $ z_ {i} ^ {\ prime} $ den Wert $ 1 $ an, wenn die $ i $ -te Seite in $ \ bar {c} ^ {\ prime} $ enthalten ist, andernfalls $ 0 $. Da angenommen wird, dass es sich um einen Binärwert handelt, finden Sie in Gleichung (18) $ \ bar {r}, wenn Sie die Binärreihe $ \ {z_ {i} ^ {\ prime} \} $ finden, die Gleichung (19) maximiert. Sie kennen $. Wie Sie bei genauer Betrachtung von Gleichung (19) sehen können, sollte die Anzahl von $ 1 $, die in der Binärreihe $ \ {z_ {i} ^ {\ prime} \} $ enthalten ist, minimiert werden, um dies zu maximieren. Es sollte sein. Mit anderen Worten, alle Endpunkte sollten so verbunden sein, dass der Abstand minimiert wird (rote Linie in der folgenden Abbildung). Ein solcher Graphoptimierungsalgorithmus wird als "perfekter Anpassungsalgorithmus mit minimalem Gewicht" bezeichnet, und ein Algorithmus, der in polymorphen Schritten gelöst werden kann, ist bekannt (aber er ist nicht gut verstanden, so dass eine Erklärung weggelassen wird. Masu, Schweiß).

fig11.png

Fehlerwahrscheinlichkeit und Korrekturfehlerrate

Wenn die Anzahl der zu codierenden Bits erhöht wird, um die Redundanz zu erhöhen, kann im Allgemeinen eine Fehlerkorrektur mit guter Leistung (niedrige Korrekturfehlerrate) realisiert werden, aber als Voraussetzung liegt die Fehlerwahrscheinlichkeit pro Bit unter einem bestimmten Schwellenwert. Muss sein.

Wenn beispielsweise ein klassischer Iterationscode betrachtet wird, der ein Bit mit $ N $ Bits überflüssig macht, kann ein Fehler, der die Hälfte der $ N $ Bits nicht überschreitet, durch Mehrheitsentscheidung vollständig wiederhergestellt werden. Wenn die Fehlerwahrscheinlichkeit pro Bit unter dem Schwellenwert von $ 1/2 $ liegt, kann sie grob wiederhergestellt werden. Wenn Sie hier "grob" sagen, bedeutet dies, dass es wahrscheinlich ist, dass ein Fehler in mehr als der Hälfte der Bits gemischt wird, aus denen ein Signal besteht, das Sie senden möchten. In diesem Fall schlägt die Wiederherstellung fehl. Wenn der Wert von $ N $ jedoch groß genug gemacht werden kann, kann diese Fehlerrate auf Null reduziert werden. Zu diesem Zeitpunkt ist natürlich die Voraussetzung, dass die Fehlerwahrscheinlichkeit kleiner als der Schwellenwert ($ 1/2 $) ist, unabdingbar. Wenn die Fehlerwahrscheinlichkeit größer als der Schwellenwert ist, ist eine Erhöhung des Werts von $ N $ kontraproduktiv. Je größer es ist, desto sicherer wird die Restauration scheitern [^ 10].

[^ 10]: Die Eigenschaften des Fehlerkorrekturcodes können durch eine Kurve mit der Fehlerwahrscheinlichkeit auf der horizontalen Achse und der Korrekturfehlerrate auf der vertikalen Achse ausgedrückt werden, es handelt sich jedoch um eine S-förmige Kurve mit der Fehlerwahrscheinlichkeitsschwelle als Wendepunkt. .. Wenn der Wert von $ N $ zunimmt, wird die S-förmige Kurve enger und an der Grenze von $ N $ unendlich wird sie zu einer abgestuften Kennlinie.

Gleiches gilt für den Quantenfehlerkorrekturcode, und ob eine Fehlerkorrektur wirksam ist oder nicht, muss unter einem bestimmten Schwellenwert für die Fehlerwahrscheinlichkeit pro Bit liegen. Wenn es unter einem bestimmten Schwellenwert liegt und $ N $ groß genug gemacht wird, liegt die Korrekturfehlerrate so nahe wie möglich bei Null. Im Gegenteil, wenn die Fehlerwahrscheinlichkeit über dem Schwellenwert liegt, erhöht eine Erhöhung von $ N $ die Korrekturfehlerrate.

Was ist diese Schwelle für Oberflächencodes? Die Ergebnisse der numerischen Simulation werden in Referenz 3 veröffentlicht, die unten aufgeführt sind.

figure1.png

Hier repräsentiert die horizontale Achse die Fehlerwahrscheinlichkeit für jedes Bit, die vertikale Achse repräsentiert die Korrekturfehlerrate, die durchgezogene Linie ist $ n = 10 $, die unterbrochene Linie ist $ n = 20 $ und die gepunktete Linie ist $ n = 30 $. (Ich denke jetzt an ein $ n \ times n $ Gitter). Es scheint, dass die Schwelle der Fehlerwahrscheinlichkeit vom Wendepunkt dieser S-förmigen Kurve auf etwa 10,3% berechnet wird. Übrigens ist diese Simulation der Fall, wenn die Fehlerkette durch den "Perfect Weight Perfect Matching Algorithmus" geschätzt wird.

Der Oberflächencode ist ein Regressionscode, der die gleichen Ergebnisse der Syndrommessung für mehrere Fehlerkettenmuster liefert, sodass der Mindestabstand nicht immer optimal ist. Die optimale Decodierung ist diejenige, die die Gesamtwahrscheinlichkeit maximiert, dasselbe Korrekturergebnis zu liefern. In diesem Fall liegt dieser Schwellenwert also bei etwa 10,9%.

In einem quadratischen Gitter haben sowohl der Bitinversionsfehler als auch der Phaseninversionsfehler die gleiche Fehlerwahrscheinlichkeitsschwelle, aber wenn die Gitterform in eine Wabenform oder eine Käfigform geändert wird, werden der Bitinversionsfehler und die Phaseninversionsfehlerschwellen asymmetrisch. .. In einem tatsächlichen physikalischen System ist die Phaseninversion häufig größer als die Bitinversion, so dass anscheinend auch Simulationen durchgeführt werden, die auf solchen Annahmen basieren (Einzelheiten siehe [Referenz 3](https: // arxiv.). Bitte beziehen Sie sich auf org / abs / 1504.01444)).

Die soeben erläuterte Fehlerschwelle von etwa $ 10 % $ hängt mit dem Fehler zusammen, der auftritt, wenn der Codezustand vom Oberflächencode gehalten und übertragen wird. Bei der eigentlichen Quantenberechnung müssen die Fehler berücksichtigt werden, die mit der Vorbereitung des Anfangszustands, der logischen Berechnung und der Messung verbunden sind. Es scheint, dass die Fehlerrate pro Komponente auf etwa 1% geschätzt wird, um eine fehlertolerante Quantenberechnung durch Kombination aller zu realisieren. Wie in Vorheriger Artikel erläutert, wird unter der Annahme eines CSS-Code-basierten Verkettungscodes wie Steane-Code $ 10 ^ {-4} = 0,01 \ Dies ist ein großer Schritt nach vorne, da wir einen Schwellenwert [^ 11] unter% $ brauchten. Dies habe ich in der "Einleitung" als "Licht der Hoffnung" gesagt.

[^ 11]: Dies scheint eine ziemlich süße Schätzung zu sein, und es scheint, dass es tatsächlich $ 10 ^ {-5} -10 ^ {-6} $ ist.

Funktionsprüfung

Verwenden Sie nun den Quantenberechnungssimulator qlazy, um den Oberflächencode im $ 3 \ times 3 $ -Gitter zu konfigurieren und zu überprüfen, ob die Fehlerkorrektur korrekt durchgeführt werden kann. Ich werde.

Implementierung

Hier ist der gesamte Python-Code.

from qlazypy import QState

Lattice = [{'edge': 0, 'faces':[0, 6], 'vertices':[0, 1]},
           {'edge': 1, 'faces':[1, 7], 'vertices':[1, 2]},
           {'edge': 2, 'faces':[2, 8], 'vertices':[0, 2]},
           {'edge': 3, 'faces':[0, 2], 'vertices':[0, 3]},
           {'edge': 4, 'faces':[0, 1], 'vertices':[1, 4]},
           {'edge': 5, 'faces':[1, 2], 'vertices':[2, 5]},
           {'edge': 6, 'faces':[0, 3], 'vertices':[3, 4]},
           {'edge': 7, 'faces':[1, 4], 'vertices':[4, 5]},
           {'edge': 8, 'faces':[2, 5], 'vertices':[3, 5]},
           {'edge': 9, 'faces':[3, 5], 'vertices':[3, 6]},
           {'edge':10, 'faces':[3, 4], 'vertices':[4, 7]},
           {'edge':11, 'faces':[4, 5], 'vertices':[5, 8]},
           {'edge':12, 'faces':[3, 6], 'vertices':[6, 7]},
           {'edge':13, 'faces':[4, 7], 'vertices':[7, 8]},
           {'edge':14, 'faces':[5, 8], 'vertices':[6, 8]},
           {'edge':15, 'faces':[6, 8], 'vertices':[0, 6]},
           {'edge':16, 'faces':[6, 7], 'vertices':[1, 7]},
           {'edge':17, 'faces':[7, 8], 'vertices':[2, 8]}]

F_OPERATORS = [{'face':0, 'edges':[ 0,  3,  4,  6]},
               {'face':1, 'edges':[ 1,  4,  5,  7]},
               {'face':2, 'edges':[ 2,  3,  5,  8]},
               {'face':3, 'edges':[ 6,  9, 10, 12]},
               {'face':4, 'edges':[ 7, 10, 11, 13]},
               {'face':5, 'edges':[ 8,  9, 11, 14]},
               {'face':6, 'edges':[ 0, 12, 15, 16]},
               {'face':7, 'edges':[ 1, 13, 16, 17]},
               {'face':8, 'edges':[ 2, 14, 15, 17]}]

V_OPERATORS = [{'vertex':0, 'edges':[ 0,  2,  3, 15]},
               {'vertex':1, 'edges':[ 0,  1,  4, 16]},
               {'vertex':2, 'edges':[ 1,  2,  5, 17]},
               {'vertex':3, 'edges':[ 3,  6,  8,  9]},
               {'vertex':4, 'edges':[ 4,  6,  7, 10]},
               {'vertex':5, 'edges':[ 5,  7,  8, 11]},
               {'vertex':6, 'edges':[ 9, 12, 14, 15]},
               {'vertex':7, 'edges':[10, 12, 13, 16]},
               {'vertex':8, 'edges':[11, 13, 14, 17]}]

LZ_OPERATORS = [{'logical_qid':0, 'edges':[0, 1,  2]},
                {'logical_qid':1, 'edges':[3, 9, 15]}]

LX_OPERATORS = [{'logical_qid':0, 'edges':[0, 6, 12]},
                {'logical_qid':1, 'edges':[3, 4, 5]}]

def make_logical_zero():

    qs = QState(19)  # data:18 + ancilla:1

    mvals = [0, 0, 0, 0, 0, 0, 0, 0, 0] # measured values of 9 plaquette operators
    for vop in V_OPERATORS: # measure and get measured values of 9 star operators
        qid = vop['edges']
        qs.h(18).cx(18,qid[0]).cx(18,qid[1]).cx(18,qid[2]).cx(18,qid[3]).h(18)
        mvals.append(int(qs.m(qid=[18]).last))
        qs.reset(qid=[18])
        
    return qs, mvals

def measure_syndrome(qs, mvals):

    syn = []
    for fop in F_OPERATORS:  # plaquette operators
        qid = fop['edges']
        qs.h(18).cz(18,qid[0]).cz(18,qid[1]).cz(18,qid[2]).cz(18,qid[3]).h(18)
        syn.append(int(qs.m(qid=[18]).last))
        qs.reset(qid=[18])
        
    for vop in V_OPERATORS:  # star operators
        qid = vop['edges']
        qs.h(18).cx(18,qid[0]).cx(18,qid[1]).cx(18,qid[2]).cx(18,qid[3]).h(18)
        syn.append(int(qs.m(qid=[18]).last))
        qs.reset(qid=[18])
        
    for i in range(len(syn)): syn[i] = syn[i]^mvals[i]

    return syn

def get_error_chain(syn):

    face_id = [i for i,v in enumerate(syn) if i < 9 and v == 1]
    vertex_id = [i-9 for i,v in enumerate(syn) if i >= 9 and v == 1]

    e_chn = []
    if face_id != []:  # chain type: X
        for lat in Lattice:
            if lat['faces'][0] == face_id[0] and lat['faces'][1] == face_id[1]:
                e_chn.append({'type':'X', 'qid':[lat['edge']]})
                break

    if vertex_id != []: # chain type: Z
        for lat in Lattice:
            if lat['vertices'][0] == vertex_id[0] and lat['vertices'][1] == vertex_id[1]:
                e_chn.append({'type':'Z', 'qid':[lat['edge']]})
                break

    return e_chn

def error_correction(qs, e_chn):

    for c in e_chn:
        if c['type'] == 'X': [qs.x(i) for i in c['qid']]
        if c['type'] == 'Z': [qs.z(i) for i in c['qid']]

def Lz(self, q):

    [self.z(i) for i in LZ_OPERATORS[q]['edges']]
    return self
        
def Lx(self, q):

    [self.x(i) for i in LX_OPERATORS[q]['edges']]
    return self
    
if __name__ == '__main__':

    QState.add_methods(Lz, Lx)
    
    print("* initial state: logical |11>")
    qs_ini, mval_list = make_logical_zero()  # logical |00>
    qs_ini.Lx(0).Lx(1)  # logical |00> -> |11>
    qs_fin = qs_ini.clone()  # for evaluating later

    print("* add noise")
    qs_fin.x(7)  # bit flip error at #7
    # qs_fin.z(7).x(7)  # bit and phase flip error at #7

    syndrome = measure_syndrome(qs_fin, mval_list)
    err_chain = get_error_chain(syndrome)
    print("* syndrome measurement:", syndrome)
    print("* error chain:", err_chain)

    error_correction(qs_fin, err_chain)
    print("* fidelity after error correction:", qs_fin.fidelity(qs_ini))
    
    QState.free_all(qs_ini, qs_fin)

Zuerst wurden die Flächen, Seiten und Scheitelpunktnummern auf dem Gitter wie folgt bestimmt. Hier ist $ v_i $ das Gesicht, $ e_i $ die Seite und $ f_i $ die Spitze.

fig12.png

Die zu Beginn des Programms beschriebenen globalen Variablen Lattice, F_OPERATORS, V_OPERATORS, LZ_OPERATORS und LX_OPERATORS sind Daten zum Definieren der Diagrammstruktur, des Generators und des logischen Operators unter Annahme dieser Flächen, Seiten und Eckpunkte. Lattice ist eine Liste von Wörterbüchern, die aus Oberflächen- und Scheitelpunktnummern bestehen, die mit jeder Seite verbunden sind. Jetzt können Sie die Diagrammstruktur des Rasters ohne Auslassung beschreiben. F_OPERATORS ist eine Liste von Seitenzahlen, die die Grenzen jeder Fläche bilden und die $ 9 $ Gesichtsoperatoren definieren. V_OPERATORS ist eine Liste von Seitenzahlen, die mit jedem Scheitelpunkt verbunden sind und die $ 9 $ der Scheitelpunktoperatoren definieren. LZ_OPERATORS dient zum Definieren von zwei logischen $ Z $ -Operatoren, wobei das $ 0 $ -te logische $ Z $ $ Z_ {0} Z_ {1} Z_ {2} $ und das $ 1 $ -te logische $ Z $ ist Gibt an, dass dies $ Z_ {3} Z_ {9} Z_ {15} $ ist. LX_OPERATORS dient zum Definieren von zwei logischen $ X $ -Operatoren, wobei die $ 0 $ -te Logik $ X $ $ X_ {0} X_ {6} X_ {12} $ ist, die $ 1 $ -te Logik $ X $ Gibt an, dass dies $ X_ {3} X_ {4} X_ {5} $ ist.

Schauen wir uns anhand dieser Konfiguration jeden Teil des Hauptverarbeitungsabschnitts der Reihe nach an.

qs_ini, mval_list = make_logical_zero()  # logical |00>

Erstellt einen logischen Nullzustand. Der Inhalt der Funktion make_logical_zero lautet wie folgt.

def make_logical_zero():

    qs = QState(19)  # data:18 + ancilla:1

    mvals = [0, 0, 0, 0, 0, 0, 0, 0, 0] # measured values of 9 plaquette operators
    for vop in V_OPERATORS: # measure and get measured values of 9 star operators
        qid = vop['edges']
        qs.h(18).cx(18,qid[0]).cx(18,qid[1]).cx(18,qid[2]).cx(18,qid[3]).h(18)
        mvals.append(int(qs.m(qid=[18]).last))
        qs.reset(qid=[18])
        
    return qs, mvals

Dieses Mal sind die erforderlichen Datenbits 18 Bits (0-17), aber 1 Hilfsbit wird hinzugefügt (18), um den Anfangszustand zu erzeugen und das Syndrom zu messen, und insgesamt werden 19 Bits vorbereitet. Benötigen Sie mehr Hilfsbits? Sie mögen das denken, aber es ist in Ordnung, weil Sie es wiederverwenden können, während Sie es viele Male zurücksetzen.

Erstellen Sie zunächst mit QState (19) einen physischen Nullzustand und messen Sie indirekt die Quelle in der for-Schleife. Es sieht so aus, als würden Sie nur für den Scheitelpunktoperator messen, was in Ordnung ist. Als erstes muss der physikalische Nullzustand vorbereitet werden, dh der simultane Eigenzustand, der dem Eigenwert +1 des Oberflächenoperators entspricht, sodass sich der Zustand auch dann nicht ändert, wenn der Oberflächenoperator gemessen wird. Da der Oberflächenoperator und der Scheitelpunktoperator austauschbar sind, können Sie auch zuerst den Oberflächenoperator messen. Aus diesem Grund ist es in Ordnung, hier nur den Scheitelpunktoperator zu messen.

Ich messe also 9 Scheitelpunktoperatoren der Reihe nach, aber wenn das Messergebnis +1 ist (0 als Index des gemessenen Werts), kann ich mit der Messung des nächsten Scheitelpunktoperators fortfahren, wie er ist, aber mit der Messung Das Problem ist, wenn der Wert -1 ist (1 als Index des gemessenen Wertes). Es gibt auch eine Möglichkeit, einen Operator vorzubereiten, der den Eigenwert umdreht und die Operation ausführt, aber hier werden wir ihn weglassen. Das heißt, durch. Notieren Sie jedoch den Messwert (Index). Es ist nicht möglich, simultane Eigenzustände für die Eigenwerte aller Quellen +1 zu erhalten, aber es ist möglich, das Syndrom zu messen, da es möglich ist zu wissen, welche Quelle gemessen werden sollte, um den gemessenen Wert -1 zu erhalten. Wenn Sie den Ursprung des Eigenwerts von -1 messen möchten, müssen Sie nur die Interpretation der Syndrommessung umkehren. In der obigen Funktion wird der gemessene Wert (Index) in einer Listenvariablen namens mvals gespeichert. Es gibt 18 Elemente, aber da der Gesichtsoperator absolut 0 ist, erstelle ich zuerst eine Liste mit 9 Nullen, unabhängig von Anwesenheit oder Abwesenheit, und hänge das Ergebnis jedes Mal an mvals an, wenn ich den Scheitelpunktoperator messe. Ich werde es weiterhin tun. Schließlich werden die Quantenzustände qs und mvals zurückgegeben.

Kehren Sie zum Hauptverarbeitungsabschnitt zurück.

qs_ini.Lx(0).Lx(1)  # logical |00> -> |11>

Dann wird der logische Zustand $ \ ket {1_ {L} 1_ {L}} $ erstellt, indem logisches $ X $ auf die beiden logischen Bits angewendet wird ($ \ ket {0_ {L} 0_ {L} Es war in Ordnung, mit} $ zu beginnen, aber ich wollte den logischen Operator $ X $ verwenden, also habe ich den Startpunkt auf $ \ ket {1_ {L} 1_ {L}} $ gesetzt. Der logische $ X $ -Operator ist

def Lx(self, q):

    [self.x(i) for i in LX_OPERATORS[q]['edges']]
    return self

Es ist definiert als. Wie Sie sehen können, werde ich die Erklärung weglassen.

qs_fin = qs_ini.clone()  # for evaluating later

Schließlich wird der Zustand dupliziert, um das Fehlerkorrekturergebnis auszuwerten. Sie haben jetzt den Ausgangszustand angelegt.

Nächster,

qs_fin.x(7)  # bit flip error at #7

Fügen Sie dann dem 7. Bit einen Bitinversionsfehler hinzu (alles ist in Ordnung, also habe ich mich entsprechend entschieden).

syndrome = measure_syndrome(qs_fin, mval_list)

Messen Sie dann das Syndrom, um das Fehlerbit und die Art des Fehlers zu identifizieren. Der Inhalt der Funktion Measure_Syndrome lautet wie folgt.

def measure_syndrome(qs, mvals):

    syn = []
    for fop in F_OPERATORS:  # plaquette operators
        qid = fop['edges']
        qs.h(18).cz(18,qid[0]).cz(18,qid[1]).cz(18,qid[2]).cz(18,qid[3]).h(18)
        syn.append(int(qs.m(qid=[18]).last))
        qs.reset(qid=[18])
        
    for vop in V_OPERATORS:  # star operators
        qid = vop['edges']
        qs.h(18).cx(18,qid[0]).cx(18,qid[1]).cx(18,qid[2]).cx(18,qid[3]).h(18)
        syn.append(int(qs.m(qid=[18]).last))
        qs.reset(qid=[18])
        
    for i in range(len(syn)): syn[i] = syn[i]^mvals[i]

    return syn

Die Messergebnisse werden in der Liste gespeichert, während der Oberflächenoperator und der Scheitelpunktoperator der Reihe nach gemessen werden. Dies ist der Syndromwert, aber wie bereits erläutert, gibt es einige Generatoren, bei denen der Eigenwert -1 (Messindex ist 1) ein Normalwert ist. In diesem Fall muss die Interpretation umgekehrt werden. Entsprechend dem Wert der Messwertliste mvals, die zum Zeitpunkt der Erzeugung des Anfangszustands aufgezeichnet wurden

for i in range(len(syn)): syn[i] = syn[i]^mvals[i]

Invertiert den Syndromwert wie in. Dieses Ergebnis wird als korrekter Syndromwert zurückgegeben.

Kehren Sie zum Hauptverarbeitungsabschnitt zurück.

err_chain = get_error_chain(syndrome)

Schätzen Sie die Fehlerkette. Es ist einfach, weil das $ 3 \ times 3 $ -Raster nur 1-Bit-Fehler korrigieren kann. Der Inhalt der Funktion get_error_chain lautet wie folgt.

def get_error_chain(syn):

    face_id = [i for i,v in enumerate(syn) if i < 9 and v == 1]
    vertex_id = [i-9 for i,v in enumerate(syn) if i >= 9 and v == 1]

    e_chn = []
    if face_id != []:  # chain type: X
        for lat in Lattice:
            if lat['faces'][0] == face_id[0] and lat['faces'][1] == face_id[1]:
                e_chn.append({'type':'X', 'qid':[lat['edge']]})
                break

    if vertex_id != []: # chain type: Z
        for lat in Lattice:
            if lat['vertices'][0] == vertex_id[0] and lat['vertices'][1] == vertex_id[1]:
                e_chn.append({'type':'Z', 'qid':[lat['edge']]})
                break

    return e_chn

Identifizieren Sie die Gesichtsoperatornummer face_id und die Scheitelpunktoperatornummer vertex_id, von der aus der Syndromwert 1 ist. Da die Nummer der Seite, die die Grenze der entsprechenden Fläche bildet, vom angegebenen Flächenoperator bekannt ist, ist die Nummer der gemeinsamen Seite die Bitnummer, bei der der Bitinversionsfehler aufgetreten ist. Da die Nummer der Seite, die mit dem entsprechenden Scheitelpunkt verbunden ist, vom angegebenen Scheitelpunktoperator bekannt sein kann, ist die Nummer der gemeinsamen Seite die Bitnummer, bei der der Phaseninversionsfehler aufgetreten ist. Auf diese Weise können Sie die Bitnummern und Fehlertypen anzeigen, aus denen die Fehlerkette besteht. Speichern Sie es in der Wörterbuchliste e_chn und kehren Sie zurück.

Kehren Sie zum Hauptverarbeitungsabschnitt zurück. Aus der gerade erhaltenen Fehlerkette

error_correction(qs_fin, err_chain)

So stellen Sie den ursprünglichen Zustand wieder her Der Inhalt der Funktion error_correction lautet wie folgt.

def error_correction(qs, e_chn):

    for c in e_chn:
        if c['type'] == 'X': [qs.x(i) for i in c['qid']]
        if c['type'] == 'Z': [qs.z(i) for i in c['qid']]

Der Prozess ist so, wie Sie es sehen (Erklärung weggelassen). Damit ist die Fehlerkorrektur abgeschlossen. Am Ende des Hauptverarbeitungsabschnitts

print("* fidelity after error correction:", qs_fin.fidelity(qs_ini))

Zeigt die Wiedergabetreue zwischen dem Anfangszustand und dem Endzustand nach der Fehlerkorrektur an. Wenn die Wiedergabetreue 1,0 beträgt, ist die Fehlerkorrektur erfolgreich.

Ergebnis

Das Ausführungsergebnis ist unten dargestellt.

* initial state: logical |11>
* add noise
* syndrome measurement: [0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
* error chain: [{'type': 'X', 'qid': [7]}]
* fidelity after error correction: 1.0

Syndrommessungen ergaben, dass der 1. und 4. Gesichtsoperator reagiert hatten und dass das 7. Bit einen Bitinversionsfehler aufwies. Die Wiedergabetreue mit dem Ausgangszustand betrug 1,0, und es wurde festgestellt, dass sie korrekt wiederhergestellt wurde.

Als nächstes habe ich versucht, den Fehler wie folgt als Bit- / Phaseninversionsfehler hinzuzufügen.

# qs_fin.x(7)  # bit flip error at #7
qs_fin.z(7).x(7)  # bit and phase flip error at #7

Das Ausführungsergebnis ist

* initial state: logical |11>
* add noise (phase and bit flip): X_7 Z_7
* syndrome measurement: [0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0]
* error chain: [{'type': 'X', 'qid': [7]}, {'type': 'Z', 'qid': [7]}]
* fidelity after error correction: 1.0

Es stellte sich heraus, dass dies auch richtig korrigiert werden kann.

abschließend

Jetzt verstehen Sie die Grundlagen von Oberflächencodes. Es war sehr frisch und interessant, einen starken Code unter vollständiger Nutzung der Topologie erstellen zu können. Durch die Referenzen konnte ich auch algebraische Topologien studieren, mit denen ich nicht sehr vertraut war.

Dieses Mal habe ich den Oberflächencode erklärt, der in Form eines Torus aufgebaut ist, aber wie erkennt man den Torus physisch? Oder selbst wenn es realisiert werden kann, gibt es ein Problem, dass nur zwei logische Bits ausgedrückt werden können (selbst wenn es ein Loch gibt). Um dies zu überwinden, wird anscheinend auch ein Oberflächencode vorgeschlagen, der eine einfache Ebene (aber mit Fehlern) verwendet, die kein Torus ist. Deshalb möchte ich ihn das nächste Mal untersuchen.

Danksagung: Bei der Zusammenstellung dieses Artikels wurde eine von Nextremer Co., Ltd. ["4. topologische Quantenberechnung und Umgebung"](https: / /nextremer.connpass.com/event/176939/) und studiert. Die Vorträge zu den wichtigsten Punkten waren leicht zu verstehen und das Verständnis ging voran. Vielen Dank, dass Sie diese Gelegenheit genutzt haben.

das ist alles


  1. Formel(17)Auf den ersten Blick mag es schwierig erscheinen,\bar{c}Die Anzahl der Seiten inMWenn du es versuchstp(\bar{c})=(1-p)^{|E|-M} p^{M}=(1-p)^{|E|}(\frac{p}{1-p})^{M}Sie können sehen, was Sie tun können. ↩︎

Recommended Posts

Grundlagen der Quanteninformationstheorie: Topologische Oberflächencodes
Grundlagen der Quanteninformationstheorie: Universelle Quantenberechnung durch Oberflächencode (1)
Grundlagen der Quanteninformationstheorie: Logische Operation durch Oberflächencode (Brading)
Grundlagen der Quanteninformationstheorie: Entropie (2)
Grundlagen der Quanteninformationstheorie: Quantenfehlerkorrektur (Shor Code)
Grundlagen der Quanteninformationstheorie: Quantenfehlerkorrektur (CSS-Code)
Grundlagen der Quanteninformationstheorie: Quantenfehlerkorrektur (Stabilisatorcode: 4)
Grundlagen der Quanteninformationstheorie: Datenkomprimierung (1)
Grundlagen der Quanteninformationstheorie: Horebaud-Grenzen
Grundlagen der Quanteninformationstheorie: Quantenzustands-Tomographie
Grundlagen der Quanteninformationstheorie: Datenkomprimierung (2)
Grundlagen der Quanteninformationstheorie: Fehlertolerante Quantenberechnung
Lesen Sie "Grundlagen des Quantenglühens", Tag 5
Lesen Sie "Grundlagen des Quantenglühens", Tag 6
Grundlagen der Tableau-Grundlagen (Visualisierung mit geografischen Informationen)
Python-Grundlagen ①
Grundlagen von Python ①
Lassen Sie uns die Grundlagen des Python-Codes von TensorFlow aufschlüsseln