Implementacja w Qiskit
W poprzedniej lekcji zapoznałeś się po raz pierwszy z klasami Statevector i Operator w Qiskit i użyłeś ich do symulowania operacji oraz pomiarów na pojedynczych qubitach.
W tej sekcji użyjemy tych klas, żeby zbadać zachowanie wielu qubitów.
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit
from qiskit import __version__
print(__version__)
2.1.1
Zaczniemy od zaimportowania klas Statevector i Operator oraz funkcji pierwiastka kwadratowego z NumPy.
Od tej pory, co do zasady, będziemy dbać o to, żeby wszystkie wymagane importy znajdowały się na początku każdej lekcji.
from qiskit.quantum_info import Statevector, Operator
from numpy import sqrt
Iloczyny tensorowe
Klasa Statevector ma metodę tensor, która zwraca iloczyn tensorowy danego Statevector z innym, podanym jako argument.
Argument jest interpretowany jako czynnik tensorowy po prawej stronie.
Na przykład poniżej tworzymy dwa wektory stanu reprezentujące i i używamy metody tensor, żeby utworzyć nowy wektor
Zauważ, że używamy tutaj metody from_label do zdefiniowania stanów i zamiast definiować je ręcznie.
zero = Statevector.from_label("0")
one = Statevector.from_label("1")
psi = zero.tensor(one)
display(psi.draw("latex"))
Inne dozwolone etykiety to „+" i „-" dla stanów plus i minus, a także „r" i „l" (skróty od „right" i „left") dla stanów
Tutaj „+", „-" lub „right" i „left" pochodzą z kontekstu kwantowomechanicznego spinu, w którym składowa spinu może wskazywać w lewo lub w prawo w doświadczeniu; nie chodzi tu o skrajnie prawy lub skrajnie lewy qubit w układach wieloqubitowych. Oto przykład iloczynu tensorowego i
plus = Statevector.from_label("+")
minus_i = Statevector.from_label("l")
phi = plus.tensor(minus_i)
display(phi.draw("latex"))
Alternatywą jest użycie operatora ^ do iloczynów tensorowych, który naturalnie daje te same wyniki.
display((plus ^ minus_i).draw("latex"))
Klasa Operator ma również metodę tensor (a także metodę from_label), co widać w poniższych przykładach.
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"))
Podobnie jak w przypadku wektorów, operator ^ jest równoważny.
display((H ^ Id ^ X).draw("latex"))
Złożone stany można ewoluować za pomocą złożonych operacji dokładnie tak, jak można by się spodziewać — podobnie jak widzieliśmy dla pojedynczych układów w poprzedniej lekcji. Na przykład poniższy kod oblicza stan dla (który został już zdefiniowany powyżej).
display(phi.evolve(H ^ Id).draw("latex"))
Oto kod, który definiuje operację i oblicza dla Żeby było jasne, jest to operacja , w której qubit po lewej stronie jest qubit kontrolny, a qubit po prawej stronie jest qubit docelowy. Wynikiem jest stan Bella
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"))
Pomiary cząstkowe
W poprzedniej lekcji użyliśmy metody measure do symulowania pomiaru wektora stanu kwantowego.
Metoda ta zwraca dwie rzeczy: symulowany wynik pomiaru oraz nowy Statevector po tym pomiarze.
Domyślnie measure mierzy wszystkie qubity w wektorze stanu.
Możemy alternatywnie podać listę liczb całkowitych jako argument, co powoduje, że mierzone są tylko qubity o tych indeksach.
Żeby to zademonstrować, poniższy kod tworzy stan
i mierzy qubit numer 0, czyli qubit skrajnie prawy. (Qiskit numeruje qubity począwszy od 0, od prawej do lewej. Wrócimy do tej konwencji numerowania w następnej lekcji.)
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"))
Measured: 0
State after measurement:
Measured: 00
State after measurement: