Komputery kwantowe nie są już urządzeniami teoretycznymi. Najlepsze zastosowania nowej technologii niekoniecznie są odkrywane przez jej wynalazców, ale przez ekspertów dziedziny, którzy eksperymentują z nią jako nowym narzędziem w swojej pracy. Mając to na uwadze, niniejszy tekst jest praktycznym przewodnikiem dla programistów na temat korzystania z technologii obliczeń kwantowych. W kolejnych częściach zapoznasz się z symbolami i operacjami, takimi jak te na rysunku, i nauczysz się, jak stosować je do problemów, na których Ci zależy.



Wypróbowanym i przetestowanym podejściem do opanowania nowych paradygmatów programowania jest nauczenie się zestawu pojęciowych podstaw. Na przykład każdy, kto uczy się programowania w GPU, powinien najpierw skupić się na opanowaniu koncepcji równoległości, a nie na składni lub specyfice sprzętowej. Sedno tego tekstu skupia się na budowaniu intuicji dla zestawu kwantowych podstaw - pomysłów tworzących zestaw bloków konstrukcyjnych do rozwiązywania problemów za pomocą QPU. Aby przygotować Cię na to, najpierw przedstawimy podstawowe pojęcia kubitów (jeśli chcesz, zasady gry). Następnie, po nakreśleniu zestawu podstaw jednostek przetwarzania kwantowego (QPU), pokazujemy, jak można ich używać jako bloków konstrukcyjnych w użytecznych aplikacjach QPU. W konsekwencji mamy trzy części. Zachęcamy czytelnika do zapoznania się z częścią I i zdobycia praktycznego doświadczenia przed przejściem do bardziej zaawansowanych części:

Część I: Programowanie QPU

Tutaj przedstawiamy podstawowe pojęcia wymagane do zaprogramowania QPU, takie jak kubity, podstawowe instrukcje, wykorzystanie superpozycji, a nawet teleportacja kwantowa. Podano przykłady, które można łatwo uruchomić za pomocą symulatorów lub fizycznego QPU.

Część II: Podstawy QPU

Druga część zawiera szczegółowe informacje na temat niektórych podstawowych algorytmów i technik na wyższym poziomie. Obejmują one amplitudę, kwantową transformatę Fouriera i estymację fazy. Można je traktować jako "funkcje biblioteczne", które programiści wywołują w celu tworzenia aplikacji. Zrozumienie, jak działają, jest niezbędne, aby zostać wykwalifikowanym programistą QPU. Aktywna społeczność naukowców pracuje nad opracowaniem nowych prymitywów QPU, więc spodziewaj się, że ta biblioteka będzie się rozwijać w przyszłości.

Część III: Aplikacje QPU

Świat aplikacji QPU - które łączą podstawy z Części II w celu wykonywania użytecznych zadań w świecie rzeczywistym - ewoluuje tak szybko, jak same QPU. Tutaj przedstawiamy przykłady istniejących aplikacji. Mamy nadzieję, że pod koniec czytelnik zrozumie, co potrafią aplikacje kwantowe, co czyni je potężnymi i jak zidentyfikować rodzaje problemów, które mogą rozwiązać.



Część 1 : Wstęp

Niezależnie od tego, czy jesteś ekspertem w dziedzinie inżynierii oprogramowania, grafiki komputerowej, nauki o danych, czy po prostu ciekawym komputerofilem, ten tekst ma na celu pokazanie, jak moc obliczeń kwantowych może być dla ciebie istotna, umożliwiając ci faktycznie rozpoczęcie ich używania. Aby to ułatwić, kolejne części nie zawierają dokładnych wyjaśnień fizyki kwantowej (praw leżących u podstaw obliczeń kwantowych) ani nawet teorii informacji kwantowej (jak te prawa określają nasze zdolności przetwarzania informacji). Zamiast tego przedstawiają praktyczne przykłady zapewniające wgląd w możliwości tej ekscytującej nowej technologii. Większość, co ważne, kod, który przedstawiamy w tych przykładach, można modyfikować i dostosowywać. Pozwala to uczyć się od nich w najbardziej efektywny sposób: poprzez zdobycie praktycznych umiejętności. Po drodze podstawowe pojęcia są wyjaśniane w miarę ich używania i tylko w takim zakresie, w jakim budują intuicję pisania programów kwantowych. Mamy skromną nadzieję, że zainteresowani czytelnicy będą mogli wykorzystać te spostrzeżenia, aby zastosować i rozszerzyć zastosowania obliczeń kwantowych w dziedzinach, o których fizycy mogli nawet nie słyszeć. Trzeba przyznać, że nadzieja na pomoc w wywołaniu rewolucji kwantowej nie jest taka pokorna, ale bycie pionierem jest zdecydowanie ekscytujące.

Wymagane tło

Fizyka leżąca u podstaw obliczeń kwantowych jest pełna gęstej matematyki. Ale z drugiej strony fizyka stoji za tranzystorem, a mimo to nauka C++ nie musi obejmować pojedynczego równania fizycznego. Przyjmujemy podobne podejście zorientowane na programistę, omijając wszelkie istotne podstawy matematyczne. To powiedziawszy, oto krótka lista wiedzy, która może być pomocna w przetrawieniu pojęć, które wprowadzamy:

