練習 - 使用 Q# 利用糾纏進行傳送

已完成

在上一個單元中,您學習了量子隱形傳態協議的步驟。 現在輪到你幫助愛麗絲和鮑勃實現他們的量子隱形傳態實驗了!

在本單元中,您會建立程式 Q# ,其中使用量子隱形傳態通訊協定,將訊息量子位元的狀態從 Alice 傳送給 Bob。 該程序包含四個操作,它們協同工作以執行傳送。

在 Q# 中建立量子傳送通訊協定

要開始您的瞬間移動計劃,請按照下列步驟執行:

  1. 開啟 Visual Studio Code (VS Code)。
  2. 開啟 [檔案 ] 功能表,然後選擇 [新增文字檔案] 以建立新檔案。
  3. 將檔案儲存為 Main.qs

匯入必要的程式庫

若要匯入包含 Q# 撰寫程式所需作業和函式的程式庫,請將下列程式碼複製到 Main.qs 檔案中:

import Microsoft.Quantum.Diagnostics.*; // Aka Std.Diagnostics.*;
import Microsoft.Quantum.Intrinsic.*; // Aka Std.Intrinsic.*;
import Microsoft.Quantum.Measurement.*; // Aka Std.Measurement.*;

定義 Teleport 運算

建立名為 Teleport 的作業,以實作量子隱形傳態協定。 作業會採用兩個量子位元作為輸入: message 包含傳送狀態的量子位,以及 bob 接收傳送狀態的量子位。

operation Teleport(message : Qubit, bob : Qubit) : Unit {
    // Allocate an alice qubit.
    use alice = Qubit();

    // Create some entanglement that we can use to send our message
    H(alice);
    CNOT(alice, bob);

    // Encode the message into the entangled pair
    CNOT(message, alice);

    // Transform the Bell states into computational states for measurement
    H(message);

    // Measure the qubits to extract the classical data we need to decode
    // the message by applying the corrections on the bob qubit
    // accordingly.
    if M(message) == One {
        Z(bob);
    }
    if M(alice) == One {
        X(bob);
    }

    // Reset alice qubit before releasing
    Reset(alice);
}

讓我們分解一下我們 Teleport 操作中的步驟:

  1. 建立alice量子位元。 我們現在擁有執行量子隱形傳態所需的三個量子位元:alice、 和 bobmessage

  2. 糾纏alicebob量子位元。 我們以通常的方式執行此操作:應用 Hadamard 門將量子位元置 alice 於疊加狀態。

  3. message量子位編碼為alicebob的糾纏對量子位。 為此,我們應用一個 CNOT 門,message 作為控制量子比特,而 alice 作為 target 量子比特。 alicemessage量子位元狀態現在處於貝爾基礎中。

  4. 將貝爾狀態轉換為計算狀態。 我們這樣做是因為,在 中 Q#,我們無法直接對貝爾狀態進行測量。 將 Hadamard 閘套用 message 至量子位元,將狀態轉換為計算基礎。 下表將貝爾狀態與其對應的計算狀態相關聯:

    Bell 狀態 計算基礎狀態
    $\ket{\phi^+}$ $\ket{00}$
    $\ket{\phi^-}$ $\ket{01}$
    $\ket{\psi^+}$ $\ket{10}$
    $\ket{\psi^-}$ $\ket{11}$
  5. 測量 alicemessage 量子位,並根據測量結果將適當的閘口 bob 應用於量子位。 首先,使用 M 操作來測量 message。 如果結果為 1,則將 $Z$ 閘門應用到 bob。 接下來,用M操作測量alice。 如果結果為 1,則將 $X$ 閘口應用於 bob

此通訊協定會將量子位元的 message 初始狀態傳送到量子位元 bob 上。

定義 SetToPlusSetToMinus 運算

在現實生活中的傳送協定中,訊息量子位元可以處於任何疊加狀態。 Alice 和 Bob 都不知道訊息量子位元的狀態。 即使狀態未知,狀態也會從訊息量子位元傳送到 Bob 的量子位元。 但是在 Q#中,我們必須在傳送協定之前設定訊息量子位元的狀態。

為了使用不同初始狀態(例如 |0⟩、 |1⟩、 |+⟩ 和 |-⟩)測試訊息量子位元的傳送協議,我們建立了 SetToPlusSetToMinus 操作。 這些作業會在我們傳送訊息量子位元之前,將其置於所需的初始狀態。

將 和 SetToPlusSetToMinus 作業的下列程式碼複製到 Main.qs 檔案中:

/// Sets a qubit in state |0⟩ to |+⟩.
operation SetToPlus(q : Qubit) : Unit is Adj + Ctl {
    H(q);
}

/// Sets a qubit in state |0⟩ to |−⟩.
operation SetToMinus(q : Qubit) : Unit is Adj + Ctl {
    X(q);
    H(q);
}

定義 Main 運算

每個Q#程式必須有一個入口點操作,在默認情況下,這是Main操作。 在這裡,我們的Main操作針對訊息量子位元、$\ket{{0}$、$\ket{1}$$\ket{+}$和 $\ket{-}$的不同初始狀態執行傳送協定。 如果通訊協定成功,則 Bob 的量子位最終會處於我們最初將訊息量子位設定為的相同狀態。

以下是量子傳送程式的 Main 作業:

