Anwenden eines Multi-Qubit-Quantengatters auf bestimmte Qubits

9

Eine kontrollierte Nicht-Gate-Matrix sieht folgendermaßen aus:

[1000010000010010]

Das funktioniert gut, wenn Sie nur zwei Qubits haben und das erste Qubit als Steuerelement und das zweite Qubit als Eingang verwenden möchten, der gespiegelt werden soll (oder nicht).

Gibt es eine Methode, um diese Matrix zu konvertieren, um sie beispielsweise zu verwenden, wenn Sie 3 Qubits hatten und Qubit 1 als Steuerung und Qubit 3 als Eingabe verwenden möchten, die möglicherweise umgedreht wird?

Wenn ich logisch darüber nachdenke, kann ich mir Folgendes einfallen lassen:

[1000000001000000001000000001000000000100000010000000000100000010]

Gibt es eine bessere, formalere / allgemeinere Möglichkeit, Multi-Qubit-Gates in bestimmte Qubits umzuwandeln, als das erste in einer Qubit-Schaltung?N.NN

Alan Wolfe
quelle

Antworten:

7

Expand-n-Swap

Wenn Sie ein Gate auf eine Teilmenge der Qubits anwenden möchten:

  • Erweitern Sie die Operationen mit dem Tensorprodukt / Kronecker-Produkt auf x .2n2n
  • Verwenden Sie Swap-Gates , um die Ziel-Qubits aufeinanderfolgend zu machen.
  • Wechseln Sie zu einer einfachen Bestellung, bewerben Sie sich, tauschen Sie zurück.

Es kann mühsam sein, all diese großen Matrixmultiplikationen durchzuführen, aber Swap-Matrizen sind spärlich und die Idee ist sehr einfach.

Die Steuerung ist einfacher

Wenn Sie einer Operation Steuerelemente hinzufügen (dies gilt für das von Ihnen angegebene Beispiel), gibt es einen einfacheren Trick. Erweitern Sie einfach die Operation wie gewohnt, und ersetzen Sie dann alle Teile der Matrix, die Eingaben mit Steuerungsfehlern entsprechen, durch die Identitätsmatrix.

Dies ist etwas einfacher zu verfolgen, wenn Sie einen gefälschten "Kontrollwert" einführen , der das übliche Verhalten des Tensorprodukts überschreibtc , sodass anstelle von Sie haben (mit anderen Worten: Wenn ein Eintrag ist, Sie über den Eintrag und skalieren nach dem Eintrag, den Sie verwenden statt ).[c]U=cU[c]U=cIcUUIU

Definieren Sie die "Operation" eines Qubit-Must-Be-ON-Steuerelements als . A no-op ist , und ein NICHT ist . Dann könnte die Operation aus Ihrer Frage folgendermaßen berechnet werden (unter der Annahme einer Big-Endian-Ordnung):C=[c001]IX

CNOT31=CIX

=[c001][1001][0110]

=[c[1001]0[1001]0[1001]1[1001]][0110]

=[[c00c][0000][0000][1001]][0110]

=[c0000c0000100001][0110]

(Hinweis: Verwenden Sie eine einzelne Null, um eine 2x2-Nullmatrix mehrdeutig zu bezeichnen, wo dies zweckmäßig ist.)

=[c[0110]0000c[0110]0000[0110]0000[0110]]

=[[c00c]0000[c00c]0000[0110]0000[0110]]

=[c00000000c00000000c00000000c000000000100000010000000000100000010]

(Jetzt sind wir mit den Tensorprodukten fertig und brauchen die nicht mehr.)c

[1000000001000000001000000001000000000100000010000000000100000010]

Sinn ergeben?

Craig Gidney
quelle
8

Verwenden Sie nicht die Swap-Methode, sie ist sehr ineffizient. Und die Antwort der anderen Person ist spezifisch für das CNOT-Gate, und um ehrlich zu sein, die Dinge werden zu kompliziert.

Hier ist ein sehr einfacher Algorithmus, der Ihr Problem für jeden einzelnen Fall löst, nicht nur für das CNOT-Gatter, für beliebige Bits.

