Sdílet prostřednictvím


Průvodce: 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#.
  • Napište okruh kvantové 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: Diagram kvantového fourierového transformačního obvodu

Tip

Pokud chcete urychlit svou cestu ke kvantovému výpočetnictví, podívejte se na Code with Azure Quantum, což je jedinečná funkce webové stránky 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

Vytvoření nového Q# souboru

  1. Ve VS Code vyberte Soubor > nový textový soubor.
  2. Uložte soubor jako QFTcircuit.qs. Tento soubor obsahuje kód Q# programu.
  3. Otevřete QFTcircuit.qs.

Napište okruh 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 zatím vrací Unit objekt, který je analogický návratu void v jazyce C# nebo prázdné n-tici 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. S use jsou qubity 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.

Aplikujte jednoqubitové a řízené operace

Dále použijete operace, které samotnou operaci Main tvoří. Q# již obsahuje mnoho z těchto a dalších základních kvantových operací v Microsoft.Quantum.Intrinsic prostoru 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í operace, kterou použijeme, je Hadamardova operace na první qubit:

Diagram znázorňující okruh pro tři qubitové QFT přes první Hadamard

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ínění spuštění operace na základě jednoho, nebo několika řídicích qubitů. Obecně platí, že volání je předzvěděné Controlleda argumenty operace se mění takto:

Op(<normal args>) $\to$ Controlled Op([<control qubits>], (<normal args>))

Poznamenejte si, že argument řídicího qubitu 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):

Diagram znázorňující okruh pro tříqubitové kvantové Fourierovy transformace prostřednictvím prvního qubitu.

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í obvodu. 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:

Diagram znázorňující obvod pro tří qubitovou kvantovou fourierovou transformaci

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

}                                                                                                                                                                               

Spusťte okruh 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[]).

  1. 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.
  2. Program spustíte tak, že v rozevíracím seznamu u ikony přehrávání v pravém horním rohu vyberete Spustit souborQ#, nebo stisknete Ctrl+F5. Program spustí Main() operaci na výchozím simulátoru.
  3. Výstupy Message a DumpMachine se zobrazí v ladicí konzole.

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[] {

Definujte a inicializujte 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];

Umístění klíčového slova mutableresultArray umožňuje, aby proměnná byla později v kódu upravena, 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 volaná na pole (například pole qubitů, qs) vrátí rozsah přes indexy tohoto 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á pro Q#, ale odpovídá podobnému znovupřiřazení proměnných resultArray[i] <- M(qs[i]) v jiných jazycích, jako jsou 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;

Spusťte okruh QFT s měřeními

Teď změňte umístění funkcí DumpMachine tak, aby zobrazily stav před 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.

  1. 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.
  2. 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.
  3. Výstupy Message a DumpMachine se 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í:

  1. 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.
  2. Z následného měření DumpMachinevidí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 nedokonalý, by to přesto reprodukovalo pouze relativní amplitudy základních stavů, 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}$.

Použijte operace Q# ke zjednodušení okruhu QFT.

Jak je uvedeno v úvodu, velká část síly Q# spočívá ve skutečnosti, že umožňuje odstranit znepokojivé aspekty práce s jednotlivými qubity. Pokud chcete skutečně vyvíjet plně škálovatelné a použitelné kvantové programy, přemýšlení o tom, zda operace H je před nebo za konkrétní rotací, by vás pouze zpomalilo. Azure Quantum poskytuje ApplyQFT operaci, kterou můžete použít a použít pro libovolný počet qubitů.

  1. Nahraďte vše od první H operace po SWAP operaci včetně:

    ApplyQFT(qs);
    
  2. 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;
    
    }
    
  3. Q# Spusťte program znovu a všimněte si, že výstup je stejný jako předtím.

  4. 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.

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 tutoriály a programovací cvičení zaměřená na výuku prvků kvantového počítání a Q# programování současně.