Quantum Development Kit (QDK) zajszimulátor

Azok a kvantumrendszerek, amelyek nagyon jól elkülönülnek a környezetüktől, így más rendszer nem kommunikál a qubitekkel, zárt kvantumrendszereknek nevezzük. Ezzel szemben egy olyan eszköz, amely valamilyen mértékű interakciónak vagy zajnak van kitéve a környezetéből, egy nyílt kvantumrendszer.

A Quantum Development Kit előzetes szimulátort biztosít a nyílt kvantumrendszerek szimulációihoz. Ez a funkció lehetővé teszi a zaj hatására a programok viselkedésének Q# szimulálását, valamint a kvantumalgoritmusok stabilizáló reprezentációjának (más néven CHP-szimulációjának) használatát, azaz a kizárólag CNOT-, Hadamard- és fáziskapukból álló algoritmusokat.

A zajszimulátor a következőkkel használható:

  • Python-gazdaprogramok
  • Q# különálló jegyzetfüzetek
  • C#-gazdagépprogramok

A zajszimulátorok még nem támogatottak:

  • Q# önálló parancssori programok
  • QIR-alapú végrehajtható fájlok

Az előzetes verziójú szimulátorok meghívása a Pythonból

Létre kell hoznia egy Python-gazdaprogramot, amely meghívja a kvantumprogramot, és tovább tudja feldolgozni a visszaadott eredményeket. További információ: Programok futtatásának módjaiQ#.

  1. Első lépésként importálja a QuTiP-kódtárat, amely egy népszerű Python-kódtár a zárt és nyitott kvantumrendszerek állapotainak és folyamatainak a manipulálására.

    import qutip as qt
    
  2. A nyílt rendszerszimulátor használatát a qsharp csomag használatával engedélyezheti:

    import qsharp
    

    A Pythonba importált műveletek a .simulate() metódushoz Q# hasonlóan egy olyan metódust .simulate_noise() is közzétenek, amely programok nyílt rendszerszimulátorokon való futtatására Q# használható.

    Alapértelmezés szerint a .simulate_noise() metódus ideális hibamodellt feltételez (azaz nincs zaj). Egy adott hibamodell konfigurálásához a és qsharp.set_noise_model függvényekkel qsharp.get_noise_model lekérheti és beállíthatja az előzetes verziójú szimulátorok aktuális zajmodellét. Minden hibamodell szótárként jelenik meg a belső műveletnevektől a belső műveletek hibáit képviselő objektumokig. További információ: Nyílt rendszerek zajmodelljeinek konfigurálása.

  3. A Python gazdaprogramjának mappájában hozza létre a következő Q# programot egy nevű NoisySimulation.qsfájlban:

    namespace NoisySimulation {
        open Microsoft.Quantum.Intrinsic;
        open Microsoft.Quantum.Measurement;
        open Microsoft.Quantum.Canon;
        open Microsoft.Quantum.Diagnostics;
    
        @EntryPoint()
        operation DumpPlus() : Unit {
            use q = Qubit();
            H(q);
            DumpMachine();
            X(q);
            Reset(q);
        }
    }
    
  4. Adja hozzá a következő kódot a gazdaprogramhoz a Q# művelet DumpPlusimportálásához:

    from NoisySimulation import DumpPlus
    
    print(DumpPlus.simulate_noise())
    
    'text/plain': 'Mixed state on 3 qubits: [ [0.5000000000000001 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0.5000000000000001 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i] [0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i] [0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i] [0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i] [0.5000000000000001 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0.5000000000000001 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i] [0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i] [0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i] [0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i, 0 + 0 i] ]'
    
  5. A kimenetet tekintve két különböző különbséget láthat az alapértelmezett szimulátor kimenetéhez képest, amelyeket a használatával .simulate()hívhat meg:

  • Az előzetes verziójú szimulátorok meghatározott méretű kvantumregisztrációs adatbázisokat (alapértelmezés szerint három qubitet) használnak, és qubiteket foglalnak le a regiszterből.

  • Az előzetes verziójú szimulátorok alapértelmezés szerint a kvantumállapotokat sűrűségoperátorként, $\rhoként =\left|\psi\right\rangle\left\langle\psi\right|$jelölik, nem pedig állapotvektorokként. $\left|\psi\right\rangle$

    A fenti kimenetben például az előnézeti szimulátor a \rho\left|= +00+00\right\rangle\left\langle\right|$ sűrűségoperátort $adja ki, amelyet a QuTiP használatával ellenőrizheti.

    ket_zero = qt.basis(2, 0)
    ket_one = qt.basis(2, 1)
    ket_plus = (ket_zero + ket_one).unit()
    
    ket_psi = qt.tensor(ket_plus, ket_zero, ket_zero)
    
    rho = ket_psi * ket_psi.dag()
    print(rho)
    
    Quantum object: dims = [[2, 2, 2], [2, 2, 2]], shape = (8, 8), type = oper, isherm = True
    Qobj data =
    [[0.5 0.  0.  0.  0.5 0.  0.  0. ]
     [0.  0.  0.  0.  0.  0.  0.  0. ]
     [0.  0.  0.  0.  0.  0.  0.  0. ]
     [0.  0.  0.  0.  0.  0.  0.  0. ]
     [0.5 0.  0.  0.  0.5 0.  0.  0. ]
     [0.  0.  0.  0.  0.  0.  0.  0. ]
     [0.  0.  0.  0.  0.  0.  0.  0. ]
     [0.  0.  0.  0.  0.  0.  0.  0. ]]
    

