[PYTHON] Grundlagen der Quanteninformationstheorie: Logische Operation durch Oberflächencode (Brading)

\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

Vorheriger Artikel erstellt einen Hochleistungsfehlerkorrekturcode (Oberflächencode) unter Verwendung von Quantenbits, die auf einem einem Torus zugeordneten Gitter platziert sind. Ich habe gesehen, dass es möglich ist. Es ist jedoch sehr schwierig, einen solchen Torus tatsächlich physikalisch zu erzeugen, und die Anzahl der logischen Quantenbits, die ausgedrückt werden können, ist proportional zur Anzahl der Löcher im Torus, also ein Quantencomputer mit einer großen Anzahl logischer Bits in dieser Richtung. Scheint fast unmöglich zu schaffen. Daher wurde ein Oberflächencodierungsverfahren vorgeschlagen, das logische Operationen ausführen kann, indem mehrere Defekte eines bestimmten Typs auf einer bloßen Ebene, die kein Torus ist, erzeugt, bewegt und wie ein Geflecht um sie gewickelt (geflochten) werden. Dieses Mal werde ich das aufgreifen.

Lassen Sie mich zunächst sagen, was ich in den folgenden Abschnitten zu erklären versuche. Erstens, in der "theoretischen Erklärung", welche Art von Defekt erzeugt werden kann, um das logische Bit auszudrücken, wie der logische $ X $ -Operator und der logische $ Z $ -Operator definiert werden können und weiter durch Verschieben des Defekts (Braid). Zeigt an, dass eine logische 2-Quantenbit-Operation (logische CNOT-Operation) realisiert werden kann. Verwenden Sie in "Operation check" den Quantenberechnungssimulator qlazy, um zu bestätigen, dass die CNOT-Operation tatsächlich ausgeführt werden kann, indem Sie den in der Ebene erzeugten Fehler flechten. ..

Die folgenden Dokumente wurden als Referenz verwendet.

  1. Koshiba, Morimae, Fujii "Quantenberechnung basierend auf Beobachtung" Corona (2017)
  2. K.Fujii,"Quantum Computation with Topological Codes - from qubit to topological fault-tolerance",arXiv:1504.01444v1 [quant-ph] 7 Apr 2015

Erklärung der Theorie

Gesichtsoperator und Scheitelpunktoperator

Betrachten Sie ein Raster wie in der folgenden Abbildung gezeigt. Dieses Mal nehmen wir keine periodische Randbedingung wie vorherige an. Stellen Sie sich diese also als ein Gitter vor, das auf einer bloßen Ebene definiert ist.

fig1.png

Definieren Sie darüber hinaus den Gesichtsoperator und den Scheitelpunktoperator. Die Gesichtsoperatoren sind das Tensorprodukt der $ Z $ -Operatoren auf den vier Seiten, die jede Fläche umgeben und ordentlich in derselben Form angeordnet sind. Der Scheitelpunktoperator ist jedoch etwas anders. Die Anzahl der $ X $ -Operatoren für die Scheitelpunktoperatoren an den Rändern der Ebene beträgt nicht vier, da jeder Scheitelpunkt am Rand der Ebene nur mit drei oder zwei Seiten verbunden ist. Stellen Sie sich eine Gruppe von Stabilisatoren vor, deren Quelle der auf diese Weise definierte Oberflächenoperator und Scheitelpunktoperator ist. Wenn die Anzahl der Gitter $ M \ mal N $ beträgt, beträgt die Anzahl der Gesichtsoperatoren $ MN $ und die Anzahl der Scheitelpunktoperatoren $ (M + 1) (N + 1) = MN + M + N + 1 $. Die Gesamtzahl der Generatoren beträgt $ 2MN + M + N + 1 $. Es sind jedoch nicht alle unabhängig. Wie Sie der obigen Abbildung entnehmen können, ist das Produkt aller Scheitelpunktoperatoren $ I $ (gleicher Operator) [^ 1]. Mit anderen Worten, wenn Sie einen Scheitelpunktoperator willkürlich auswählen, kann er durch das Produkt aller anderen Scheitelpunktoperatoren ausgedrückt werden, sodass die Anzahl der unabhängigen Generatoren von $ MN + M + N + 1 $ um 1 reduziert wird. Es wird $ MN + M + N $. Andererseits beträgt die Anzahl der Quantenbits $ (M + 1) N + M (N + 1) = 2MN + M + N $, was der Anzahl der unabhängigen Generatoren entspricht. Daher bestimmt diese Gruppe von Stabilisatoren eindeutig den Quantenzustand. Dieser Zustand wird hier als "Vakuum" bezeichnet. In den folgenden Abschnitten werden wir erklären, wie Quantenoperationen ausgeführt werden können, indem Defekte erzeugt und verschoben werden, wobei dieses Vakuum als Ausgangspunkt verwendet wird.

[^ 1]: Wenn Sie alle Scheitelpunktoperatoren nebeneinander platzieren, können Sie sehen, dass alle Produkte Gleichheitsoperatoren sind, da der Operator $ X $, der demselben Quantenbit entspricht, immer zweimal erscheint. Das Produkt aller Gesichtsoperatoren ist übrigens das Tensorprodukt der $ Z $ -Operatoren, die in einer die Ebene umgebenden Schleife angeordnet sind.

Erstellen eines Vakuumzustands

Erstens, wie man einen Vakuumzustand erzeugt. Überlegen wir uns, welche Art von Quantenoperation an einer Gruppe von Quantenbits durchgeführt werden soll, die in einem Gitter angeordnet sind, um einen solchen Stabilisatorzustand (Vakuumzustand) zu erzeugen. Im Allgemeinen Stabilisatorgruppe

S = <g_1, g_2, g_3, \cdots , g_n>  \tag{1}

Der in angegebene Stabilisatorzustand wird erhalten, indem $ g_1, g_2, \ cdots, g_n $ in der Reihenfolge unter dem Anfangszustand $ \ ket {00 \ cdots 0} $ gemessen werden. Wie ich in Vorheriger Artikel erklärt habe, lassen Sie es uns kurz überprüfen. Das Messen von $ g_1 $ unter dem Status $ \ ket {00 \ cdots 0} $ entspricht dem Einwirkenlassen des Projektionsoperators $ (I \ pm g_1) / 2 $ auf den Status. Hier entspricht das Vorzeichen $ \ pm $, ob der gemessene Wert $ + 1 $ oder $ -1 $ war. Der Zustand nach der Messung ist

g_1 \frac{I \pm g_1}{2} \ket{00 \cdots 0} = \pm \frac{I \pm g_1}{2} \ket{00 \cdots 0}  \tag{2}

Daher wird es der Zustand auf dem Eigenraum, der dem Eigenwert $ + 1 $ oder $ -1 $ von $ g_1 $ (projiziert) entspricht. Wenn als nächstes $ g_2 $ für diesen gemessenen Zustand gemessen wird, wird es auf den Eigenraum projiziert, der dem Eigenwert von $ g_2 $ $ + 1 $ oder $ -1 $ entspricht, abhängig vom gemessenen Wert. Wenn Sie außerdem $ g_3, g_4, \ cdots, g_n $ usw. messen, wird es schließlich auf den Zustand (gleichzeitiger Eigenzustand) im Produktraum des Eigenraums von $ g_1, g_2, \ cdots, g_n $ projiziert. Getan werden. Es ist jedoch völlig wahrscheinlich, welcher Eigenwert, der jedem $ g_i $ entspricht, in den Eigenraum projiziert wird. In Vorheriger Artikel haben wir eine Operation zum Invertieren des Eigenwerts hinzugefügt, wenn dieser auf den Eigenraum von $ -1 $ projiziert wird. .. Dann kann der Stabilisatorzustand, der der Stabilisatorgruppe der Formel (1) entspricht, sauber erhalten werden. Wenn die Prozedur jedoch unterbrochen ist, z.

S = <-g_1, g_2, -g_3, \cdots , -g_n>  \tag{3}

Sie können den Stabilisatorzustand erhalten, der der Stabilisatorgruppe entspricht (dies geschieht, wenn der gemessene Wert des 1., 3. und n-ten Generators -1 ist). Im Allgemeinen

S = <\pm g_1, \pm g_2, \pm g_3, \cdots , \pm g_n>  \tag{4}

In können Sie den Stabilisatorzustand erhalten, der der Stabilisatorgruppe entspricht, in der das Vorzeichen von $ g_i $ je nach dem gemessenen Wert jedes Generators $ + $ oder $ - $ ist. Dies ist überhaupt kein Problem, da die Syndrom-Messkriterien für jeden Generator nur im Voraus beibehalten werden müssen, wenn Fehlerkorrekturen vorgenommen werden. Mit anderen Worten, unter der Annahme, dass die Stabilisatorgruppe des Messergebnisses wie in Gleichung (3) gezeigt erhalten wird, ist das Ergebnis der Messung des ersten Generators $ g_1 $ $ -1 $, es ist ein normaler Wert und es gibt keinen Fehler. Sie können beurteilen, und umgekehrt, wenn es $ + 1 $ ist, können Sie beurteilen, dass ein Fehler aufgetreten ist, und so weiter.

Wenn eine solche Messung tatsächlich durchgeführt wird, um einen Vakuumzustand zu erzeugen, werden zusätzlich zu den Quantenbits (Datenquantenbits), die an den Seiten des Gitters eingesetzt sind, zusätzliche Hilfsquantenbits für die indirekte Messung (Symdromessung) zusätzlich eingesetzt. Es ist gut zu tun. Die spezifische Methode besteht darin, der Mitte und jedem Scheitelpunkt jeder Oberfläche des Gitters Hilfsquantenbits hinzuzufügen, wie in der folgenden Abbildung gezeigt. Das in der Mitte jeder Oberfläche eingesetzte Hilfsquantenbit dient zur indirekten Messung (Symdrom-Messung) des Oberflächenoperators, und das an jedem Scheitelpunkt eingesetzte Hilfsquantenbit dient zur indirekten Messung (Symdrom-Messung) des Scheitelpunktoperators. Es ist.

fig2.png

Initialisieren Sie vor dem Messen der Flächen- und Scheitelpunktoperatoren zunächst alle Daten und Hilfsquantenbits auf $ \ ket {0} $. Messen Sie dann indirekt den Oberflächenoperator, der jeder Oberfläche entspricht. Die der zu messenden Oberfläche entsprechende Hilfsquantenbitnummer beträgt $ f_0 $, und die Datenquantenbitnummer auf der die Oberfläche umgebenden Seite beträgt $ f_1, f_2, f_3, f_4 $.

f0 --H--*--*--*--*--H-- M
        |  |  |  |
f1 -----Z--|--|--|-----
f2 --------Z--|--|-----
f3 -----------Z--|-----
f4 --------------Z-----

Messen Sie den Oberflächenoperator mit einer Quantenschaltung wie. Tun Sie dies an allen Fronten. Messen Sie dann den Scheitelpunktoperator für jeden Scheitelpunkt. Die Hilfsquantenbitnummer, die dem zu messenden Scheitelpunkt entspricht, ist $ v_0 $, und die Datenquantenbitnummer auf der mit dem Scheitelpunkt verbundenen Seite ist $ v_1, v_2, v_3, v_4 $.

v0 --H--*--*--*--*--H-- M
        |  |  |  |
v1 -----X--|--|--|-----
v2 --------X--|--|-----
v3 -----------X--|-----
v4 --------------X-----

Messen Sie den Scheitelpunktoperator mit einer Quantenschaltung wie. Tun Sie dies für alle Eckpunkte. Der Vakuumzustand wird nun erstellt.

Der Vakuumzustand ist ein Zustand. Es ist kein Codebereich. Um daraus einen Codebereich zu machen, muss mindestens eine Quelle entfernt und eine Reihe von Stabilisatoren mit $ n-1 $ unabhängigen Quellen in Betracht gezogen werden. Letztes Mal logisiert die $ X $ - oder $ Z $ -Operatoren, die in der Schleife angeordnet sind, die sich um das Loch wickelt, indem die periodische Randbedingung = Torus berücksichtigt wird. Ich konnte ein Operator sein. Dieses Mal definieren wir den logischen Operator, indem wir künstlich einen Defekt (Loch) in der Ebene erzeugen.

Fehler vs. Quantenbit-Erzeugung

Definieren Sie zunächst einen "Defekt". Fehler sind Bereiche, in denen keine Flächen- oder Scheitelpunktoperatoren definiert sind. Der zuvor erläuterte Vakuumzustand war ein Stabilisatorzustand, in dem Oberflächenoperatoren und Scheitelpunktoperatoren dicht über das gesamte Gitter verteilt waren. Wenn Sie eine Region in dieser Ebene ohne einen Gesichtsoperator (oder einen Scheitelpunktoperator) erstellen könnten, wäre dies ein Fehler. Wie machen Sie diesen Fehler? Tatsächlich kann es leicht erzeugt werden, indem eines der Quantenbits in der Ebene gemessen wird, die den Vakuumzustand ausmacht.

Beachten Sie die beiden benachbarten Flächen, aus denen das Raster besteht (siehe Abbildung unten). Erwägen Sie, den Operator $ X $ zu messen, der den Quantenbits entspricht, über denen die beiden Flächen eine gemeinsame Seite haben. Mit anderen Worten, messen Sie das 4. Quantenbit in der Abbildung auf der $ X $ -Basis (oder Sie können sich das 4. Quantenbit als Adamal-Gated vorstellen und dann auf der $ Z $ -Basis messen).

fig3.png

Beschreiben wir diese Messung in stabilisatorischen Begriffen [^ 2]. Es gibt nur zwei Quellen, die gegen den zu messenden Operator $ X_4 $ gegenkonvertierbar sind: den Oberflächenoperator $ Z_1 Z_3 Z_4 Z_6 \ Äquiv. A_1 $ und den Oberflächenoperator $ Z_2 Z_4 Z_5 Z_7 \ Äquiv. A_2 $. Alle anderen Gesichtsoperatoren und Scheitelpunktoperatoren sind austauschbar. In diesem Fall kann ein Anti-Commutable-Operator auf die anderen Anti-Commutable-Operatoren angewendet werden, um einen Anti-Commutable-Operator zu erstellen, während die Stabilisatoren unveränderlich bleiben. Das heißt, die Stabilisatorgruppe

[^ 2]: Messungen vom Stabilisatortyp werden in den folgenden Diskussionen häufig erwähnt. Weitere Informationen finden Sie im vorherigen Artikel "Grundlagen der Quanteninformationstheorie: Quantenfehlerkorrektur (Stabilisatorcode: 2)".

S = <A_1, A_2, \cdots>  \tag{5}

Zu

S = <A_1 A_2, A_2, \cdots>  \tag{6}

Die einzige nicht austauschbare Quelle kann $ A_2 $ sein, wie in. Dann messe ich $ X_4 $, das ist das Messziel. Wenn der gemessene Wert $ + 1 $ ist, ersetze $ A_2 $ durch $ X_4 $, und wenn es $ -1 $ ist, ersetze $ A_2 $ durch $ -. Stabilisatorgruppe durch X_4 $ ersetzt

S = <A_1 A_2, \pm X_4, \cdots>  \tag{7}

Der entsprechende Stabilisatorzustand ist der Zustand nach der Messung. Sie können sehen, dass die Oberflächenoperatoren $ A_1 $ und $ A_2 $, die sich im ursprünglichen Vakuumzustand befanden, verschwunden sind und durch $ A_1 A_2 $ und $ \ pm X_4 $ ersetzt wurden. Mit anderen Worten kann gesagt werden, dass die Messung von $ X_4 $ zwei Fehlerpaare in den Teilen erzeugt hat, die $ A_1 $ und $ A_2 $ entsprechen. Dieser Status ist auch für $ X_4 $ eindeutig, da die Quelle $ \ pm X_4 $ enthält.

Fehler wurden durch Messung gepaart, aber Gleichung (7) stellt einen eindeutigen Zustand dar und befindet sich nicht im Code-Raum. Zum Beispiel Stabilisatoren ohne $ \ pm X_4 $,

S^{\prime} = <A_1 A_2, \cdots>  \tag{8}

Ist der Code-Raum zur Beschreibung eines logischen Quantenbits.

Wie kann der logische $ X $ -Operator in diesem Codespace definiert werden? Bringen Sie $ X_4 $ erneut. Dieses $ X_4 $ fungiert als logischer Operator, da es mit allen Quellen von $ S ^ {\ prime} $ austauschbar ist und kein Element von $ S ^ {\ prime} $ ist. Und

<A_1 A_2, X_4, \cdots>  \tag{9}

Entspricht dem eindeutigen Wert $ + 1 $ von $ X_4 $

<A_1 A_2, -X_4, \cdots>  \tag{10}

