練習 - 使用糾纏透過 Q# 進行傳送
在上一個單元中,您已檢閱量子遠端通訊協定的步驟。 現在輪到你幫助 Alice 和 Bob 進行量子傳送實驗了!
在本單元中,您將在 Q# 中建立一個量子傳送程式,該程式使用量子傳送通訊協定將量子位元的狀態從 Alice 傳送到 Bob。
在 Q# 中建立量子傳送通訊協定
- 打開 Visual Studio Code。
- 選取 [檔案] > [新增文字檔],並將它另存為 Main.qs。
- 選取 [檢視] -> [命令選擇區] 並鍵入 Q#:設定 Azure Quantum QIR target 設定檔。 按 Enter 鍵。
- 選取 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
運算:
運算會使用
alice
量子位元,並在alice
與bob
量子位元之間建立糾纏。 然後,message
量子位元會與alice
量子位元糾纏,因此兩個量子位元會與bob
量子位元糾纏,並編碼message
。然後,您必須在 Bell 基礎中測量
alice
和message
量子位元。 如何在 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 和計算基礎狀態的等價性。 祝您好運!
最後,
if
陳述式會檢查測量結果,並據以將更正套用至bob
量子位元。 如果message
量子位元在One
中測量,則將 Z 閘道套用於bob
量子位元。 如果alice
量子位元也是在One
中測量,則將 Z 閘道套用於bob
量子位元。
定義 SetToPlus
和 SetToMinus
運算
如果您想要以不同狀態傳送量子位元,例如 |0⟩、|1⟩、|+⟩ 和 |−⟩,您必須定義初始化的狀態。 您已經擁有 Teleport
運算來傳送量子位元,但您需要在傳送量子位元之前,先準備處於正確狀態的量子位元。
您必須定義另外兩個運算,SetToPlus
和 SetToMinus
,以分別將狀態 |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
運算:
- 此工作會設定兩個量子位元:
message
和bob
。 - 它會定義包含量子狀態的 Tuple 清單、初始化運算式作業,以這類狀態初始化量子位所需的初始化表達式作業,以及傳送的基礎。 初始設定式作業為:
I
適用於 $\ket{0}$、X
適用於 $\ket{1}$、SetToPlus
適用於 $\ket{+}$,以及SetToMinus
適用於 $\ket{-}$。SetToPlus
和SetToMinus
作業定義於先前的步驟中。 - 作業會逐一查看 Tuple 清單,並初始化對應狀態中的
message
量子位元,並使用DumpMachine
來顯示狀態。 然後,它會使用先前步驟中定義的Teleport
作業,將message
量子位元的狀態傳送至bob
量子位元。 - 在傳送狀態之後,作業會以對應的基礎測量
bob
量子位元,並重設量子位元以繼續傳送更多訊息。 - 最後,作業會傳回每個傳送的度量結果。
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
運算、SetToPlus
和 SetToMinus
運算,以及針對不同量子狀態執行傳送通訊協定的 Main
運算。
您的 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); }
若要在內建模擬器上執行程式,請按下
Main
作業上方的 [執行],或按 Ctrl+F5。 您的輸出會出現在偵錯控制台中。檢查接收的狀態是否符合傳送狀態。 例如:
Teleporting state |0〉 DumpMachine: Basis | Amplitude | Probability | Phase ----------------------------------------------- |00⟩ | 1.0000+0.0000𝑖 | 100.0000% | 0.0000 Received state |0〉