Megjegyzés

A QuTiP-kódtár egy nagyon hasznos kódtár a kvantumállapotok használatakor. A QuTiP-jelölésben a kvantumállapotok a következőképpen vannak megírva qt.basis(d,s): , ahol d a rendszerek dimenziója, az s pedig az állapot. A 0\rangle$ kvantumállapot $|például a következőként ket_zero = qt.basis(2, 0)írható: . A QuTiP-módszerekkel és -funkciókkal kapcsolatos további információkért tekintse meg a QuTiP felhasználói útmutatóját.

Nyílt rendszerek zajmodelljeinek konfigurálása

Az előzetes verziójú szimulátorok az qsharp.config objektummal konfigurálhatók. Ha például egy qubitre szeretné módosítani a regiszter méretét, módosíthatja a simulators.noisy.nQubits konfigurációs beállítást:

qsharp.config['simulators.noisy.nQubits'] = 1
print(DumpPlus.simulate_noise())
'text/plain': 'Mixed state on 1 qubits: [ [0.5000000000000001 + 0 i, 0.5000000000000001 + 0 i] [0.5000000000000001 + 0 i, 0.5000000000000001 + 0 i] ]'

Ideális zajmodell

A programok szimulálásához Q# használt zajmodellt a csomag számos függvényének qsharp használatával módosíthatja. Ha például a zajmodellt egy ideális modellre szeretné inicializálni (azaz zaj nélkül), használhatja a következőt set_noise_model_by_name: . Ezután a következő paranccsal get_noise_modelérheti el a zajmodellt:

qsharp.set_noise_model_by_name('ideal')
noise_model = qsharp.get_noise_model()

Megjegyzés

Ha Jupyter Notebooksot használ a Python-program fejlesztéséhez, a %noise_model --set-by-name magic paranccsal inicializálhatja a zajmodellt egy ideális modellre.

Ez a zajmodell Python-szótárként jelenik meg az előkészületektől, mérésektől és kapuktól a Python-objektumokig, amelyek a zajt képviselik mindegyikben. Az ideális zajmodellben például a H operation szimulált értéket egy egységes mátrix szimulálja:

print(noise_model.h)
Quantum object: dims = [[2], [2]], shape = (2, 2), type = oper, isherm = True
Qobj data =
[[ 0.70710678  0.70710678]
 [ 0.70710678 -0.70710678]]

Zajmodell depolarizálása

