A Q# program felépítése

Ez a cikk a program általános összetevőit Q# ismerteti. Vegye figyelembe, hogy a Q# Jupyter Notebooksban írt programok nem használnak néhány ilyen összetevőt – ezeket a különbségeket az egyes szakaszok ismertetik.

Fontolja meg a következő Q# programot:

namespace Superposition {

    @EntryPoint()
    operation MeasureOneQubit() : Result {
        // Allocate a qubit, by default it is in zero state      
        use q = Qubit();  
        // We apply a Hadamard operation H to the state
        // It now has a 50% chance of being measured 0 or 1  
        H(q);      
        // Now we measure the qubit in Z-basis.
        let result = M(q);
        // We reset the qubit before releasing it.
        Reset(q);
        // Finally, we return the result of the measurement.
        return result;
    }
}

A megjegyzések elolvasásával (//) megállapíthatja, hogy ez a program qubitet foglal le, egy műveletet alkalmaz a szuperpozícióba helyezéséhez, méri a qubit állapotát, majd alaphelyzetbe állítja, és visszaadja az eredményt.

A program Visual Studio Code-ban való futtatásához lásd: Ismerkedés a programokkal és a VS Code-talQ#.

Felhasználónévterek

Q# programok általában egy felhasználó által elnevezett névtérrel kezdődnek, például

namespace Superposition {
    // Your code goes here.
}

A névterek segítenek a kapcsolódó funkciók rendszerezésében. A névterek felhasználónevűek, és qsharp -fájlonként csak egy namespace lehet.

A Q# standard kódtár előre definiált névterekkel rendelkezik, amelyek kvantumprogramokban használható függvényeket és műveleteket tartalmaznak. További információ: Beépített névterek.

A Jupyter-jegyzetfüzetek nem használnak felhasználói névtereket.

EntryPoint()

Az @EntryPoint() attribútum közli a fordítóval Q# , hogy hol kezdje el végrehajtani a programot. A több függvény- és műveletdefinícióval rendelkező programokban a @EntryPoint() függvények vagy műveletek és a programfolyamatok bármelyike előtt elhelyezhető, és sorrendben folytatódik.

    ...
    @EntryPoint()
    operation MeasureOneQubit() : Result {
        ...

A Jupyter notebookok nem használnak belépési pontokat.

A%%qsharp parancs

Alapértelmezés szerint a Q# Jupyter Notebooks-programok az ipykernel Python-kernelt használják. Ha kódot szeretne hozzáadni Q# egy jegyzetfüzetcellához, a %%qsharp Python-csomaggal qsharp engedélyezett parancsot kell használnia. Például egy Jupyter Notebook előző mintakódja a következőképpen néz ki:

import qsharp
%%qsharp

    operation MeasureOneQubit() : Result {
        // Allocate a qubit, by default it is in zero state      
        use q = Qubit();  
        // We apply a Hadamard operation H to the state
        // It now has a 50% chance of being measured 0 or 1  
        H(q);      
        // Now we measure the qubit in Z-basis.
        let result = M(q);
        // We reset the qubit before releasing it.
        Reset(q);
        // Display the result
        Message($"Result is {result}");
        // Finally, we return the result of the measurement.
        return result;
    
    }
    MeasureOneQubit();

Figyelje meg, hogy nincs szükség olyan felhasználónévre vagy @EntryPoint()névtérre, amelyre nincs szükség a Jupyter-notebookokhoz. Belépési pont helyett a rendszer közvetlenül az utolsó sorban hívja meg a műveletet. Azt is vegye figyelembe, hogy egy Message utasítás lett hozzáadva a Jupyter Notebook kódhoz az eredmény megjelenítéséhez. Ha a korábbi Q# programot a VS Code-ban futtatja, a beépített szimulátor alapértelmezés szerint megjeleníti az eredményt.

A parancs használatakor %%qsharp :

  • A parancs engedélyezéséhez először futtatnia import qsharp kell az %%qsharp parancsot.
  • A %%qsharp parancs hatóköre a teljes cellára kiterjed, amelyben megjelenik. Vegye figyelembe, hogy a jegyzetfüzet cellatípusát Pythonról értékre módosítja Q#.
  • A Q# parancsot követő kódnak meg kell felelnie a szabványos Q# kódolási szintaxisnak. A megjegyzéseket például cellák helyett %%qsharp# használva // jelöli, a kódsoroknak pedig pontosvesszővel ;kell végződniük.
  • A %%qsharp parancsot nem lehet megelőzni vagy követni egy Python-utasítással a cellában.

Ha egy Jupyter Notebook program használatát szemlélteti, olvassa el az Ismerkedés a programokkal és a VS Code-tal Q#című témakört.

Típusok

Q# számos olyan beépített típust biztosít, amelyek a legtöbb nyelvben gyakoriak, például Inta , Double, Boolés a , valamint Stringa kvantum-számítástechnikára jellemző típusokat. A típus például bármely qubitmérés eredményét jelöli, Result és két lehetséges definiált érték egyikével rendelkezhet: One és Zero. A példaprogramban a művelet MeasureOneQubit() visszatérési Result típust vár, a M művelet pedig a qubitet méri, és a Resultértéket adja vissza.

...
// operation definition expecting a return type of Result
operation MeasureOneQubit() : Result {
    ...
    // Now we measure the qubit in Z-basis, returning a Result type
    let result = M(q);
    ...
}

Q# olyan típusokat is biztosít, amelyek tartományokat, tömböket és rekordokat határoznak meg. Akár saját egyéni típusokat is definiálhat.

A qubitek lefoglalása

A fájlban Q#a qubitek a use kulcsszón keresztül vannak lefoglalva.

A példánk egyetlen qubitet határoz meg:

// Allocate a qubit.
use q = Qubit();
...

de több qubitet is lefoglalhat, és mindegyikhez hozzáférhet az indexén keresztül:

...
use qubits = Qubit[2];
X(qubits[1]);
H(qubits[0]);
...

Alapértelmezés szerint a use kulcsszóval lefoglalt összes qubit nulla állapotban kezdődik. Minden qubitet vissza kell állítani a nulla állapotba, mielőtt a program végén kibocsátanák. A qubit alaphelyzetbe állításának sikertelensége futásidejű hibát vált ki.

// Reset a qubit.
Reset(q);
...

Kvantumműveletek

A lefoglalás után a qubit átadható a műveleteknek és függvényeknek, más néven hívható függvényeknek. A műveletek a program alapvető építőelemei Q# . A Q# művelet egy kvantum-alrutin. Azaz olyan meghívható rutin, amely olyan kvantumműveleteket tartalmaz, amelyek módosítják a qubit-regiszter állapotát.

A Q# művelet definiálásához meg kell adnia a művelet nevét a bemeneteivel és kimenetével együtt. Példánkban az egyetlen művelet lényegében a teljes program. Nem vesz fel paramétereket, és a következő visszatérési típusra Resultszámít:

operation MeasureOneQubit() : Result {
    ...
}

Íme egy alapszintű példa, amely nem vesz fel paramétereket, és nem számít visszatérési értékre. Az Unit érték más nyelveken is megegyezik NULL .

operation SayHelloQ() : Unit {
    Message("Hello quantum world!");
}

A Q# standard kódtár olyan műveleteket is biztosít, amelyeket a programokban használhat, például a Hadamardot vagy a H példaprogramban használt műveletet. A Z-alapú qubitet figyelembe véve a H művelet egyenletes szuperpozícióba helyezi a qubitet. A szuperpozíciót követően a qubit 50%-os eséllyel nulla vagy egy értéket mér.

Qubitek mérése

A kvantumméréseknek számos típusa létezik, de Q# az egy qubiten, más néven Pauli-méréseken végzett projektív mérésekre összpontosít. Egy adott alapban történő méréskor (például a számítási alap $\ket{0},\ket{1}$) a qubit állapotát a mérés alapjául szolgáló állapotra vetíti, így a kettő közötti szuperpozíció megsemmisül.

A példaprogram a M műveletet használja, amely egyetlen qubit mérését hajtja végre a Pauli Z alapján, és egy típust Result ad vissza.

Beépített névterek

A standard Q# kódtár beépített névtereket használ, amelyek kvantumprogramokban használható függvényeket és műveleteket tartalmaznak. A névtér Microsoft.Quantum.Intrinsic például olyan gyakran használt műveleteket és függvényeket tartalmaz, mint Ma , az eredmények mérésére és Messagea felhasználói üzeneteknek a program bármely pontjára való megjelenítéséhez.

Meghívhat egy függvényt vagy műveletet a teljes névtér megadásával, vagy egy open utasítással elérhetővé teheti az adott névtér összes függvényét és műveletét, és könnyebben olvashatóvá teheti a kódot. Ez a két példa ugyanazt a műveletet hívja meg:

 Microsoft.Quantum.Intrinsic.Message("Hello quantum world!");
open Microsoft.Quantum.Intrinsic;
Message("Hello quantum world!");

Figyelje meg, hogy a példaprogramban nincsenek open utasítások vagy hívások teljes névtérrel. Ennek az az oka, hogy a Q# fejlesztői környezet alapértelmezés szerint automatikusan betölt két névteret – Microsoft.Quantum.Core és Microsoft.Quantum.Intrinsic – amelyek gyakran használt függvényeket és műveleteket tartalmaznak.

Kihasználhatja a Microsoft.Quantum.Measurement névteret, és a MResetZ művelettel optimalizálhatja a kódot a példaprogramban. MResetZ a mérési és alaphelyzetbe állítási műveleteket egyetlen lépésben egyesíti, ahogyan az alábbi példában is látható:

namespace Superposition {

    // open the namespace for the MResetZ operation
    open Microsoft.Quantum.Measurement;

    @EntryPoint()
    operation MeasureOneQubit() : Result {
        // Allocate a qubit, by default it is in zero state      
        use q = Qubit();  
        // We apply a Hadamard operation H to the state
        // It now has a 50% chance of being measured 0 or 1  
        H(q);   
        // Measure and reset the qubit, and return the result value   
        return MResetZ(q);
    }
    
}