operation Main() : Result[] {
    // Allocate the message and bob qubits
    use (message, bob) = (Qubit(), Qubit());

    // Use the `Teleport` operation to send different quantum states
    let stateInitializerBasisTuples = [
        ("|0〉", I, PauliZ),
        ("|1〉", X, PauliZ),
        ("|+〉", SetToPlus, PauliX),
        ("|-〉", SetToMinus, PauliX)
    ];

    mutable results = [];
    for (state, initializer, basis) in stateInitializerBasisTuples {
        // Initialize the message and show its state using the `DumpMachine`
        // function.
        initializer(message);
        Message($"Teleporting state {state}");
        DumpMachine();

        // Teleport the message and show the quantum state after
        // teleportation.
        Teleport(message, bob);
        Message($"Received state {state}");
        DumpMachine();

        // Measure bob in the corresponding basis and reset the qubits to
        // continue teleporting more messages.
        let result = Measure([basis], [bob]);
        set results += [result];
        ResetAll([message, bob]);
    }

    return results;
}

讓我們分解一下操作的 Main 組成部分:

  1. 配置兩個量子位, message 以及 bob
  2. 建立包含量子狀態的元組清單、將量子位初始化 message 為所需狀態的作業,以及測量的基礎。 初始化作業是 I 對應 $\ket{0}$,X 對應 $\ket{1}$,SetToPlus 對應 $\ket{+}$,以及 SetToMinus 對應 $\ket{-}$。
  3. 逐一查看元組清單以初始化 message 量子位並顯示初始狀態。 然後,呼叫 Teleport 作業,將量子位的 message 狀態傳送到量子位元 bob 上。
  4. 在對應的基礎上測量 bob 量子位,並重置量子位,以便您可以重複使用它們進行傳送。
  5. 傳回每次傳送的測量結果。

如果通訊協定正常運作,則您的 bob 測量結果會符合 的 message初始化狀態。

執行程式

您的量子傳送程式已就緒! 執行程式,以查看量子隱形傳態如何適用於訊息量子位元的不同初始狀態。

完整的程式包含Teleport操作、和SetToPlusSetToMinus操作以及Main操作。 若要執行程式碼並分析結果,請遵循下列步驟:

  1. Main.qs 檔案的內容取代為下列 Q# 程式碼:

    /// This Q# program implements quantum teleportation
    import Microsoft.Quantum.Diagnostics.*;
    import Microsoft.Quantum.Intrinsic.*;
    import Microsoft.Quantum.Measurement.*;
    
    operation Main() : Result[] {
        // Allocate the message and bob qubits.
        use (message, bob) = (Qubit(), Qubit());
    
        // Use the `Teleport` operation to send different quantum states
        let stateInitializerBasisTuples = [
            ("|0〉", I, PauliZ),
            ("|1〉", X, PauliZ),
            ("|+〉", SetToPlus, PauliX),
            ("|-〉", SetToMinus, PauliX)
        ];
    
        mutable results = [];
        for (state, initializer, basis) in stateInitializerBasisTuples {
            // Initialize the message and show its state using the `DumpMachine`
            // function
            initializer(message);
            Message($"Teleporting state {state}");
            DumpMachine();
    
            // Teleport the message and show the quantum state after
            // teleportation
            Teleport(message, bob);
            Message($"Received state {state}");
            DumpMachine();
    
            // Measure bob in the corresponding basis and reset the qubits to
            // continue teleporting more messages
            let result = Measure([basis], [bob]);
            set results += [result];
            ResetAll([message, bob]);
        }
    
        return results;
    }
    
    /// # Summary
    /// Sends the state of a message qubit to a bob qubit by teleportation
    ///
    /// Notice that after calling Teleport, the state of `message` is collapsed
    ///
    /// # Input
    /// ## message: A qubit whose state we wish to send
    /// ## bob: A qubit initially in the |0〉 state that we want to send
    /// the state of message to
    operation Teleport(message : Qubit, bob : Qubit) : Unit {
        // Allocate an alice qubit.
        use alice = Qubit();
    
        // Create some entanglement that we can use to send our message
        H(alice);
        CNOT(alice, bob);
    
        // Encode the message into the entangled pair
        CNOT(message, alice);
        H(message);
    
        // Measure the qubits to extract the classical data we need to decode
        // the message by applying the corrections on the bob qubit
        // accordingly
        if M(message) == One {
            Z(bob);
        }
        if M(alice) == One {
            X(bob);
        }
    
        // Reset alice qubit before releasing.
        Reset(alice);
    }
    
    /// # Summary
    /// Sets a qubit in state |0⟩ to |+⟩
    operation SetToPlus(q : Qubit) : Unit is Adj + Ctl {
        H(q);
    }
    
    /// # Summary
    /// Sets a qubit in state |0⟩ to |−⟩
    operation SetToMinus(q : Qubit) : Unit is Adj + Ctl {
        X(q);
        H(q);
    }
    
  2. 若要在內建模擬器上執行程式,請選擇 Main 作業上方的 [執行] 程式碼功能濾鏡。 或者,按 Ctrl + F5。 您的輸出會出現在偵錯主控台中。

  3. 檢查接收的狀態是否與傳送的狀態相符。 例如:

    Teleporting state |0〉
    
     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
      |00⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
    
    Received state |0〉
    
     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
      |00⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
    

祝賀! 您透過量子隱形傳態協定,成功將 Alice 的量子位元狀態傳送到 Bob 的量子位元。 這一切都要歸功於量子糾纏!