Symulator komputera kwantowego
Napisz mały obwód kwantowy w JavaScript, uruchom symulację bezpośrednio w przeglądarce i zobacz schemat, prawdopodobieństwa oraz wektor stanu. Możesz też opisać obliczenie na wysokim poziomie, na przykład dodawanie, i obserwować, jak automatycznie powstaje rzeczywisty odwracalny obwód kwantowy.
Model szumu
Rzeczywiste komputery kwantowe nie obliczają idealnie: kubity są wyjątkowo wrażliwe i tracą część informacji wskutek każdej niepożądanej interakcji z otoczeniem — ciepłem, polami elektromagnetycznymi czy sąsiednimi kubitami. Operacje bramek również nigdy nie są doskonale precyzyjne, a nawet końcowy odczyt może być błędny. Domyślnie ten symulator oblicza idealnie; tutaj możesz włączyć typowe modele błędów i bezpośrednio obserwować ich wpływ na wyniki.
Opisz obliczenie za pomocą quantum.add, quantum.subtract, quantum.multiply, quantum.divide albo quantum.random. Ctrl+Enter uruchamia symulację. Pełna dokumentacja jest dostępna pod przyciskiem „Dokumentacja”.
Ten kod został automatycznie wygenerowany z powyższego kodu programu i bezpośrednio zasymulowany. Możesz go tutaj ręcznie edytować i uruchomić ponownie.
Wygenerowany obwód został ręcznie zmieniony. Grupowanie rejestrów na schemacie jest dlatego ukryte; ponowne uruchomienie powyższego kodu programu zastąpi te zmiany.
Maksymalnie 4000 znaków. Dostępne metody QuantumCircuit: x, y, z, h, s, sdg, t, tdg, rx, ry, rz, cnot, cz, ccnot (alias: toffoli), swap, measureAll, run. Ctrl+Enter uruchamia symulację.
Schemat obwodu
Widok krokowy pokazuje prawdopodobieństwa i wektor stanu dokładnie po wybranej bramce. Poniższe wyniki prób zawsze dotyczą całego obwodu.
OpenQASM 2.0
OpenQASM 2.0 jest powszechnie stosowanym formatem wymiany obwodów kwantowych, odczytywanym między innymi przez Qiskit. Uwaga o kolejności bitów: ten symulator odczytuje q0 jako najbardziej znaczący, lewy bit, natomiast Qiskit traktuje q[0] jako bit najmniej znaczący — zmierzone ciągi bitów wyglądają tam zatem jak odbicie lustrzane.
Prawdopodobieństwa
Prawdopodobieństwo zmierzenia każdego możliwego ciągu bitów, obliczone dokładnie z wektora stanu. Kierunek odczytu: q0 jest lewym, najbardziej znaczącym bitem.
Sfery Blocha
Stan każdego pojedynczego kubitu jako strzałka na sferze Blocha: biegun północny = |0⟩, biegun południowy = |1⟩, równik = superpozycja o równych wagach. Gdy strzałka jest wyraźnie krótsza od promienia sfery, kubit nie ma własnego stanu czystego — jest splątany z innymi kubitami. Krótka strzałka może również wynikać z szumu: przy aktywnym modelu szumu kubit traci koherencję, a strzałka kurczy się do środka. Zaszumione sfery są tutaj przybliżeniem — wektor Blocha uśrednia się po trajektoriach szumu. W powyższym widoku krokowym strzałki poruszają się bramka po bramce, wyłącznie bez szumu.
Wyniki prób
Rzeczywista liczba wystąpień każdego ciągu bitów w symulowanych pomiarach. Przy kilku możliwych wynikach liczby losowo odchylają się od dokładnych prawdopodobieństw.
Wektor stanu
Amplitudy zespolone stojące za prawdopodobieństwami: kwadrat modułu amplitudy (część rzeczywista² + część urojona²) daje prawdopodobieństwo jej stanu.
| Stan | Część rzeczywista | Część urojona |
|---|
Podstawy: jak to działa?
Od programu do fizycznego kubitu
Prawdziwy komputer kwantowy to coś więcej niż układ scalony. Klasyczna elektronika sterująca przekształca obwód w precyzyjne impulsy. W pokazanym przykładzie lasery chłodzące, repompujące, sterujące kubitem i odczytujące kształtują te sygnały na stole optycznym i kierują je do ekranowanej komory próżniowej. Tam zmieniają i mierzą stan kubitu, po czym wynik pomiaru wraca do komputera klasycznego.
Kubit i stany bazowe
Klasyczny bit ma wartość 0 albo 1. Kubit może ponadto znajdować się w superpozycji dwóch stanów bazowych |0⟩ i |1⟩. Przy kilku kubitach wszystkie stany bazowe zapisuje się jako ciąg bitów, na przykład |10⟩ dla 2 kubitów — przy czym q0 w tym symulatorze jest zawsze najbardziej znaczącym, lewym bitem.
Superpozycja
Kubit w superpozycji jednocześnie zawiera składowe kilku stanów bazowych. Składowe te opisują amplitudy zespolone; kwadrat modułu amplitudy daje prawdopodobieństwo uzyskania odpowiadającego jej stanu w pomiarze.
Sfera Blocha
Stan pojedynczego kubitu można przedstawić jako strzałkę na sferze: biegun północny oznacza |0⟩, biegun południowy |1⟩, a wszystkie punkty na równiku są superpozycjami o równych wagach — faza określa kierunek na równiku, w który wskazuje strzałka. Bramki obrotu rx, ryi rz obracają strzałkę wokół odpowiedniej osi, a bramki fazowe, takie jak S i T, obracają ją wokół osi Z. Przy splątanych kubitach strzałka kurczy się w kierunku środka sfery: pojedynczy kubit nie ma już własnego stanu czystego — splątanie staje się więc dosłownie widoczne.
Pomiar i próby
measureAll() mierzy wszystkie kubity jednocześnie i kończy obwód. Ponieważ pojedynczy pomiar daje tylko jeden losowy wynik, obwód jest pojęciowo mierzony wielokrotnie, zgodnie z liczbą „shots”, za pomocą run({ shots }), dzięki czemu rozkład prawdopodobieństwa staje się widoczny jako histogram. Dokładne prawdopodobieństwa są dodatkowo obliczane bezpośrednio z wektora stanu, niezależnie od losowości prób.
Bramka Hadamarda
Bramka Hadamarda h(q) przekształca kubit ze stanu określonego (|0⟩ albo |1⟩) w superpozycję o równych wagach stanów |0⟩ i |1⟩ — czyli w pomiarze około 50% / 50%.
Bramki fazowe: S i T
Bramki s(q) i t(q) nie zmieniają prawdopodobieństw pomiaru pojedynczego kubitu; obracają jedynie fazę amplitudy |1⟩ — S o 90°, a T o 45°. Ich działanie ujawnia się dopiero w połączeniu z superpozycją: między dwiema bramkami Hadamarda faza decyduje, jak amplitudy się łączą lub wzajemnie znoszą, czyli interferują. Warianty dagger sdg(q) i tdg(q) obracają dokładnie w przeciwnym kierunku i cofają działanie S oraz T. Reguła brzmi: dwie bramki T tworzą S, a dwie S tworzą Z.
CNOT i warunkowe splątanie
Bramka CNOT cnot(control, target) odwraca kubit docelowy dokładnie wtedy, gdy kubit sterujący znajduje się w stanie |1⟩. Jeśli kubit sterujący był wcześniej w superpozycji, może to utworzyć splątanie — obu kubitów nie można już wtedy opisywać niezależnie, jak w przykładzie stanu Bella. Jeżeli kubit sterujący jest natomiast w określonym stanie bazowym, CNOT wykonuje jedynie warunkowe odwrócenie bitu bez splątania. Nie każda bramka CNOT automatycznie tworzy więc splątanie.
CZ: symetryczny krewny CNOT
Bramka CZ cz(a, b) odwraca znak amplitudy dokładnie wtedy, gdy oba kubity są w stanie |1⟩. W przeciwieństwie do CNOT nie ma kubitu sterującego ani docelowego — bramka działa identycznie na oba kubity, dlatego na schemacie jest przedstawiana jako dwie połączone kropki. CZ i CNOT można przekształcać wzajemnie: CNOT to CZ, którego kubit docelowy przechodzi przez bramkę Hadamarda przed i po operacji. CZ jest głównym elementem wielu algorytmów, na przykład wyszukiwania Grovera.
Stan GHZ: splątanie trzech kubitów
Stan GHZ, nazwany od nazwisk Greenbergera, Horne'a i Zeilingera, rozszerza zasadę stanu Bella na trzy kubity: jedna bramka Hadamarda i dwie CNOT splątują wszystkie trzy tak, że pomiar daje wyłącznie |000⟩ albo |111⟩ — nigdy mieszane ciągi bitów. Żaden kubit nie ma już własnego stanu; informacja znajduje się wyłącznie we wspólnej korelacji.
Algorytm Deutscha: najmniejsza przewaga kwantowa
Algorytm Deutscha po jednym wywołaniu nieznanej wyroczni odpowiada na pytanie, do którego komputer klasyczny potrzebuje dwóch wywołań: czy funkcja jest stała, czy zrównoważona? Sztuczka polega na przesłaniu wejścia przez wyrocznię w superpozycji — dzięki interferencji odpowiedź zostaje następnie jednoznacznie zakodowana w kubicie wejściowym. Stojąca za tym zasada, zwana odrzutem fazowym, stanowi rdzeń niemal wszystkich algorytmów kwantowych.
Wyszukiwanie Grovera: wzmacnianie amplitud
Wyszukiwanie Grovera znajduje oznaczony element w nieposortowanym zbiorze za pomocą znacznie mniejszej liczby zapytań niż rozwiązanie klasyczne. Wyrocznia oznacza szukany stan zmianą fazy, tutaj przez bramkę CZ, a następnie operator dyfuzji wzmacnia oznaczoną amplitudę kosztem wszystkich pozostałych. Przy 2 kubitach jedna iteracja wystarcza, aby zmierzyć trafienie z prawdopodobieństwem 100%.
Odwracalne dodawanie: od quantum.add() do obwodu
Powyższy edytor kodu programu przekształca quantum.add({ a, b }) w obwód bramek X, CNOT i CCNOT (Toffoliego), który odtwarza klasyczne dodawanie w sposób całkowicie odwracalny: każdą bramkę można dokładnie cofnąć, ponieważ żadna informacja nie jest odrzucana. Bramka CCNOT (ccnot(c1, c2, target)) odwraca kubit docelowy tylko wtedy, gdy oba kubity sterujące są w stanie |1⟩ — to wystarcza jako element konstrukcyjny do odwracalnego odtworzenia dowolnego obwodu klasycznego, w tym pełnego sumatora z przeniesieniem. Wejścia A i B są najpierw inicjalizowane jako określone stany bazowe, bez superpozycji, za pomocą bramek X. Ponieważ cały obwód przechodzi wyłącznie przez stany określone, a nie superpozycje, końcowy pomiar daje dokładnie jeden wynik z prawdopodobieństwem 100% — klasycznie poprawną sumę. Dlatego quantum.add() mimo symulacji kwantowej daje wynik deterministyczny, a nie kilka możliwych stanów o prawdopodobieństwach niższych niż 100%.
Odejmowanie: dodawanie od końca
Ponieważ każda bramka obwodu kwantowego jest dokładnie odwracalna, cały obwód sumatora można wykonać od końca — wtedy dodawanie staje się odejmowaniem: quantum.subtract({ a, b }) wykorzystuje dokładnie te same bramki sumatora w odwróconej kolejności i oblicza w ten sposób a − b. Nie jest to sztuczka, lecz podstawowa zasada obliczeń odwracalnych: żaden krok nie niszczy informacji i każdy można cofnąć. Ta wersja wymaga a ≥ b, aby nie powstał wynik ujemny.
Mnożenie: quantum.multiply()
Mnożenie powstaje tutaj z dokładnie tych samych odwracalnych elementów co dodawanie: zgodnie z metodą pisemną czynnik a jest wielokrotnie dodawany na przesuniętych pozycjach odpowiadających ustawionym bitom czynnika b. Każde dodawanie cząstkowe jest takim samym odwracalnym sumatorem z przeniesieniem szeregowym; przeniesienie za każdym razem przechodzi do następnego bitu iloczynu. Ponieważ rejestr wyniku rośnie wraz z iloczynem, czynniki są tutaj ograniczone do 3 bitów (0–7) — tylko wtedy czynnik, iloczyn i kubit przeniesienia mieszczą się razem w 10 kubitach symulatora.
Dzielenie: quantum.divide()
Dzielenie również wykorzystuje wyłącznie odwracalne elementy: quantum.divide({ a, b }) wykonuje dzielenie pisemne zbudowane z przesuniętych, odwracalnych odejmowań dzielnika od rejestru reszty; wynikiem jest iloraz i reszta (a = quotient · b + remainder). Ponieważ dzielna, dzielnik, iloraz oraz kubit pożyczki muszą razem zmieścić się w 10 kubitach, dzielenie jest najbardziej ograniczoną operacją: bits(a) + bits(b) + bits(a÷b) + 1 ≤ 10 musi być spełnione, a dzielnik b musi być ≥ 1, ponieważ nie można dzielić przez zero. Jeśli dane wejściowe nie mieszczą się w budżecie, edytor zgłasza to zamiast wykonywać obliczenie.
Prawdziwa losowość: quantum.random()
Klasyczne komputery nie potrafią generować prawdziwej losowości — ich „liczby losowe” pochodzą z algorytmów deterministycznych, czyli pseudolosowych. Komputer kwantowy potrafi: quantum.random({ bits }) wprowadza każdy bit w superpozycję 50/50 za pomocą bramki Hadamarda i dopiero pomiar w fundamentalnie nieprzewidywalny sposób rozstrzyga, jaka wartość powstanie. Na rzeczywistym sprzęcie kwantowym jest to fizycznie prawdziwa losowość; ten symulator naśladuje ją za pomocą pseudolosowości przeglądarki.
Symulator a rzeczywisty sprzęt kwantowy
Ten symulator dokładnie oblicza stan za pomocą klasycznej arytmetyki zmiennoprzecinkowej w przeglądarce — jest to możliwe tylko dlatego, że rozpatruje wyłącznie bardzo małe obwody, do 10 kubitów. Rzeczywiste komputery kwantowe wykorzystują fizyczne kubity, są podatne na błędy, dekoherencję i szum, a ich przewaga pojawia się dopiero przy znacznie większych obwodach, których w praktyce nie można już symulować klasycznie. To narzędzie edukacyjne, a nie prawdziwy procesor kwantowy.