•  Znajomość programowania struktur sterujących (if, while, itp.). Używamy JavaScript , aby zapewnić łatwy dostęp do próbek, które można uruchomić online. Jeśli dopiero zaczynasz korzystać z JavaScript, ale masz już pewne doświadczenie w programowaniu, poziom potrzebnego Ci tła prawdopodobnie zostanie podniesiony w mniej niż godzinę.

•  Trochę odpowiedniej matematyki na poziomie programisty, wymagająca:

-Zrozumienie korzystania z funkcji matematycznych

-Znajomość funkcji trygonometrycznych

-Wygoda manipulowania liczbami binarnymi i konwersji między reprezentacjami binarnymi i dziesiętnymi

-Zrozumienie podstawowego znaczenia liczb zespolonych

•  Bardzo elementarne zrozumienie sposobu oceny złożoności obliczeniowej algorytmu (tj. notacja Big-O).

Jedną z części, która wykracza poza te wymagania, jest Część 13, w którym omawiamy szereg zastosowań obliczeń kwantowych w uczeniu maszynowym. Ze względu na ograniczenia przestrzenne nasza ankieta daje tylko bardzo pobieżne wprowadzenie do każdej aplikacji uczenia maszynowego, zanim pokaże, w jaki sposób komputer kwantowy może zapewnić przewagę. Chociaż zamierzamy, aby treść była zrozumiała dla zwykłego czytelnika, ci, którzy chcą naprawdę eksperymentować z tymi aplikacjami, skorzystają na nieco większym zapleczu uczenia maszynowego. Nasz tekst dotyczy programowania (nie budowania ani badania) komputerów kwantowych, dlatego możemy obejść się bez zaawansowanej matematyki i teorii kwantów. Jednak dla zainteresowanych zbadaniem bardziej akademickiej literatury na ten temat, Część 14 zawiera dobre początkowe odniesienia i łączy pojęcia, które wprowadzamy z notacjami matematycznymi powszechnie używanymi przez społeczność badaczy komputerów kwantowych.

Co to jest QPU?

Pomimo swojej wszechobecności, termin "komputer kwantowy" może być nieco mylący. Przywołuje obrazy całkowicie nowego i obcego rodzaju maszyny - maszyny, która zastępuje wszystkie istniejące oprogramowanie komputerowe futurystyczną alternatywą. Jest to powszechne, choć ogromne, błędne przekonanie. Obietnica komputerów kwantowych nie wynika z tego, że są zabójcami konwencjonalnych komputerów, ale raczej z ich zdolności do radykalnego rozszerzenia rodzajów problemów, które można rozwiązać w komputerach. Istnieją ważne problemy obliczeniowe, które można łatwo obliczyć na komputerze kwantowym, ale byłoby to dosłownie niemożliwe na żadnym możliwym standardowym urządzeniu obliczeniowym, jakie moglibyśmy kiedykolwiek zbudować. Ale co najważniejsze, tego rodzaju przyspieszenia zaobserwowano tylko w przypadku pewnych problemów (z których wiele wyjaśnimy później) i chociaż przewiduje się, że zostanie odkrytych więcej, jest bardzo mało prawdopodobne, aby kiedykolwiek miało sens przeprowadzanie wszystkich obliczeń na komputerze kwantowym. W przypadku większości zadań, które zajmują cykle zegara laptopa, komputer kwantowy nie działa lepiej. Innymi słowy - z punktu widzenia programisty - komputer kwantowy jest tak naprawdę koprocesorem. W przeszłości komputery korzystały z wielu różnych koprocesorów, z których każdy był dostosowany do ich własnych specjalizacji, takich jak arytmetyka zmiennoprzecinkowa, przetwarzanie sygnałów i grafika w czasie rzeczywistym. Mając to na uwadze, będziemy używać terminu QPU (Quantum Processing Unit) w odniesieniu do urządzenia, na którym działają nasze próbki kodu. Uważamy, że wzmacnia to ważny kontekst, w którym należy umieścić obliczenia kwantowe. Podobnie jak w przypadku innych koprocesorów, takich jak GPU (Graphics Processing Unit), programowanie QPU polega na pisaniu przez programistę kodu, który będzie działał głównie na CPU (Central Processing Unit) normalnego komputera. CPU wydaje polecenia koprocesorowi QPU tylko w celu zainicjowania zadań dostosowanych do jego możliwości.

Kod debugowania

Debugowanie programów QPU może być trudne. Dość często najłatwiejszym sposobem zrozumienia działania programu jest powolne przechodzenie przez niego, sprawdzanie wizualizacji na każdym kroku. Najeżdżając kursorem myszy na wizualizator obwodu, powinieneś zobaczyć pionową pomarańczową linię w ustalonym miejscu oraz szarą pionową linię w każdym miejscu obwodu, w którym znajduje się kursor. Pomarańczowa linia pokazuje, które położenie w obwodzie (a tym samym w programie) jest obecnie reprezentowane przez wizualizator ruchu kołowego. Domyślnie jest to koniec programu, ale klikając inne części obwodu, można wyświetlić w programie wizualizator cyrklenotacji konfigurację jednostki QPU w tym miejscu. Na przykład rysunek pokazuje, jak zmienia się wizualizator notacji kołowej, gdy przełączamy się między dwoma różnymi krokami w domyślnym programie QCEngine



Mając dostęp do symulatora QPU, prawdopodobnie chcesz zacząć majsterkować. Nie pozwól nam Cię powstrzymać! W Części 2 omówimy kod coraz bardziej złożonych programów QPU.

Natywne instrukcje QPU