Az ideális zajmodell mellett más zajmodelleket is konfigurálhat. A depolarizáló csatorna például a kvantumrendszerek zajának egyszerű modellje. A kvantumcsatornák térképként $tekinthetők meg \Delta_{p}$, egy paramétertől $\lambda$ függően, amely egy kvantumállapotot \rho$ kvantumállapotra $$képez le \rho^{'}$. Az egy qubites depolarizáló csatorna a következőképpen íródik:

$$\Delta_{p}(\rho) = (1 p) \frac{\mathbb{I}}{{2} + p \rho $$

A zajmodellt módosíthatja úgy, hogy a QuTiP-függvények használatával depolarizáló zajt adjon hozzá.

I, X, Y, Z = [P.as_qobj() for P in qsharp.Pauli]

def depolarizing_noise(p=1.0):
    return p * qt.to_super(I) + ((1 - p) / 4) * sum(map(qt.to_super, [I, X, Y, Z]))
    
noise_model.h = depolarizing_noise(0.99) * qt.to_super(qt.qip.operations.hadamard_transform())

print(noise_model.h)
Quantum object: dims = [[[2], [2]], [[2], [2]]], shape = (4, 4), type = super, isherm = True
Qobj data =
[[ 0.5    0.495  0.495  0.5  ]
 [ 0.495 -0.495  0.495 -0.495]
 [ 0.495  0.495 -0.495 -0.495]
 [ 0.5   -0.495 -0.495  0.5  ]]

A depolarizáló zajmodellt alkalmazhatja a \rho_{\text{zero=\left|}}0 0\right\rangle\left\langle\right|$ sűrűségoperátorra$, hogy ellenőrizze, hogyan változik a zaj depolarizáló hatása alatt. Ezzel a modellel már nem kapja meg a pontos \rho_+++|$\rangle\langle állapotot$, mert a Q# program kisebb hibát észlelt a zaj miatt a(z) H operationalkalmazásában:}=|{

ket_zero = qt.basis(2, 0)
rho_zero = ket_zero * ket_zero.dag()
rho_zero_dep_noise = noise_model.h(rho_zero)
print(rho_zero_dep_noise)
Quantum object: dims = [[2], [2]], shape = (2, 2), type = oper, isherm = True
Qobj data =
[[0.5   0.495]
 [0.495 0.5  ]]

Zajmodellek beállítása

Miután módosította a zajmodellt, beállíthatja a programok szimulálásához Q# használt aktív zajmodellként:

qsharp.set_noise_model(noise_model)
print(DumpPlus.simulate_noise())
'text/plain': 'Mixed state on 1 qubits: [ [0.5002403569793327 + 0 i, 0.49578581259001314 + 0 i] [0.49578581259001314 + 0 i, 0.499235767960659 
+ 0 i] ]'

Tipp

Bármely kvantumcsatorna rendelkezik operátor-összeg ábrázolású sűrűségmátrixon $(\rho$), így $a \Delta_{p}(\rho )=\sum_{i}K_{i\rho K_{i}}^{\dagger}$ és $\sum_{i}K_{i}^{\dagger}K_{i}= \mathcal{I}$, ahol $a mátrixok K_{i}$ a Kraus operátorok.

Egy zajmodell Kraus-felbontását a QuTiP-kódtár használatával számíthatja ki:

kraus_operators = qt.to_kraus(noise_model.h)
print(kraus_operators)
[Quantum object: dims = [[2], [2]], shape = (2, 2), type = oper, isherm = True
Qobj data =
[[ 0.06123724 -0.02041241]
[-0.02041241  0.02041241]], Quantum object: dims = [[2], [2]], shape = (2, 2), type = oper, isherm = True
Qobj data =
[[ 0.70445014  0.70445014]
[ 0.70445014 -0.70445014]], Quantum object: dims = [[2], [2]], shape = (2, 2), type = oper, isherm = False
Qobj data =
[[ 0.01550345 -0.03309488]
[ 0.0506863   0.03309488]], Quantum object: dims = [[2], [2]], shape = (2, 2), type = oper, isherm = False
Qobj data =
[[-2.74180053e-18  5.00000000e-02]
[-5.27753089e-18  5.00000000e-02]]]

Az olyan rotációk folyamatos idejű hibái, mint például a Rx, Ryés Rz a műveletek, úgy határozhatók meg, hogy kvantumdinamikus generátorokat állít be, amelyek koherens és dekódoló evolúciót is tartalmaznak. A függvény különösen qsharp.to_generator egy hamiltoni és egy vagy több ugróoperátor (más néven Lindblad operátorok) dinamikus generátorának létrehozására használható.

Ha például úgy szeretné beállítani a Rz műveletet, hogy egy H = -0,48 Z$ hamiltonost $alkalmazzon egy véges $T_1$ és $T_2$ folyamattal együtt:

qsharp.set_noise_model_by_name(
    'ideal',
    rz=to_generator(
        -0.48 * qt.sigmaz(),
        t1_dissipation(100.0),
        t2_dissipation(25.0)
    )
)

A folyamatos idejű hibafolyamatok generátor-együttesekként is megadhatóak; azaz olyan rögzített kvantumfolyamatokkal, amelyek egy dinamikus generátor előtt vagy után lépnek érvénybe. A folyamatos idejű fejlődés előtt vagy után alkalmazandó folyamatok megadásához a és post a pre kulcsszó argumentumok a következőhöz to_generatoradhatók meg:

qsharp.set_noise_model_by_name(
    'ideal',
    rz=to_generator(
        -0.48 * qt.sigmaz(),
        t1_dissipation(100.0),
        t2_dissipation(25.0),
        # Applies a 5% depolarizing process after each call to Rz.
        post=depolarizing_process(0.95)
    )
)

Stabilizátorzaj-modellek konfigurálása

