練習 - 使用 Q# 建立不同的疊加狀態

已完成

在上一個單元中,您已了解疊加和 Dirac 表示法。 現在理論已經足夠了! 讓我們透過撰寫一些程式碼來探索 Q# 中的疊加。

在本單元中,您會使用 DumpMachine 函式透過 Q# 來建立量子疊加並深入探討機率。 DumpMachine 函式會在呼叫它時傾印有關量子系統目前狀態的資訊。

建立新的 Q# 檔案

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

開始使用疊加

讓我們從一個簡單的程式開始,該程式使用處於疊加狀態的量子位元來產生隨機位元。 您將使用 DumpMachine 函式來查看該程式中不同點的量子位元的狀態。

  1. 將下列程式碼新增至 Main.qs 檔案:

    import Microsoft.Quantum.Diagnostics.*;
    
    operation Main() : Result {
        use q = Qubit();
        Message("Initialized qubit:");
        DumpMachine(); // First dump
        Message(" ");
        H(q);
        Message("Qubit after applying H:");
        DumpMachine(); // Second dump
        Message(" ");
        let randomBit = M(q);
        Message("Qubit after the measurement:");
        DumpMachine(); // Third dump
        Message(" ");
        Reset(q);
        Message("Qubit after resetting:");
        DumpMachine(); // Fourth dump
        Message(" ");
        return randomBit;
    }
    

    在這裡,您將會呼叫 DumpMachine 四次:

    • 配置量子位元之後。
    • 將量子位元放入疊加之後。
    • 測量量子位元的狀態之後。
    • 重設量子位元之後。

    您將作業 MResetZ 分割為兩個作業:MReset。 因為您想要檢查測量之後的狀態,所以您這麼做。

  2. 若要在內建模擬器上執行程式,請按下 Main 作業上方的 [執行],或按 Ctrl+F5 您的輸出會出現在偵錯控制台中。

  3. DumpMachine 函式會建立一個資料表,其中包含描述量子位元暫存器狀態的資訊。 具體而言,其會為每個基礎狀態提供機率幅、機率與以弧度為單位的階段。

  4. 在程式結束時,您會取得 ZeroOne 的結果。 讓我們看看每個步驟。

    1. 初始化的量子位元:use 陳述式配置的每個量子位元都會以狀態 $|0\rangle$ 開頭。 因此 DumpMachine 會產生對應至狀態 $|0\rangle$ 中單一量子位元暫存器的資訊。

      Initialized qubit:
      
      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
         |0⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
      
    2. 套用 H 後的量子位元:套用 H 之後,我們會在疊加狀態 $|\psi\rangle=\frac1{\sqrt2} |0\rangle + \frac1{\sqrt2} |1\rangle$ 中準備量子位元。

      Qubit after applying H:
      
      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
         |0⟩ |  0.7071+0.0000𝑖 |    50.0000% |   0.0000
         |1⟩ |  0.7071+0.0000𝑖 |    50.0000% |   0.0000
      
    3. 測量後的量子位元:在我們測量並儲存結果之後,結果可能是 ZeroOne。 例如,如果產生的狀態是 One,則暫存器的狀態將折疊為 $|1\rangle$ 且不再處於疊加狀態。

      Qubit after the measurement:
      
      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
         |1⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
      
    4. 重設後的量子位元:作業 Reset 會將量子位元重設為狀態 $|0\rangle$。 請記住,針對任何 Q# 作業,您一律必須將所使用的量子位元留在狀態 $|0\rangle$,以便其他作業加以使用。

      Qubit after resetting:
      
      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
         |0⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
      

    注意

    您的輸出可能會有所不同,因為隨機數產生器是機率性的。 結果的機率不是確定性的。

探索其他類型的疊加狀態

既然您已經知道如何檢查暫存器的狀態,您可以查看修改量子位元狀態的更多作業,並將其放入累加。

目前的亂數產生器會產生具有 50% 機率的 ZeroOne。 讓我們看看第二個範例,其會產生具有不同機率的亂數。

扭曲的隨機位元產生器

假設您要建立一個偏斜的隨機位元產生器,即獲得 Zero 的機率與獲得 One 的機率不同。

例如,您想要使 Zero 結果具有 $P$ 的機率,並使 One 結果具有 $1-P$ 的機率。 可以產生這類隨機位元產生器的有效量子位元狀態如下:

$$|\psi\rangle=\sqrt{P}|0\rangle+\sqrt{1-P}|1\rangle$$

