Kurz: Implementace kvantové fourierovy transformace v Q#
V tomto kurzu se dozvíte, jak napsat a simulovat základní kvantový program, který funguje na jednotlivých qubitech.
I když Q# byl primárně vytvořen jako programovací jazyk vysoké úrovně pro rozsáhlé kvantové programy, lze ho použít také k prozkoumání nižší úrovně kvantového programování, tj. přímé adresování konkrétních qubitů. Konkrétně se v tomto kurzu podrobněji podíváme na Kvantovou fourierovou transformaci (QFT) – podprogram, který je nedílnou součástí mnoha větších kvantových algoritmů.
V tomto kurzu se naučíte:
- Definujte kvantové operace v Q#.
- Napsání okruhu quantum Fourierovy transformace
- Simulace kvantové operace z přidělení qubitu do výstupu měření
- Podívejte se, jak se simulovaná vlnová funkce kvantového systému v průběhu operace vyvíjí.
Poznámka:
Toto nižší zobrazení kvantového zpracování informací je často popsáno z hlediska kvantových obvodů, které představují sekvenční použití bran nebo operací pro konkrétní qubity systému. Operace s jedním a více qubity, které postupně použijete, se tedy dají snadno znázornit v diagramech okruhů. Například úplná tří qubitová kvantová fourierová transformace použitá v tomto kurzu má následující reprezentaci jako okruh:
Tip
Pokud chcete urychlit cestu k kvantovému computingu, podívejte se na kód s Využitím Azure Quantum, která je jedinečnou funkcí webu Azure Quantum. Tady můžete spouštět předdefinované Q# ukázky nebo vlastní Q# programy, vygenerovat nový Q# kód z výzev, otevřít a spustit kód ve VS Code pro web jedním kliknutím a pokládat Copilot jakékoli otázky týkající se kvantového computingu.
Požadavky
Nejnovější verze editoru Visual Studio Code nebo otevření editoru VS Code na webu
Nejnovější verze rozšíření Azure Quantum Development Kit (QDK). Podrobnosti o instalaci najdete v tématu Instalace sady QDK ve VS Code.
Pokud chcete používat poznámkové bloky Jupyter, musíte také nainstalovat rozšíření Pythonu a Jupyter a nejnovější
qsharp
balíček Pythonu. Uděláte to tak, že otevřete terminál a spustíte následující příkaz:$ pip install --upgrade qsharp
Vytvoření nového Q# souboru
- Ve VS Code vyberte Soubor > nový textový soubor.
- Uložte soubor jako QFTcircuit.qs. Tento soubor obsahuje kód Q# programu.
- Otevřete QFTcircuit.qs.
Napsání okruhu QFT v Q#
První část tohoto kurzu se skládá z definování Q# operace Main
, která provádí kvantovou fourierovou transformaci na třech qubitech. Tato DumpMachine
funkce se používá k pozorování toho, jak se simulovaná vlnová funkce tří qubitového systému v rámci operace vyvíjí. V druhé části kurzu přidáte funkce měření a porovnáte stavy před a po měření qubitů.
Operaci sestavíte krok za krokem. Zkopírujte a vložte kód v následujících částech do souboru QFTcircuit.qs .
Úplný Q# kód pro tuto část si můžete prohlédnout jako referenci.
Import požadovaných Q# knihoven
Q# Do souboru naimportujte relevantní Microsoft.Quantum.*
obory názvů.
import Microsoft.Quantum.Diagnostics.*;
import Microsoft.Quantum.Math.*;
import Microsoft.Quantum.Arrays.*;
// operations go here
Definování operací s argumenty a návraty
Dále definujte Main
operaci:
operation Main() : Unit {
// do stuff
}
Operace Main()
nikdy nepřijímá argumenty a prozatím vrací Unit
objekt, který je podobný návratu void
v jazyce C# nebo prázdné řazené kolekci členů v Tuple[()]
Pythonu.
Později operaci upravíte tak, aby vracela pole výsledků měření.
Přidělení qubitů
Q# V rámci operace přidělte registr tří qubitů s klíčovým slovemuse
. V use
případě , qubity jsou automaticky přiděleny ve stavu $\ket{0}$.
use qs = Qubit[3]; // allocate three qubits
Message("Initial state |000>:");
DumpMachine();
Stejně jako v reálných kvantových výpočtech Q# neumožňuje přímý přístup ke stavům qubitu. Operace DumpMachine
ale vytiskne aktuální stav target počítače, takže může poskytnout cenný přehled pro ladění a učení při použití společně se simulátorem celého stavu.
Použití jedno qubitů a kontrolovaných operací
Dále použijete operace, které tvoří Main
samotnou operaci.
Q# již obsahuje mnoho z těchto a dalších základních kvantových operací v Microsoft.Quantum.Intrinsic
oboru názvů.
Poznámka:
Všimněte si, že Microsoft.Quantum.Intrinsic
se v dřívějším fragmentu kódu neimportoval s jinými obory názvů, protože je automaticky načten kompilátorem pro všechny Q# programy.
První použitou H
operací je operace (Hadamard) na první qubit:
Pokud chcete použít operaci na konkrétní qubit z registru (například jeden Qubit
z pole Qubit[]
), použijte standardní zápis indexu.
Takže použití H
operace na první qubit registru qs
má tvar:
H(qs[0]);
Kromě použití H
operace na jednotlivé qubity se okruh QFT skládá především z kontrolovaných R1
rotací. Operace R1(θ, <qubit>)
obecně ponechá komponentu qubitu $\ket{0}$ beze změny při použití otočení $e^{i\theta}$ na komponentu $\ket{1}$.
Q# usnadňuje podmínce spuštění operace na jednom nebo několika řídicích qubitech. Obecně platí, že volání je předzvěděné Controlled
a argumenty operace se mění takto:
Op(<normal args>)
$\to$ Controlled Op([<control qubits>], (<normal args>))
Všimněte si, že argument qubitu ovládacího prvku musí být pole, i když se jedná o jeden qubit.
Řízené operace v QFT jsou R1
operace, které fungují na prvním qubitu (a řídí se druhým a třetím qubitem):
Q# V souboru volejte tyto operace pomocí těchto příkazů:
Controlled R1([qs[1]], (PI()/2.0, qs[0]));
Controlled R1([qs[2]], (PI()/4.0, qs[0]));
Funkce PI()
se používá k definování rotací z hlediska radiánů pí.
Použití operace SWAP
Jakmile použijete relevantní H
operace a řízené rotace na druhý a třetí qubit, okruh bude vypadat takto:
//second qubit:
H(qs[1]);
Controlled R1([qs[2]], (PI()/2.0, qs[1]));
//third qubit:
H(qs[2]);
Nakonec použijete SWAP
operaci na první a třetí qubity k dokončení okruhu. Tato operace je nezbytná, protože kvantová Fourierova transformace poskytuje qubity v obráceném pořadí, takže výměny umožňují bezproblémovou integraci podprogramu do větších algoritmů.
SWAP(qs[2], qs[0]);
Teď jste dokončili psaní operací na úrovni qubitu kvantové fourierovy transformace na vaši Q# operaci:
Zrušení přidělení qubitů
Posledním krokem je znovu zavolat DumpMachine()
, aby se zobrazil stav po operaci, a uvolnit qubity. Qubity byly ve stavu $\ket{0}$, když jste je přidělili, a je potřeba je resetovat do počátečního ResetAll
stavu pomocí operace.
Vyžadování explicitního resetování všech qubitů na $\ket{0}$ je základní funkcí Q#, protože umožňuje jiným operacím přesně zjistit jejich stav, když začnou používat stejné qubity (málo prostředků). Resetováním navíc zajistíte, že nejsou propletené s žádnými dalšími qubity v systému. Pokud se resetování neprovádí na konci bloku přidělení use
, může dojít k chybě za běhu.
Do souboru přidejte následující řádky Q# :
Message("After:");
DumpMachine();
ResetAll(qs); // deallocate qubits
Úplná operace QFT
Program Q# je dokončen. Váš soubor QFTcircuit.qs by teď měl vypadat takto:
import Microsoft.Quantum.Diagnostics.*;
import Microsoft.Quantum.Math.*;
import Microsoft.Quantum.Arrays.*;
operation Main() : Unit {
use qs = Qubit[3]; // allocate three qubits
Message("Initial state |000>:");
DumpMachine();
//QFT:
//first qubit:
H(qs[0]);
Controlled R1([qs[1]], (PI()/2.0, qs[0]));
Controlled R1([qs[2]], (PI()/4.0, qs[0]));
//second qubit:
H(qs[1]);
Controlled R1([qs[2]], (PI()/2.0, qs[1]));
//third qubit:
H(qs[2]);
SWAP(qs[2], qs[0]);
Message("After:");
DumpMachine();
ResetAll(qs); // deallocate qubits
}
Spuštění okruhu QFT
Main
Prozatím operace nevrací žádnou hodnotu – operace vrátí Unit
hodnotu. Později upravíte operaci tak, aby vracela pole výsledků měření (Result[]
).
- Před spuštěním programu ověřte ve stavovém řádku v dolní části editoru VS Code, že target je profil nastavený na Q#: Unrestricted. Pokud chcete profil změnit target , vyberte target profil na stavovém řádku a v rozevírací nabídce vyberte Unrestricted (Bez omezení ). Pokud není profil target nastavený na neomezený, zobrazí se při spuštění programu chyba.
- Program spustíte tak, že v rozevíracím seznamu s ikonou přehrávání v pravém horním rohu vyberete Spustit soubor nebo stisknete Kombinaci kláves Q#. Program spustí
Main()
operaci na výchozím simulátoru. - Výstupy
Message
seDumpMachine
zobrazí v konzole ladění.
Pokud vás zajímají další vstupní stavy, doporučujeme experimentovat s použitím dalších operací qubitu před transformací.
Přidání měření do okruhu QFT
Zobrazení funkce DumpMachine
ukázalo výsledky operace, ale bohužel základní kámen kvantové mechaniky uvádí, že skutečný kvantový systém nemůže mít takovou funkci DumpMachine
.
Místo toho se informace extrahují prostřednictvím měření, což obecně nejen nedokáže poskytnout informace o úplném kvantovém stavu, ale může také výrazně změnit samotný systém.
Existuje mnoho druhů kvantových měření, ale v tomto příkladu se zaměřujeme na nejzákladnější: projektová měření na jednom qubitu. Při měření v daném základu (například výpočetní základna $ { \ket{0}, \ket{1} } $), stav qubitu se promítá do libovolného základního stavu, čímž se zničí jakákoli superpozice mezi těmito dvěma hodnotami.
Úprava operace QFT
K implementaci měření v rámci Q# programu použijte M
operaci, která vrací Result
typ.
Nejprve upravte Main
operaci tak, aby vracela pole výsledků měření, Result[]
nikoli Unit
.
operation Main() : Result[] {
Definice a inicializace Result[]
pole
Před přidělením qubitů deklarujte a vytvořte vazbu pole se třemi prvky (jedno Result
pro každý qubit):
mutable resultArray = [Zero, size = 3];
Předpřipravení mutable
resultArray
klíčového slova umožňuje pozdější úpravu proměnné v kódu, například při přidávání výsledků měření.
Provádění měření ve smyčce for
a přidání výsledků do pole
Po operacích transformace QFT vložte následující kód:
for i in IndexRange(qs) {
resultArray w/= i <- M(qs[i]);
}
IndexRange
Funkce volat na matici (například pole qubitů, qs
) vrátí rozsah nad indexy pole.
Tady se používá ve smyčce for
k postupnému měření každého qubitu pomocí příkazu M(qs[i])
.
Každý měřený Result
typ (buď Zero
nebo One
) se pak přidá do odpovídající pozice resultArray
indexu pomocí příkazu update-and-reassign.
Poznámka:
Syntaxe tohoto příkazu je jedinečná Q#pro , ale odpovídá podobné proměnné, která se znovu přiřazuje resultArray[i] <- M(qs[i])
v jiných jazycích, jako je F# a R.
Klíčové slovo set
se vždy používá k opětovnému přiřazení proměnných vázaných pomocí mutable
.
Vrátit resultArray
Jakmile jsou měřeny všechny tři qubity a výsledky přidány do resultArray
, můžete bezpečně qubity resetovat a uvolnit jako předtím. Pokud chcete vrátit měření, vložte:
return resultArray;
Spuštění okruhu QFT s měřením
Teď změňte umístění DumpMachine
funkcí tak, aby výstupem stavu před měřením a po měření.
Konečný Q# kód by měl vypadat takto:
import Microsoft.Quantum.Diagnostics.*;
import Microsoft.Quantum.Math.*;
import Microsoft.Quantum.Arrays.*;
operation Main() : Result[] {
mutable resultArray = [Zero, size = 3];
use qs = Qubit[3];
//QFT:
//first qubit:
H(qs[0]);
Controlled R1([qs[1]], (PI()/2.0, qs[0]));
Controlled R1([qs[2]], (PI()/4.0, qs[0]));
//second qubit:
H(qs[1]);
Controlled R1([qs[2]], (PI()/2.0, qs[1]));
//third qubit:
H(qs[2]);
SWAP(qs[2], qs[0]);
Message("Before measurement: ");
DumpMachine();
for i in IndexRange(qs) {
resultArray w/= i <- M(qs[i]);
}
Message("After measurement: ");
DumpMachine();
ResetAll(qs);
Message("Post-QFT measurement results [qubit0, qubit1, qubit2]: ");
return resultArray;
}
Tip
Nezapomeňte soubor uložit pokaždé, když před opětovným spuštěním souboru představíte změnu kódu.
- Před spuštěním programu ověřte ve stavovém řádku v dolní části editoru VS Code, že target je profil nastavený na Q#: Unrestricted. Pokud chcete profil změnit target , vyberte target profil na stavovém řádku a v rozevírací nabídce vyberte Unrestricted (Bez omezení ). Pokud není profil target nastavený na neomezený, zobrazí se při spuštění programu chyba.
- Pokud chcete program spustit, vyberte v rozevíracím seznamu Ikona přehrávání v pravém horním rohu možnost Spustit Q# soubor nebo stiskněte Kombinaci kláves Ctrl+5. Program spustí
Main()
operaci na výchozím simulátoru. - Výstupy
Message
seDumpMachine
zobrazí v konzole ladění.
Výstup by měl vypadat nějak takto:
Before measurement:
Basis | Amplitude | Probability | Phase
-----------------------------------------------
|000⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000
|001⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000
|010⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000
|011⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000
|100⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000
|101⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000
|110⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000
|111⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000
After measurement:
Basis | Amplitude | Probability | Phase
-----------------------------------------------
|010⟩ | 1.0000+0.0000𝑖 | 100.0000% | 0.0000
Post-QFT measurement results [qubit0, qubit1, qubit2]:
[Zero, One, Zero]
Tento výstup znázorňuje několik různých věcí:
- Když porovnáte vrácený výsledek s předměření
DumpMachine
, jasně neukazuje superpozici po-QFT nad základními stavy. Měření vrátí pouze jeden základní stav s pravděpodobností určenou amplitudou tohoto stavu ve vlnové funkci systému. - Z následného měření
DumpMachine
vidíte, že měření změní samotný stav a promítá ho z počáteční superpozice na základní stavy do jediného základního stavu, který odpovídá měřené hodnotě.
Pokud tuto operaci zopakujete mnohokrát, uvidíte, že statistika výsledku začne ukazovat rovnoměrně váženou superpozici stavu po-QFT, která vede k náhodnému výsledku při každém pokusu. Kromě toho, že je neefektivní a stále nedokončí, by to přesto reprodukovalo pouze relativní amplitudy základního stavu, nikoli relativní fáze mezi nimi. V tomto příkladu se nejedná o problém, ale zobrazí se relativní fáze, pokud byste získali složitější vstup pro QFT než $\ket{000}$.
Q# Použití operací ke zjednodušení okruhu QFT
Jak je uvedeno v úvodu, velká část Q#energie spočívá ve skutečnosti, že umožňuje abstraktovat obavy z práce s jednotlivými qubity.
Pokud chcete skutečně vyvíjet plně škálovatelné, použitelné kvantové programy, obáváte se, jestli nějaká H
operace předchází nebo po určité obměně by vás zpomalovala. Azure Quantum poskytuje ApplyQFT
operaci, kterou můžete použít a použít pro libovolný počet qubitů.
Nahraďte vše od první
H
operace poSWAP
operaci včetně:ApplyQFT(qs);
Váš kód by teď měl vypadat takto:
import Microsoft.Quantum.Diagnostics.*; import Microsoft.Quantum.Math.*; import Microsoft.Quantum.Arrays.*; operation Main() : Result[] { mutable resultArray = [Zero, size = 3]; use qs = Qubit[3]; //QFT: //first qubit: ApplyQFT(qs); Message("Before measurement: "); DumpMachine(); for i in IndexRange(qs) { resultArray w/= i <- M(qs[i]); } Message("After measurement: "); DumpMachine(); ResetAll(qs); Message("Post-QFT measurement results [qubit0, qubit1, qubit2]: "); return resultArray; }
Q# Spusťte program znovu a všimněte si, že výstup je stejný jako předtím.
Pokud chcete zjistit skutečnou výhodu použití Q# operací, změňte počet qubitů na něco jiného než
3
:
mutable resultArray = [Zero, size = 4];
use qs = Qubit[4];
//...
Můžete tedy použít správný QFT pro libovolný počet qubitů, aniž byste se museli starat o přidání nových H
operací a otočení na každý qubit.
Související obsah
Prozkoumejte další Q# kurzy:
- Generátor kvantových náhodných čísel ukazuje, jak napsat Q# program, který generuje náhodná čísla z qubitů v superpozici.
- Groverův vyhledávací algoritmus ukazuje, jak napsat Q# program, který používá Groverův vyhledávací algoritmus.
- Kvantové propletení ukazuje, jak napsat Q# program, který manipuluje s qubity a měří je a ukazuje účinky superpozice a propletení.
- Kvantové katy jsou kurzy a programovací cvičení zaměřená na výuku prvků kvantového computingu a Q# programování současně.