Konfigurálhatja az előnézeti szimulátort a stabilizátor-kapcsolatcsoportokhoz (vagy stabilizátor-algoritmusokhoz), más néven CHP-szimulációkhoz. A CHP (CNOT-Hadamard-Phase) szimuláció lehetővé teszi a stabilizátorprogramok nagy teljesítményű szimulációját; azaz olyan kvantum-algoritmusok, amelyek kizárólag ellenőrzött-NOT, Hadamard és π/2 fázisú kapukból (amelyeket a S művelet jelölQ#) és Pauli-alapú mérésekből állnak. A stabilizátor programok hatékonyan szimulálhatók egy klasszikus számítógépen, ahogy azt a Gottesman–Knill tétel is mutatja.

  1. Hozzon létre egy új zajmodellt a használatával get_noise_model_by_name , és állítsa be aktív zajmodellként:

    qsharp.set_noise_model_by_name('ideal_stabilizer')
    
  2. Ahhoz, hogy a legjobban kihasználhassa a stabilizátor zajmodelljeit, konfigurálnia kell a szimulátort, hogy elinduljon a stabilizátor-ábrázolásban:

    qsharp.config['simulators.noisy.representation'] = 'stabilizer'
    print(DumpPlus.simulate_noise())
    

    A kimenet vizualizációja a következő:

    $$\begin{align}\left(\begin{tömb}{c|c c}| 0 & 1 & 0 \\ \hline 1 & 0 & 0 \end{tömb}\right)\end{align}$$

    Tipp

    Ha a Python-gazdaprogramot a terminálról futtatja, a HTML-metaadatokat a kimenetéből szerzi print(.simulate_noise())be. A könnyebb vizualizáció érdekében a Jupyter Notebooks html-táblázatokat jelenít meg ugyanabban a jegyzetfüzetben.

  3. Nevezetesen a stabilizátor-ábrázolás nem támogatja a stabilizátor formalizmusán kívüli műveleteket, mint például a T és a CCNOT. Ez lehetővé teszi, hogy a stabilizátor-ábrázolás jelentősen több qubitet támogatjon, mint más reprezentációk. Vegyük például egy 10 qubitből álló kvantumregisztrációs adatbázist:

    qsharp.config['simulators.noisy.nQubits'] = 10
    print(DumpPlus.simulate_noise())
    

    A kimenet vizualizációja a következő:

    $$\begin{align}\left(\begin{tömb}{cccccccccc|cccccccc|c} 0 & 0 & 0 & 0 & 0 && 0 & 0 & 0 0 && 1 & 0 & 0 & 0 0 & 0 & 0 & 0 & 0 & 0 0 & 0 & 0 0 0 &\\ 1 & 0 0 & 0 & 0 & 0 && 0 & 0 && 0 & 0 & 0 & 0 && 0 0 & 0 & 0 & 0 & 0 & 0 \\ 0 0 && 1 & 0 & 0 & 0 0 & 0 0 0 0 && 0 0 & 0 & 0 & 0 & 0 && 0 & 0 && 0 & 0 & 0 & 0 \\&& 0 0 & 1 & 0 & 0 & 0 0 & 0 & 0 &&& 0 0 & 0 &&&&& 0 0 0 0 0 0 & 0 \\&&&&& 0 0 0 0 0 0 0 & 1 & 0 &&& 0 0 0 & 0 & 0 0 &&&&&&&&&& 0 0 0 0 0 0 \\ 0 & 0 & 0 & 0 && 1 & 0 & 0 & 0 && 0 && 0 0 & 0 & 0 &&& 0 0 0 & 0 \\&&& 0 0 0 & 0 & 0 && 0 0 & 1 & 0 & 0 & 0 & 0 &&&&& 0 0 0 0 0 0 & 0 &&&&&&&&&&\\& 0 0 0 0 0 0 0 0 0 0 1 & 0 0 & 0 & 0 & 0 && 0 & 0 && 0 & 0 & 0 \\&& 0 0 & 0 &&&& 0 0 0 0 0 & 0 && 1 & 0 & 0 & 0 & 0 & 0 && 0 0 & 0 & 0 0 &&&&\\& 0 0 0 0 0 & 0 0 && 0 0 0 &&& 0 0 0 0 & 1 & 0 & 0 & 0 0 &&& 0 & 0 0 & 0 & 0 & 0 \\& \hline 1 & 0 & 0 & 0 && 0 & 0 & 0 0 &&& 0 0 & 0 & 0 &&&& 0 0 0 0 &&&\\&& 0 0 0 0 0 0 & 0 0 &&&&&&& 0 0 0 0 0 0 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 0 &&&&&\\ 0 0 & 0 & 0 0 & 0 & 0 && 0 & 0 & 0 && 0 & 1 & 0 & 0 & 0 & 0 & 0 &&& 0 0 \\ 0 0 &&& 0 0 & 0 & 0 & 0 0 &&&&& 0 0 0 0 0 & 0 0 & 1 & 0 &&& 0 0 & 0 0 & 0 & 0 0 &&&\\&&&&&& 0 0 0 0 0 0 0 & 0 0 & 0 & 0 && 1 & 0 & 0 & 0 & 0 && 0 \\ 0 &&& 0 0 0 & 0 &&& 0 0 & 0 0 & 0 && 0 && 0 0 & 0 & 1 & 0 && 0 0 & 0 0 & 0 \\ 0 &&&&& 0 0 0 0 & 0 0 & 0 && 0 0 0 &&&&&& 0 0 0 0 0 0 0 &&& 0 0 & 0 & 0 \\ 0 && 0 & 0 & 0 && 0 & 0 & 0 &&& 0 0 0 && 0 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ 0 & 0 &&&&& 0 0 0 0 & 0 0 &&&&&& 0 0 0 0 0 & 0 0 & 0 0 & 0 & 0 0 0 &&&&&\\&& 0 0 0 0 & 0 & 0 & 0 0 && 0 & 0 & 0 & 0 && 0 0 & 0 & 0 & 0 & 0 & 1 & 0 \end{tömb}\right)\end{\end{align}$$

  4. Módosítsa a Q# programot a következő kóddal, ahol a DumpBellPair művelet egy függvényt DumpMachine hajt végre egy Bell-párra, amely egy összefonódott qubitpár.

    operation DumpBellPair() : Unit {
        use left = Qubit();
        use right = Qubit();
        within {
            H(left);
            CNOT(left, right);
        } apply {
            DumpMachine();
        }
    }
    
  5. Futtassa a DumpBellPair műveletet a stabilizátor zajszimulátorával. Az egyszerűség kedvéért használjon négy qubitből álló kvantumregisztrációs regisztert.

    from NoisySimulation import DumpBellPair
    
    qsharp.config['simulators.noisy.nQubits'] = 4
    DumpBellPair.simulate_noise()
    

    A kimenet vizualizációja a következő:

    $$\begin{align}\left(\begin{tömb}{cccc|cccc|c} 0 & 0 0 && 0 & 1 & 0 & 0 & 0 \\& 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 0 & 0 &\\ 0 & 1 & 0 & 0 & 0 0 0 && 0 & 0 \\ 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 &\\ \hline 1 1 && 0 0 && 0 & 0 & 0 & 0 & 0 &\\ 0 0 & 0 0 & 0 1 1 &&& 0 & 0 0 & 0 &\\ 0 & 0 & 0 & 0 && 1 & 0 0 \\& 0 & 0 & 0 0 & 0 & 0 && 0 & 1 & 0 \end{tömb}\right)\end{align}$$

  6. A stabilizátorállapotok vizualizációs stílusa a simulators.noisy.stabilizerStateStyle konfigurációs beállítással választható ki. A destabilizálók nélküli vizualizációt például a használatával matrixWithoutDestabilizersválaszthatja ki:

    qsharp.config['simulators.noisy.stabilizerStateStyle'] = 'matrixWithoutDestabilizers'
    

    $$\begin{align}\left(\begin{tömb}{cccc|cccc|c} 1 & 1 & 0 0 && 0 & 0 && 0 & 0 \\& 0 0 & 0 && 1 & 1 & 0 & 0 & 0 \\ 0 0 && 0 & 0 & 0 & 0 0 & 1 & 0 & 0 \\ 0 & 0 0 & 0 & 0 & 0 0 & 0 & 0 0 & 1 & 0 \end{tömb)}\right\end{align}$$

  • A stabilizátorcsoport ábrázolásának kiválasztásához használja a következőt denseGroupPresentation:

    qsharp.config['simulators.noisy.stabilizerStateStyle'] = 'denseGroupPresentation'
    

    $$\left\langle XX11, ZZ11, 11Z1, 111Z \right\rangle$$

  • A stabilizátorcsoport identitásmátrix nélküli ábrázolásának kiválasztásához használja a következőt sparseGroupPresentation:

    qsharp.config['simulators.noisy.stabilizerStateStyle'] = 'sparseGroupPresentation'
    

    $$\left\langle{0}X_X_{1}, Z_{0}Z_{1}, Z_{2}, Z_{{3}\right\rangle$$

Lásd még