[PYTHON] Grundlagen der Quanteninformationstheorie: Quantenzustands-Tomographie

\def\bra#1{\mathinner{\left\langle{#1}\right|}} \def\ket#1{\mathinner{\left|{#1}\right\rangle}} \def\braket#1#2{\mathinner{\left\langle{#1}\middle|#2\right\rangle}}

Einführung

Ich habe verschiedene Themen unter dem Titel "Grundlagen der Quanteninformationstheorie" behandelt, aber um den Quantenzustand auszudrücken, ist immer "Density Operator" erschienen. Besonders wenn ich ein gemischtes Quantensystem betrachte, ist es ein sehr praktisches theoretisches Werkzeug, das ich verwenden muss, damit ich nicht mehr ohne es leben kann. Es ist so praktisch, dass Sie bei einem unbekannten physikalischen System versucht sein werden zu fragen: "Durch welchen Dichteoperator kann dieser Quantenzustand dargestellt werden?" (Bitte!). Tatsächlich kann es unter Verwendung einer Technik geschätzt werden, die als "Quantenzustands-Tomographie" bezeichnet wird. In diesem Artikel werde ich zuerst die Methode erläutern und dann den Quantenberechnungssimulator qlazy verwenden, um den Dichteoperator für jeden Quantenzustand zu schätzen. Ich werde.

Die folgenden Dokumente wurden als Referenz verwendet.

  1. Neilsen, Chan "Quantencomputer und Quantenkommunikation (3)" Ohm (2005)
  2. Ishizaka, Ogawa, Kawachi, Kimura, Hayashi "Einführung in die Quanteninformationswissenschaft" Kyoritsu Publishing (2012)
  3. Tomita "Quanteninformationstechnik" Morikita Publishing (2017)

Was ist Quantenzustandstomographie?

Über gemischten Zustand (Überprüfung)

Bevor wir den Dichteoperator schätzen, wollen wir uns ein wenig mit der Darstellung gemischter Zustände befassen. Dies ist zu verstehen, wann diese Schätzmethode nützlich ist. Ich denke, dass es zwei Muster gibt, wie unten gezeigt.

[1] ist ein gemischter Zustand, der auftritt, wenn Alice beispielsweise über ein Gerät verfügt, das mehrere Muster des reinen Zustands auslösen kann, und mit dem der reine Zustand wahrscheinlich ausgewählt und nacheinander ausgelöst wird. Stellen Sie sich einen Photonenwerfer vor, der den Polarisationswinkel nach Belieben einstellen kann. Wenn Sie einen reinen Zustand messen und das Messergebnis vergessen, erhalten Sie einen gemischten Zustand dieses Musters [^ 1].

Ausdrücken eines probabilistischen Ensembles reiner Zustände als $ \ {p_i, \ ket {\ psi_i} \} $, der Dichteoperator $ \ rho $

[^ 1]: Eine solche Messung wird übrigens als "nicht selektive Messung" bezeichnet. Wenn ich ein Lehrbuch über Quanteninformationen lese, stoße ich oft auf die Worte "vergessen" und "die Messergebnisse verlieren". Ich glaube nicht, dass es so einen dummen Experimentator gibt, aber stellen wir uns das als Aya der Worte vor (als ich Student war, habe ich manchmal nicht selektive Messungen durchgeführt, aber geschwitzt). Im Gegenteil, die Messung, die sich fest an das Messergebnis erinnert, wird als "selektive Messung" bezeichnet. In diesem Fall ist der Zustand des Systems rein.

\rho = \sum_{i} p_i \ket{\psi_i} \bra{\psi_i}  \tag{1}

Kann ausgedrückt werden als.

[2] ist ein gemischter Zustand, der durch Beachtung des Teilsystems S des geschlossenen Systems (= reiner Zustand) als Ganzes auftritt [^ 2]. Es wird allgemein angenommen, dass das Teilsystem S mit dem Rest der anderen Systeme (Umweltsystem E) interagiert, so dass es ein offenes System wird (= gemischter Zustand). Wenn Sie eine Quantenschaltung auf einem Quantencomputer ausführen und sich einige der Quantenbits ansehen, befinden sie sich im Allgemeinen in einem gemischten Zustand [^ 3].

[^ 2]: Es ist ein interessanter Teil des Quantenzustands. Wenn das gesamte System des reinen Zustands, dessen Zustand festgelegt ist, geteilt wird, wird die "Verschränkung" abgewickelt und es wird ein gemischter Zustand. Mit anderen Worten, das einfache Teilen eines Systems mit einer Entropie von Null führt aus irgendeinem Grund zu einer Entropie im Teilsystem!

[^ 3]: Die Quantenberechnung ist eine einheitliche Transformation in den reinen Zustand als Ganzes. Wenn Sie also den gesamten Quantenzustand betrachten, behält sie immer den reinen Zustand bei, aber wenn Sie auf einige der Quantenbits achten, Es ist in einem gemischten Zustand. Befindet sich das interessierende Teilquantenbit jedoch in einem unabhängigen = entwirrten = Produktzustand mit anderen Quantenbits, befindet es sich in einem reinen Zustand.

Wenn das gesamte System $ \ ket {\ Psi} $ ist, wenn Sie die Aufmerksamkeit mit einer Formel auf das Teilsystem schreiben,