QCEngine jest jednym z kilku narzędzi, które pozwalają nam uruchamiać i sprawdzać kod QPU, ale jak właściwie wygląda kod QPU? Konwencjonalne języki wysokiego poziomu są powszechnie używane do kontrolowania instrukcji QPU niższego poziomu (jak to już widzieliśmy w przypadku opartego na JavaScript silnika QCE). Będziemy regularnie przechodzić między tymi poziomami. Opisanie programowania QPU z wyraźnie kwantowymi operacjami na poziomie maszyny pomaga nam uporać się z podstawową, nowatorską logiką QPU, jednocześnie widząc, jak manipulować tymi operacjami z konwencjonalnych języków wyższego poziomu, takich jak JavaScript, Python lub C++, bardziej pragmatyczny paradygmat faktycznego pisania kodu. Definicja nowych, szytych na miarę, kwantowych języków programowania jest aktywnym obszarem rozwoju. Nie będziemy ich podkreślać w tej książce, ale odniesienia dla zainteresowanych czytelników znajdują się w Części 14.

Ograniczenia symulatora

Chociaż symulatory oferują fantastyczną możliwość prototypowania małych programów QPU, w porównaniu z prawdziwymi QPU są beznadziejnie słabe. Jedną z miar mocy jednostki QPU jest liczba kubitów, na których może on działać (kwantowy odpowiednik bitów, o którym wkrótce będziemy mieli znacznie więcej do powiedzenia). Aktualny rekord największej symulacji QPU wynosi 51 kubitów. W praktyce symulatory i sprzęt dostępny dla większości czytelników będą zazwyczaj w stanie obsłużyć około 26 kubitów przed zgrzytem do zatrzymania. Przykłady zostały napisane z myślą o tych ograniczeniach. Stanowią świetny punkt wyjścia, ale każdy dodany do nich kubit podwaja ilość pamięci wymaganej do uruchomienia symulacji, zmniejszając jej szybkość o połowę.

Ograniczenia sprzętowe I odwrotnie, największy rzeczywisty sprzęt QPU dostępny w tym momencie ma około 70 fizycznych kubitów, podczas gdy największy dostępny publicznie QPU, za pośrednictwem zestawu programistycznego Qiskit open source, zawiera 16 fizycznych kubitów. Pod względem fizycznym, w przeciwieństwie do logicznego, rozumiemy, że te 70 kubitów nie ma korekcji błędów, przez co są hałaśliwe i niestabilne. Kubity są znacznie bardziej kruche niż ich konwencjonalne odpowiedniki; najmniejsza interakcja z otoczeniem może zakłócić obliczenia. Praca z kubitami logicznymi pozwala programiście być niezależnym od sprzętu QPU i implementować dowolny podręcznikowy algorytm bez martwienia się o określone ograniczenia sprzętowe. Skupiamy się wyłącznie na programowaniu za pomocą logicznych kubitów i chociaż przykłady, które podajemy, są wystarczająco małe, aby można je było uruchomić na mniejszych jednostkach QPU (takich jak te dostępne w momencie publikacji), oderwanie fizycznych szczegółów sprzętu oznacza, że umiejętności a intuicja, którą rozwiniesz, pozostanie bezcenna w miarę rozwoju sprzętu w przyszłości.

QPU a GPU: kilka wspólnych cech

Pomysł na zaprogramowanie zupełnie nowego rodzaju procesora może być onieśmielający, nawet jeśli ma już własną społeczność Stack Exchange. Oto lista istotnych faktów na temat programowania QPU:

•  Bardzo rzadko zdarza się, że program działa w całości na QPU. Zwykle program działający na CPU wydaje instrukcje QPU, a później pobiera wyniki.

•  Niektóre zadania są bardzo dobrze dopasowane do QPU, a inne nie.

•  QPU działa na niezależnym zegarze procesora i zwykle ma własne dedykowane interfejsy sprzętowe do urządzeń zewnętrznych (takich jak wyjścia optyczne).

•  Typowy QPU ma własną specjalną pamięć RAM, do której procesor nie może efektywnie uzyskać dostępu.

•  Prosty QPU to jeden układ, do którego ma dostęp laptop, a może nawet obszar w innym układzie. Bardziej zaawansowany QPU to duży i drogi dodatek, który zawsze wymaga specjalnego chłodzenia.

•  Wczesne QPU, nawet proste, są wielkości lodówek i wymagają specjalnych gniazd zasilania o wysokim natężeniu.

•  Po zakończeniu obliczeń projekcja wyniku jest zwracana do procesora, a większość wewnętrznych danych roboczych QPU jest odrzucana.

•  Debugowanie QPU może być bardzo trudne i wymaga specjalnych narzędzi i technik. Przechodzenie przez program może być trudne i często najlepszym podejściem jest wprowadzenie zmian w programie i obserwowanie ich wpływu na wynik.

•  Optymalizacje, które przyspieszają jeden QPU, mogą spowolnić inny.

Brzmi dość trudno. Ale o to chodzi - możesz zamienić QPU na GPU w każdym z tych stwierdzeń i nadal są one całkowicie aktualne. Chociaż QPU to prawie obca technologia o niesamowitej mocy, jeśli chodzi o problemy, z którymi możemy się spotkać podczas nauki ich programowania, całe pokolenie inżynierów oprogramowania widziało to wszystko już wcześniej. Prawdą jest, oczywiście, że istnieją pewne niuanse programowania QPU, które są naprawdę nowatorskie (w przeciwnym razie ta książka nie byłaby potrzebna!), Ale niesamowita liczba podobieństw powinna uspokajać. Możemy to zrobić!

