Edukacja

Bramki kwantowe


Bramki kwantowe to elementarne jednostki służące do programowania komputerów kwantowych. Każda bramka kwantowa może oddziaływać na jeden lub więcej kubitów. Bramki kwantowe operujące na jednym kubicie są reprezentowane przez macierze (operatory liniowe) o rozmiarach 2\times2, a bramki działające na dwóch kubitach poprzez macierze 4\times4.

Matematycznie, działanie wykonywane przez bramkę kwantową na kubicie jest niczym innym jak mnożeniem wektora stanu kubitu przez macierz odpowiadającą danej bramce. Wszystkie bramki kwantowe muszą zachowywać normę (gwarantować, że po aplikacji prawdopodobieństwa stanów bazowych wciąż będą sumować się do jedynki), czyli ich macierze muszą być unitarne.

Do najprostszych i najpopularniejszych bramek kwantowych należy bramka X zapisana jako macierz:

    \[X = \begin{bmatrix} 0 & 1\\ 1 & 0 \end{bmatrix}\]

Jest odpowiednikiem klasycznej bramki NOT. Jej przykładowe użycie na kubicie w stanie |\psi\rangle = \alpha|0\rangle + \beta|1\rangle obrazują obliczenia:

    \[X |\psi\rangle = \begin{bmatrix} 0 & 1\\ 1 & 0 \end{bmatrix} \begin{bmatrix} \alpha \\ \beta \end{bmatrix} =  \begin{bmatrix} \beta\\ \alpha \end{bmatrix}\]

W poniższej komórce z kodem znajduje się krótki program definiujący obwód kwantowy. Na jednym kubicie zainicjalizowanym (domyślnie) stanem |0\rangle stosuje operację X, a następnie odczytuje wynik.

from qiskit import QuantumCircuit

#utworzenie obwodu kwantowego z jednym kubitem
qc = QuantumCircuit(1)
# dodanie bramki X do kubitu 0
qc.x(0)
# dodanie operacji pomiaru kubitu
qc.measure_all()
# rysowanie schematu obwodu kwantowego
qc.draw()Code language: Python (python)

Kolejnym etapem jest odczyt wyniku obwodu kwantowego. W tym przypadku, dla prostego obwodu, wynik będzie deterministyczny. Dlatego można sprawdzić wynik pojedynczego uruchomienia obwodu. W tym przypadku jednokrotnie została zmierzona wartość 1, co jest spodziewanym wynikiem po zastosowaniu operacji NOT na stanie wejściowym |0\rangle.

from qiskit.primitives import StatevectorSampler

# Tworzenie Samplera wykonującego dokładne obliczenia na wektorach stanu 
sampler = StatevectorSampler()
# Wykonanie 128 pomiarów na przygotowanym obwodzie
job = sampler.run([qc], shots=128)
# Zapisanie wyników symulacji
result = job.result()[0]
# Wyświetlanie uzyskanego rozkładu
print("The counts are: ", result.data.meas.get_counts())Code language: Python (python)

Po uruchomieniu powyższego kodu otrzymamy następującą informację:

The counts are:  {'1': 128}Code language: Shell Session (shell)

Ponieważ zazwyczaj stany mają charakter probabilistyczny, często do wizualizacji wyników używa się histogramu rozkładu zmierzonych wartości. Dla tego prostego przypadku, w którym wynik jest deterministyczny (np. po zastosowaniu operacji NOT na stanie |0\rangle, histogram będzie zawierał pojedynczą wartość. W bardziej złożonych obwodach histogram może zawierać wiele wartości odpowiadających różnym wynikom z różnymi prawdopodobieństwami tak jak na poniższym przykładzie.