\rho = Tr_E (\ket{\Psi} \bra{\Psi})  \tag{2}

Es wird sein.

Schätzung des Dichteoperators (1 Quantenzustand)

Nachdem wir das spezifische Erscheinungsbild des gemischten Zustands kurz besprochen haben, erklären wir, wie der Dichteoperator zu diesem Zeitpunkt geschätzt wird. Aber hier ist eine Annahme. Wenn die $ \ rho $ -Bedingung nur einmal auftritt und Sie nur eine Chance haben, sie zu messen, ist es leider unmöglich zu schätzen. Während die durch Messung erhaltene Zahl eins ist, gibt es viele Zahlen zur Beschreibung des Dichteoperators, so dass dies zu einem schlechten Einstellungsproblem wird und nicht geschätzt werden kann. Daher wird angenommen, dass der Zustand von $ \ rho $ wiederholt erzeugt und jedes Mal gemessen werden kann. Die Grundidee besteht darin, den Dichteoperator zu schätzen, indem eine große Anzahl der Messergebnisse gesammelt und integriert wird.

Betrachten wir zunächst den Dichteoperator für einen Quantenzustand.

Nur im Fall eines Quanten könnte der Dichteoperator als lineare Summe des Pauli-Operators ausgedrückt werden [^ 4]. Dieser Ausdruck wird die Grundlage für die Erklärung der Schätzmethode sein. Schauen wir uns also genauer an, wie sie abgeleitet wurde.

[^ 4]: In dem vorherigen Artikel, der "Quantenkanäle" abdeckte, erklärte ich die Bloch-Anzeige des Dichteoperators.

Der Pauli-Operator wurde wie folgt definiert:

\sigma_0 = I = 
\begin{pmatrix}
1 & 0 \\
0 & 1
\end{pmatrix}, \space
\sigma_1 =  
\begin{pmatrix}
0 & 1 \\
1 & 0
\end{pmatrix}, \space
\sigma_2 =
\begin{pmatrix}
0 & -i \\
i & 0
\end{pmatrix}, \space
\sigma_3 =
\begin{pmatrix}
1 & 0 \\
0 & -1
\end{pmatrix}  \tag{3}

Wie aus dieser Definition hervorgeht, ist der Pauli-Operator der Hermeet-Operator. Und,

\frac{1}{2} Tr(\sigma_i \sigma_j) = \delta_{ij}  \tag{4}

Es hat die Eigenschaft von. Übrigens ist $ Tr (AB) $, das hier erscheint, eine Art inneres Produkt, wenn die Matrizen $ A und B $ als Vektoren betrachtet werden, und wird manchmal als "Hilbert-Schmidt-inneres Produkt" bezeichnet (später erwähnt). Bitte denken Sie daran, wie es kommen wird.

Unter Berücksichtigung dieser Eigenschaft des Pauli-Operators ist jeder im zweidimensionalen Hilbert-Raum definierte Elmeet-Operator $ A $ $ \ {u_i \} \ space (i = 0,1,2,3). Sie können sehen, dass $ durch die folgende lineare Summe als beliebige reelle Zahl ausgedrückt werden kann.

A = u_0 \sigma_0 + u_1 \sigma_1 + u_2 \sigma_2 + u_3 \sigma_3 = \sum_{i=0}^{3} u_i \sigma_i \tag{5}

Es ist einfach, also lasst es uns ein wenig beweisen.

[Beweis]

Erstens, ob die rechte Seite von Gleichung (3) Elmeat ist.

\begin{align}
A &=
u_0
\begin{pmatrix}
1 & 0 \\
0 & 1
\end{pmatrix} +
u_1
\begin{pmatrix}
0 & 1 \\
1 & 0
\end{pmatrix} +
u_2
\begin{pmatrix}
0 & -i \\
i & 0
\end{pmatrix} +
u_3
\begin{pmatrix}
1 & 0 \\
0 & -1
\end{pmatrix}  \\
&= 
\begin{pmatrix}
u_0 & 0 \\
0 & u_0
\end{pmatrix} +
\begin{pmatrix}
0 & u_1 \\
u_1 & 0
\end{pmatrix} +
\begin{pmatrix}
0 & -i u_2 \\
i u_2 & 0
\end{pmatrix} +
\begin{pmatrix}
u_3 & 0 \\
0 & -u_3
\end{pmatrix}  \\
&=
\begin{pmatrix}
u_0 + u_3 & u_1 - iu_2 \\
u_1 + iu_2 & u_0 - u_3
\end{pmatrix}  \tag{6}
\end{align}

Und offensichtlich ist $ A ^ {\ dagger} = A $, also ist $ A $ Elmeat.

Als nächstes kommt der gegenteilige Beweis. Das heißt, ob ein Elmeat-Operator wie in Gleichung (5) ausgedrückt werden kann.

Angenommen, $ A $ ist Elmeat, unter Verwendung einer beliebigen reellen Zahl $ a, b, c, d $,

A =
\begin{pmatrix}
a & b-ic \\
b+ic & d
\end{pmatrix}  \tag{7}

Es kann ausgedrückt werden als. Egal welche $ a, b, c, d $ Sie hierher bringen