Programowanie dla QPU

Czym właściwie jest kubit? Jak możemy go sobie wyobrazić? Jak to jest przydatne? To krótkie pytania ze skomplikowanymi odpowiedziami. W pierwszej części odpowiemy na te pytania w praktyczny sposób. Rozpoczynamy , najpierw opisując i wykorzystując pojedynczy kubit. Omówimy dodatkową złożoność systemów wielokubitowych .Po drodze napotkamy szereg operacji jedno- i wielokubitowych, a później przedstawimy je bezpośrednio w użyciu, opisując sposób wykonywania teleportacji kwantowej. Należy pamiętać, że przykłady kodu, które przerywają naszą dyskusję, można uruchomić w Symulatorze QCEngine, przy użyciu dostarczonych linków.

Jeden Qubit

Konwencjonalne bity mają jeden parametr binarny do zabawy - możemy zainicjować bit w stanie 0 lub stanie 1. To sprawia, że matematyka logiki binarnej jest wystarczająco prosta, ale możemy wizualnie przedstawić możliwe wartości 0/1 bitu przez dwa oddzielne puste / wypełnione kółka



Teraz przejdźmy do kubitów. W pewnym sensie kubity są bardzo podobne do bitów: za każdym razem, gdy odczytujesz wartość kubitu, zawsze otrzymasz 0 lub 1. Tak więc po odczycie kubitu zawsze możemy go opisać, jak pokazano powyżej. Jednak charakteryzowanie kubitów przed odczytem nie jest tak czarno-białe i wymaga bardziej wyrafinowanego opisu. Przed odczytem kubity mogą istnieć w superpozycji stanów. Wkrótce postaramy się zająć, czym jest superpozycja. Aby jednak najpierw dać ci wyobrażenie, dlaczego może być potężny, zwróć uwagę, że istnieje nieskończona liczba możliwych superpozycji, w których pojedynczy kubit może istnieć przed odczytaniem. W poniższej Tabeli wymieniono tylko niektóre z różnych superpozycji, w których moglibyśmy przygotować kubit. Chociaż zawsze odczytujemy na końcu 0 lub 1, jeśli jesteśmy sprytni, to dostępność tych dodatkowych stanów będzie pozwalają nam wykonywać bardzo potężne obliczenia.









UWAGA : Matematycznie w drugiej tabeli zmieniliśmy nasze etykiety z 0 i 1 na ?0⟩ i ?1⟩. Nazywa się to notacją bra-ket i jest powszechnie stosowana w komputerach kwantowych. Przyjmuje się, że liczby zawarte w notacji bra-ket oznaczają wartości, którymi może być kubit znaleziony podczas odczytu. Odnosząc się do wartości, dla której odczytano kubit, po prostu używamy liczby do reprezentowania wynikowej wartości cyfrowej.

Pierwsze dwa wiersze w drugiej tabeli kwantowe odpowiedniki stanów konwencjonalnego bitu, bez żadnej superpozycji. Kubit przygotowany w stanie ?0⟩ jest równoważny konwencjonalnemu bitowi o wartości 0 - przy odczycie zawsze daje wartość 0 - i podobnie dla ?1⟩. Gdyby nasze kubity były kiedykolwiek tylko w stanach ?0⟩ lub ?1⟩, mielibyśmy tylko kilka bardzo drogich konwencjonalnych bitów. Ale jak możemy zacząć uporać się z bardziej egzotycznymi możliwościami superpozycji pokazanymi w innych wierszach? Aby uzyskać trochę intuicji co do oszałamiających wariacji w tabeli 2-2, pomocne może być bardzo krótkie rozważenie czym właściwie jest kubit.

Szybkie spojrzenie na fizyczny kubit

Jednym z obiektów, który łatwo demonstruje superpozycję kwantową, jest pojedynczy foton. Aby to zilustrować, cofnijmy się o krok i przypuśćmy, że próbowaliśmy wykorzystać położenie fotonu do przedstawienia konwencjonalnego bitu cyfrowego. W urządzeniu pokazanym na rysunku przełączane lustro (które można ustawić jako odblaskowe lub przezroczyste) pozwala nam kontrolować, czy foton trafia na jedną z dwóch ścieżek - co odpowiada kodowaniu 0 lub 1.



Urządzenia takie jak to faktycznie istnieją w technologii komunikacji cyfrowej, ale mimo to pojedynczy foton wyraźnie stanowi bardzo kłopotliwy bit (na początek nie pozostanie w żadnym miejscu zbyt długo). Aby użyć tej konfiguracji do zademonstrowania niektórych właściwości kubitu, załóżmy, że zamienimy przełącznik, którego używamy do ustawienia fotonu na 0 lub 1, lustrem w połowie posrebrzanym. Lustro w połowie posrebrzane, jak pokazano na drugim rysunku 2-2(znane również jako rozdzielacz wiązki),



jest półodblaskową powierzchnią, która z 50% prawdopodobieństwem albo odbije światło na ścieżkę, którą kojarzymy z 1, albo pozwoli mu przejść prosto do ścieżki, którą kojarzymy z 0. Nie ma innych opcji.

