Sdílet prostřednictvím


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: Diagram kvantového fourierového transformačního obvodu

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

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.

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 usepří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:

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ínce spuštění operace na jednom nebo několika řídicích qubitech. 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>))

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):

Diagram znázorňující okruh pro tři 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í 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:

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

}                                                                                                                                                                               

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[]).

  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 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.
  3. Výstupy Message se DumpMachine 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í mutableresultArray 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.

  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 se DumpMachine 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 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ů.

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