Zum Hauptinhalt springen

Qiskit-Implementierung

In der vorherigen Lektion haben wir einen ersten Blick auf die Klassen Statevector und Operator in Qiskit geworfen und sie verwendet, um Operationen und Messungen auf einzelnen Qubits zu simulieren. In diesem Abschnitt nutzen wir diese Klassen, um das Verhalten mehrerer Qubits zu untersuchen.

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit
from qiskit import __version__

print(__version__)
2.1.1

Wir beginnen damit, die Klassen Statevector und Operator sowie die Quadratwurzelfunktion aus NumPy zu importieren. Von nun an kümmern wir uns generell zu Beginn jeder Lektion um alle nötigen Importe.

from qiskit.quantum_info import Statevector, Operator
from numpy import sqrt

Tensorprodukte

Die Klasse Statevector hat eine tensor-Methode, die das Tensorprodukt dieses Statevector mit einem anderen zurückgibt, der als Argument übergeben wird. Das Argument wird als der rechte Tensorfaktor interpretiert.

Im folgenden Beispiel erstellen wir zwei Zustandsvektoren für 0\vert 0\rangle und 1\vert 1\rangle und nutzen die tensor-Methode, um einen neuen Vektor ψ=01\vert \psi\rangle = \vert 0\rangle \otimes \vert 1\rangle zu erzeugen. Beachte, dass wir hier die Methode from_label verwenden, um die Zustände 0\vert 0\rangle und 1\vert 1\rangle zu definieren, anstatt sie manuell anzugeben.

zero = Statevector.from_label("0")
one = Statevector.from_label("1")
psi = zero.tensor(one)
display(psi.draw("latex"))

01 |01\rangle

Weitere erlaubte Labels sind "+" und "-" für die Plus- und Minuszustände sowie "r" und "l" (kurz für „right" und „left") für die Zustände

+i=120+i21undi=120i21.\vert {+i} \rangle = \frac{1}{\sqrt{2}} \vert 0 \rangle + \frac{i}{\sqrt{2}} \vert 1 \rangle \qquad\text{und}\qquad \vert {-i} \rangle = \frac{1}{\sqrt{2}} \vert 0 \rangle - \frac{i}{\sqrt{2}} \vert 1 \rangle.

Hierbei stammen „+", „-" bzw. „right" und „left" aus dem Kontext des quantenmechanischen Spins, bei dem eine Spin-Komponente in einem Experiment nach links oder rechts zeigen kann; es geht nicht um das rechts- oder linksstehende Qubit in Systemen mit mehreren Qubits. Hier ist ein Beispiel für das Tensorprodukt von +\vert {+} \rangle und i.\vert {-i} \rangle.

plus = Statevector.from_label("+")
minus_i = Statevector.from_label("l")
phi = plus.tensor(minus_i)
display(phi.draw("latex"))

1200i201+1210i211\frac{1}{2} |00\rangle- \frac{i}{2} |01\rangle+\frac{1}{2} |10\rangle- \frac{i}{2} |11\rangle

Alternativ kann der ^-Operator für Tensorprodukte verwendet werden, der erwartungsgemäß dieselben Ergebnisse liefert.

display((plus ^ minus_i).draw("latex"))

1200i201+1210i211\frac{1}{2} |00\rangle- \frac{i}{2} |01\rangle+\frac{1}{2} |10\rangle- \frac{i}{2} |11\rangle

Die Klasse Operator hat ebenfalls eine tensor-Methode (sowie eine from_label-Methode), wie die folgenden Beispiele zeigen.

