Bramki jednokubitowe
Podstawowe bramki jednokubitowe
Znasz już bramkę Hadamarda, bramkę \(X\) oraz bramki rotacji (\(R_x\), \(R_y\), \(R_z\))
Dla przypomnienia :
Bramka \(X\):
\[ \textbf{X} = \begin{bmatrix} 0 \,\, 1 \\ 1 \,\, 0 \end{bmatrix} \]
\[ \textbf{X} \ket{0} = \begin{bmatrix} 0\,\, 1 \\ 1 \, 0 \end{bmatrix} \begin{bmatrix} 1 \\ 0 \end{bmatrix} = \begin{bmatrix} 0 \\ 1 \end{bmatrix} = \ket{1} \] oraz \[ \textbf{X} \ket{0} = \begin{bmatrix} 0\,\, 1 \\ 1 \, 0 \end{bmatrix} \begin{bmatrix} 0 \\ 1 \end{bmatrix} = \begin{bmatrix} 1 \\ 0 \end{bmatrix} = \ket{0} \]
Bramka \(H\):
\[ \textbf{H}= \frac{1}{\sqrt{2}}\begin{bmatrix} 1\,\,\,\,\,\,\, 1 \\ 1 \, -1 \end{bmatrix} \]
dla której
\[ \textbf{H} \ket{0} = \frac{1}{\sqrt{2}}\begin{bmatrix} 1\,\,\,\,\,\,\, 1 \\ 1 \, -1 \end{bmatrix} \begin{bmatrix} 1 \\ 0 \end{bmatrix} = \frac{1}{\sqrt{2}} \left( \ket{0} + \ket{1} \right) = \ket{+} \] oraz \[ \textbf{H} \ket{1} = \frac{1}{\sqrt{2}}\begin{bmatrix} 1\,\,\,\,\,\,\, 1 \\ 1 \, -1 \end{bmatrix} \begin{bmatrix} 0 \\ 1 \end{bmatrix} = \begin{bmatrix} 0 \\ 1 \end{bmatrix} = \frac{1}{\sqrt{2}} \left( \ket{0} - \ket{1} \right) = \ket{-} \]
Losowy bit
klasycznie
# generator liczb losowych
from random import randrange
''.join([str(randrange(2)) for i in range(8)])
lub
# mozna takze zrealizowac jako rzut monetą
import random
for n in range(5):
if random.random()<0.5: #if the random number is less than 0.5 print heads
print('HEADS')
else:
print('TAILS')
KWANTOWO
Użyj
default.qubit
jako klasyczny symulator w funkcjidevice
zmień funkcję
qc
w obwód kwantowy korzystając z dekoratora@qml.qnode
zdefinuj funkcję
qc
z jednym kubitemna kubicie wykorzystaj bramkę Hadamarda
wyświetl stan po pomiarze pojedynczego kubitu
wyświetl prawdopodobieństwa otrzymania stanu 0 i 1
uruchom obwód 3 razy (do dev dodaj parametr , shots=3) i sprawdź wyniki otrzymywane przez metodę
qml.counts()
linkuruchom powyzszą prcedurę 100 razy
Do jakiego zdarzenia losowego podobne są wyniki?
Losowy bajt
bajt to 8 bitów - jaki zakres wartości jesteś w stanie przechowywać w 8 kubitach ?
wygeneruj losowy bajt z wykorzystaniem tylko bramki X
if randrange(2) == 0:
qc.x(i)
wygeneruj losowy bajt z wykorzystaniem bramek hadamarda
wygeneruj 10 prób w pełni losowego bajtu - odkoduj wyniki w systemie int
oblicz różnicę dwóch bajtów dla których pierwsze cztery bity to 0, piąty bit pierwszego bajtu to 0 a drugiego bajtu to 1 . pozostałe bity są równe 1
Losowa liczba w zakresie 0-15
Za pomocą odpowiedniego obwodu kwantowego wylosuj liczbę z zakresu 0-15
Wykorzystaj 1000 wykonań modelu i narysuj histogram wyników dla poszczególnych liczb 0-15
Wartość oczekiwana operatora Z na obwodzie
Rozszerz wygenerowany obwód dla losowego bitu i dodaj parametryzowaną bramkę \(R_x\) z kątem ustawionym jako pi/4
Oblicz wartość oczekiwaną operatora \(<\sigma_z>\) wykorzystując qml.expval(qml.PauliZ(0))
Bramka (i operator) Z, w bazie obliczeniowej dany jest macierzą: \[ \textbf{Z} = \begin{bmatrix} 1 \,\,\,\,\,\,\,\, 0 \\ 0 \,\, -1 \end{bmatrix} \]
Operator ten mierzy różnicę pomiędzy prawdopodobieństwem, że kubit jest w stanie \(\ket{0}\) a prawdopodobieństwem, że jest w stanie \(\ket{1}\)
W ogólności wartość oczekiwana (wartość średnia wyniku pomiaru w bazie operatora Z) dana jest wzorem: \[ \textbf{<Z>} = \bra{\psi} \textbf{Z} \ket{\psi} \]
Niech \[ \ket{\psi} = \alpha\ket{0} + \beta\ket{1} \] wtedy \[ \bra{\psi} = \alpha^*\bra{0} + \beta^*\bra{1} \]
Możemy obliczyć: \[ \bra{\psi} \textbf{Z} \ket{\psi} = (\alpha^*\bra{0} + \beta^*\bra{1} ) \,\,\, Z \,\,\,(\alpha\ket{0} + \beta\ket{1}) = |\alpha|^2 - |\beta|^2 \] Czyli dla kubitu w stanie \(\ket{0}\) \[ \textbf{<Z>} = 1 \] Dla kubitu w stanie \(\ket{1}\) \[ \textbf{<Z>} = -1 \] Dla kubitu w superpozycji \(\ket{0} +\ket{1}\) \[ \textbf{<Z>} = 0 \]
Gra w obracanie monety
Wykorzystując powyżej zdefiniowane bramki możemy zrealizowa następującą grę:
W grze bierze udział dwóch graczy. Gracze dysponują monetą, której nie widzą w trakcie gry (np. jest zamknięta w pudełku). Natomiast wiedzą, że początkowo moneta ułożona jest orłem do góry (w stanie \(\ket{0}\)) Gra polega na wykonaniu trzech ruchów na przemian. Każdy ruch polega na odwróceniu monety bądź pozostawieniu jej w takim stanie w jakim była. Gracze nie wiedzą jaki ruch wykonuje przeciwnik. Po ostatnim ruchu pudełko zostaje otwarte i gracze sprawdzają w jakiej pozycji jest moneta. Pierwszy gracz wygrywa jeśli moneta jest w pozycji orła, a drugi jeśli przeciwnie.
Szansa wygranej wynosi dla każdego \(50\%\) i jak można sprawdzic nie istnieje strategia wygrywająca.
Zweryfikuj powyższy wynik wykorzystując obwód kwantowy.
def klasycze_strategie():
= []
wyniki for ruch_1 in ['I','X']:
for ruch_2 in ['I','X']:
for ruch_3 in ['I','X']:
= ruch_1 + ruch_2 + ruch_3
strategia = obwod(strategia)
ob = sedzia(ob())
stats
wyniki.append((strategia, stats))return wyniki
Utwórz odpowiedni obwód parametryzowany stringiem “strategia” oraz dodaj funkcję sędziego.
Obracanie monety przypadek kwantowy
Możliwe operacje pozostawienia kubitu w takim samym stanie - bramka I, zmiany stanu na przeciwny bramka X.
Czyli pierwszy gracz ustala pierwszą bramkę, drugi drugą i ponownie pierwszy trzecią. Otwarcie pudełka to pomiar stanu kubitu.
Przeanalizuj wynik dla sekwencji I X I
A co jeśli pierwszy gracz wie, że działa na kubicie?
Czy może sprawic on, że wygra zawsze? (skoro wie, że działa na kubicie może użyc innych bramek)
zmodyfikuj kod obwodu i sprawdź strategię w której pierwszy gracz zawsze użyje dwóch bramek Hadamarda.
def kwantowa_strategia():
= []
wyniki for ruch_1 in ['H']:
for ruch_2 in ['I','X']:
for ruch_3 in ['H']:
= ruch_1 + ruch_2 + ruch_3
strategia = obwod(strategia)
ob = sedzia(ob())
stats
wyniki.append((strategia, stats))return wyniki