Befindet sich in einem Zustand, der dem eindeutigen Wert $ -1 $ von $ X_4 $ entspricht. Wenn also $ X_4 $ als logischer $ X $ -Operator definiert ist, ist Gleichung (9) $ \ ket {+ ^ {L}} $, Gleichung (10). ) Stellt $ \ ket {- ^ {L}} $ dar ($ L $ mit einer Überwachung muss ein logisches Quantenbit darstellen; dasselbe gilt im Folgenden).

Andererseits kann der logische $ Z $ -Operator mit dem logischen $ X $ -Operator $ X_4 $ gegenkommutierbar sein und aus allen Quellen von $ S ^ {\ prime} $ ausgewählt werden. Zum Beispiel erfüllt $ A_1 $ diese Anforderung und kann als logischer $ Z $ -Operator [^ 3] definiert werden. Alternativ kann $ A_2 $ ein logischer $ Z $ -Operator sein.

[^ 3]: Bitte beachten Sie, dass $ A_1 $ oder $ A_2 $ nicht mehr der Ursprung dieser Stabilisatorgruppe ist.

Das Obige ist die einfachste Methode zum Erstellen eines Fehlerpaars (= Erstellen eines Codebereichs). Diese Art von Defekt wird als p-Typ-Defekt bezeichnet, da der Defekt ein Mangel an Oberflächenoperatoren auf dem regulären Gitter ist. Es gibt auch eine andere Art von Fehler. Es ist das Fehlen von Oberflächenoperatoren in Doppelgittern (dh Scheitelpunktoperatoren in regulären Gittern). Die Methode zum Erstellen wird unten erläutert.

Achten Sie auf die beiden benachbarten Flächen, aus denen das Doppelgitter besteht (siehe Abbildung unten) (vergessen Sie die obige Quantenbitnummer und weisen Sie die Quantenbitnummer neu zu). Im ursprünglichen normalen Raster handelt es sich um ein benachbartes Kreuzzeichen. Erwägen Sie, den $ Z $ -Operator zu messen, der den Quantenbits entspricht, über denen diese beiden Kreuze eine gemeinsame Seite haben. Das heißt, messen Sie das 4. Quantenbit in der Figur auf der $ Z $ -Basis.

fig4.png

Beschreiben wir diese Messung im Stabilisatorstil. Es gibt nur zwei Quellen, die für den zu messenden Operator $ Z_4 $ nicht konvertierbar sind: den Scheitelpunktoperator $ X_1 X_3 X_4 X_6 \ Äquiv. B_1 $ und den Scheitelpunktoperator $ X_2 X_4 X_5 X_7 \ Äquiv. B_2 $. Alle anderen Gesichtsoperatoren und Gesichtsoperatoren sind austauschbar. Wie in der vorherigen Diskussion ist der Zustand nach der Messung

S = <B_1 B_2, \pm Z_4, \cdots>  \tag{11}

Und dies ist der eindeutige Zustand von $ \ pm Z_4 $. Schließen Sie hier $ \ pm Z_4 $ aus

S^{\prime} = <B_1 B_2, \cdots>  \tag{12}

In Anbetracht dessen ist dies eine Gruppe von Stabilisatoren, die den Codebereich definieren. Wenn Sie also $ Z_4 $ erneut bringen, ist es mit allen Quellen von $ S ^ {\ prime} $ austauschbar und kein Element von $ S ^ {\ prime} $, also die Rolle des logischen Operators Werde spielen. Und

<B_1 B_2, Z_4, \cdots>  \tag{13}

Entspricht dem eindeutigen Wert $ + 1 $ von $ Z_4 $

<B_1 B_2, -Z_4, \cdots>  \tag{14}

Entspricht der Zustand dem eindeutigen Wert $ -1 $ von $ Z_4 $? Wenn also $ Z_4 $ als logischer $ Z $ -Operator definiert ist, ist Gleichung (13) $ \ ket {0 ^ {L}} $, Gleichung (14). ) Repräsentiert $ \ ket {1 ^ {L}} $.

Andererseits können Sie für den logischen Operator $ X $ einen Operator auswählen, der nicht konvertierbar in $ Z_4 $ ist und mit allen Quellen von $ S $ konvertierbar ist. Beispielsweise erfüllt $ B_1 $ diese Anforderung, sodass Sie sie als logischen $ X $ -Operator definieren können. Alternativ kann $ B_2 $ ein logischer $ X $ -Operator sein.

Das Obige ist die einfachste Methode zum Erstellen von Fehlerpaaren in einem Doppelgitter. Diese Art von Defekt wird als D-Typ-Defekt bezeichnet, da der Defekt ein Mangel an Oberflächenoperatoren auf dem Doppelgitter ist.

Defekt vs. Quantenbitbewegung

Sie können den Bereich des Defekts auch erweitern, indem Sie die Messung wiederholen. Durch Messen der Quantenbits um den p-Typ-Defekt auf der $ X $ -Basis, wie in der folgenden Abbildung gezeigt, erweitert sich der Defektbereich (hellblauer Bereich). Die durch schwarze Kreise angezeigten Quantenbits sind die gemessenen Quantenbits.

fig5.png

Sie können auch Mängel beseitigen. Vergrößern Sie zunächst den p-Typ-Defekt in horizontaler Richtung, wie in der folgenden Abbildung links gezeigt. Lassen Sie uns außerdem die Mitte der drei aufgedeckten Fehler beseitigen. Da dies der Wiederherstellung des dieser Oberfläche entsprechenden Oberflächenoperators entspricht, ist es ausreichend, den Oberflächenoperator zu messen. Tatsächlich wird eine indirekte Messung unter Verwendung des der Oberfläche entsprechenden Hilfsquantenbits durchgeführt (in der folgenden Abbildung nicht gezeigt). Dann ist es wie in der folgenden Abbildung rechts gezeigt.

fig6.png

Ist es wahr, auch wenn gesagt wird, dass es sein wird? Ich werde das hören, also lassen Sie uns diesen Vorgang wie zuvor im Stabilisatorformat überprüfen. Der Zustand links in der obigen Figur kann erhalten werden, indem die Diskussion erweitert wird, wenn Gleichung (7) erhalten wurde.

S = <A_1 A_2 A_3, \pm X_5, \pm X_6, \cdots> \tag{15}

Sie können sehen, dass Hier wird das Vorzeichen von $ \ pm $ anhand des Messergebnisses von $ X_5 $ und des Messergebnisses von $ X_6 $ bestimmt. Messen Sie unter dieser Bedingung $ A_2 $. $ A_2 $ ist mit $ X_5 $ und $ X_6 $ anti-konvertierbar. Multiplizieren Sie also zuerst eines der beiden, um ein Anti-Commutable zu erhalten. Zum Beispiel

S = <A_1 A_2 A_3, \pm X_5 X_6, \pm X_6, \cdots> \tag{16}

Machen. Dann ist $ \ pm X_6 $ die einzige Quelle, die in $ A_2 $ nicht konvertierbar ist. Messen Sie außerdem $ A_2 $. Abhängig vom Messergebnis

S = <A_1 A_2 A_3, \pm X_5 X_6, \pm A_2, \cdots> \tag{17}

Der Zustand ändert sich so. Der Stabilisatorzustand ändert sich auch dann nicht, wenn eine Quelle auf eine andere Quelle übertragen wird. Versuchen Sie beispielsweise, die dritte Quelle mit der ersten Quelle zu multiplizieren. Dann

S = <\pm A_1 A_3, \pm X_5 X_6, \pm A_2, \cdots> \tag{18}

Es wird sein. Damit ist der Status rechts in der obigen Abbildung abgeschlossen. Mit anderen Worten, Sie können Fehler verschieben, indem Sie Expansion und Verschwinden kombinieren.

In Anbetracht des von der Stabilisatorgruppe definierten Code-Raums ohne $ \ pm X_5 X_6 $ wird hier die Kette von $ X_5 X_6 $ als logischer $ X $ -Operator wie in der vorherigen Diskussion verwendet, und der Fehler ist $ A_1 $. Wir können sehen, dass wir die Schleife um den als logischen $ Z $ -Operator definieren können.