Kiedy pojedynczy niepodzielny foton uderza w tę powierzchnię, doświadcza pewnego rodzaju kryzysu tożsamości. W efekcie, który nie ma konwencjonalnego odpowiednika, kończy się istnieniem w stanie, w którym mogą wpływać na niego efekty zarówno na ścieżce 0, jak i ścieżce 1. Mówimy, że foton jest w superpozycji podróżowania po każdej możliwej ścieżce. Innymi słowy, nie mamy już konwencjonalnego bitu, ale kubit, który może znajdować się w superpozycji wartości 0 i 1. Bardzo łatwo jest źle zrozumieć naturę superpozycji (jak w wielu popularnych artykułach o komputerach kwantowych). Nie jest prawdą, że foton znajduje się jednocześnie na ścieżce 0 i 1. Jest tylko jeden foton, więc jeśli umieścimy detektory na każdej ścieżce, jak pokazano na rysunku 2-2, wyłączy się tylko jeden. Kiedy tak się stanie, zredukuje superpozycję fotonu do bitu cyfrowego i da ostateczny wynik 0 lub 1. Jednak, jak zbadamy wkrótce, istnieją przydatne obliczeniowo sposoby, w jakie QPU może wchodzić w interakcje z kubitem w superpozycji, zanim będziemy musieli odczytać go za pomocą takiego wykrywania. Rodzaj superpozycji pokazany na rysunku 2-2 będzie miał kluczowe znaczenie dla wykorzystania mocy kwantowej jednostki QPU. W związku z tym będziemy musieli nieco bardziej ilościowo opisać i kontrolować superpozycje kwantowe. Kiedy nasz foton znajduje się w superpozycji ścieżek, mówimy, że ma amplitudę związaną z każdą ścieżką. Istnieją dwa ważne aspekty tych amplitud - dwa pokrętła, które możemy obracać, aby zmienić określoną konfigurację superpozycji kubita:

•  Wielkość związana z każdą ścieżką superpozycji fotonu jest wartością analogową, która mierzy, jak bardzo foton rozprzestrzenił się na każdej ścieżce. Wielkość ścieżki jest związana z prawdopodobieństwem, że foton zostanie wykryty na tej ścieżce. Konkretnie, kwadrat wielkości określa prawdopodobieństwo zaobserwowania fotonu na danej ścieżce. Na Rysunku 2-2 możemy zmienić wielkości amplitud związanych z każdą ścieżką, zmieniając stopień odbijania lustra w połowie posrebrzanego.

•  Względna faza między różnymi ścieżkami w superpozycji fotonu oddaje wielkość opóźnienia fotonu na jednej ścieżce względem drugiej. Jest to również wartość analogowa, którą można kontrolować różnicą między tym, jak daleko foton przemieszcza się po ścieżkach odpowiadających 0 i 1. Zauważ, że możemy zmienić względną fazę bez wpływu na szansę wykrycia fotonu na każdej ścieżce.

Warto jeszcze raz podkreślić, że termin amplituda jest sposobem odnoszącym się zarówno do wielkości, jak i do względnej fazy związanej z jakąś wartością z superpozycji kubitu.

WSKAZÓWKA : W przypadku nachylenia matematycznego amplitudy związane z różnymi ścieżkami w superpozycji są ogólnie opisane liczbami zespolonymi. Wielkość związana z amplitudą jest dokładnie modułem tej liczby zespolonej (pierwiastek kwadratowy z liczby pomnożony przez jej sprzężoną liczbę zespoloną), podczas gdy jej faza względna to kąt, jeśli liczba zespolona jest wyrażona w postaci biegunowej. Dla osób nie skłonnych matematycznie wkrótce wprowadzimy notację wizualną, aby nie musieli martwić się o tak złożone kwestie (gra słów zamierzona).

Wielkość i faza względna to wartości, które możemy wykorzystać podczas obliczeń i możemy myśleć o nich jako o zakodowanych w naszym kubicie. Ale jeśli kiedykolwiek mamy odczytać z niego jakiekolwiek informacje, foton musi w końcu trafić w jakiś detektor. W tym momencie obie te wartości analogowe zanikają - zniknęła kwantowość kubitu. W tym tkwi sedno obliczeń kwantowych: znalezienie sposobu na wykorzystanie tych eterycznych wielkości w taki sposób, aby po destrukcyjnym akcie odczytu przetrwała jakaś użyteczna pozostałość.

UWAGA : Konfiguracja na drugim rysunku jest równoważna przykładowi kodu, który wkrótce przedstawimy w przykładzie 1, w przypadku, gdy fotony są używane jako kubity.

Dobra, wystarczy fotonów! To jest przewodnik programisty, a nie podręcznik fizyki. Odejdźmy od fizyki i zobaczmy, jak możemy opisać i wizualizować kubity w sposób oderwany od fotonów i fizyki kwantowej, tak jak logika binarna jest od elektronów i fizyki półprzewodników.

Wprowadzenie do notacji kołowej

Mamy teraz pojęcie, czym jest superpozycja, ale jest to dość powiązane z określonym zachowaniem fotonów. Znajdźmy abstrakcyjny sposób opisania superpozycji, który pozwoli nam skupić się tylko na abstrakcyjnych informacjach. Pełnowymiarowa matematyka fizyki kwantowej dostarcza takiej abstrakcji, ale matematyka ta jest znacznie bardziej nieintuicyjna i niewygodna niż prosta logika binarna konwencjonalnych bitów. Ponieważ naszym celem jest zbudowanie płynnego i pragmatycznego zrozumienia tego, co dzieje się w QPU bez konieczności okopywania się na matematyce, od teraz będziemy myśleć o kubitach całkowicie zgodnie z tym zapisem okręgu. Eksperymentując z fotonami widzieliśmy, że istnieją dwa aspekty ogólnego stanu kubitu, które musimy śledzić w QPU: wielkość jego amplitud superpozycji i względna faza między nimi. Zapis okręgu wyświetla te parametry w następujący sposób:

•  Wielkość amplitudy związanej z każdą wartością, jaką kubit może przyjąć (do tej pory |0> i ?1 is) jest powiązana z promieniem wypełnionego obszaru pokazany dla każdego z okręgów |0> lub |1>.
•  Względna faza między amplitudami tych wartości jest wskazywana przez obrót koła |1> względem koła |0> (ciemniejsza linia jest rysowana w kołach, aby ten obrót był widoczny).

My będziemy polegać na notacji okręgów, dlatego warto trochę bardziej uważać, aby zobaczyć, jak rozmiary i obroty okręgów odzwierciedlają te pojęcia.

Rozmiar koła

Wcześniej zauważyliśmy, że kwadrat wielkości skojarzonej z | 0> lub | 1> określa prawdopodobieństwo uzyskania tej wartości podczas odczytu. Ponieważ promień wypełnienia okręgu reprezentuje wielkość, oznacza to, że zacieniony obszar w każdym okręgu (lub, bardziej potocznie, jego rozmiar) jest wprost proporcjonalny do prawdopodobieństwa uzyskania wartości tego okręgu (0 lub 1), jeśli odczytamy kubit. Przykłady na rysunku 2-3 pokazują notację kołową dla różnych stanów kubitu i możliwość odczytania 1 w każdym przypadku. Zauważ, że gdy obszar zacieniowany w okręgu |0> powiększa się, jest większa szansa, że odczytasz 0, a to oczywiście oznacza, że szansa na uzyskanie wyniku 1 maleje (pozostanie tym, co zostało). W ostatnim przykładzie na rysunku



istnieje 90% szansy odczytania kubitu jako 0, a zatem odpowiadające 10% szansy odczytania 1. Często mówimy o wypełnionym obszarze koła w naszym zapisie koła jako reprezentującym wielkość związaną z tą wartością w superpozycji. Chociaż może się to wydawać irytujące, ważne jest, aby mieć z tyłu głowy, że jasność związana z tą wartością naprawdę odpowiada promieniu okręgu - choć często zrównanie tych dwóch wartości dla wygody wizualnej nie zaszkodzi. Łatwo też zapomnieć, choć ważne jest, aby pamiętać, że w notacji kołowej rozmiar koła związanego z danym wynikiem nie reprezentuje pełnej amplitudy superpozycji. Ważną dodatkową informacją, której brakuje, jest względna faza naszej superpozycji.

Okrąg rotacji

Niektóre instrukcje QPU pozwolą nam także zmienić względne obroty okręgów |0> i |1> kubitu. Reprezentuje względną fazę kubitu. Faza względna stanu kubitu może przyjmować dowolną wartość od 0 ° do 360 °; kilka przykładów pokazano na rysunku



We wszystkich poprzednich przykładach obróciliśmy tylko okrąg |1>. Dlaczego też nie koło |0>? Jak sama nazwa wskazuje, tylko względna faza superpozycji kubitu ma znaczenie. W konsekwencji interesuje nas tylko względna rotacja między naszymi kręgami. Gdyby operacja QPU miałaby obrócić oba okręgi, to zawsze moglibyśmy w równoważny sposób ponownie rozważyć efekt, tak że obrócono tylko koło |1>, dzięki czemu względny obrót był bardziej widoczny. Przykład pokazano na rysunku



Zauważ, że względna faza może się zmieniać niezależnie od wielkości superpozycji. Ta niezależność działa również w drugą stronę. Porównując trzeci i czwarty przykład na rysunku 3, widzimy, że względna faza między wynikami dla pojedynczego kubitu nie ma bezpośredniego wpływu na szanse tego, co przeczytamy. Fakt, że względna faza pojedynczego kubitu nie ma wpływu na wielkości w superpozycji, oznacza, że nie ma ona bezpośredniego wpływu na obserwowalne wyniki odczytu. Może to sprawić, że względna właściwość fazy będzie wydawać się nieistotna, ale prawda nie może być bardziej inna! W obliczeniach kwantowych obejmujących wiele kubitów możemy zasadniczo wykorzystać tę rotację, aby sprytnie i pośrednio wpłynąć na szanse, że ostatecznie odczytamy różne wartości. W rzeczywistości dobrze zaprojektowane względne fazy mogą zapewnić zadziwiającą przewagę obliczeniową. Wprowadzimy teraz operacje, które pozwolą nam to zrobić - w szczególności te, które działają tylko na jednym kubicie - i zwizualizujemy ich efekty za pomocą notacji kołowej.

UWAGA: W przeciwieństwie do wyraźnie cyfrowej natury konwencjonalnych bitów, wielkości i względne fazy są ciągłymi stopniami swobody. Prowadzi to do szeroko rozpowszechnionego błędnego przekonania, że obliczenia kwantowe są porównywalne do niefortunnych obliczeń analogowych. Co godne uwagi, pomimo umożliwienia nam manipulowania ciągłymi stopniami swobody, błędy napotykane przez QPU można skorygować cyfrowo. Dlatego QPU są bardziej wytrzymałe niż 4 analogowe urządzenia komputerowe.