H = Operator.from_label("H")
Id = Operator.from_label("I")
X = Operator.from_label("X")
display(H.tensor(Id).draw("latex"))
display(H.tensor(Id).tensor(X).draw("latex"))
[220220022022220220022022] \begin{bmatrix} \frac{\sqrt{2}}{2} & 0 & \frac{\sqrt{2}}{2} & 0 \\ 0 & \frac{\sqrt{2}}{2} & 0 & \frac{\sqrt{2}}{2} \\ \frac{\sqrt{2}}{2} & 0 & - \frac{\sqrt{2}}{2} & 0 \\ 0 & \frac{\sqrt{2}}{2} & 0 & - \frac{\sqrt{2}}{2} \\ \end{bmatrix} [02200022002200022000000220002200220002200220002200220002200000022000220022000220] \begin{bmatrix} 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 \\ \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 \\ 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} \\ 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 \\ 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 & 0 \\ \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 & 0 & 0 \\ 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} \\ 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 \\ \end{bmatrix}

Wie bei den Vektoren ist auch hier der ^-Operator äquivalent.

display((H ^ Id ^ X).draw("latex"))
[02200022002200022000000220002200220002200220002200220002200000022000220022000220] \begin{bmatrix} 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 \\ \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 \\ 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} \\ 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 \\ 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 & 0 \\ \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 & 0 & 0 \\ 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} \\ 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 \\ \end{bmatrix}

Zusammengesetzte Zustände können mit zusammengesetzten Operationen entwickelt werden, genau wie man es erwartet – genauso wie wir es für Einzelsysteme in der vorherigen Lektion gesehen haben. Der folgende Code berechnet zum Beispiel den Zustand (HI)ϕ(H\otimes I)\vert\phi\rangle für ϕ=+i\vert\phi\rangle = \vert + \rangle \otimes \vert {-i}\rangle (der bereits oben definiert wurde).

display(phi.evolve(H ^ Id).draw("latex"))

22002i201\frac{\sqrt{2}}{2} |00\rangle- \frac{\sqrt{2} i}{2} |01\rangle

Hier ist Code, der eine CXCX-Operation definiert und CXψCX \vert\psi\rangle für ψ=+0\vert\psi\rangle = \vert + \rangle \otimes \vert 0 \rangle berechnet. Es handelt sich um eine CXCX-Operation, bei der das linke Qubit das Kontroll-Qubit und das rechte Qubit das Ziel-Qubit ist. Das Ergebnis ist der Bell-Zustand ϕ+.\vert\phi^{+}\rangle.

CX = Operator([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]])
psi = plus.tensor(zero)
display(psi.evolve(CX).draw("latex"))

2200+2211\frac{\sqrt{2}}{2} |00\rangle+\frac{\sqrt{2}}{2} |11\rangle

Partielle Messungen

In der vorherigen Lektion haben wir die measure-Methode genutzt, um eine Messung eines Quantenzustandsvektors zu simulieren. Diese Methode gibt zwei Werte zurück: das simulierte Messergebnis und den neuen Statevector nach dieser Messung.

Standardmäßig misst measure alle Qubits im Zustandsvektor. Alternativ kann eine Liste von ganzen Zahlen als Argument übergeben werden, wodurch nur die Qubits mit diesen Indizes gemessen werden. Um dies zu demonstrieren, erstellt der folgende Code den Zustand

w=001+010+1003\vert w\rangle = \frac{\vert 001\rangle + \vert 010\rangle + \vert 100\rangle}{\sqrt{3}}

und misst Qubit Nummer 0, also das rechtsstehende Qubit. (Qiskit nummeriert Qubits beginnend bei 0, von rechts nach links. Auf diese Nummerierungskonvention kommen wir in der nächsten Lektion zurück.)

w = Statevector([0, 1, 1, 0, 1, 0, 0, 0] / sqrt(3))
display(w.draw("latex"))

result, state = w.measure([0])
print(f"Measured: {result}\nState after measurement:")
display(state.draw("latex"))

result, state = w.measure([0, 1])
print(f"Measured: {result}\nState after measurement:")
display(state.draw("latex"))

33001+33010+33100\frac{\sqrt{3}}{3} |001\rangle+\frac{\sqrt{3}}{3} |010\rangle+\frac{\sqrt{3}}{3} |100\rangle

Measured: 0
State after measurement:

22010+22100\frac{\sqrt{2}}{2} |010\rangle+\frac{\sqrt{2}}{2} |100\rangle

Measured: 00
State after measurement:

100 |100\rangle