Was ist übrigens, wenn Sie sich unwohl fühlen, wenn das Zeichen je nach gemessenem Wert $ + $ oder $ - $ ist? Ich werde ein wenig hinzufügen. Angenommen, $ X_6 $ wird gemessen und das Vorzeichen von $ X_6 $ in Gleichung (15) wird zu $ - $. In diesem Fall bringen Sie den logischen $ Z $ -Operator $ A_3 $ (oder $ A_1 A_2 $) ein, der mit $ X_6 $ gegenkommutierbar ist und mit allen anderen Quellen austauschbar ist, und führen Sie die gesamte Operation aus. Das ist gut. Wenn andererseits das Vorzeichen von $ A_2 $ in Gleichung (17) als Ergebnis der Messung von $ A_2 $ zu $ - $ wird, sollte der logische Operator $ X $ vor dem Verschieben von $ X_5 $ als Ganzes berechnet werden. Es ist gut [^ 4]. Ergebnis,

[^ 4]: Wenn Sie den Vorgang später überprüfen, führen Sie die Simulation der Fehlerpaarbewegung auf diese Weise durch.

S = <A_1 A_3, X_5 X_6, A_2, \cdots> \tag{19}

Sie können einen sauberen Zustand wie diesen bekommen. Dies ist der eindeutige Status, der dem eindeutigen Wert $ + 1 $ von $ X_5 X_6 $ entspricht. Dieser Vorgang kann unbegrenzt ausgeführt werden und Sie können das Fehlerpaar an eine beliebige Stelle verschieben. Unabhängig von der Platzierung ist der dadurch bestimmte Zustand jedoch der eindeutige Zustand des Tensorprodukts des $ X $ -Operators an der Kette, die die beiden Defekte verbindet [^ 5]. Das Tensorprodukt des Operators $ X $ in dieser Kette fungiert als logischer Operator $ X $, und der Operator $ Z $ in der Schleife, die einen der beiden Fehler umgibt, ist der logische Operator $ Z $. Es spielt eine Rolle [^ 6].

[^ 5]: Gleiches gilt für jede Kette, die Defekte verbindet. Vorheriger Artikel ähnelt der Aussage, dass das Produkt von Operatoren in einer Schleife, die kontinuierlich transformiert werden kann, denselben Effekt darstellt.

[^ 6]: Unter Berücksichtigung des von der Stabilisatorgruppe bestimmten Code-Raums ohne $ X_5 X_6 $ aus Gleichung (19) sind die logischen Operatoren $ X $ und $ Z $ wie im Text beschrieben. Gleichung (19) repräsentiert den Zustand $ \ ket {+ ^ {L}} $, da er für den Eigenwert $ + 1 $ von logischem $ X $ eindeutig ist. Wenn Sie in diesem Zustand das logische $ Z $ berechnen, wird die logische Phase invertiert und in den Zustand $ \ ket {- ^ {L}} $ geändert.

Das Obige ist dasselbe für Defekte vom Typ d, und die Defekte können durch wiederholtes Ausdehnen und Aussterben bewegt werden, und das Tensorprodukt des $ Z $ -Operators an der Kette, die die Defekte verbindet, wird zu einem eindeutigen Zustand. Und das Tensorprodukt des $ Z $ -Operators in dieser Kette fungiert als logischer $ Z $ -Operator, und der $ X $ -Operator in der Schleife (im dualen Gitter), die einen der beiden Fehler umgibt, ist das logische $ X. Dient als $ -Operator.

Bisher haben wir der Einfachheit halber hauptsächlich die Fehler berücksichtigt, die auf das Fehlen eines Gesichtsoperators (oder Scheitelpunktoperators) zurückzuführen sind. Wie bereits erläutert, kann dieser jedoch beliebig erweitert werden. Zum Beispiel kann ein großes Fehlerpaar, wie in der folgenden Abbildung gezeigt, leicht durch Wiederholen der Messung erzeugt werden.

fig7.png

Wenn Sie einen so großen Fehler machen, erhöht sich die Anzahl der Pauli-Operatoren, aus denen der logische Operator besteht, entsprechend. Mit anderen Worten, der Codeabstand nimmt zu [^ 7]. Je größer der Codeabstand ist, desto mehr Quantenbits können korrigiert werden. Insbesondere ermöglicht ein Code mit einem Abstand von $ 2t + 1 $ das Korrigieren von Fehlern im $ t $ -Quantenbit. Übrigens beträgt im Fall der obigen Abbildung der Codeabstand 16 (wie Sie durch Zählen sehen können), sodass die Anzahl der Quantenbits, die korrigiert werden können, 7 beträgt.

[^ 7]: Der Codeabstand im Quantenfehlerkorrekturcode ist definiert als die Mindestanzahl von Pauli-Operatoren, aus denen ein logischer Operator besteht. Die Implikation ist die minimale Anzahl von Quantenbits, die sich geändert haben, wenn eine logische Operation von einem Code ausgeführt und in einen anderen Code verschoben wurde. Der Codeabstand wird auf diese Weise definiert, da die Anzahl der sich ändernden Quantenbits gleich der Anzahl der im logischen Operator enthaltenen Pauli-Operatoren ist. Der Codeabstand im klassischen linearen Code ist übrigens der Minimalwert des Brummabstands zwischen logisch unterschiedlichen Codes. Mit anderen Worten, sowohl im Quanten- als auch im klassischen Fall kann der Codeabstand als Index betrachtet werden, der angibt, wie viele Bits geändert werden sollten, um von einem Code zum anderen zu wechseln.

2 Quantenbitarithmetik durch Flechten

Ich werde den Inhalt bis zum vorherigen Abschnitt zusammenfassen. Wenn Sie durch Messung aus einem Vakuumzustand ein Fehlerpaar vom p-Typ erstellen, ist dieser Zustand der Eigenzustand des Tensorprodukts des Pauli $ X $ -Operators an der Kette, die diese Fehler verbindet. In Anbetracht des Ursprungs ohne die Kette, dh des Code-Raums, der durch die beiden im Vakuum erzeugten (p-Typ) Defekte definiert ist, ist das Tensorprodukt des Pauli $ X $ -Operators an der Kette, die die Defekte verbindet, dieser Code. Sie können sich das als logischen $ X $ -Operator im Raum vorstellen. In diesem Fall wird auch das Tensorprodukt des Pauli $ Z $ -Operators in der Schleife, die einen der Fehler umgibt, zum logischen $ Z $ -Operator in diesem Codespace. Wenn Sie dagegen ein Fehlerpaar vom Typ d erstellen, ist sein Zustand der Eigenzustand des Tensorprodukts des Pauli $ Z $ -Operators in der Kette, die die Fehler verbindet. In Anbetracht des Ursprungs ohne die Kette, dh des Code-Raums, der durch die beiden im Vakuum erzeugten (d-Typ) Defekte definiert ist, ist das Tensorprodukt des Pauli $ Z $ -Operators an der Kette, die die Defekte verbindet, dieser Code. Sie können sich das als logischen $ Z $ -Operator im Raum vorstellen. In diesem Fall wird auch das Tensorprodukt des Pauli $ X $ -Operators in der Schleife, die einen der Fehler umgibt, zum logischen $ X $ -Operator in diesem Codespace. Es war das.

Angenommen, ein p-Typ-Defektpaar und ein d-Typ-Defektpaar existieren getrennt in einer Ebene, wie in der folgenden Abbildung gezeigt. Im Fall des p-Typ-Defektpaars wird anstelle des Verschwindens der beiden Gesichtsoperatoren das Produkt der beiden fehlenden Gesichtsoperatoren neu zum Generator hinzugefügt, sodass jetzt ein logisches Quantenbit verfügbar ist. Du kannst es ausdrücken. Im Fall des Defektpaars vom Typ d wird anstelle des Verschwindens der beiden Scheitelpunktoperatoren das Produkt der beiden fehlenden Scheitelpunktoperatoren neu zum Generator hinzugefügt, sodass dies ein logisches Quantum ist. Dies bedeutet, dass das Bit ausgedrückt werden kann. Daher können zwei logische Quantenbits durch den in der folgenden Abbildung gezeigten Fehler ausgedrückt werden.

fig8.png