Der Algorithmus:

let sys = matrix representing the current state of the system
let n = number of qubits being simulated
let lgm = logic gate matrix of size 2^n by 2^n
let f = our logic gate transformation function
for i = 0 to (2^n) - 1:
    lgm[column = i] = f(i)
sys = sys × lgg

In klassischen Computern gibt es etwas, das als "Decoder" bekannt ist. Nehmen wir an, ich habe nur 3 Drähte, effektiv 3 Bits. Aber ich möchte 8 Drähte steuern. Kann das gemacht werden? Ja, da 3 Bits 8 verschiedene Möglichkeiten haben: 000, 001, 010, 011, 100, 101, 110, 111. Wir können also jede Möglichkeit einem unserer 8 Ausgangsdrähte zuordnen. Dies wird als "Decodierung" bezeichnet.

Wenn ich die Nummer 101 übergebe und wir 3 Bits haben, wissen wir 101 = 5, also setze ich die Ausgangsleitung 5 auf eine hohe Spannung und die anderen 7 Ausgangsleitungen sind 0, was wir wie folgt darstellen können: decodieren (101) = [0, 0, 0, 0, 0, 1, 0, 0].

In diesem Algorithmus erwähne ich die "Transformationsfunktion" namens "f". Bei klassischen Computern nimmt die Transformationsfunktion lediglich einen Eingabewert auf und gibt die "decodierte" Version des Ausgabewerts zurück. Wenn wir also 3 Bits haben und die Ausgabe 4 ist, geben wir [0, 0, 0, 0, 1, 0, 0, 0] zurück. Wir weisen das dann als Spalte unserer Matrix für diesen Wert zu.

Denken wir an "Decodieren" in Qubits. Wie können wir die Qubits | 101> dekodieren?

Wir wissen, dass für unsere Qubit-Wahrscheinlichkeitsvektoren | 0> [1, 0] und | 1> [0, 1] ist. Das Dekodieren von Qubits kann dann durchgeführt werden, was als Kronecker-Produkt bezeichnet wird.

Wenn wir also jedes Bit in das Wahrscheinlichkeitsvektoräquivalent konvertieren und das Kronecker-Produkt von allen nehmen, erhalten wir ...

|101> = |1> ⊗ |0> ⊗ |1> = [0, 1] ⊗ [1, 0] ⊗ [0, 1] = [0, 0, 0, 0, 0, 1, 0, 0]

So möchten wir Qubits dekodieren. Dieser Algorithmus kann auf diese Weise auf Qubits angewendet werden.

Versuchen wir diesen Algorithmus an einem einfacheren Problem.

Nehmen wir an, wir haben ein System mit nur 2 Qubits. Wenn wir das Hadamard-Gatter auf nur 1 Qubit anwenden möchten, können wir für beide Qubits ein Logikgatter erzeugen, das das Hadamard-Gatter nur auf ein einzelnes Qubit anwendet. Nehmen wir an, das einzelne Qubit, auf das wir es anwenden möchten, ist unser höchstwertiges Qubit, und das niedrigstwertige ist davon nicht betroffen.

Wir wollen eine Transformationsfunktion, die für jede unserer möglichen Eingaben die richtige Ausgabe erzeugt. Wir haben zwei Qubits, das heißt, es gibt vier mögliche Ausgänge.

f(|00>) = ?
f(|01>) = ?
f(|10>) = ?
f(|11>) = ?

Wir wissen, dass das niedrigstwertige Qubit nicht betroffen sein wird, also können wir das ausfüllen.

f(|00>) = ? ⊗ |0>
f(|01>) = ? ⊗ |1>
f(|10>) = ? ⊗ |0>
f(|11>) = ? ⊗ |1>

Wir wissen auch, was der Hadamard mit einem Qubit macht, so dass:

H(|0>) = 1/sqrt(2)|0> + 1/sqrt(2)|1>
H(|1>) = 1/sqrt(2)|0> - 1/sqrt(2)|1>

Unsere Transformationsfunktion lautet also einfach:

f(|00>) = (1/sqrt(2)|0> + 1/sqrt(2)|1>) ⊗ |0>
f(|01>) = (1/sqrt(2)|0> + 1/sqrt(2)|1>) ⊗ |1>
f(|10>) = (1/sqrt(2)|0> - 1/sqrt(2)|1>) ⊗ |0>
f(|11>) = (1/sqrt(2)|0> - 1/sqrt(2)|1>) ⊗ |1>

Erweitern Sie dies auf unsere normalisierte Wahrscheinlichkeitsvektorform ...

f(|00>) = [ 1/sqrt(2), 1/sqrt(2) ] ⊗ [ 1, 0 ]
f(|01>) = [ 1/sqrt(2), 1/sqrt(2) ] ⊗ [ 0, 1 ]
f(|10>) = [ 1/sqrt(2), -1/sqrt(2) ] ⊗ [ 1, 0 ]
f(|11>) = [ 1/sqrt(2), -1/sqrt(2) ] ⊗ [ 0, 1 ]

Lassen Sie uns das nun tatsächlich lösen ...

f(|00>) = [ 1/sqrt(2), 0, 1/sqrt(2), 0 ]
f(|01>) = [ 0, 1/sqrt(2), 0, 1/sqrt(2) ]
f(|10>) = [ 1/sqrt(2), 0, -1/sqrt(2), 0 ]
f(|11>) = [ 0, 1/sqrt(2), 0, -1/sqrt(2) ]

Das ist unsere Transformationsfunktion.

Unsere Logikgatter-Matrix "lgm" hat die Größe 2 ^ n mal 2 ^ n, wobei n = Anzahl der simulierten Qubits ist, also in diesem Fall 2 ^ 2 mal 2 ^ 2 oder 4x4. Unser Algorithmus sagt uns, dass wir für jede Spalte i die Spalte gleich f (i) setzen. Wir haben unsere Wahrscheinlichkeitstransformationsfunktion definiert, damit wir diese Spalten problemlos ausfüllen können.

lgm = 
    |00>       |01>        |10>        |11>
[ 1/sqrt(2),         0,  1/sqrt(2),          0 ] 
[         0, 1/sqrt(2),          0,  1/sqrt(2) ]
[ 1/sqrt(2),         0, -1/sqrt(2),          0 ]
[         0, 1/sqrt(2),          0, -1/sqrt(2) ]

Der letzte Schritt in unserem Algorithmus besteht einfach darin, unsere Matrix, die das gesamte Quantensystem sys darstellt, mit diesem Logikgatter lgm zu multiplizieren.

Und das macht was wir wollen. Das Hadamard-Gate wird nur auf das meiste Qubit angewendet und das niedrigstwertige Qubit in Ruhe gelassen. Wenn Sie mir nicht glauben, können Sie es selbst versuchen und sehen, dass es funktioniert.

Der Grund, warum dies so mächtig ist, ist, dass es auf jeden Fall gilt.

Versuchen wir diesen Algorithmus für Ihr Problem.

Stellen Sie sich vor, wir haben ein 3-Qubit-System und möchten ein CNOT-Gatter auf Qubit [0] und Qubit [2] anwenden. Wenn Sie die CNOT-Matrix auf Wikipedia nachschlagen, gilt diese Matrix nur für ein 2-Qubit-System. Eine naive Lösung wäre, Identitätsmatrizen mit dem Kronecker-Produkt anzuhängen, damit es auf Systemen mit drei Qubits funktioniert. Dies schlägt hier jedoch fehl: Qubit [0] und Qubit [2] sind nicht benachbart, sodass das einfache Anhängen von Identitätsmatrizen nicht funktioniert.

Wir könnten Qubit [0] mit Qubit [1] tauschen, das CNOT-Gate anwenden und sie dann zurück tauschen. Aber das ist langsam. Stattdessen könnten wir einfach ein nicht benachbartes CNOT-Gatter für unser Problem unter Verwendung des obigen Algorithmus erzeugen.

Wir müssen zuerst für jeden Fall eine Transformationsfunktion entwickeln.

