練習 - 使用 Q# 建立量子糾纏
在上一個單元中,您已了解量子糾纏和貝爾狀態的概念。
在本單元中,您會使用 Azure Quantum Development Kit (QDK) 來撰寫 Q# 程式碼,以在兩個量子位元之間建立糾纏的 Bell 狀態。 若要建立第一個 Bell 狀態,請套用兩個量子運算:Hadamard 運算和 Controlled-NOT (CNOT) 運算。
首先,讓我們了解這些操作的工作原理以及它們為何會產生糾纏狀態。
哈達瑪德行動
回想一下,Hadamard 或 H 操作會將處於純態 $\ket{0}$ 或 $\ket{1}$ 狀態的量子位元置於相等疊加態。
$$ H \ket{0} = \frac1{\sqrt2} \ket{0} + \frac1{\sqrt2} \ket{1}$$ $$ H \ket{1} = \frac1{\sqrt2} \ket{0} - \frac1{\sqrt2} \ket{1}$$
建立 Bell 狀態的第一步是在其中一個量子位元上執行 Hadamard 運算。
Controlled-NOT (CNOT) 運算
當兩個量子位元糾纏時,一個量子位元的狀態相依於另一個量子位元的狀態。 因此,要糾纏兩個量子位元,你需要施加多量子位運算,也就是同時作用於兩個量子位元的操作。 Controlled-NOT (或 CNOT) 運算是一種有助於建立糾纏的多量子位元運算。
CNOT 作業會採用兩個量子位元作為輸入。 其中一個量子位元是控制量子位元,另一個量子位元是target量子位元。 如果控制量子位元處於 $\ket{1}$ 狀態,則 CNOT 操作會翻轉 target 量子位元的狀態。 否則,CNOT 不會執行任何動作。
例如,在下列兩個量子位元狀態中,控制量子位元是最左邊的量子位元,target量子位元是最右邊的量子位元。
輸入至 CNOT |
輸出來自 CNOT |
|---|---|
| $\ket{00}$ | $\ket{00}$ |
| $\ket{01}$ | $\ket{01}$ |
| $\ket{10}$ | $\ket{11}$ |
| $\ket{11}$ | $\ket{10}$ |
在 Q#中,作業 CNOT 會作用於兩個量子位元的陣列,而且只有在第一個量子位元為 One時,它才會翻轉第二個量子位元。
與 Hadamard 和 CNOT 作業的糾纏
假設你有一個狀態為 $\ket{00}$的雙量子位元系統。 在此狀態下,量子位不會糾纏。 要將這些量子位元置於糾纏貝爾態 $\ket{\phi^+}=\frac1{\sqrt2}(\ket{00}+\ket{11})$,應用 Hadamard 與 CNOT 操作。
其運作方式如下:
選擇一個處於 c 狀態的量子位元為控制量子位元,另一個量子位元為量 target 子位元。 在這裡,我們選擇最左邊的量子位元作為控制項,而最右邊的量子位元則作為 target。
只將控制量子位元置於相等的疊加狀態。 若要這樣做,請只將 H 作業套用至控制量子位:
$$H \ket{0_c} = \frac{1}{\sqrt{2}}(\ket{0_c} + \ket{1_c})$$
備註
下標 ${}_c$ 和 ${}_t$ 分別指定控制與 target 量子位元。
將 CNOT 作業套用至量子位對。 請記住,控制量子位元處於疊加態,且量子位元target處於$\ket{0_t}$態。
$ \begin{aligned} CNOT \frac{{1}{\sqrt{{2}}(\ket{0_c}+\ket{1_c})\ket{0_t}&= CNOT \frac{{1}{\sqrt2}(\ket{0_c 0_t}+\ket{1_c 0_t})\\&=\frac{{1}{\sqrt2}(CNOT \ket{0_c 0_t} + CNOT \ket{1_c 0_t})\\&=\frac{{1}{\sqrt2}(\ket{0_c 0_t}+\ket{1_c 1_t}) \end{aligned}$
狀態 $\frac{1}{\sqrt2}(\ket{0_c 0_t}+\ket{1_c 1_t})$ 是糾纏的。 這個特定的糾纏態是四個貝爾態之一。 $\ket{\phi^{+}}$
備註
在量子計算中,操作通常被稱為「門」。 例如,H 閘門和 CNOT 閘門。
在Q#中建立量子糾纏
若要使用程式碼建立 Q# Bell 狀態,請在 Visual Studio Code (VS Code) 中遵循下列步驟:
- 開啟 VS Code。
- 開啟 [檔案 ] 功能表,然後選擇 [新增文字檔案] 以建立新檔案。
- 將檔案儲存為 Main.qs。
建立貝爾狀態
要在Q#中創建貝爾態$\ket{\phi^+}$,請遵循以下步驟:
從標準程式庫匯
Std.Diagnostics入Q#命名空間,以便您可以使用該DumpMachine函數。 當您在程式碼中呼叫函式時,此函式會顯示量子位元狀態的相關資訊。 若要匯入命名空間,請將下列 Q# 程式碼複製到 Main.qs 檔案中:import Std.Diagnostics.*;建立傳回兩個
Main類別值的Result作業,也就是量子位元的測量結果。import Std.Diagnostics.*; operation Main() : (Result, Result) { // Your code goes here }在運算
Main內,分配兩個量子位以進行糾纏,分別是q1和q2。import Std.Diagnostics.*; operation Main() : (Result, Result) { use (q1, q2) = (Qubit(), Qubit()); }將 Hadamard 閘門 ,
H應用於控制量子位元。q1這只會將該量子位元置於疊加狀態。 然後將 CNOT 閘門CNOT,套用至兩個量子位元,以糾纏兩個量子位元。 第一個CNOT引數是控制量子位,第二個引數是 target 量子位。import Std.Diagnostics.*; operation Main() : (Result, Result) { use (q1, q2) = (Qubit(), Qubit()); H(q1); CNOT(q1, q2); }使用
DumpMachine函式來顯示量子位元在糾纏之後的狀態。 請注意,DumpMachine不會在量子位元上執行測量,因此DumpMachine不會影響量子位元狀態。import Std.Diagnostics.*; operation Main() : (Result, Result) { use (q1, q2) = (Qubit(), Qubit()); H(q1); CNOT(q1, q2); DumpMachine(); }使用
M操作來測量量子位元,並將結果儲存在m1和m2中。 然後使用該Reset操作重置量子位。import Std.Diagnostics.*; operation Main() : (Result, Result) { use (q1, q2) = (Qubit(), Qubit()); H(q1); CNOT(q1, q2); DumpMachine(); let (m1, m2) = (M(q1), M(q2)); Reset(q1); Reset(q2); }返回量子位元的測量結果,使用
return陳述式。 這是 Main.qs 文件中的最終程序:import Std.Diagnostics.*; operation Main() : (Result, Result) { use (q1, q2) = (Qubit(), Qubit()); H(q1); CNOT(q1, q2); DumpMachine(); let (m1, m2) = (M(q1), M(q2)); Reset(q1); Reset(q2); return (m1, m2); }若要在內建的模擬器上執行程式,請選擇操作上方的 執行 程式碼鏡像,或按
Main。 您的輸出會出現在偵錯主控台中。測量結果是相關的,因此在程序結束時,您會得到 或
(Zero, Zero)(One, One)具有相同機率的結果。 多次重新運行程序並觀察輸出以說服自己相關性。若要視覺化電路圖,請選擇 運算上方的
Main程式碼功能濾鏡。 電路圖顯示套用至第一個量子位元的 Hadamard 邏輯閘,以及套用至這兩個量子位元的 CNOT 邏輯閘。
建立其他貝爾狀態
若要建立其他貝爾態,請對量子位元施加額外的泡利$X$或$Z$運算。
例如,要建立貝爾狀態 $\ket{\phi^-}=\frac1{\sqrt2}(\ket{00}-\ket{11})$,在施加哈達瑪閘後、但應用 CNOT 之前,對控制量子位元施加泡利 $Z$ 運算。 該 $Z$ 操作將狀態 $\ket{+}$ 翻轉為 $\ket{-}$。
備註
$\frac{1}{\sqrt{2}}(\ket{0}+\ket{1})$狀態 和 $\frac{1}{\sqrt{2}}(\ket{0} - \ket{1})$ 分別稱為 $\ket{+}$ 和 $\ket{-}$。
以下是如何創建 $\ket{\phi^-}$ 狀態的方法:
在狀態 $\ket{00}$中建立兩個量子位元。
將控制量子位元置於疊加態,操作如下 $H$ :
$$H \ket{0_c} = \frac{1}{\sqrt{2}}(\ket{0_c} + \ket{1_c}) = \ket{+_c}$$
將操作 $Z$ 套用到控制量子位元。
$$Z \frac{1}{\sqrt{2}}(\ket{0_c} + \ket{1_c}) = \frac{1}{\sqrt{2}}(\ket{0_c} - \ket{1_c}) = \ket{-_c}$$
對控制量子位元 target 和處於 $\ket{0_t}$ 狀態的量子位元施加 CNOT 操作。
$ \begin{aligned} CNOT \frac{{1}{\sqrt{{2}}(\ket{0_c}-\ket{1_c})\ket{0_t}&= CNOT \frac{{1}{\sqrt2}(\ket{0_c 0_t}-\ket{1_c 0_t})\\&=\frac{{1}{\sqrt2}(CNOT \ket{0_c 0_t} - CNOT \ket{1_c 0_t})\\&=\frac{{1}{\sqrt2}(\ket{0_c 0_t}-\ket{1_c 1_t}) \end{aligned}$
要在$\ket{\phi^-}$Q#中建立 Bell 狀態,請將您Main.qs中的程式碼替換為以下程式碼:
import Std.Diagnostics.*;
operation Main() : (Result, Result) {
use (q1, q2) = (Qubit(), Qubit());
H(q1);
Z(q1); // Apply the Pauli Z operation to the control qubit
CNOT(q1, q2);
DumpMachine();
let (m1, m2) = (M(q1), M(q2));
Reset(q1);
Reset(q2);
return (m1, m2);
}
同樣地,你也可以透過對量子位元應用泡利 $\ket{\psi^+}$ and $\ket{\psi^-}$X 和$$Z$ 運算來建立貝爾態$。
- 要建立貝爾態 $\ket{\psi^+}=\frac1{\sqrt2}(\ket{01}+\ket{10})$,在對控制量子位元施加哈達瑪閘後,對另一個量子比特施加泡利 $X$ 閘 target 。 然後套用 CNOT 邏輯閘。
- 要建立貝爾態$\ket{\psi^-}=\frac1{\sqrt2}(\ket{01}-\ket{10})$,在對控制量子位元施加哈達瑪閘門後,將泡利 $Z$ 施加於控制量子位元,然後將泡利 $X$ 施加於target量子位元。 然後套用 CNOT 邏輯閘。
在下一個單元中,您將學習如何使用糾纏來傳送量子資訊,這個過程稱為量子隱形傳態。