Hier ist das Fehlerpaar vom p-Typ das 0. logische Quantenbit, und das Fehlerpaar vom d-Typ ist das 1. logische Quantenbit. Angenommen, Sie möchten, dass das 0. logische Quantenbit der Eigenzustand des logischen Operators $ X $ ist. Angenommen, Sie möchten das 0. Quantenbit mit $ \ ket {+ ^ {L}} $ oder $ \ ket {- ^ {L}} $ initialisieren. Was soll ich machen? Wenn Sie sich an die Grundlagen des Stabilisatorformats erinnern, werden Sie es sofort verstehen. Alles, was Sie tun müssen, ist, das Tensorprodukt des logischen $ X $ -Operators, dh des $ X $ -Operators an der Kette, die die Defekte verbindet, zum Generator hinzuzufügen (siehe Abbildung unten). Dadurch wird der Status $ \ ket {+ ^ L} $ erstellt. Wie im vorherigen Abschnitt erläutert, ist entweder der Status $ \ ket {+ ^ L} $ oder $ \ ket {- ^ L} $ natürlich, wenn Sie ein Paar Fehler vom Typ p generieren und einen der Fehler verschieben. Du kannst es haben. Wenn Sie $ \ ket {- ^ L} $ (oder $ \ ket {+ ^ L} $) erhalten, dann der logische $ Z $ -Operator, dh der Pauli $ Z $ in der Schleife, die einen der Fehler umgibt. Sie kann in $ \ ket {+ ^ L} $ (oder $ \ ket {- ^ L} $) geändert werden, indem das Tensorprodukt des Operators auf diesen Zustand angewendet wird.

Wenn Sie das erste Quantenbit mit $ \ ket {0 ^ L} $ oder $ \ ket {1 ^ L} $ initialisieren möchten, möchten Sie den logischen $ Z $ -Operator verwenden, dh $, der in die Fehlerkette eingefügt wird. Sie müssen lediglich das Tensorprodukt des Z $ -Operators zur Quelle hinzufügen (siehe unten). Dadurch wird der Status $ \ ket {0 ^ L} $ erstellt. Wie im vorherigen Abschnitt erläutert, befindet sich ein Paar von Fehlern vom Typ d, wenn Sie eines davon verschieben und eines davon verschieben, natürlich in diesem Zustand $ \ ket {0 ^ L} $ oder $ \ ket {1 ^ L} $. Es kann erhalten werden. Wenn Sie $ \ ket {1 ^ L} $ (oder $ \ ket {0 ^ L} $) erhalten, dann der logische $ X $ -Operator, dh Pauli $ X $ in der Schleife, die einen der Fehler umgibt. Indem das Tensorprodukt des Operators auf diesen Zustand einwirkt, kann es in $ \ ket {0 ^ L} $ (oder $ \ ket {1 ^ L} $) geändert werden.

fig9.png

Lassen Sie uns nun zeigen, dass eine logische CNOT-Operation unter Verwendung dieser beiden logischen Quantenbits ausgeführt werden kann. In Bezug auf den Stabilisator sollte Folgendes erreicht werden

CNOT: <XI,IZ> \rightarrow <XX,ZZ>   \tag{20}

Es ist eine Bekehrung. Ausgedrückt als Quantenschaltung für zwei logische Quantenbits

X --*-- X    I --*-- Z
    |            |
I --X-- X    Z --X-- Z

Es wäre gut, wenn realisiert werden könnte.

Lassen Sie mich zuerst schließen [^ 8]. Bewegen Sie eines der p-Typ-Defektpaare so, dass es sich um einen der d-Typ-Defekte wickelt. Zum Beispiel wird, wie in der folgenden Abbildung (1) gezeigt, das 0. logische Quantenbit auf den Eigenzustand (der Eigenwert ist 1) des logischen $ X $ -Operators und einen der p-Typ-Defekte (die rechte Seite) gesetzt, wie in der folgenden Abbildung (2) gezeigt. ) Wird um einen der d-Typ-Defekte (rechts) bewegt. Dann umschließt die Kette von $ X $ -Operatoren den d-Typ-Defekt. Da sich der gesamte Status auch dann nicht ändert, wenn der Operator $ X $ auf die offensichtliche Schleife angewendet wird, wird die Schleife des Operators $ X $ (angezeigt durch die orange Linie) wie in (3) unten gezeigt angewendet. Schließlich ist, wie in (4) unten gezeigt, die Kette von $ X $ -Operatoren in zwei Teile unterteilt. Eine ist eine Kette, die das ursprüngliche Defektpaar vom p-Typ verbindet, und die andere ist eine Schleife, die den Defekt vom d-Typ umschließt. Da diese Schleife ihren Zustand nicht ändert, selbst wenn sie sich kontinuierlich zusammenzieht, zieht sie sich bis zu der Grenze zusammen, die den d-Typ-Defekt in (4) unten umgibt. Da der $ X $ -Operator in dieser Schleife der logische $ X $ -Operator des ersten logischen Quantenbits war, befindet sich das erste logische Quantenbit im Eigenzustand (eindeutiger Wert ist 1) des logischen $ X $ -Operators. Ich bin. Dies bedeutet, dass der logische Anfangszustand $ XI $ in den logischen Endzustand $ XX $ geändert wurde.

[^ 8]: Ich verstehe den Ursprung der Idee nicht wirklich, warum man dachte, dass CNOT damit realisiert werden könnte, also schwitze ich.

fig10.png fig11.png

Das Folgende zeigt, dass eine ähnliche Bewegung den logischen Anfangszustand $ IZ $ in den logischen Endzustand $ ZZ $ ändert. Setzen Sie, wie in (1) unten gezeigt, das erste logische Quantenbit auf den Eigenzustand des logischen $ Z $ -Operators (der Eigenwert ist 1) und lassen Sie den p-Typ-Defekt den d-Typ-Defekt wie zuvor umgehen. Ziehen nach. Wenn der p-Typ-Defekt die Kette des $ Z $ -Operators erreicht, der die d-Typ-Defekte verbindet, und sich weiter bewegt, bewegt er sich, während er die Kette des $ Z $ -Operators drückt, wie in (2) unten gezeigt. Es wird in Form sein [^ 9]. Der Status ändert sich auch dann nicht, wenn der Operator $ Z $ auf die offensichtliche Schleife angewendet wird. Wenn Sie also die Schleife des Operators $ Z $ (angezeigt durch die orange Linie) anwenden, wie in (3) unten gezeigt, Schließlich ist die Kette der $ Z $ -Operatoren in zwei Teile unterteilt, wie in (4) unten gezeigt. Eine ist eine Kette, die das ursprüngliche d-Typ-Defektpaar verbindet, und die andere ist eine Schleife, die den p-Typ-Defekt umschließt. Da der $ Z $ -Operator in dieser Schleife der logische $ Z $ -Operator des 0. logischen Quantenbits war, befindet sich das 0. logische Quantenbit im Eigenzustand (eindeutiger Wert ist 1) des logischen $ Z $ -Operators. Ich bin. Jetzt wissen wir, dass sich der logische Anfangszustand $ IZ $ in den logischen Endzustand $ ZZ $ geändert hat.

[^ 9]: Ich werde nicht im Detail erklären, warum dies passiert. Sie können es sehen, indem Sie die Messungen im Stabilisatorformat überprüfen und jeweils manuell berechnen.

fig12.png fig13.png

Auf diese Weise konnte Braiding eine CNOT-Operation an einem logischen 2-Quantenbit ausführen. Der Anfangszustand ist $ \ ket {+ ^ {L} 0 ^ {L}} $ und die CNOT-Operation wird darauf ausgeführt, so dass der Endzustand der logische Bell-Zustand $ (\ ket {0 ^ {L} 0 ^ {L ist }} + \ ket {1 ^ {L} 1 ^ {L}}) / \ sqrt {2} $. Es ist das.

Funktionsprüfung

Dann wird unter Verwendung des Quantenberechnungssimulators qlazy der Oberflächencode konstruiert, indem Fehler in einer Gitterebene erzeugt werden, und die CNOT-Operation durch Flechten wird korrekt ausgeführt. Mal sehen, was wir tun können. Ich möchte das oben gezeigte Beispiel so ausführen, wie es ist. Der Anfangszustand ist $ \ ket {+ ^ {L} 0 ^ {L}} $ und es wird eine CNOT-Operation ausgeführt, so dass der Endzustand der logische Bell-Zustand $ (\ ket {0 ^ {L} 0 ^ {L ist }} + \ ket {1 ^ {L} 1 ^ {L}}) / \ sqrt {2} $ sollte sein. Gemessen auf einer logischen $ Z $ -Basis hat der Zustand $ \ ket {0 ^ {L} 0 ^ {L}} $ oder der Zustand $ \ ket {1 ^ {L} 1 ^ {L}} $ eine 50-50-Chance. Es sollte beachtet werden, also überprüfen Sie es.

Implementierung

Hier ist der gesamte Python-Code.

from collections import Counter
from qlazypy import Stabilizer

def get_common_qid(obj_A, obj_B):

    return list(set(obj_A['dat']) & set(obj_B['dat']))