在這裡,$\alpha=\sqrt{P}$ 和 $\beta=\sqrt{1-P}$ 分別是基態 $|0\rangle$ 和 $|1\rangle$ 的振幅。

若要取得此狀態,您可以將 $R_y(2\arccos\sqrt{P})$ 運算子依序套用到處於 $|0\rangle.$ 狀態的量子位元。您可以透過使用標準程式庫的 Ry 作業,在 Q# 中達成此結果。

提示

若要深入了解單一量子位元運算背後的數學運算,請參閱 Quantum Katas 中的單一量子位元閘教學課程

  1. 如以下範例所示修改 Main.qs,然後儲存檔案。 此範例會將 $\alpha$ 選擇為大約是 $\frac13$。

    import Microsoft.Quantum.Diagnostics.*;
    import Microsoft.Quantum.Math.*;
    
    operation Main() : Result {
        use q = Qubit();
        let P = 0.333333; // P is 1/3
        Ry(2.0 * ArcCos(Sqrt(P)), q);
        Message("The qubit is in the desired state.");
        Message("");
        DumpMachine(); // Dump the state of the qubit 
        Message("");
        Message("Your skewed random bit is:");
        let skewedrandomBit = M(q);
        Reset(q);
        return skewedrandomBit;
    }
    
  2. 若要在內建模擬器上執行程式,請按下 Main 作業上方的 [執行],或按 Ctrl+F5 您的輸出會出現在偵錯控制台中。

  3. 您可以看見 DumpMachine 如何在套用作業並顯示相關聯的機率之後顯示預期的狀態。 請注意,獲得 Zero 的機率約為 33.33%,而獲得 One 的機率約為 66.67%。 因此,隨機位元產生器是偏斜的。

    The qubit is in the desired state.
    
    DumpMachine:
    
     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
       |0⟩ |  0.5773+0.0000𝑖 |    33.3333% |   0.0000
       |1⟩ |  0.8165+0.0000𝑖 |    66.6667% |   0.0000
    
    
    Your skewed random bit is:
    Result: "One"
    

    注意

    您的輸出可能會有所不同,因為隨機數產生器是機率性的。 結果的機率不是確定性的。

多量子位元疊加

現在讓我們探索包含許多量子位元之暫存器的疊加。 例如,如果您的暫存器包含三個量子位元,您便有八個基礎狀態:

$$|000\rangle,|001\rangle,|010\rangle,|011\rangle,|100\rangle,|101\rangle, |110\rangle,|111\rangle $$

因此您可將任意三個量子位元的狀態表示為:

$$|\psi\rangle=\alpha_0|000\rangle+\alpha_1|001\rangle+\alpha_2|010\rangle+\alpha_3|011\rangle+\alpha_4|100\rangle+\alpha_5|101\rangle+\alpha_6 |110\rangle+\alpha_7|111\rangle$$

在這裡,$\alpha_i$ 是滿足 $\sum|\alpha_i|^2=1$ 的複數。

例如,您可以將 H 套用到每個量子位元,來以統一的疊加形式放置量子位元。 您可以使用此統一的疊加來建立不同版本的量子亂數產生器,使其能透過測量疊加中的三個量子位元 (而非測量單一量子位元三次) 來產生三位元數字。

