Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Ez az oktatóanyag bemutatja, hogyan írhat és szimulálhat egy alapszintű kvantumprogramot, amely egyéni qubiteken működik.
Bár Q# elsősorban nagy léptékű kvantumprogramok magas szintű programozási nyelveként hozták létre, a kvantumprogramozás alacsonyabb szintjének, vagyis az adott qubitek közvetlen kezelésére is használható. Ez az oktatóanyag közelebbről is áttekinti a Quantum Fourier Transform (QFT) nevű alrutint, amely számos nagyobb kvantum-algoritmus szerves része.
Ebben az oktatóanyagban a következőket sajátíthatja el:
- Kvantumműveletek definiálása a következőben Q#: .
- Írja meg a Quantum Fourier Transform áramkört.
- Kvantumművelet szimulálása a qubit-foglalástól a mérési kimenetig.
- Figyelje meg, hogyan fejlődik a kvantumrendszer szimulált hullámfüggése a művelet során.
Megjegyzés
A kvantuminformáció-feldolgozás ezen alacsonyabb szintű nézetét gyakran kvantumkörökben írják le, amelyek a kapuk vagy műveletek szekvenciális alkalmazását jelölik a rendszer meghatározott qubitjeire. Így az egymás után alkalmazott egy- és több qubites műveletek könnyen ábrázolhatók a kapcsolatcsoportok diagramjaiban. Az oktatóanyagban használt három qubites kvantum Fourier-transzformáció például a következő kapcsolatcsoportként jelenik meg:
Előfeltételek
A Visual Studio Code (VS Code) legújabb verziója vagy a WEBES VS Code megnyitása.
A (QDK) bővítmény legújabb verziójaMicrosoft Quantum Development Kit. A telepítés részleteiért lásd: QDK-bővítmény beállítása.
A Jupyter Notebookok használatához telepítse a Python - és Jupyter-bővítményeket a VS Code-ban.
A legújabb
qdkPython-csomag azjupyterextrával. A telepítéshez nyisson meg egy terminált, és futtassa a következő parancsot:pip install --upgrade "qdk[jupyter]"
Új Q# fájl létrehozása
- A VS Code-ban nyissa meg a Fájl menüt, és válassza az Új szövegfájl lehetőséget.
- Mentse a fájlt QFTcircuit.qs néven. Ez a fájl tartalmazza a program Q# kódját.
- Nyissa meg a QFTcircuit.qs parancsot.
QFT áramkör írása Q#
Az oktatóanyag első része a Q# művelet Mainmeghatározásából áll, amely három qubiten hajtja végre a kvantum Fourier-átalakítást. A DumpMachine függvény annak megfigyelésére szolgál, hogyan fejlődik a három qubites rendszer szimulált hullámfüggvénye a művelet során. Az oktatóanyag második részében mérési funkciókat ad hozzá, és összehasonlítja a qubitek mérés előtti és utáni állapotát.
A műveletet lépésről lépésre kell felépíteni. Másolja és illessze be a kódot a következő szakaszokban a QFTcircuit.qs fájlba.
A szakasz teljes Q# kódját hivatkozásként tekintheti meg.
Importálja a szükséges Q# könyvtárakat
A fájlodon belül importáld a megfelelő névtereket.
import Std.Diagnostics.*;
import Std.Math.*;
import Std.Arrays.*;
// operations go here
Műveletek definiálása argumentumokkal és visszatérésekkel
Ezután adja meg a Main műveletet:
operation Main() : Unit {
// do stuff
}
A Main művelet soha nem vesz fel argumentumokat, és egyelőre egy Unit olyan objektumot ad vissza, amely hasonló a C# void vagy egy üres tuple Tuple[()] visszaadásához a Pythonban.
Később módosíthatja a műveletet, hogy a mérési eredmények tömbje legyen visszaadva.
Qubitek hozzárendelése
A műveleten Q# belül foglaljon le egy három qubitből álló nyilvántartást a use kulcsszóval. A use segítségével a qubitek automatikusan a $\ket{0}$ állapotban lesznek lefoglalva.
use qs = Qubit[3]; // allocate three qubits
Message("Initial state |000>:");
DumpMachine();
A valós kvantumszámításokhoz hasonlóan Q# nem teszi lehetővé a qubitállapotok közvetlen elérését. A DumpMachine művelet azonban kinyomtatja a target gép aktuális állapotát, így értékes betekintést nyújthat a hibakereséshez és a tanuláshoz, ha a teljes állapotú szimulátorral együtt használják.
Egy qubites és szabályozott műveletek alkalmazása
Ezután alkalmazza a műveletet alkotó Main műveleteket.
Q# már tartalmaz sok ilyen és más alapvető kvantumműveletet a Std.Intrinsic névtérben.
Megjegyzés
Std.Intrinsic nem került importálásra a korábbi kódrészletbe a többi névtérrel együtt, mivel a fordító minden Q# programhoz automatikusan betölti.
Az első lépésként elvégezzük a H (Hadamard) műveletet az első qubit esetében.
Ha egy műveletet egy adott qubitre szeretne alkalmazni egy regiszterből (például egy Qubit tömbből Qubit[]), használjon szabványos indexjelezést.
A műveletet tehát a H regiszter qs első qubitre való alkalmazása a következő formában történik:
H(qs[0]);
A művelet egyes qubitekre való alkalmazása H mellett a QFT-kapcsolatcsoport elsősorban szabályozott R1 forgásokból áll. Egy R1(θ, <qubit>) művelet általában változatlanul hagyja a qubit $\ket{0}$ összetevőjét, miközben $e^{i\theta}$ forgást alkalmaz a $\ket{1}$ összetevőre.
Q# megkönnyíti egy művelet futtatásának kondicioncióját egy vagy több vezérlési qubiten. A hívás általában a Controlled előtaggal kezdődik, és a művelet argumentumai a következőképpen változnak:
Op(<normal args>) $\to$ Controlled Op([<control qubits>], (<normal args>))
Vegye figyelembe, hogy a vezérlő qubit argumentumának tömbnek kell lennie, még akkor is, ha egyetlen qubitről van szó.
A QFT szabályozott műveletei azok az R1 műveletek, amelyek az első qubitre hatnak, és amelyeket a második és harmadik qubit szabályoz.
Q# A fájlban hívja meg ezeket a műveleteket az alábbi utasításokkal:
Controlled R1([qs[1]], (PI()/2.0, qs[0]));
Controlled R1([qs[2]], (PI()/4.0, qs[0]));
A PI() függvény a pi radiánok forgásának meghatározására szolgál.
SWAP művelet alkalmazása
A megfelelő H műveletek és szabályozott forgások második és harmadik qubitre való alkalmazása után a kapcsolatcsoport a következőképpen néz ki:
//second qubit:
H(qs[1]);
Controlled R1([qs[2]], (PI()/2.0, qs[1]));
//third qubit:
H(qs[2]);
Végül egy SWAP műveletet alkalmaz az első és a harmadik qubitre a kvantumáramkör befejezéséhez. Ez a művelet azért szükséges, mert a kvantum Fourier-transzformáció fordított sorrendben adja ki a qubiteket, így a felcserélések lehetővé teszik az alrutin zökkenőmentes integrációját nagyobb algoritmusokba.
SWAP(qs[2], qs[0]);
A Q# művelet most már tartalmazza a kvantum Fourier-transzformáció qubitszintű műveleteit:
Qubitek felszabadítása a memóriából
Végső lépésként ismételten meghívja DumpMachine(), hogy ellenőrizze a művelet utáni állapotot, és felszabadítsa a qubiteket. A qubitek $\ket{0}$ állapotban voltak, amikor lefoglalta őket, és a művelettel ResetAll vissza kell állítani a kezdeti állapotukat.
Annak megkövetelése, hogy az összes qubitet explicit módon állítsa vissza a $\ket{0}$ értékre, annak alapvető funkciója Q#, hogy más műveletek pontosan tudják az állapotukat, amikor ugyanazokat a qubiteket (szűkös erőforrást) kezdik használni. Emellett az alaphelyzetbe állításuk biztosítja, hogy nincsenek összekapcsolva a rendszer más qubitjeivel. Ha az alaphelyzetbe állítást nem egy use foglalási blokk végén hajtják végre, futásidejű hiba fordulhat elő.
Adja hozzá a következő sorokat a Q# fájlhoz:
Message("After:");
DumpMachine();
ResetAll(qs); // deallocate qubits
A teljes QFT-művelet
A Q# program befejeződött. A QFTcircuit.qs fájlnak így kell kinéznie:
import Std.Diagnostics.*;
import Std.Math.*;
import Std.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
}
A QFT-áramkör futtatása
A művelet egyelőre Main nem ad vissza értéket – a művelet értéket ad Unit vissza. Később módosítja a műveletet, hogy a mérési eredmények tömbje (Result[]) legyen visszaadva.
- A program futtatásához válassza a Fájl futtatása Q# parancsot
Mainaz előző menüben, vagy nyomja le a Ctrl + F5 billentyűkombinációt. A program azMainalapértelmezett szimulátoron futtatja a műveletet. - A
Messageés aDumpMachinekimenetek a hibakeresési konzolon jelennek meg.
Ha kíváncsi arra, hogy más bemeneti állapotokat hogyan érint, kísérletezzen más qubitműveletek alkalmazásával az átalakítás előtt.
Mérések hozzáadása a QFT-kapcsolatcsoporthoz
A DumpMachine függvény kijelzője a művelet eredményeit mutatta, de sajnos a kvantummechanika egyik sarokköve azt állítja, hogy egy valódi kvantumrendszer nem rendelkezhet ilyen DumpMachine függvénnyel.
Ehelyett az információkat méréseken keresztül nyerik ki, amelyek általában nem csak a teljes kvantumállapotról nyújtanak információt, hanem magát a rendszert is drasztikusan megváltoztathatják.
Számos kvantummérés létezik, de az alábbi példa a legalapvetőbbre összpontosít: az egy qubiten végzett projektív mérésekre. Ha egy adott alapon végzett mérés (például a számítási alap $ { \ket{0}, \ket{1} } $), a qubit állapota a mért alapállapotra lesz kivetítve, így a kettő közötti szuperpozíciót megsemmisíti.
A QFT-művelet módosítása
A programon belüli Q# mérések végrehajtásához használja a M műveletet, amely egy típust Result ad vissza.
Először módosítsa a Main műveletet, hogy a Result[] helyett a mérési eredmények tömbjét adja vissza Unit.
operation Main() : Result[] {
Tömb definiálása és inicializálása Result[]
A qubitek kiosztása előtt deklaráljon és kösse össze a háromelemű tömböt (minden qubithez egyet Result ):
mutable resultArray = [Zero, size = 3];
A mutable kulcsszó-előbontás resultArray lehetővé teszi a változó módosítását a kód későbbi részében, például mérési eredmények hozzáadásakor.
Hajtsd végre a méréseket a for ciklusban, és add hozzá az eredményeket a tömbhöz.
A QFT-átalakítási műveletek után szúrja be a következő kódot:
for i in IndexRange(qs) {
resultArray w/= i <- M(qs[i]);
}
A IndexRange tömböt meghívó függvény (például qubitek qstömbje) egy tartományt ad vissza a tömb indexei felett.
Itt a for ciklusban használják az egyes qubitek egymás utáni mérésére a M(qs[i]) utasítás használatával.
Ezután minden mért Result típus (vagy Zero, vagy One) hozzáadódik a megfelelő indexpozícióhoz resultArray egy frissítési és újbóli hozzárendelési utasítással.
Megjegyzés
Ennek az utasításnak a szintaxisa egyedi a Q# kontextusban, de megfelel a más nyelvek, például F# és R esetén látható változó-újra-hozzárendelésnek resultArray[i] <- M(qs[i]).
A set kulcsszó mindig a mutable-val kötött változók újrahozzárendelésére szolgál.
Visszatérés resultArray
A három qubit mérésével és az eredmények resultArray-hoz való hozzáadásával biztonságosan alaphelyzetbe állíthatja és felszabadíthatja a qubiteket, mint korábban. A mérések visszaadásához szúrja be a következőt:
return resultArray;
A QFT-kapcsolatcsoport futtatása a mérésekkel
Most módosítsa a függvények elhelyezését úgy DumpMachine , hogy a mérések előtti és utáni állapotot adja ki.
A végleges Q# kódnak így kell kinéznie:
import Std.Diagnostics.*;
import Std.Math.*;
import Std.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;
}
Tipp.
Ne felejtse el menteni a fájlt minden alkalommal, amikor módosítja a kódot, mielőtt újra futtatja.
- A program futtatásához válassza a Futtatás Q# lehetőséget a fenti
Mainmenüben, vagy nyomja le a Ctrl + F5 billentyűkombinációt. A program azMainalapértelmezett szimulátoron futtatja a műveletet. - A
Messageés aDumpMachinekimenetek a hibakeresési konzolon jelennek meg.
A kimenetnek a következőhöz hasonlóan kell kinéznie:
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]
Ez a kimenet néhány különböző dolgot szemléltet:
- A visszaadott eredményt az előméréssel
DumpMachineösszehasonlítva egyértelműen nem mutatja a QFT utáni szuperpozíciót az alapállapotok alapján. A mérés csak egy alapállapotot ad vissza, amelynek valószínűségét az adott állapot amplitúdója határozza meg a rendszer hullámfüggvényében. - A mérés
DumpMachineutáni mérés megváltoztatja magát az állapotot, és az alapállapotok feletti kezdeti szuperpozícióból a mért értéknek megfelelő egyetlen alapállapotra vetít.
Ha többször megismételi ezt a műveletet, az eredménystatisztikák a QFT utáni állapot egyenlően súlyozott szuperpozícióját mutatják, amely véletlenszerű eredményt ad minden egyes lövéshez. Azonban amellett, hogy nem hatékony és még mindig tökéletlen, ez mégis csak az alapállapotok relatív amplitúdóit reprodukálná, nem pedig a közöttük lévő relatív fázisokat. Az utóbbi nem jelent problémát ebben a példában, de a relatív fázisok akkor jelennek meg, ha összetettebb bemenetet adnak a QFT-hez, mint a $\ket{000}$.
A Q# műveletek használatával egyszerűsítheti a QFT áramkört
Ahogy a bevezetésben említettük, a hatalom nagy része Q#abban rejlik, hogy lehetővé teszi az egyes qubitek kezelésével kapcsolatos aggodalmak absztrakcióját.
Valóban, ha alkalmazható, teljes körű kvantumprogramokat szeretne fejleszteni, azzal foglalkozni, hogy egy H művelet egy adott rotáció előtt vagy után megy-e, csak lelassítaná. Az Azure Quantum biztosítja a ApplyQFT műveletet, amelyet tetszőleges számú qubithez használhat és alkalmazhat.
Az első
Hművelettől kezdve aSWAPműveletig tartó részt a következőre cserélje:ApplyQFT(qs);A kódnak így kell kinéznie
import Std.Diagnostics.*; import Std.Math.*; import Std.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; }Futtassa újra a Q# programot, és figyelje meg, hogy a kimenet megegyezik a korábbival.
A műveletek Q# valódi előnyeinek megtekintéséhez módosítsa a qubitek számát valami másra, mint
3.
mutable resultArray = [Zero, size = 4];
use qs = Qubit[4];
//...
Így tetszőleges számú qubithez alkalmazhatja a megfelelő QFT-t anélkül, hogy minden qubithez új H műveleteket és forgatásokat kellene hozzáadnia.
Kapcsolódó tartalom
További Q# oktatóanyagok:
- A kvantum véletlenszerű számgenerátor bemutatja, hogyan írhat olyan Q# programot, amely véletlenszerű számokat hoz létre qubitből szuperpozícióban.
- A Grover keresési algoritmusa bemutatja, hogyan írhat olyan Q# programot, amely a Grover keresési algoritmusát használja.
- A kvantum-összefonódás bemutatja, hogyan írhat olyan Q# programot, amely manipulálja és méri a qubiteket, és bemutatja a szuperpozíció és az összefonódás hatásait.
- A Quantum Katas öngyors oktatóanyagok és programozási gyakorlatok, amelyek célja a kvantum-számítástechnika és Q# a programozás elemeinek egyidejű tanítása.