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

已完成

在上一個單元中,您已檢閱量子遠端通訊協定的步驟。 現在輪到你幫助 Alice 和 Bob 進行量子傳送實驗了!

在本單元中,您將在 Q# 中建立一個量子傳送程式,該程式使用量子傳送通訊協定將量子位元的狀態從 Alice 傳送到 Bob。

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

  1. 打開 Visual Studio Code。
  2. 選取 [檔案] > [新增文字檔],並將它另存為 Main.qs
  3. 選取 [檢視] -> [命令選擇區] 並鍵入 Q#:設定 Azure Quantum QIR target 設定檔。 按 Enter 鍵。
  4. 選取 Q#:不受限制

匯入必要的程式庫

首先,您必須匯入必要的連結庫,才能使用 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);
        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 量子位元,並在 alicebob 量子位元之間建立糾纏。 然後,message 量子位元會與 alice 量子位元糾纏,因此兩個量子位元會與 bob 量子位元糾纏,並編碼 message

  2. 然後,您必須在 Bell 基礎中測量 alicemessage 量子位元。 如何在 Q#中以 Bell 為基礎來表示測量? 你無此權限。 或者至少不是直接的。 在 Q# 中,您有 M 運算,其會在 $Z$ 基礎或計算基礎中執行測量。 因此,若要正確使用 M 運算,您必須將 Bell states 轉換成計算基礎狀態。 您可以將 H 運算套用至 message 量子位元,以執行這項操作。 下表顯示 Bell states 與計算基礎狀態之間的對應。

    Bell 狀態 計算基礎狀態
    $\ket{\phi^+}$ $\ket{00}$
    $\ket{\phi^-}$ $\ket{01}$
    $\ket{\psi^+}$ $\ket{10}$
    $\ket{\psi^-}$ $\ket{11}$

    提示

    一個好的練習是在將 Hadamard 運算套用到第一個量子位元後驗證 Bell states 和計算基礎狀態的等價性。 祝您好運!

  3. 最後,if 陳述式會檢查測量結果,並據以將更正套用至 bob 量子位元。 如果 message 量子位元在 One 中測量,則將 Z 閘道套用於 bob 量子位元。 如果 alice 量子位元也是在 One 中測量,則將 Z 閘道套用於 bob 量子位元。

定義 SetToPlusSetToMinus 運算

如果您想要以不同狀態傳送量子位元,例如 |0⟩、|1⟩、|+⟩ 和 |−⟩,您必須定義初始化的狀態。 您已經擁有 Teleport 運算來傳送量子位元,但您需要在傳送量子位元之前,先準備處於正確狀態的量子位元。

您必須定義另外兩個運算,SetToPlusSetToMinus,以分別將狀態 |0⟩ 中的量子位元設定為 |+⟩ 和 |−⟩。

    /// 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{-}$ 執行遠端通訊協定。

讓我們詳細說明 Main 運算:

  1. 此工作會設定兩個量子位元: messagebob
  2. 它會定義包含量子狀態的 Tuple 清單、初始化運算式作業,以這類狀態初始化量子位所需的初始化表達式作業,以及傳送的基礎。 初始設定式作業為: I 適用於 $\ket{0}$、X 適用於 $\ket{1}$、SetToPlus 適用於 $\ket{+}$,以及 SetToMinus 適用於 $\ket{-}$。 SetToPlusSetToMinus 作業定義於先前的步驟中。
  3. 作業會逐一查看 Tuple 清單,並初始化對應狀態中的 message 量子位元,並使用 DumpMachine 來顯示狀態。 然後,它會使用先前步驟中定義的 Teleport 作業,將 message 量子位元的狀態傳送至 bob 量子位元。
  4. 在傳送狀態之後,作業會以對應的基礎測量 bob 量子位元,並重設量子位元以繼續傳送更多訊息。
  5. 最後,作業會傳回每個傳送的度量結果。
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;
}

執行程式

您的量子傳送程式已就緒! 您可以執行程式,以查看量子傳送如何針對不同的量子狀態運作。 程式會將不同狀態的 message 量子位元初始化,並將狀態傳送至 bob 量子位元。

下列程式碼包含 Teleport 運算、SetToPlusSetToMinus 運算,以及針對不同量子狀態執行傳送通訊協定的 Main 運算。

  1. 您的 Main.qs 檔案看起來應該像這樣:

    /// 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 one qubit to a bob qubit by using 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〉
    
    DumpMachine:
    
     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
      |00⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
    
    Received state |0〉