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.