\begin{align}
a &= u_0 + u_3 \\
b &= u_1 \\
c &= u_2 \\
d &= u_0 - u_3 \tag{8}
\end{align}

Da es immer reelle Werte $ u_0, u_1, u_2, u_3 $ gibt, die erfüllen, ist Gleichung (7)

\begin{align}
A &=
\begin{pmatrix}
u_0 + u_3 & u_1 - iu_2 \\
u_1 + iu_2 & u_0 - u_3
\end{pmatrix} \\
&=
u_0
\begin{pmatrix}
1 & 0 \\
0 & 1
\end{pmatrix} +
u_1
\begin{pmatrix}
0 & 1 \\
1 & 0
\end{pmatrix} +
u_2
\begin{pmatrix}
0 & -i \\
i & 0
\end{pmatrix} +
u_3
\begin{pmatrix}
1 & 0 \\
0 & -1
\end{pmatrix}  \\
&= u_0 \sigma_0 + u_1 \sigma_1 + u_2 \sigma_2 + u_3 \sigma_3 \\
&= \sum_{i=0}^{3} u_i \sigma_i \tag{9}
\end{align}

Dann wurde Gleichung (5) bewiesen.

(Ende der Zertifizierung)

Lassen Sie uns nun etwas anderes darüber sagen, was Gleichung (5) bedeutet. Das heißt, der im zweidimensionalen Hilbert-Raum definierte Elmeet-Operator kann als Vektor im linearen Raum betrachtet werden, der von den vier Pauli-Operatoren gestreckt wird, wenn sie orthogonale Basen im Sinne des inneren Hilbert-Schmidt-Produkts sind. Das kannst du sagen.

Hmm? Was bedeutet "Vektor", wenn Sie "Operator (= Matrix)" sagen? ?? Sie können die Frage hören, aber bitte erweichen Sie Ihren Kopf und folgen Sie ihm. Nehmen wir grob an, dass alles als "Vektor" bezeichnet werden kann, wenn das innere Produkt definiert werden kann, es eine orthogonale Basis gibt und es etwas gibt, das durch die lineare Summe dargestellt werden kann.

Der Ein-Mengen-Dichteoperator $ \ rho $ war also genau der Elmeet-Operator im zweidimensionalen Hilbert-Raum, sodass er wie die gerade bewiesene Gleichung (5) erweitert werden kann.

\rho = u_0 \sigma_0 + u_1 \sigma_1 + u_2 \sigma_2 + u_3 \sigma_3 = \sum_{i=0}^{3} u_i \sigma_i \tag{10}

Der Dichteoperator hat jedoch eine Einschränkung von $ Tr (\ rho) = 1 $ und $ Tr (\ sigma_1) = Tr (\ sigma_2) = Tr (\ sigma_3) = 0 $, also $ u_0 = Tr (\ rho) = 1 $. Das heißt, eine Variable wird reduziert,

\rho = I + u_1 \sigma_1 + u_2 \sigma_2 + u_3 \sigma_3 = I + \sum_{i=1}^{3} u_i \sigma_i \tag{11}

Kann geschrieben werden. Unter Berücksichtigung der Natur des Pauli-Operators in Gleichung (4),

u_i = \frac{1}{2} Tr(\sigma_i \rho)  \tag{12}

Daher ist Gleichung (11) schließlich

\begin{align}
\rho &= \frac{1}{2} (Tr(\rho) I + Tr(\sigma_1 \rho) \sigma_1 + Tr(\sigma_2 \rho) \sigma_2+ Tr(\sigma_3 \rho) \sigma_3) \\
&= \frac{1}{2} \sum_{i=0}^{3} Tr(\sigma_i \rho) \sigma_i  \tag{13}
\end{align}

Es wird sein.

Jetzt ist es Zeit, darüber zu sprechen, wie der Dichteoperator geschätzt wird.

Schauen Sie sich Gleichung (13) genauer an. $ Tr (\ sigma_i \ rho) $ für $ i = 1,2,3 $ war der erwartete Wert, als die Beobachterblase $ \ sigma_i $ gemessen wurde. $ \ Sigma_1, \ sigma_2, \ sigma_3 $ sind wie Drehungen in der X-, Y- und Z-Achse. Daher wird für das Flugquantum die Messung in Richtung der X-Achse viele Male durchgeführt, der gemessene Wert (+1, -1) wird aufgezeichnet, um den erwarteten Wert zu erhalten, und dann wird die Messung in Richtung der Y-Achse durchgeführt. Wird viele Male ausgeführt, um den erwarteten Wert auf die gleiche Weise zu erhalten, und dann wird die Messung in Richtung der Z-Achse viele Male ausgeführt, um den erwarteten Wert zu erhalten, der in Gleichung (13) eingesetzt wird. $ Tr (\ sigma_0 \ rho) $ $ \ sigma_0 $ ist eine Einheitsmatrix, und die Spur von $ \ rho $ ist 1, daher spielt es keine Rolle, ob sie existiert oder nicht, dieser Begriff sollte auf 1 gesetzt werden. Somit kann Gleichung (13) perfekt berechnet werden.

Nun erklärte ich, während ich mir den von Alice physikalisch emittierten Quantenzustand vorstellte, aber als weiteres Beispiel denke ich, dass Sie den Dichteoperator für ein Quantenbit eines Quantencomputers schätzen möchten. Es ist im Grunde dasselbe, aber Sie müssen nur dort vorsichtig sein, wo Sie jedes Mal die Messrichtung des Quantenbits ändern. Wenn Sie einen Simulator oder Cloud-Dienst verwenden, der nur Messungen in Z-Richtung unterstützt, müssen Sie vor Messungen in Z-Richtung ein Quantentor beißen, das die Messrichtung ändert.

Messung in X-Richtung

--H--M--

Messung in Y-Richtung

--S+--H--M--

Messung der Z-Richtung

--M--

Ich kann gehen. Wenn Sie sich eine Bloch-Kugel vorstellen, können Sie sehen, dass sie einfach die Achse dreht.

Schätzung des Dichteoperators (2 Quantenzustände)

Die bisherige Diskussion kann auf den Dichteoperator der beiden Quantenzustände ausgedehnt werden.

Ich erklärte, dass der Dichteoperator im Fall eines Quanten als Vektor in einem linearen Raum betrachtet werden kann, der auf den vier Pauli-Operatoren basiert. Im Fall eines Zwei-Quanten-Zustands können Sie einen anderen linearen Raum einfügen, um einen direkten Produktraum zu erstellen und einen Vektor darauf zu definieren. Die Basis dieses direkten Produktraums wird durch das Tensorprodukt der vier Pauli-Operatoren definiert. Mit anderen Worten

\{\sigma_i \otimes \sigma_j \} \space (i,j = 0,1,2,3)  \tag{14}

16 4X4-Matrizen bilden die Basis für diesen direkten Produktraum. Wie Sie sehen können, ist diese Basis

\frac{1}{2^2} Tr[(\sigma_i \otimes \sigma_j)(\sigma_k \otimes \sigma_l)] = \delta_{ik} \delta_{jl} \tag{15}

Da die orthogonale Bedingung erfüllt ist, ist der Dichteoperator dieses Zwei-Quanten-Zustands der gleiche wie zuvor.

\rho = \sum_{i}^{3} \sum_{j}^{3} u_{ij} \sigma_i \otimes \sigma_j \tag{16}

Es kann mit dem Pauli-Operator wie in mit einer Basis erweitert werden. Beachten Sie, dass Gleichung (15) dieses $ u_ {ij} $ ist

u_{ij} = \frac{1}{2^2} Tr[(\sigma_i \otimes \sigma_j) \rho]  \tag{17}

Da es berechnet werden kann als, ist Gleichung (16)

\rho = \frac{1}{2^2} \sum_{i=0}^{3} \sum_{j=0}^{3} Tr[(\sigma_i \otimes \sigma_j) \rho] \cdot \sigma_i \otimes \sigma_j  \tag{18}

Es wird sein.

Um den Dichteoperator abzuschätzen, müssen Messungen mit zwei Größen durchgeführt werden, wobei zwischen den Richtungen gewechselt wird. Es gibt 4X4 = 16 Kombinationen von Pauli-Operatoren. Finden Sie also den erwarteten Wert für jeden Fall. Insbesondere erhalten Sie zunächst für eine Kombination von Pauli-Operatoren die gemessenen Werte (+1, -1) für jedes der beiden Flugquanten. Notieren Sie das Produkt als den gemessenen Wert der gesamten 2 Quanten. Wiederholen Sie dies viele Male, um den erwarteten Wert zu erhalten. Nachdem wir den erwarteten Wert für eine Kombination von Pauli-Operatoren haben, werden wir dies für alle Kombinationen von Pauli-Operatoren (16 Muster) tun. Da 16 erwartete Werte erhalten werden, wird die Schätzung des Dichteoperators abgeschlossen, indem sie in Gleichung (17) eingesetzt werden. Es gibt jedoch einen Fall, in dem alle Pauli-Operatoren Einheitenoperatoren sind, sodass der erwartete Wert nicht berechnet werden muss. Belassen Sie es bei 1, ohne zu sagen, ob es vorhanden ist oder nicht. das ist alles.

Schätzung des Dichteoperators (n Quantenzustand)

Darüber hinaus ist die gleiche Diskussion für den Dichteoperator des n-Quantenzustands in Ordnung. Der Dichteoperator ist

\rho = \frac{1}{2^n} \sum_{\mu_1=0}^{3} \sum_{\mu_2=0}^{3} \cdots \sum_{\mu_{n}=0}^{3} Tr[(\sigma_{\mu_1} \otimes \sigma_{\mu_2} \otimes \cdots \otimes \sigma_{\mu_{n}})\rho] \cdot \sigma_{\mu_1} \otimes \sigma_{\mu_2} \otimes \cdots \otimes \sigma_{\mu_{n}} \tag{19}

Es kann ausgedrückt werden als Es sieht ein wenig kompliziert aus, aber wenn Sie genau hinschauen, werden Sie es verstehen.

Die Schätzmethode des Dichteoperators ist

Tr[(\sigma_{\mu_1} \otimes \sigma_{\mu_2} \otimes \cdots \otimes \sigma_{\mu_{n}})\rho]   \tag{20}

Sie müssen nur den erwarteten Wert finden. Da es sich um n Quanten handelt, beträgt die Kombination der Pauli-Operatoren 4 nach der n-ten Potenz. Für jede Kombination wird die Richtung gemessen, die dem jedem Quantenbit zugewiesenen Pauli-Operator entspricht, der gemessene Wert von n Quanten (das Produkt des gemessenen Wertes jedes Quanten) wird erhalten und der erwartete Wert wird erhalten. Ist gut.

Das oben beschriebene Schätzverfahren ist "Quantenzustands-Tomographie".

Geschätzte Simulation

Implementierung

Nun möchte ich ein beliebiges Quantenzustandsensemble erstellen und den Dichteoperator durch Quantenzustandstomographie abschätzen [^ 5]. Selbst wenn Sie so etwas nicht tun, verfügt der Quantenberechnungssimulator qlazy über eine Funktion, mit der Sie den Dichteoperator durch Matrixberechnung direkt aus dem Quantenzustandsensemble abrufen können. Es ist gewesen. Dieses Mal studiere ich jedoch die Quantenzustands-Tomographie, daher werde ich sie vergessen und den Dichteoperator nur durch Messen des Quantenzustands-Ensembles schätzen. Verwenden Sie den von qlazy berechneten Dichteoperator als Referenzwert (True Value), um die Genauigkeit der Schätzung zu messen. Ich werde die Genauigkeit anhand der Wiedergabetreue bewerten (die Wiedergabetreue wird auch als Funktion von [qlazy] installiert (https://github.com/samn33/qlazy)).

[^ 5]: In dieser Simulation haben wir den gemischten Zustand geschätzt, der aus dem Quantenzustandsensemble hervorgeht. Ich denke jedoch, dass die Schätzung des gemischten Zustands, der durch Konzentration auf das Subsystem des reinen Zustands auftritt, auch durch geringfügiges Ändern des Programms (?) Erreicht werden kann.

Schauen wir uns nun den gesamten Python-Code an.

import random
import math
import numpy as np
from scipy.stats import unitary_group
from qlazypy import QState,DensOp

def random_qstate_ensemble(qubit_num, mimxed_num):

    qstate = []
    dim = 2**qubit_num
    for _ in range(mixed_num):
        vec_ini = np.zeros(dim)
        vec_ini[0] = 1.0
        mat = unitary_group.rvs(dim)
        vec = np.dot(mat, vec_ini)
        qstate.append(QState(vector=vec))
        
    prob = [random.random() for _ in range(mixed_num)]
    total = sum(prob)
    prob = [p/total for p in prob]

    return (qstate,prob)

def get_pauli_index(index, total):
    # ex) index = 9 = 1001 -> [10,01] -> [2,1] --reverse-> [1,2] = pauli_index
    #     '1' means X for 0th-qubit, '2' means Y for 1st-qubit

    pauli_index = [0]*int(math.log2(total)/2)
    count = 0
    while index > 0:
        pauli_index[count] = index%4
        index = index // 4
        count += 1
    pauli_index.reverse()

    return pauli_index

def make_pauli_product(index, total, pauli_mat):

    pauli_index = get_pauli_index(index, total)
    pauli_prod_dim = 2**len(pauli_index) 
    pauli_prod = np.array([1.0])
    for pid in pauli_index:
        pauli_prod = np.kron(pauli_prod, pauli_mat[pid])

    return pauli_prod
    
def make_densop(expect, qubit_num, pauli_mat):

    dim = 2**qubit_num
    measure_num = len(expect)
    matrix = np.zeros((dim,dim))
    for i in range(measure_num):
        pauli_prod = make_pauli_product(i,measure_num,pauli_mat)
        matrix = matrix + expect[i] * pauli_prod
    matrix = matrix / (2.0**qubit_num)
    
    return DensOp(matrix=matrix)

def calc_expect(prb):

    N = len(prb)
    val = np.zeros(N)
    for index in range(N):
        bin_list = [int(s) for s in list(format(index, 'b'))]
        val[index] = (-1)**sum(bin_list)  # odd -> -1, even -> +1

    return np.dot(prb, val)

def estimate_densop(prob,qstate,shots):

    pauli_mat = [np.eye(2),                   # = I
                 np.array([[0,1],[1,0]]),     # = X
                 np.array([[0,-1j],[1j,0]]),  # = Y
                 np.array([[1,0],[0,-1]])]    # = Z
    
    mixed_num = len(prob)
    qubit_num = qstate[0].qubit_num
    measure_num = 4**qubit_num

    for i in range(mixed_num):

        expect = {}
        for index in range(measure_num):

            pauli_index = get_pauli_index(index,measure_num)

            if index == 0:
                expect[index] = 1.0
                continue
                    
            qs = qstate[i].clone()

            for qid in range(len(pauli_index)):

                if pauli_index[qid] == 0:
                    continue
                elif pauli_index[qid] == 1:
                    qs.h(qid)
                elif pauli_index[qid] == 2:
                    qs.s_dg(qid).h(qid)
                else:
                    pass

            frq = qs.m(shots=shots).frq
            prb = np.array([f/shots for f in frq])
            expect[index] = calc_expect(prb)

            qs.free()

        de_tmp = make_densop(expect, qubit_num, pauli_mat)
        
        if i == 0:
            de_tmp.mul(prob[i])
            densop_est = de_tmp.clone()
        else:
            de_tmp.mul(prob[i])
            densop_est.add(de_tmp)

    de_tmp.free()

    return densop_est
    
if __name__ == '__main__':

    # settings
    qubit_num = 2
    mixed_num = 4
    shots = 100

    # quantum state ensemble (original)
    qstate, prob = random_qstate_ensemble(qubit_num, mixed_num)

    # density operator (original)
    densop_ori = DensOp(qstate=qstate, prob=prob)

    # density operator estimation only from quantum state ensemble
    # (quantum state tomography)
    densop_est = estimate_densop(prob,qstate,shots)

    print("** density operator (original)")
    densop_ori.show()
    print("** density operator (estimated)")
    densop_est.show()
    print("** fidelity =",densop_ori.fidelity(densop_est))

    for q in qstate:
        q.free()
    densop_ori.free()
    densop_est.free()

Ich werde erklären, was Sie tun. Schauen Sie sich den Hauptverarbeitungsabschnitt an.

# settings
qubit_num = 2
mixed_num = 4
shots = 1000

Dies ist der Einstellwert für die Simulation. qubit_num ist die Anzahl der angenommenen Quanten, Mixed_num ist die Anzahl der zu mischenden reinen Zustände und Shots ist die Anzahl der Messungen.

# quantum state ensemble (original)
qstate, prob = random_qstate_ensemble(qubit_num, mixed_num)

Hier erstellen wir zufällig ein Quantenzustandsensemble. qstate ist eine Liste von 4 Quantenzuständen. prob ist eine Liste von Wahrscheinlichkeiten, die den Anteil der vier zu mischenden reinen Zustände bestimmen. Sowohl der reine Zustand als auch die Wahrscheinlichkeit werden zufällig bestimmt. Einzelheiten finden Sie in der Funktionsdefinition.

# density operator (original)
densop_ori = DensOp(qstate=qstate, prob=prob)

Dies ist der Teil, der qlazy verwendet, um den wahren Wert des Dichteoperators zu berechnen, über den wir nachdenken. Schließlich wird es als Referenzwert für die Genauigkeitsbewertung verwendet.

# density operator estimation only from quantum state ensemble
# (quantum state tomography)
densop_est = estimate_densop(prob,qstate,shots)

Dies ist der Teil der Dichteoperatorschätzung, der der Schlüssel zu dieser Zeit ist, daher werde ich ihn etwas genauer erläutern. Schauen Sie sich den Inhalt der Funktion Estimate_densop an.

def estimate_densop(prob,qstate,shots):

    pauli_mat = [np.eye(2),                   # = I
                 np.array([[0,1],[1,0]]),     # = X
                 np.array([[0,-1j],[1j,0]]),  # = Y
                 np.array([[1,0],[0,-1]])]    # = Z
    
    mixed_num = len(prob)
    qubit_num = qstate[0].qubit_num
    measure_num = 4**qubit_num
    ...

Das erste pauli_mat setzt die Pauli-Matrix. mix_num und qubit_num werden aus den Argumenten erneut berechnet. Aus qubit_num kann die Anzahl der Kombinationen von Pauli-Operatoren mit 4 ** qubit_num erhalten werden (dies wird in der Variablen Measure_num gespeichert).

Die nächste for-Schleife ist

for i in range(mixed_num):

    expect = {}
    for index in range(measure_num):

        pauli_index = get_pauli_index(index,measure_num)
	...

Es ist wie verdoppelt. Die äußere for-Schleife dient zum Schätzen des Dichteoperators für jeden reinen Zustand, der gemischt wird. Später werden wir die Wahrscheinlichkeiten gewichten und addieren, um den endgültigen Dichteoperator [^ 5] zu erhalten.

[^ 5]: Um einem realistischeren Experiment näher zu kommen, wäre es besser gewesen, diesen Teil so zu implementieren, dass einer der reinen Zustände wahrscheinlich einmal fliegen und messen würde, und so weiter. Ich dachte jedoch, dass der Code lang und schwer zu verstehen sein würde, deshalb habe ich die Implementierung ein wenig übersprungen.

Die innere for-Schleife dient zur Berechnung des erwarteten Werts für die Häufigkeit, mit der der Pauli-Operator kombiniert werden kann. Initialisieren Sie zunächst die Wörterbucherwartung zum Speichern der erwarteten Werte für jede Kombination als leeres Wörterbuch. Ich wiederhole für die Nummer von Measure_Num, aber die Kombinationsnummer ist im Variablenindex. Da dies nur ein ganzzahliger Wert ist, ist es schwierig, die Messrichtung jedes Quantenbits zu steuern. Die Funktion get_pauli_index konvertiert sie also in eine Liste von Pauli-Operatornummern. Konvertiert einen ganzzahligen Wert in eine quaternäre Zahl und gibt jede Ziffer als Liste zurück. Einzelheiten finden Sie in der Funktionsdefinition.

Als nächstes folgt der Inhalt der for-Schleife.

if index == 0:
    expect[index] = 1.0
    continue
        
qs = qstate[i].clone()

for qid in range(len(pauli_index)):

    if pauli_index[qid] == 0:
        continue
    elif pauli_index[qid] == 1:
        qs.h(qid)
    elif pauli_index[qid] == 2:
        qs.s_dg(qid).h(qid)
    else:
        pass

frq = qs.m(shots=shots).frq
prb = np.array([f/shots for f in frq])
expect[index] = calc_expect(prb)

qs.free()

Wenn index = 0 ist, wird der erwartete Wert unabhängig von der Anwesenheit oder Abwesenheit auf 1 gesetzt. Wenn nicht,

qs = qstate[i].clone()

Kopieren Sie also den i-ten reinen Zustand und speichern Sie ihn in qs als temporär [^ 6].

[^ 6]: Da es sich um einen Simulator handelt, kopiere ich ihn leicht, aber wenn ich ihn in einem tatsächlichen Experiment oder einem realen Quantencomputer mache, erzeugt dieser Teil viele Male dasselbe vom Quantengenerator oder dieselbe Quantenschaltung Es ist notwendig, die Operation durchzuführen, um den Zustand viele Male durchzuhalten.

Als nächstes kam die for-Schleife wieder heraus.

for qid in range(len(pauli_index)):
...

Dies gilt für das Quantentor, das vor der Messung angewendet wird, da jedes Quantenbit in der Reihenfolge gemessen wird, in der die Messrichtung der Pauli-Operator-Nummer entspricht. Der Inhalt ist wie oben zu sehen. Wenn die Schleife vorbei ist

frq = qs.m(shots=shots).frq
prb = np.array([f/shots for f in frq])
expect[index] = calc_expect(prb)

qs.free()

Es wird gesagt. Jetzt führen Sie die eigentliche Messung durch. Da der Schuss 1000 war, werde ich 1000 mal messen [^ 7]. Als Ergebnis wird eine Frequenzliste erhalten, also normalisieren Sie sie so, dass die Summe für die Wahrscheinlichkeit 1 ist. Übergeben Sie es an die Funktion calc_expect, um den erwarteten Wert zu berechnen. Da wir jetzt 2 Quantenzustände annehmen, beträgt die Wahrscheinlichkeit 4. Jeder von ihnen repräsentiert eine bestimmte Gruppe von Pauli-Operatoren. Für einen bestimmten Satz von Pauli-Operatoren können die Zwei-Quanten-Messungen als das Produkt von jedem berechnet werden (das +1 oder -1 sein kann). Sobald die vier Wahrscheinlichkeiten und die vier gemessenen Werte bestimmt sind, kann der erwartete Wert berechnet werden. Die Funktion calc_expect macht das. Einzelheiten finden Sie in der Funktionsdefinition. Geben Sie nach Verwendung von qs den Speicher mit qs.free () frei [^ 8].

[^ 7]: Auch hier wird die Implementierung durch die für den Simulator eindeutige Verarbeitung übersprungen. In einem realistischen Experiment muss qs wirklich viele Male erzeugt und gemessen werden.

[^ 8]: Dieser Prozess ist wichtig, wenn derselbe Quantenzustand mehrmals in einer Schleife verwendet wird. qlazy verwendet die darin enthaltene C-Sprachbibliothek und weist auch Speicher in der C-Welt zu. Daher ist die Spezifikation, dass der Speicher explizit für den Quantenzustands- und Dichteoperator freigegeben werden sollte. Ich habe es Pythons \ _ \ _ del \ _ \ _ überlassen und eine Spezifikation ausprobiert, die es nicht explizit freigibt, aber ich weiß nicht, wann der Speicher auf der Python-Seite freigegeben wird, daher bin ich misstrauisch. Da es Fälle gab, in denen dies getan wurde, haben wir diese Spezifikation vorgenommen.

de_tmp = make_densop(expect, qubit_num, pauli_mat)

if i == 0:
    de_tmp.mul(prob[i])
    densop_est = de_tmp.clone()
else:
    de_tmp.mul(prob[i])
    densop_est.add(de_tmp)

Sobald alle vier erwarteten Werte gefunden wurden, berechnet die Funktion make_densop einmal den Dichteoperator für diesen reinen Zustand (Einzelheiten zu make_densop finden Sie in der Funktionsdefinition). Addieren Sie die Gewichte der Wahrscheinlichkeiten durch die Anzahl der gemischten Zahlen (4). Die if-Anweisung ist dieser Prozess. Nach dem Verlassen der äußeren Schleife haben wir den letzten densop_est, also geben wir ihn zurück.

Kehren Sie zum Hauptverarbeitungsabschnitt zurück

print("** density operator (original)")
densop_ori.show()
print("** density operator (estimated)")
densop_est.show()
print("** fidelity =",densop_ori.fidelity(densop_est))

Nun werden die Elemente des Operators für die reale Dichte (densop_ori) und die Elemente des Operators für die geschätzte Dichte (densop_est) der Reihe nach angezeigt, und schließlich wird die Genauigkeit beider berechnet und angezeigt.

Ergebnis

Das Ergebnis der Simulation wird angezeigt.

Das obige Programm diente zur Schätzung von 2 Quantenzuständen, aber das erste ist die Schätzung von 1 Quantenzustand. Die Parameter sind

qubit_num = 1
mixed_num = 2
shots = 100

Es wurde gemacht. Als ich es lief

** density operator (original)
elm[0][0] = +0.3270-0.0000*i : 0.1069 |++
elm[0][1] = +0.1508-0.2138*i : 0.0684 |++
elm[1][0] = +0.1508+0.2138*i : 0.0684 |++
elm[1][1] = +0.6730+0.0000*i : 0.4530 |++++++
** density operator (estimated)
elm[0][0] = +0.3224+0.0000*i : 0.1040 |++
elm[0][1] = +0.1584-0.1887*i : 0.0607 |++
elm[1][0] = +0.1584+0.1887*i : 0.0607 |++
elm[1][1] = +0.6776+0.0000*i : 0.4591 |++++++
** fidelity = 0.9996155234243419

ist geworden. Da die Wiedergabetreue 0,9996 ... beträgt, konnte ich sie mit beträchtlicher Genauigkeit abschätzen.

Als nächstes folgt die Schätzung des Zwei-Größen-Zustands. Die Parameter sind

qubit_num = 2
mixed_num = 4
shots = 1000

Ich versuchte es. Da das Element des Dichteoperators lang wird, wenn nur die Wiedergabetreue angezeigt wird,

** fidelity = 0.9814099144563044

Und die Genauigkeit sank ein wenig. Ich glaube jedoch, dass ich vorerst den Zweck des Studiums der Quantenzustands-Tomographie erreicht habe, also werde ich es hier so gut belassen [^ 9].

[^ 9]: Quantum Information Engineering enthält die folgende Beschreibung. "Im Fall eines Quantenbits ist dies relativ einfach, aber um den Zustand mehrerer Quantenbits zu bestimmen, ist es notwendig, die Komponente des Dichteoperators zu bestimmen, die in der Reihenfolge des Quadrats der Anzahl der Quantenbits zunimmt. Daher ist es notwendig. Wenn der Zustand zufällig ein reiner Zustand ist, ist der Rang der Dichtematrix 1 (ein diagonales Element bleibt übrig und alle anderen Elemente sind 0), was nicht erforderlich ist. Es scheint ziemlich schwierig zu sein, die Parameter abzuschätzen. " Wenn Sie es tatsächlich simulieren, können Sie diese Art von Schwierigkeit erkennen.

abschließend

Dieses Mal haben wir die "Quantenzustands-Tomographie" zur Schätzung des Zustands aufgenommen, aber es gibt auch eine Methode namens "Quantenprozess-Tomographie", die den "Prozess" und nicht den "Zustand" schätzt. Es ist eine Methode zur Schätzung des Klaus-Operators, die Änderungen im physikalischen System darstellt, und scheint im Grunde eine Methode zur wiederholten Verwendung dieser "Zustands" -Tomographie zu sein. Ich habe jedoch noch nicht studiert. Bitte nutzen Sie diese Gelegenheit erneut.

Das nächste Mal denke ich über Themen im Zusammenhang mit der Quantenkommunikation nach. Ich möchte die "Datenkomprimierung" aufnehmen, eine Kommunikationsmethode, bei der der Quantenzustand selbst anstelle klassischer Informationen auf den Quantenkommunikationskanal gesetzt wird (obwohl der Zeitplan unentschlossen ist).

das ist alles

Recommended Posts

Grundlagen der Quanteninformationstheorie: Quantenzustands-Tomographie
Grundlagen der Quanteninformationstheorie: Entropie (2)
Grundlagen der Quanteninformationstheorie: Datenkomprimierung (1)
Grundlagen der Quanteninformationstheorie: Horebaud-Grenzen
Grundlagen der Quanteninformationstheorie: Spurenentfernung
Grundlagen der Quanteninformationstheorie: Datenkomprimierung (2)
Grundlagen der Quanteninformationstheorie: Topologische Oberflächencodes
Grundlagen der Quanteninformationstheorie: Fehlertolerante Quantenberechnung
Grundlagen der Quanteninformationstheorie: Quantenfehlerkorrektur (Shor Code)
Grundlagen der Quanteninformationstheorie: Quantenfehlerkorrektur (CSS-Code)
Grundlagen der Quanteninformationstheorie: Quantenfehlerkorrektur (Stabilisatorcode: 4)
Grundlagen der Quanteninformationstheorie: Quantenfehlerkorrektur (klassischer linearer Code)
Grundlagen der Quanteninformationstheorie: Universelle Quantenberechnung durch Oberflächencode (1)
Grundlagen der Quanteninformationstheorie: Logische Operation durch Oberflächencode (Brading)
Lesen Sie "Grundlagen des Quantenglühens", Tag 5
Quantencomputer-Implementierung eines 3-Zustands-Quantenlaufs
Lesen Sie "Grundlagen des Quantenglühens", Tag 6
Grundlagen der Tableau-Grundlagen (Visualisierung mit geografischen Informationen)
Python-Grundlagen ①
Grundlagen von Python ①
Grundlagen der Python-Scraping-Grundlagen
# 4 [Python] Grundlagen der Funktionen
Grundlagen von Netzwerkprogrammen?
Die Gründung der Perceptron-Stiftung
Grundlagen der Regressionsanalyse
Grundlagen von Python: Ausgabe