Kilka pierwszych operacji QPU

Podobnie jak ich odpowiedniki z procesorami CPU, operacje na pojedynczym kubicie QPU przekształcają informacje wejściowe w żądane dane wyjściowe. Dopiero teraz nasze dane wejściowe i wyjściowe są oczywiście kubitami, a nie bitami. Wiele instrukcji QPU ma skojarzoną odwrotność, o której warto wiedzieć. W tym przypadku mówi się, że operacja QPU jest odwracalna, co ostatecznie oznacza, że żadna informacja nie jest tracona ani odrzucana po jej zastosowaniu. Niektóre operacje QPU są jednak nieodwracalne i nie mają odwrotności (w jakiś sposób powodują utratę informacji). W końcu dojdziemy do wniosku, że to, czy operacja jest odwracalna, czy nie, może mieć ważne konsekwencje dla sposobu, w jaki z niej korzystamy. Niektóre z tych instrukcji QPU mogą wydawać się dziwne i wątpliwe, ale po przedstawieniu zaledwie kilku z nich szybko zaczniemy ich używać.

Instrukcja QPU: NOT



NOT jest kwantowym odpowiednikiem tytułowej operacji konwencjonalnej. Zero staje się jednym i odwrotnie. Jednak w przeciwieństwie do swojego tradycyjnego kuzyna, operacja QPU NOT może również działać na kubicie w superpozycji. W zapisie koła prowadzi to w bardzo prosty sposób do zamiany kół |0> i ?1 as, jak na rysunku



Odwracalność: tak jak w logice cyfrowej, operacja NOT jest swoją własną odwrotnością; jego dwukrotne zastosowanie przywraca kubitowi jego pierwotną wartość.

Instrukcja QPU: HAD



Operacja HAD (skrót od Hadamard) zasadniczo tworzy równa się superpozycjiprzy przedstawianiu stanu |0> lub |1>. To są nasze wrota do używania dziwacznego i delikatnego paralelizmu superpozycji kwantowej! W przeciwieństwie do NOT, nie ma konwencjonalnego odpowiednika. W zapisie kołowym HAD daje kubit wyjściowy mający taką samą ilość wypełnionego obszaru zarówno dla |0>, jak i |1>, jak na rysunku



To pozwala HAD na tworzenie jednolitych superpozycji wyników w kubicie; tj. superpozycja, w której każdy wynik jest równie prawdopodobny. Zauważ również, że działanie HAD na kubitach początkowo w stanach |0> i |1> jest nieco inne: wynik działania HAD na |1> daje niezerową rotację (fazę względną) jednego z okręgów, podczas gdy wynik działania to na |0> nie. Możesz się zastanawiać, co się stanie, jeśli zastosujemy HAD do kubitów, które są już w superpozycji. Najlepszym sposobem, aby się tego dowiedzieć, jest eksperymentowanie! Robiąc to, wkrótce zauważysz, że zachodzi następująca sytuacja: HAD działa oddzielnie na stany |0> i |1>, zgodnie z regułami przedstawionymi na powyższym rysunku. Generowane przez to wartości |0> i |1> są łączone, ważone przez amplitudy oryginalnych superpozycji. Odwracalność: Podobnie jak w przypadku NOT, operacja HAD jest odwrotna; jego dwukrotne zastosowanie przywraca kubitowi jego pierwotną wartość.

Instrukcja QPU: READ



Operacja READ jest formalnym wyrazem wcześniej wprowadzonego procesu odczytu. READ jest jedyną częścią zestawu instrukcji QPU, która potencjalnie zwraca losowy wynik.

Instrukcja QPU: WRITE



Operacja WRITE pozwala nam zainicjować rejestr QPU, zanim zaczniemy na nim operować. To jest proces deterministyczny. Zastosowanie polecenia READ do pojedynczego kubitu zwróci wartość 0 lub 1 z prawdopodobieństwami określonymi przez (kwadrat) powiązanych wielkości w stanie kubitu (ignorując fazę względną). Po wykonaniu operacji READ kubit pozostaje w stanie |0>, jeśli uzyskano wynik 0, a stan |1>, jeśli uzyskano wynik 1. Innymi słowy, każda superpozycja zostaje nieodwracalnie zniszczona. W zapisie koła wynik występuje z prawdopodobieństwem określonym przez wypełniony obszar w każdym skojarzonym okręgu. Następnie przesuwamy wypełniony obszar między okręgami, aby odzwierciedlić ten wynik: okrąg powiązany z występującym wynikiem zostanie całkowicie wypełniony, a pozostałe kółko stanie się puste. Ilustruje to rysunek przedstawiający operacje READ wykonywane na dwóch różnych przykładowych superpozycjach.



UWAGA: W drugim przykładzie powyższego rysunku operacja READ usuwa wszystkie znaczące informacje o fazie względnej. W rezultacie zmieniamy orientację stanu, tak aby okrąg był skierowany w górę.