f(|000>) = |0> ⊗ |0> ⊗ |0>
f(|001>) = |0> ⊗ |0> ⊗ |1>
f(|010>) = |0> ⊗ |1> ⊗ |0>
f(|011>) = |0> ⊗ |1> ⊗ |1>
f(|100>) = |1> ⊗ |0> ⊗ |1>
f(|101>) = |1> ⊗ |0> ⊗ |0>
f(|110>) = |1> ⊗ |1> ⊗ |1>
f(|111>) = |1> ⊗ |1> ⊗ |0>

Wenn Sie das CNOT-Gate verstehen, können Sie verstehen, warum dies unsere Funktion ist. Stellen Sie sich das wie eine Wahrheitstabelle vor. Da unser Kontroll-Qubit das höchstwertige Qubit Qubit [2] ist, wird das niedrigstwertige Qubit Qubit [0] nur dann negiert, wenn dieses Qubit | 1> ist.

Erweitern Sie dies auf unsere normalisierte Wahrscheinlichkeitsvektorform ...

f(|000>) = [ 1, 0 ] ⊗ [ 1, 0 ] ⊗ [ 1, 0 ]
f(|001>) = [ 1, 0 ] ⊗ [ 1, 0 ] ⊗ [ 0, 1 ]
f(|010>) = [ 1, 0 ] ⊗ [ 0, 1 ] ⊗ [ 1, 0 ]
f(|011>) = [ 1, 0 ] ⊗ [ 0, 1 ] ⊗ [ 0, 1 ]
f(|100>) = [ 0, 1 ] ⊗ [ 1, 0 ] ⊗ [ 0, 1 ]
f(|101>) = [ 0, 1 ] ⊗ [ 1, 0 ] ⊗ [ 1, 0 ]
f(|110>) = [ 0, 1 ] ⊗ [ 0, 1 ] ⊗ [ 0, 1 ]
f(|111>) = [ 0, 1 ] ⊗ [ 0, 1 ] ⊗ [ 1, 0 ]

Lassen Sie uns das nun tatsächlich lösen ...

f(|000>) = [ 1, 0, 0, 0, 0, 0, 0, 0 ]
f(|001>) = [ 0, 1, 0, 0, 0, 0, 0, 0 ]
f(|010>) = [ 0, 0, 1, 0, 0, 0, 0, 0 ]
f(|011>) = [ 0, 0, 0, 1, 0, 0, 0, 0 ]
f(|100>) = [ 0, 0, 0, 0, 0, 1, 0, 0 ]
f(|101>) = [ 0, 0, 0, 0, 1, 0, 0, 0 ]
f(|110>) = [ 0, 0, 0, 0, 0, 0, 0, 1 ]
f(|111>) = [ 0, 0, 0, 0, 0, 0, 1, 0 ]

Machen wir diese zu den Spalten unserer lgm-Matrix.

lgm =
[ 1, 0, 0, 0, 0, 0, 0, 0 ]
[ 0, 1, 0, 0, 0, 0, 0, 0 ]
[ 0, 0, 1, 0, 0, 0, 0, 0 ]
[ 0, 0, 0, 1, 0, 0, 0, 0 ]
[ 0, 0, 0, 0, 0, 1, 0, 0 ]
[ 0, 0, 0, 0, 1, 0, 0, 0 ]
[ 0, 0, 0, 0, 0, 0, 0, 1 ]
[ 0, 0, 0, 0, 0, 0, 1, 0 ]

Wenn nun die Matrix unsere gesamte Systemmatrix sys mit unserer Logikgattermatrix lgm multipliziert, ist unser Ergebnis der Effekt der Anwendung des CNOT-Gatters auf Qubit [2] und Qubit [0], wobei Qubit [2] die Steuerung ist Qubit.

Amelia Hartman
quelle
Vielen Dank, dass Sie am Ende ein Beispiel hinzugefügt haben. es war sehr hilfreich. Können Sie auch eine Definition des Kronecker-Produkts angeben? (Ich denke auch, dass Sie es vielleicht einmal als "Kornecker" falsch geschrieben haben.)
Pro Q
1
Ich empfehle dies für das Kronecker-Produkt: youtube.com/watch?v=e1UJXvu8VZk
Amelia Hartman