Basis 數字
$\ket{000}$ 0
$\ket{001}$ 1
$\ket{010}$ 2
$\ket{011}$ 3
$\ket{100}$ 4
$\ket{101}$ 5
$\ket{110}$ 6
$\ket{111}$ 7
  1. 如以下範例所示修改 Main.qs,然後儲存檔案。

    import Microsoft.Quantum.Diagnostics.*;
    import Microsoft.Quantum.Math.*;
    import Microsoft.Quantum.Convert.*;
    import Microsoft.Quantum.Arrays.*;
    
    operation Main() : Int {
        use qubits = Qubit[3];
        ApplyToEach(H, qubits);
        Message("The qubit register in a uniform superposition: ");
        DumpMachine();
        let result = ForEach(M, qubits);
        Message("Measuring the qubits collapses the superposition to a basis state.");
        DumpMachine();
        ResetAll(qubits);
        return BoolArrayAsInt(ResultArrayAsBoolArray(result));
    }
    

    在這裡,您可以看到三個概念:

    • qubits 變數現在代表長度為三的 Qubit 陣列。
    • 作業 ApplyToEachForEach 對於測量和處理多個量子位元非常有用,而且它們使用的程式碼更少。 Q# 程式庫提供許多種類的作業和函式,能使量子程式的撰寫更加有效率。
    • Microsoft.Quantum.Convert 程式庫中的 BoolArrayAsIntResultArrayAsBoolArray 函式會將 ForEach(M, qubits) 傳回的二進位 Result 陣列轉換為整數。
  2. 若要執行程式,請按下 Main 作業上方的 [執行],或按 Ctrl+F5。 您的輸出會出現在偵錯控制台中。

  3. 藉由使用 DumpMachine,您可看到測量三個量子位元的動作,會如何將暫存器的狀態塌縮為八個可能基礎狀態的其中一個。 例如,如果您得到結果 3,則表示暫存器的狀態折疊為 $|110\rangle$。

    The qubit register in a uniform superposition:
    
    DumpMachine:
    
     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
     |000⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |001⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |010⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |011⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |100⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |101⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |110⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |111⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
    
    Measuring the qubits collapses the superposition to a basis state.
    
    DumpMachine:
    
     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
     |110⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
    
    Result: "3"
    

    注意

    您的輸出可能會有所不同,因為隨機數產生器是機率性的。 結果的機率不是確定性的。

  4. ForEach(M, qubit) 作業會依序測量每個量子位元,並逐漸塌縮狀態。 您也可以在每次測量後傾印中間狀態。 若要這樣做,請如以下範例所示修改 Main.qs,然後儲存檔案。

    import Microsoft.Quantum.Diagnostics.*;
    import Microsoft.Quantum.Measurement.*;
    import Microsoft.Quantum.Math.*;
    import Microsoft.Quantum.Convert.*;
    
    operation Main() : Int {
        use qubits = Qubit[3];
        ApplyToEach(H, qubits);
        Message("The qubit register in a uniform superposition: ");
        DumpMachine();
        mutable results = [];
        for q in qubits {
            Message(" ");
            set results += [M(q)];
            DumpMachine();
        }
        Message(" ");
        Message("Your random number is: ");
        ResetAll(qubits);
        return BoolArrayAsInt(ResultArrayAsBoolArray(results));
    }
    
  5. 在這裡,您會使用 for 迴圈來依序對每個量子位元採取動作。 Q# 具有傳統的流程控制功能,例如 for 迴圈和 if 陳述式,您可以使用它們來控制程式的流程。

  6. 若要執行程式,請從 Main 作業上方命令清單中按一下 [執行],或按 Ctrl+F5

  7. 您可以看到每個連續的測量會如何變更量子狀態,並進一步改變取得每個結果的機率。 例如,如果您的結果是數字 5,您將得到以下輸出。 讓我們很快地看一下每個步驟:

    1. 狀態準備:將 H 套用到暫存器的每個量子位元後,我們會取得統一的疊加。

      The qubit register in a uniform superposition: 
      
      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
       |000⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
       |001⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
       |010⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
       |011⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
       |100⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
       |101⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
       |110⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
       |111⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
      
    2. 第一次測量:在第一次測量中,結果為 One。 因此,其最右邊的量子位元為 Zero 之狀態的所有幅度皆已不存在。 這些幅度為 $|0\rangle=|000\rangle、|2\rangle=|010\rangle、|4\rangle=|100\rangle$ 和 $|6\rangle= |110\rangle$。 剩餘的幅度會提升以滿足正規化條件。

      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
       |001⟩ |  0.5000+0.0000𝑖 |    25.0000% |   0.0000
       |011⟩ |  0.5000+0.0000𝑖 |    25.0000% |   0.0000
       |101⟩ |  0.5000+0.0000𝑖 |    25.0000% |   0.0000
       |111⟩ |  0.5000+0.0000𝑖 |    25.0000% |   0.0000
      
    3. 第一次測量:在第二次測量中,結果為 Zero。 因此,其第二個最右邊 (中間) 的量子位元為 One 之狀態的所有幅度都會消失。 幅度為 $|3\rangle=|011\rangle$ 和 $|7\rangle=|111\rangle$。 剩餘的幅度會提升以滿足正規化條件。

      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
       |001⟩ |  0.7071+0.0000𝑖 |    50.0000% |   0.0000
       |101⟩ |  0.7071+0.0000𝑖 |    50.0000% |   0.0000
      
    4. 第三次測量:在第三次測量中,結果為 One。 因此,其最左邊的量子位元為 Zero 之狀態的所有幅度都會清除。唯一相容的狀態是 $|5\rangle=|101\rangle$。 此狀態會取得 $1$ 的幅度機率。

      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
       |101⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
      
      
      Your random number is: 
      Result: "5"
      

    注意

    您的輸出可能會有所不同,因為隨機數產生器是機率性的。 結果的機率不是確定性的。