def create_lattice(row, col):

    face = [[None]*col for _ in range(row)]
    vertex = [[None]*(col+1) for _ in range(row+1)]

    q_row = 2 * row + 1
    q_col = 2 * col + 1
    q_id = 0
    for i in range(q_row):
        for j in range(q_col):
            if i%2 == 1 and j%2 == 1: # face
                dat = []
                dat.append((i - 1) * q_col + j)  # up
                dat.append((i + 1) * q_col + j)  # down
                dat.append(i * q_col + (j - 1))  # left
                dat.append(i * q_col + (j + 1))  # right
                face[i//2][j//2] = {'anc': q_id, 'dat': dat}
            elif i%2 == 0 and j%2 == 0: # vertex
                dat = []
                if i > 0: dat.append((i - 1) * q_col + j)          # up
                if i < q_row - 1: dat.append((i + 1) * q_col + j)  # down
                if j > 0: dat.append(i * q_col + (j - 1))          # left
                if j < q_col - 1: dat.append(i * q_col + (j + 1))  # right
                vertex[i//2][j//2] = {'anc': q_id, 'dat': dat}
            q_id += 1
            
    return {'face': face, 'vertex': vertex}

def initialize(sb, lattice):

    sb.set_all('Z')
    for face_list in lattice['face']:
        for face in face_list:
            sb.h(face['anc'])
            [sb.cz(face['anc'], target) for target in face['dat']]
            sb.h(face['anc'])
            sb.m(qid=[face['anc']])

    for vertex_list in lattice['vertex']:
        for vertex in vertex_list:
            sb.h(vertex['anc'])
            [sb.cx(vertex['anc'], target) for target in vertex['dat']]
            sb.h(vertex['anc'])
            sb.m(qid=[vertex['anc']])

def create_move_defect_p(sb, pos_A, pos_B, path, lattice):

    # create defect pair
    face_A = lattice['face'][pos_A[0]][pos_A[1]]
    face_B = lattice['face'][pos_B[0]][pos_B[1]]
    q = get_common_qid(face_A, face_B)[0]
    md = sb.h(q).m(qid=[q])
    sb.h(q)
    if md.last == '1': [sb.z(i) for i in face_B['dat']]
 
    # move defect
    chain = [q]
    for i in range(1,len(path)):
        # extend defect
        face_A = lattice['face'][path[i-1][0]][path[i-1][1]]
        face_B = lattice['face'][path[i][0]][path[i][1]]
        q = get_common_qid(face_A, face_B)[0]
        md = sb.h(q).m(qid=[q])
        sb.h(q)
        if md.last == '1': [sb.z(i) for i in face_B['dat']]
                
        # remove defect
        sb.h(face_A['anc'])
        [sb.cz(face_A['anc'], target) for target in face_A['dat']]
        sb.h(face_A['anc'])
        md = sb.m(qid=[face_A['anc']])
        if md.last == '1': [sb.x(i) for i in chain]
            
        chain.append(q)

def create_move_defect_d(sb, pos_A, pos_B, path, lattice):

    # create defect pair
    vertex_A = lattice['vertex'][pos_A[0]][pos_A[1]]
    vertex_B = lattice['vertex'][pos_B[0]][pos_B[1]]
    q = get_common_qid(vertex_A, vertex_B)[0]
    md = sb.m(qid=[q])
    if md.last == '1': [sb.x(i) for i in vertex_B['dat']]
 
    # move defect
    chain = [q]
    for i in range(1,len(path)):
        # extend defect
        vertex_A = lattice['vertex'][path[i-1][0]][path[i-1][1]]
        vertex_B = lattice['vertex'][path[i][0]][path[i][1]]
        q = get_common_qid(vertex_A, vertex_B)[0]
        md = sb.m(qid=[q])
        if md.last == '1': [sb.x(i) for i in vertex_B['dat']]
                
        # remove defect
        sb.h(vertex_A['anc'])
        [sb.cx(vertex_A['anc'], target) for target in vertex_A['dat']]
        sb.h(vertex_A['anc'])
        md = sb.m(qid=[vertex_A['anc']])
        if md.last == '1': [sb.z(i) for i in chain]
            
        chain.append(q)

def get_chain(pos_list, lattice):

    chain = []
    for i in range(1,len(pos_list)):
        pos_A = pos_list[i-1]
        pos_B = pos_list[i]
        chain.append(get_common_qid(lattice['vertex'][pos_A[0]][pos_A[1]],
                                    lattice['vertex'][pos_B[0]][pos_B[1]])[0])
    return chain
    
def measure_logical_Z(sb, face, chain, shots=10):

    mval_list = []
    for _ in range(shots):
        sb_tmp = sb.clone()
        mval_0 = sb_tmp.m(qid=face['dat']).last
        mval_1 = sb_tmp.m(qid=chain).last
        mval = (str(sum([int(s) for s in list(mval_0)])%2)
                + str(sum([int(s) for s in list(mval_1)])%2))
        mval_list.append(mval)
        sb_tmp.free()
    return Counter(mval_list)

if __name__ == '__main__':

    lattice_row = 4
    lattice_col = 6
    lattice = create_lattice(lattice_row, lattice_col)

    # make vacuum state
    qubit_num = (2*lattice_row + 1) * (2*lattice_col + 1)
    sb = Stabilizer(qubit_num=qubit_num)
    initialize(sb, lattice)

    # logical qubit #1
    d_pos_A = [2,1]
    d_pos_B = [2,2]
    d_path = [[2,2],[2,3],[2,4]]
    create_move_defect_d(sb, d_pos_A, d_pos_B, d_path, lattice)

    # logical qubit #0
    p_pos_A = [0,0]
    p_pos_B = [0,1]
    # p_path = [[0,1],[0,2]]
    p_path = [[0,1],[0,2],[1,2],[2,2],[3,2],[3,3],[3,4],[3,5],
              [2,5],[1,5],[0,5],[0,4],[0,3],[0,2]]
    create_move_defect_p(sb, p_pos_A, p_pos_B, p_path, lattice)

    # measure logical qubits: #0 and #1
    face = lattice['face'][p_pos_A[0]][p_pos_A[1]]
    chain = get_chain([[2,1],[2,2],[2,3],[2,4]], lattice)
    freq = measure_logical_Z(sb, face, chain, shots=100)
    print(freq)

    sb.free()

Ich werde erklären, was Sie tun. Schauen Sie sich den Hauptverarbeitungsabschnitt an.

lattice_row = 4
lattice_col = 6
lattice = create_lattice(lattice_row, lattice_col)

Erstellt Gitterinformationen zum Anordnen von Quantenbits. Die als Argumente angegebenen Werte für lattice_row und lattice_col sind die Anzahl der vertikalen Gitter (Flächen) bzw. die Anzahl der horizontalen Gitter (Flächen). Wie Sie anhand des Inhalts der Funktion sehen können, handelt es sich bei den Ausgabedaten um Wörterbuchdaten {'face': face, 'vertex': vertex}. Hier ist Gesicht ein zweidimensionales Array (Liste von Listen), das gemäß der Position des Gesichts angeordnet ist, und seine Elemente sind {'anc': q0, 'dat': [q1, q2, q3, q4]} Es sind die Wörterbuchdaten. anc ist die Nummer des Hilfsquantenbits für die entsprechende Oberfläche und dat ist die Nummer des Datenquantenbits, das sich an der Grenze dieser Oberfläche befindet. Außerdem ist der Scheitelpunkt ein zweidimensionales Array (Liste von Listen), das gemäß der Position der Scheitelpunkte angeordnet ist, und seine Elemente sind dieselben wie die Fläche {'anc': q0, 'dat': [q1, q2, q3, q4 ]} Sind die Wörterbuchdaten. anc ist die Nummer des Hilfsquantenbits für den entsprechenden Scheitelpunkt und dat ist die Nummer des Datenquantenbits, das sich auf der Seite befindet, die mit diesem Scheitelpunkt verbunden ist. Damit haben wir die Gitterinformationen definiert, über die wir ohne Auslassung nachdenken [^ 10]. Einzelheiten finden Sie in der Funktionsdefinition.

[^ 10]: Ich denke, es gibt verschiedene Möglichkeiten, die Rasterinformationen als Daten zu definieren, aber als Ergebnis der Entwicklung meiner eigenen Methode unter Berücksichtigung der Leichtigkeit der späteren Verarbeitung ist dies so Im Wind ist es etwas kompliziert geworden.

Nächster,

# make vacuum state
qubit_num = (2*lattice_row + 1) * (2*lattice_col + 1)
sb = Stabilizer(qubit_num=qubit_num)
initialize(sb, lattice)

Erstellen Sie dann einen Vakuumzustand. Berechnen Sie zunächst die Anzahl der Quantenbits und speichern Sie sie in qubit_num. Die aktuelle Annahme ist 117 Quantenbits. Es ist unmöglich, einen Quantenzustand dieser Skala mit einem Simulator zu berechnen. Aber mach dir keine Sorgen. Da ich dieses rotierende Braidinng ausführen möchte, habe ich qlazy einen Klassenstabilisator hinzugefügt, der Stabilisatorberechnungen durchführt (v.0.1.1). Grundsätzlich kann nur eine Clifford-Operation ausgeführt werden, die Berechnung kann jedoch ohne Einschränkung der Anzahl der Quantenbits durchgeführt werden (sofern der Speicher dies zulässt). Ich werde dies dieses Mal verwenden. Geben Sie dem Argument des Stabilizer-Konstruktors die Anzahl der Quantenbits an, um eine Instanz zu erstellen, und verwenden Sie sie als Variable sb. Im Ausgangszustand sind alle Generatoren Gleichheitsoperatoren. Initialisieren Sie sie daher entsprechend, um einen Vakuumzustand zu erzeugen. Ich mache das mit der Initialisierungsfunktion. In der ersten Zeile der Funktion initialisieren

sb.set_all('Z')

Dies bedeutet jedoch, dass alle Quantenbits auf den Operator $ Z $ gesetzt sind. Das heißt, alle Quantenbits werden mit $ \ ket {0} $ initialisiert. Ein Vakuumzustand wird durch indirektes Messen der Generatoren in der Reihenfolge mit diesem als Ausgangspunkt erzeugt. Führen Sie insbesondere die folgenden Schritte aus:

for face_list in lattice['face']:
    for face in face_list:
        sb.h(face['anc'])
        [sb.cz(face['anc'], target) for target in face['dat']]
        sb.h(face['anc'])
        sb.m(qid=[face['anc']])

Es wird nur der Teil extrahiert, der den Oberflächenoperator misst, aber auch der Teil, der den Scheitelpunktoperator misst, ist derselbe [^ 11].

[^ 11]: Der Einfallsreichtum der zuvor definierten Gitterdaten lebt hier. Die Struktur der Rasterdaten mag etwas verwirrend gewesen sein, aber ich denke, die Implementierung, die sie verwendet, ist relativ leicht zu verstehen und einfach, aber wie wäre es damit?

Sobald das Vakuum vorhanden ist, besteht der nächste Schritt darin, ein logisches Quantenbit durch Pairing und Verschieben von Defekten zu erzeugen. Beginnen Sie zur Vereinfachung der Implementierung mit dem 1. logischen Quantenbit anstelle des 0 ..

# logical qubit #1
d_pos_A = [2,1]
d_pos_B = [2,2]
d_path = [[2,2],[2,3],[2,4]]
create_move_defect_d(sb, d_pos_A, d_pos_B, d_path, lattice)

Hier repräsentieren d_pos_A und d_pos_B jeweils die Scheitelpunktkoordinaten des Defekts vom Typ d, der zuerst gepaart werden soll. Ich denke, es wird einfacher zu verstehen sein, wenn Sie sich auch die Abbildung ansehen, die in der vorherigen Erklärung verwendet wurde. Die Bewegungsrouteninformationen zum Verschieben des gepaarten rechten Defekts sind d_path. Zeigt an, dass sich der Defekt in der Reihenfolge der Scheitelpunktkoordinaten [2,2] -> [2,3] -> [2,4] bewegt. Create_move_defect_d ist eine Funktion, die den Status tatsächlich ändert, indem sb, d_pos_A, d_pos_B und d_path als Argumente verwendet werden. Werfen wir einen Blick auf den Inhalt der Funktion.

# create defect pair
vertex_A = lattice['vertex'][pos_A[0]][pos_A[1]]
vertex_B = lattice['vertex'][pos_B[0]][pos_B[1]]
q = get_common_qid(vertex_A, vertex_B)[0]
md = sb.m(qid=[q])
if md.last == '1': [sb.x(i) for i in vertex_B['dat']]

Erzeugt ein Paar Defekte vom Typ d. Erhalten Sie die gepaarten Scheitelpunktinformationen aus dem Gitter und speichern Sie sie in vertex_A und vertex_B, um die zu messenden Quantenbits an der $ Z $ -Basis zu identifizieren. Rufen Sie die Funktion get_common_qid auf, um die in vertex_A und vertex_B häufig enthaltenen Quantenbitnummern abzurufen (Einzelheiten siehe Funktionsdefinition). Die Variable q ist diese Zahl, also messen Sie sie auf $ Z $ -Basis. Das Messergebnis wird in der Variablen md gespeichert und die letzte Eigenschaft wird zum Messwert. Wenn das Messergebnis $ \ ket {0} $ ist, wird nichts getan, und wenn es $ \ ket {1} $ ist, wird der logische Operator $ X $ verwendet, um den Eigenwert zu invertieren. Dies bedeutet, dass die Fehler gepaart wurden, aber da sie nebeneinander liegen, verschieben Sie einen (nach rechts).

# move defect
chain = [q]
for i in range(1,len(path)):
    # extend defect
    vertex_A = lattice['vertex'][path[i-1][0]][path[i-1][1]]
    vertex_B = lattice['vertex'][path[i][0]][path[i][1]]
    q = get_common_qid(vertex_A, vertex_B)[0]
    md = sb.m(qid=[q])
    if md.last == '1': [sb.x(i) for i in vertex_B['dat']]
                
   # remove defect
   sb.h(vertex_A['anc'])
   [sb.cx(vertex_A['anc'], target) for target in vertex_A['dat']]
   sb.h(vertex_A['anc'])
   md = sb.m(qid=[vertex_A['anc']])
   if md.last == '1': [sb.z(i) for i in chain]
            
   chain.append(q)

Der Inhalt der obigen for-Schleife ist in zwei Teile unterteilt. Die erste Hälfte ist der Teil, der den Fehler gemäß den Bewegungsrouteninformationen um ein Quadrat erweitert, und die zweite Hälfte ist der Teil, der den ursprünglichen Fehler beseitigt. In der ersten Hälfte des expandierenden Teils ist der Scheitelpunkt, der dem ursprünglichen Defekt entspricht, vertex_A, der Scheitelpunkt, der dem expandierenden Defekt entspricht, ist vertex_B, und das beiden gemeinsame Quantenbit wird mit $ Z $ gemessen. Wenn das Messergebnis $ \ ket {0} $ ist, wird nach wie vor nichts unternommen, und wenn es $ \ ket {1} $ ist, wird der logische Operator $ X $ angewendet, um den Eigenwert zu invertieren. In dem letzten zu löschenden Teil wird der Scheitelpunktoperator an der ursprünglichen Fehlerposition wiederhergestellt, so dass der Scheitelpunktoperator gemessen wird. In diesem Fall muss eine indirekte Messung unter Verwendung des Hilfsquantenbits durchgeführt werden, so dass die CNOT-Operation, die auf die vier Datenquantenbits abzielt, aus denen der Scheitelpunktoperator besteht, von Adamar für das Hilfsquantenbit eingeklemmt wird. Dann wird das Hilfsquantenbit basierend auf $ Z $ gemessen, aber wenn das Messergebnis $ \ ket {0} $ ist, wird nichts getan, und wenn es $ \ ket {1} $ ist, wird der Eigenwert invertiert. Aktivieren Sie den logischen Operator $ Z $. Hier ist Kette eine Liste von Quantenbitnummern, die in der Kette enthalten sind, die der sich bewegende Defekt trägt. Da das Tensorprodukt des auf diesem Quantenbit implementierten $ Z $ -Operators zum logischen $ Z $ -Operator wird, wird die Quantenbitnummer bei jeder Verschiebung angehängt und die logische $ Z $ -Operation an diesem Punkt wird korrekt ausgeführt. Ich werde es schaffen. Wenn Sie die Eigenwerte invertieren müssen, verwenden Sie den logischen Operator $ Z $, der auf dieser Kette basiert. Das erste logische Quantenbit befindet sich jetzt im Zustand $ \ ket {0 ^ {L}} $.

Gehen Sie zurück zum Hauptverarbeitungsabschnitt und erstellen Sie dann das 0. logische Quantenbit. Mit anderen Worten, p-Typ-Defekte werden gepaart und verschoben.

# logical qubit #0
p_pos_A = [0,0]
p_pos_B = [0,1]
# p_path = [[0,1],[0,2]]
p_path = [[0,1],[0,2],[1,2],[2,2],[3,2],[3,3],[3,4],[3,5],
          [2,5],[1,5],[0,5],[0,4],[0,3],[0,2]]
create_move_defect_p(sb, p_pos_A, p_pos_B, p_path, lattice)

Hier repräsentieren p_pos_A und p_pos_B die Koordinaten der Fläche, die zuerst die p-Typ-Defekte paart. p_path repräsentiert die Bewegungsrouteninformationen, wenn einer der gepaarten Fehler (nach rechts) verschoben wird. Der auskommentierte p_path ist eine kurze Bewegung, daher ist der resultierende logische Zustand der eindeutige Zustand $ \ ket {+ ^ {L}} $ des logischen $ X $ -Operators. Andererseits bewegt sich der unkommentierte p_path neben der kurzen Bewegung auch um den d-Typ-Defekt (wie Sie sehen können, wenn Sie ihn mit der vorherigen Abbildung vergleichen). Wenn Sie es also längere Zeit verschieben, sollten Sie in der Lage sein, die CNOT-Operation für den logischen Zustand zu realisieren. Führen Sie mit diesen Argumenten die Funktion create_move_defect_p aus, um den Status zu ändern. Der Inhalt der Funktion verhält sich genauso wie der Typ d, daher wird die Erklärung weggelassen.

Messen Sie abschließend die beiden logischen Quantenbits auf der logischen $ Z $ -Basis und zeigen Sie das Ergebnis an.

# measure logical qubits: #0 and #1
face = lattice['face'][p_pos_A[0]][p_pos_A[1]]
chain = get_chain([[2,1],[2,2],[2,3],[2,4]], lattice)
freq = measure_logical_Z(sb, face, chain, shots=100)
print(freq)

Da das 0. logische Quantenbit ein p-Typ-Defekt ist, ist der logische $ Z $ -Operator der $ Z $ -Operator, der einen der Defekte einschließt. Die variable Fläche dient zum Auffinden des Operators $ Z $. Da das erste logische Quantenbit ein Defekt vom Typ d ist, ist der logische $ Z $ -Operator ein $ Z $ -Operator in der Kette, die die beiden Defekte verbindet. Die variable Kette dient zum Speichern der Position des Operators $ Z $. Holen Sie es sich mit der Funktion get_chain. Die Frequenzdaten werden erfasst, indem der Stabilisator sb, face, chain und shot = 100 angegeben wird, die die Anzahl der Messungen als Argumente für die Funktion Measure_logical_Z darstellen. In der Funktion wird die Messung ehrlich basierend auf Gesicht und Kette wiederholt, das Ergebnis wird hochgezählt, Frequenzdaten (Instanz der Python-Standardzählerklasse) werden erstellt und zurückgegeben. das ist alles.

Ergebnis

Lassen Sie uns nun das Ausführungsergebnis zeigen. Betrachten wir zunächst den Fall, in dem das 0. logische Quantenbit nicht umbrochen wird. Kommentieren Sie die im obigen Code auskommentierten Routendaten aus, die eine kurze Strecke zurücklegen, und kommentieren Sie die Routendaten aus, die eine lange Strecke zurücklegen. Mit anderen Worten

p_path = [[0,1],[0,2]]
# p_path = [[0,1],[0,2],[1,2],[2,2],[3,2],[3,3],[3,4],[3,5],
#          [2,5],[1,5],[0,5],[0,4],[0,3],[0,2]]

Ich werde versuchen, es als auszuführen. Dann

Counter({'00': 53, '10': 47})

ist geworden. Das 0. logische Quantenbit ist $ \ ket {+ ^ {L}} $ und das 1. logische Quantenbit ist $ \ ket {0 ^ {L}} $. Mit anderen Worten

\ket{+^{L} 0^{L}} = \frac{1}{\sqrt{2}} (\ket{0^{L} 0^{L}} + \ket{1^{L} 0^{L}})   \tag{21}

Es ist also richtig, dass $ \ ket {0 ^ {L} 0 ^ {L}} $ und $ \ ket {1 ^ {L} 0 ^ {L}} $ mit einer Wahrscheinlichkeit von 50% beobachtet werden. ist.

Betrachten wir dies als den Anfangszustand und betrachten wir dann den Fall, in dem der p-Typ-Defekt den d-Typ-Defekt umgeht und zum Anfangszustand zurückkehrt. Lassen Sie uns den vorherigen Kommentar umkehren und ausführen. Mit anderen Worten

# p_path = [[0,1],[0,2]]
p_path = [[0,1],[0,2],[1,2],[2,2],[3,2],[3,3],[3,4],[3,5],
         [2,5],[1,5],[0,5],[0,4],[0,3],[0,2]]

Bei Ausführung als

Counter({'11': 53, '00': 47})

Das Ergebnis ist. Das ist einfach

\frac{1}{\sqrt{2}} (\ket{0^{L} 0^{L}} + \ket{1^{L} 1^{L}})   \tag{22}

Es ist gleich dem Ergebnis der Messung des Bell-Zustands. So konnte ich bestätigen, dass die CNOT-Operation mit Sicherheit realisiert wurde. Glückwunsch Glückwunsch.

abschließend

Ich wollte irgendwie mit meinen eigenen Händen das interessante Phänomen reproduzieren, dass, wenn Sie einen Defekt in einem Flugzeug erzeugen und ihn um einen anderen Defekt wickeln, dieser zu einer CNOT-Operation wird. Deshalb habe ich diesmal mit der Implementierung einer Stabilisatorformatberechnung begonnen. Als ich es ausprobierte, war es nicht so einfach wie ich erwartet hatte (nur wegen meines Unwissens), zum Beispiel, wie man die Anzahl der unabhängigen Generatoren der Stabilisatoren und eines Bedieners der Stabilisatoren berechnet. Ich war ein wenig besorgt darüber, wie ich feststellen könnte, ob es sich um ein Element handelt (obwohl ich letztendlich die "Sweep-Methode" verwendet habe, um den Rang der Inspektionsmatrix zu berechnen). In Bezug auf die Bewegung von Oberflächencodefehlern steht im Lehrbuch "Measure it", aber es wird nicht einmal angegeben, was zu tun ist, wenn der Eigenwert -1 wird (dh "Zeilenabstand"). "Read it"), aber ich habe beim Schreiben des Programms einen Versuch und Irrtum gemacht (ich habe herausgefunden, dass ich es wie im Text beschrieben tun sollte). Ich habe also unerwartet viel Zeit gebraucht, um diesen Artikel fertigzustellen. Ich bin jedoch froh, dass ich so viel gelernt habe.

Nun, nächstes Mal. Ich habe mich noch nicht entschieden, aber jetzt, da ich die Clifford-Operation in Bezug auf den Oberflächencode realisiert habe, denke ich darüber nach, wie ich als nächstes die logische Nicht-Clifford-Operation realisieren kann.

das ist alles

Recommended Posts

Grundlagen der Quanteninformationstheorie: Logische Operation durch Oberflächencode (Brading)
Grundlagen der Quanteninformationstheorie: Universelle Quantenberechnung durch Oberflächencode (1)
Grundlagen der Quanteninformationstheorie: Topologische Oberflächencodes
Grundlagen der Quanteninformationstheorie: Quantenfehlerkorrektur (Shor Code)
Grundlagen der Quanteninformationstheorie: Quantenfehlerkorrektur (CSS-Code)
Grundlagen der Quanteninformationstheorie: Quantenfehlerkorrektur (Stabilisatorcode: 4)
Grundlagen der Quanteninformationstheorie: Entropie (2)
Grundlagen der Quanteninformationstheorie: Quantenfehlerkorrektur (klassischer linearer Code)
Grundlagen der Quanteninformationstheorie: Datenkomprimierung (1)
Grundlagen der Quanteninformationstheorie: Horebaud-Grenzen
Grundlagen der Quanteninformationstheorie: Spurenentfernung
Grundlagen der Quanteninformationstheorie: Quantenzustands-Tomographie
Grundlagen der Quanteninformationstheorie: Datenkomprimierung (2)
Grundlagen der Quanteninformationstheorie: Fehlertolerante Quantenberechnung
Lesen Sie "Grundlagen des Quantenglühens", Tag 5
Benachrichtigen Sie LINE über Informationen zum Zugbetrieb
Beispiel für das Umschreiben von Code durch ast.NodeTransformer