Używając READ i NOT, możemy również skonstruować prostą operację WRITE, która pozwala nam przygotować kubit w pożądanym stanie |0> lub |1>. Najpierw CZYTAMY kubit, a następnie, jeśli wartość nie zgadza się z wartością, którą planujemy ZAPISAĆ, wykonujemy operację NIE. Zauważ, że ta operacja WRITE nie pozwala nam przygotować kubitu w dowolnej superpozycji (z dowolną wielkością i fazą względną), ale tylko w stanie |0> lub stanie |1>. Odwracalność: Operacje ODCZYTU i ZAPISU nie są odwracalne. Niszczą superpozycje i tracą informacje. Gdy to nastąpi, analogowe wartości kubitu (zarówno wielkość, jak i faza) znikną na zawsze.

Praktyczne: idealnie losowy bit

Zanim przejdziemy do wprowadzenia kilku kolejnych operacji na jednym kubicie, zatrzymajmy się, aby zobaczyć, jak uzbrojone są operacje HAD, READ i WRITE - możemy stworzyć program do wykonania zadania, które jest niemożliwe na jakimkolwiek konwencjonalnym komputerze. Wygenerujemy prawdziwie losowy bit. W całej historii obliczeń wiele czasu i wysiłku poświęcono na opracowanie systemów generatora liczb pseudolosowych (PRNG), które znajdują zastosowanie w różnych zastosowaniach, od kryptografii po prognozowanie pogody. PRNG są pseudo w tym sensie, że jeśli znasz zawartość pamięci komputera i algorytm PRNG, możesz w zasadzie przewidzieć następną liczbę do wygenerowania. Zgodnie ze znanymi prawami fizyki, sposób odczytu kubitu w superpozycji jest zasadniczo i całkowicie nieprzewidywalny. Pozwala to jednostce QPU na utworzenie największego na świecie generatora liczb losowych, po prostu przygotowując kubit w stanie |0>, stosując instrukcję HAD, a następnie odczytując kubit. Możemy zilustrować tę kombinację operacji QPU za pomocą diagramu obwodu kwantowego, gdzie linia przesuwająca się od lewej do prawej ilustruje sekwencję różnych operacji wykonywanych na naszym (pojedynczym) kubicie, jak pokazano na rysunku



Może nie wyglądać na dużo, ale mamy to, nasz pierwszy program QPU: kwantowy generator liczb losowych (QRNG)! Jeśli wielokrotnie uruchamiasz te cztery wiersze kodu w symulatorze QCEngine, otrzymasz binarny losowy ciąg. Oczywiście symulatory zasilane z procesora, takie jak QCEngine, przybliżają nasz QRNG do PRNG, ale uruchomienie równoważnego kodu na prawdziwym QPU da idealnie losowy ciąg binarny

PRZYKŁADOWY KOD

Przykład 1. Jeden losowy bit

qc.reset (1); // przydziel jeden kubit
qc.write (0); // zapisz wartość zero
qc.had (); // umieść go w superpozycji 0 i 1
var wynik = qc.read (); // odczytaj wynik jako bit cyfrowy

Ponieważ może to być Twój pierwszy program kwantowy (gratulacje!), Podzielmy go, aby upewnić się, że każdy krok ma sens:

* qc.reset (1) ustawia naszą symulację QPU, żądając jednego kubitu. Wszystkie programy, które piszemy dla QCEngine, zainicjują zestaw kubitów taką linią.
* qc.write (0) po prostu inicjalizuje nasz pojedynczy kubit w stanie |0> - odpowiednik ustawienia konwencjonalnego bitu na wartość 0.
* qc.had () stosuje HAD do naszego kubitu, umieszczając go w superpozycji |0> i |1>,
* var wynik = qc.read () odczytuje wartość naszego kubitu w pliku koniec obliczeń jako losowy bit cyfrowy, przypisując wartość zmiennej wynikowej.

Może się wydawać, że wszystko, co tu naprawdę zrobiliśmy, to znalezienie bardzo kosztownego sposobu na rzucenie monetą, ale to nie docenia mocy HAD. Gdybyś mógł jakoś zajrzeć do środka HAD, nie znalazłbyś ani pseudo, ani sprzętowego generatora liczb losowych. W przeciwieństwie do nich, prawa fizyki kwantowej gwarantują, że HAD jest nieprzewidywalny. Nikt w znanym wszechświecie nie może zrobić nic lepszego niż beznadziejne, przypadkowe przypuszczenie, czy wartość kubitu po HAD zostanie odczytana jako 0 czy 1 - nawet jeśli dokładnie znają instrukcje, których używamy do generowania liczb losowych. W rzeczywistości, chociaż w następnym rozdziale odpowiednio wprowadzimy obsługę wielu kubitów, możemy łatwo uruchomić nasz pojedynczy losowy program kubitowy równolegle osiem razy, aby wygenerować losowy bajt. Poniższy rysunek pokazuje, jak to wygląda.



Ten kod w przykładzie 2 służący do tworzenia losowego bajtu jest prawie identyczny z przykładem 1.

PRZYKŁADOWY KOD

Przykład 2. Jeden losowy bajt

qc.reset (8);
qc.write (0);
qc.had ();
var wynik = qc.read ();
qc.print (wynik);

Zwróć uwagę, że korzystamy z faktu, że operacje QCEngine, takie jak WRITE i HAD, domyślnie działają na wszystkich zainicjowanych kubitach, chyba że jawnie przekazujemy im określone kubity do działania.

UWAGA: Chociaż w Przykładzie 2 użyto wielu kubitów, nie ma rzeczywistych operacji na wielu kubitach, które pobierają więcej niż jeden kubit jako dane wejściowe. Ten sam program można serializować, aby działał tylko na jednym kubicie.





[ 78 ]