練習 - 使用 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 操作。

其運作方式如下:

  1. 選擇一個處於 c 狀態的量子位元為控制量子位元,另一個量子位元為量 target 子位元。 在這裡,我們選擇最左邊的量子位元作為控制項,而最右邊的量子位元則作為 target。

  2. 只將控制量子位元置於相等的疊加狀態。 若要這樣做,請只將 H 作業套用至控制量子位:

    $$H \ket{0_c} = \frac{1}{\sqrt{2}}(\ket{0_c} + \ket{1_c})$$

    備註

    下標 ${}_c$ 和 ${}_t$ 分別指定控制與 target 量子位元。

  3. 將 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) 中遵循下列步驟:

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

建立貝爾狀態

要在Q#中創建貝爾態$\ket{\phi^+}$,請遵循以下步驟:

  1. 從標準程式庫匯Std.Diagnostics入Q#命名空間,以便您可以使用該DumpMachine函數。 當您在程式碼中呼叫函式時,此函式會顯示量子位元狀態的相關資訊。 若要匯入命名空間,請將下列 Q# 程式碼複製到 Main.qs 檔案中:

    import Std.Diagnostics.*;
    
  2. 建立傳回兩個 Main 類別值的 Result 作業,也就是量子位元的測量結果。

    import Std.Diagnostics.*;
    
    operation Main() : (Result, Result) {
        // Your code goes here
    }
    
  3. 在運算 Main 內,分配兩個量子位以進行糾纏,分別是 q1q2

    import Std.Diagnostics.*;
    
    operation Main() : (Result, Result) {
        use (q1, q2) = (Qubit(), Qubit());
    }
    
  4. 將 Hadamard 閘門 ,H應用於控制量子位元。q1 這只會將該量子位元置於疊加狀態。 然後將 CNOT 閘門 CNOT,套用至兩個量子位元,以糾纏兩個量子位元。 第一個 CNOT 引數是控制量子位,第二個引數是 target 量子位。

    import Std.Diagnostics.*; 
    
    operation Main() : (Result, Result) {
        use (q1, q2) = (Qubit(), Qubit());
    
        H(q1);
        CNOT(q1, q2);
    }
    
  5. 使用DumpMachine函式來顯示量子位元在糾纏之後的狀態。 請注意, DumpMachine 不會在量子位元上執行測量,因此 DumpMachine 不會影響量子位元狀態。

    import Std.Diagnostics.*;
    
    operation Main() : (Result, Result) {
        use (q1, q2) = (Qubit(), Qubit());
    
        H(q1);
        CNOT(q1, q2);
    
        DumpMachine();
    }
    
  6. 使用M操作來測量量子位元,並將結果儲存在m1m2中。 然後使用該 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);
    
    }
    
  7. 返回量子位元的測量結果,使用 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);
    }
    
  8. 若要在內建的模擬器上執行程式,請選擇操作上方的 執行 程式碼鏡像,或按 Main。 您的輸出會出現在偵錯主控台中。

  9. 測量結果是相關的,因此在程序結束時,您會得到 或(Zero, Zero)(One, One)具有相同機率的結果。 多次重新運行程序並觀察輸出以說服自己相關性。

  10. 若要視覺化電路圖,請選擇 運算上方的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^-}$ 狀態的方法:

  1. 在狀態 $\ket{00}$中建立兩個量子位元。

  2. 將控制量子位元置於疊加態,操作如下 $H$ :

    $$H \ket{0_c} = \frac{1}{\sqrt{2}}(\ket{0_c} + \ket{1_c}) = \ket{+_c}$$

  3. 將操作 $Z$ 套用到控制量子位元。

    $$Z \frac{1}{\sqrt{2}}(\ket{0_c} + \ket{1_c}) = \frac{1}{\sqrt{2}}(\ket{0_c} - \ket{1_c}) = \ket{-_c}$$

  4. 對控制量子位元 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 邏輯閘。

在下一個單元中,您將學習如何使用糾纏來傳送量子資訊,這個過程稱為量子隱形傳態。