量子計算在近年來成為熱門議題,而理解其基本原理對於入門至關重要。本文將以量子拋硬幣實驗為例,逐步介紹如何使用 Qiskit 建立和執行量子線路,並解釋其背後的執行機制。首先,我們會從單個量子位元開始,模擬基本的拋硬幣操作,接著擴充套件到多個量子位元,展示如何同時模擬拋多枚硬幣,並觀察其統計結果。過程中,我們將會使用阿達馬門(H門)來創造量子疊加態,並使用測量門來取得結果。同時,我們也會探討量子線路的視覺化表示以及如何使用 Qiskit 的模擬器來執行量子線路。最後,我們將簡要介紹量子糾纏的概念,並展示如何在 Qiskit 中實作。

3.3 深入理解量子線路

3.3.1 量子線路的執行機制

就像音樂樂譜一樣,量子線路也是從左到右按順序讀取的。也就是說,量子門是從量子線路的左側到右側依次執行的。使用者可以使用“Circuit Composer”中的“Inspect”功能檢查量子線路的執行方式。

操作步驟:

  1. 在IBM Quantum Experience中開啟之前建立的只有一個量子位元、一個非門和一個測量指令的量子線路。
  2. 在頂部選單中選擇“Inspect”。
  3. 在開啟的“Inspector”視窗中,點選“>”,一步一步地執行自己的量子線路。觀察量子門作用在量子位元上時,代表量子位元的態向量是如何變化的。

知識拓展:

  • 態向量的變化:當X門作用在量子位元上時,相應的態向量會從$|0\rangle$變為$|1\rangle$。
  • Q球(Q-sphere):它是量子線路可能的輸出結果的圖形表示。在本示例中,Q球表示該量子線路只會產生一種輸出結果,結果一定是$|1\rangle$。
  • Measurement Probabilities:如果使用者將“Statevector”切換到“Measurement Probabilities”選項,可以驗證之前提到的現象,即量子線路確實100%會產生$|1\rangle$這樣的結果。

3.3.2 進階技巧:使用屏障(Barrier)

在量子線路的第一個量子門前面新增一個屏障,可以使“Inspect”工具讀取量子位元的初始狀態並對其進行顯示。

3.4 量子拋硬幣實驗

3.4.1 操作步驟

  1. 存取IBM Quantum官方網站的“IBM Quantum Composer”頁面,登入IBM Quantum Experience。
  2. 新建一個量子線路,並找到所需的量子門。本示例僅需使用H門和測量指令。
  3. 將H門拖到第一個量子位元直線上,然後將“Measurement”指令也拖到該直線上,放在H門圖示的右側。
  4. 儲存該量子線路,並點選“Run on ibmq_qasm_simulator”按鈕。
  5. 檢視執行結果。點選“Run”按鈕下方的“Jobs”圖示,檢視該作業的執行結果。

程式碼範例:

from qiskit import QuantumCircuit, execute, Aer

# 建立量子線路
qc = QuantumCircuit(1, 1)
qc.h(0)
qc.measure([0], [0])

# 在模擬器上執行
simulator = Aer.get_backend('qasm_simulator')
job = execute(qc, simulator, shots=1024)
result = job.result()
counts = result.get_counts(qc)
print(counts)

內容解密:

  • 建立量子線路:使用Qiskit建立了一個包含1個量子位元和1個經典位元的量子線路。
  • 應用H門qc.h(0)在第0個量子位元上應用H門,使其處於疊加態。
  • 測量qc.measure([0], [0])對第0個量子位元進行測量,並將結果儲存在第0個經典位元中。
  • 執行:在ibmq_qasm_simulator上執行該量子線路1024次。

3.4.2 知識拓展:轉譯(Transpiling)

除模擬器外的其他後端只能執行一組設定好的基礎量子門,其他的量子門都是由這些基礎量子門組合而成的。當量子程式執行時,程式設計軟體會解釋量子程式,程式中相對複雜的高階量子門會被轉譯為一個僅包含一組基礎量子門的基礎量子程式。

圖表翻譯:

  graph LR
    A[原版量子線路] -->|轉譯|> B[轉譯版量子線路]
    B --> C[基礎量子門]

3.5 不同軟體之間的互動

3.5.1 準備工作

可以從本文GitHub倉函式庫中對應第3章的目錄中下載本文示例的Python檔案。

3.5.2 操作步驟

  1. 透過瀏覽器跳轉到IBM Quantum官方網站,並使用IBM Quantum Experience帳號登入。
  2. 點選“Circuit Composer”,在麵包屑導航中點選“Circuits”。
  3. 在“Circuit Composer files”頁面中,點選“Coin toss”量子線路。
  4. 在“Circuit Composer”頁面右側的窗格中,選擇“<>Code”編輯器。
  5. 將量子樂譜匯出為QASM程式碼或Qiskit程式碼。

程式碼範例:

from qiskit import QuantumCircuit

# 從QASM字串匯入量子線路
qasm_string = """
OPENQASM 2.0;
include "qelib1.inc";
qreg q[1];
creg c[1];
h q[0];
measure q[0] -> c[0];
"""

circ = QuantumCircuit.from_qasm_str(qasm_string)
print(circ)

內容解密:

  • 匯入QASM程式碼:使用QuantumCircuit.from_qasm_str()方法將QASM程式碼匯入Qiskit。
  • 列印量子線路print(circ)輸出匯入的量子線路。

4.3 再談量子拋硬幣

本文將詳細介紹曾在IBM Quantum Experience中建立的第一個量子程式——量子拋硬幣。該程式證明瞭量子計算具有機率特性。

4.3.1 準備工作

可以從本文GitHub倉函式庫中對應第4章的目錄下載本文示例的Python檔案ch4_r1_coin_toss.py。有關如何執行示例程式,詳見1.4節。

4.3.2 操作步驟

以下步驟將在後續章節中重複出現,這些步驟根據Qiskit的基本操作所需的類別和步驟。

(1)匯入所需的Qiskit類別

匯入用於建立暫存器和量子線路、設定後端等所需的Python類別。

from qiskit import QuantumRegister, ClassicalRegister
from qiskit import QuantumCircuit, Aer, execute
from qiskit.tools.visualization import plot_histogram
from IPython.core.display import display

此外,還需從IPython.core.display中匯入display()方法,用於修正Anaconda Spyder IPython環境中圖形輸出結果的顯示。

(2)建立所需的暫存器和量子線路

建立兩個暫存器,一個用於儲存量子位元,另一個用於儲存經典位元。

qreg = QuantumRegister(1, 'q')
creg = ClassicalRegister(1, 'c')
circuit = QuantumCircuit(qreg, creg)

內容解密:

此段程式碼建立了一個包含1個量子位元的量子暫存器qreg和一個包含1個經典位元的經典暫存器creg,並使用這兩個暫存器建立了一個新的量子線路circuit

(3)建立量子線路

使用阿達馬門建立量子疊加,並使用測量門將量子疊加塌縮到兩個量子位元狀態之一。

circuit.h(qreg[0])
circuit.measure(qreg[0], creg[0])

內容解密:

此段程式碼首先對量子位元qreg[0]施加阿達馬門,使其進入疊加態。接著,使用測量門將量子位元的狀態測量到經典位元creg[0]中。

(4)選擇後端並執行量子線路

選擇qasm_simulator作為後端,並執行量子線路。

backend = Aer.get_backend('qasm_simulator')
job = execute(circuit, backend, shots=1024)
result = job.result()
counts = result.get_counts(circuit)
print(counts)

內容解密:

此段程式碼選擇了qasm_simulator作為執行量子線路的後端,並使用execute()函式執行量子線路,重複執行1024次。執行結果儲存在result物件中,並透過get_counts()方法取得測量結果的統計。

(5)顯示結果

使用plot_histogram()函式顯示測量結果的直方圖。

plot_histogram(counts)
display(plot_histogram(counts))

內容解密:

此段程式碼使用plot_histogram()函式繪製測量結果的直方圖,並使用display()函式顯示圖形。

4.3.3 執行結果

執行上述程式碼後,將輸出測量結果的統計,並顯示直方圖。結果將顯示量子拋硬幣的機率特性。

4.4 同時拋兩枚硬幣

本文將介紹如何使用Qiskit同時拋兩枚硬幣。

4.4.1 準備工作

可以從本文GitHub倉函式庫中對應第4章的目錄下載本文示例的Python檔案ch4_r2_two_coin_toss.py

4.4.2 操作步驟

(1)匯入所需的Qiskit類別

from qiskit import QuantumRegister, ClassicalRegister
from qiskit import QuantumCircuit, Aer, execute
from qiskit.tools.visualization import plot_histogram
from IPython.core.display import display

(2)建立所需的暫存器和量子線路

qreg = QuantumRegister(2, 'q')
creg = ClassicalRegister(2, 'c')
circuit = QuantumCircuit(qreg, creg)

內容解密:

此段程式碼建立了兩個量子位元的量子暫存器qreg和兩個經典位元的經典暫存器creg,並使用這兩個暫存器建立了一個新的量子線路circuit

(3)建立量子線路

circuit.h(qreg[0])
circuit.h(qreg[1])
circuit.measure(qreg[0], creg[0])
circuit.measure(qreg[1], creg[1])

內容解密:

此段程式碼對兩個量子位元qreg[0]qreg[1]分別施加阿達馬門,使其進入疊加態。接著,使用測量門將兩個量子位元的狀態測量到經典位元creg[0]creg[1]中。

(4)選擇後端並執行量子線路

backend = Aer.get_backend('qasm_simulator')
job = execute(circuit, backend, shots=1024)
result = job.result()
counts = result.get_counts(circuit)
print(counts)

內容解密:

此段程式碼選擇了qasm_simulator作為執行量子線路的後端,並使用execute()函式執行量子線路,重複執行1024次。執行結果儲存在result物件中,並透過get_counts()方法取得測量結果的統計。

(5)顯示結果

plot_histogram(counts)
display(plot_histogram(counts))

內容解密:

此段程式碼使用plot_histogram()函式繪製測量結果的直方圖,並使用display()函式顯示圖形。

4.4.3 執行結果

執行上述程式碼後,將輸出測量結果的統計,並顯示直方圖。結果將顯示同時拋兩枚硬幣的機率特性。

  graph LR
    A[開始] --> B[建立量子線路]
    B --> C[施加阿達馬門]
    C --> D[測量量子位元]
    D --> E[執行量子線路]
    E --> F[顯示結果]

圖表翻譯: 此圖表呈現了量子拋硬幣的流程。首先建立量子線路,接著對量子位元施加阿達馬門使其進入疊加態,然後測量量子位元的狀態。最後執行量子線路並顯示測量結果的統計。

同時拋兩枚硬幣的量子程式實作與分析

在前面的章節中,我們已經實作了單量子位元的量子拋硬幣程式。在本文中,我們將進一步拓展到兩個量子位元,實作同時拋兩枚硬幣的量子模擬。這個例子將展示如何使用Qiskit來處理多個量子位元的情況,並分析其統計結果。

4.6.1 準備工作

首先,我們需要準備好相關的Python檔案。可以從本文GitHub倉函式庫中對應第4章的目錄中下載本文範例的Python檔案ch4_r4_two_coin_toss.py

4.6.2 實作步驟

步驟1:匯入必要的Qiskit類別和方法

from qiskit import QuantumCircuit, Aer, execute
from qiskit.tools.visualization import plot_histogram
from IPython.core.display import display

步驟2:建立包含兩個量子位元和兩個經典位元的量子線路

qc = QuantumCircuit(2,2)

這裡我們使用QuantumCircuit(2,2)建立了一個包含兩個量子位元和兩個經典位元的量子線路。

步驟3:在量子線路中新增阿達馬門和測量門

qc.h([0,1])
qc.measure([0,1],[0,1])
display(qc.draw('mpl'))

程式碼詳解:

  • qc.h([0,1]):對兩個量子位元同時作用阿達馬門,使它們進入疊加態。
  • qc.measure([0,1],[0,1]):對兩個量子位元進行測量,並將結果儲存在對應的經典位元中。
  • display(qc.draw('mpl')):使用Matplotlib將量子線路視覺化。

圖表翻譯:

此圖示展示了一個雙量子位元的量子拋硬幣量子線路,其中包含兩個量子位元和兩個經典位元,以及作用於它們的阿達馬門和測量門。

步驟4:將後端設定為本地模擬器

backend = Aer.get_backend('qasm_simulator')

這裡我們使用qasm_simulator來模擬量子線路的執行。

步驟5:執行作業

counts = execute(qc, backend, shots=1).result().get_counts(qc)

這裡我們只執行一次量子線路模擬。

步驟6:將結果視覺化

display(plot_histogram(counts))

使用直方圖來展示測量結果的統計分佈。

4.6.3 執行原理分析

雙量子位元系統的狀態表示

當我們同時拋兩枚硬幣時,系統的狀態可以用四個基態來表示:|00⟩|01⟩|10⟩|11⟩。透過對兩個量子位元同時作用阿達馬門,我們建立了以下疊加態:

[ \frac{1}{2} (|00⟩ + |01⟩ + |10⟩ + |11⟩) ]

這意味著所有可能的結果都有相等的機率出現。

測量結果分析

當我們測量這兩個量子位元時,系統會坍縮到四個基態中的一個。由於我們只執行了一次模擬,因此測量結果可能是四種狀態中的任意一種。

4.6.4 統計結果分析

增加執行次數

為了獲得更有意義的統計結果,我們可以增加shots引數的值。例如,將shots設定為1000:

counts = execute(qc, backend, shots=1000).result().get_counts(qc)

統計結果預測

當執行次數足夠多時,四種可能的測量結果(00、01、10、11)應該會趨近於均勻分佈,即每個結果的出現次數大約佔總執行次數的25%。

4.6.5 進一步探索

量子糾纏的引入

我們可以透過引入量子糾纏來建立更有趣的雙量子位元狀態。例如,使用CNOT門來建立Bell態:

qc = QuantumCircuit(2,2)
qc.h(0)
qc.cx(0,1)
qc.measure([0,1],[0,1])

程式碼詳解:

  • qc.h(0):對第一個量子位元作用阿達馬門。
  • qc.cx(0,1):將第一個量子位元作為控制位元,第二個量子位元作為目標位元,執行CNOT門操作。

圖表翻譯:

此圖示展示了建立Bell態的量子線路,其中包含一個阿達馬門和一個CNOT門。

這種糾纏態的測量結果將顯示出量子關聯的特性,與簡單的獨立拋硬幣不同。

  1. 研究更複雜的多量子位元系統。
  2. 探索量子糾纏在量子演算法中的應用。
  3. 實作更複雜的量子模擬實驗。

技術挑戰

  1. 如何最佳化多量子位元系統的模擬效率。
  2. 如何處理多量子位元系統中的糾纏和干涉效應。
  3. 如何將理論結果應用於實際的量子計算問題。

4.6 拋多枚量子硬幣

在之前的章節中,我們瞭解瞭如何使用量子計算來模擬拋一枚硬幣。在本文中,我們將探討如何使用量子計算來拋多枚量子硬幣。

4.6.3 執行原理

在建立量子線路時,我們設定了量子位元的編號。在Qiskit中,量子位元的編號從0開始,第一個量子位元的編號為0,往後依次加1。例如,一個3量子位元的量子線路將包含三個量子位元,分別稱為第一個、第二個和第三個量子位元。

  • 如果使用類別似4.3節示例中的QuantumRegister表示法,這3個量子位元可以表示為:q[0]q[1]q[2]
  • 如果使用列表表示法,這3個量子位元可以表示為[0,1,2]

當我們執行程式時,兩個量子位元上都有阿達馬門作用,建立了兩個處於量子疊加態的平行量子位元。這意味著每個量子位元都有50%的機率被測量為0或1。

程式碼範例

from qiskit import QuantumCircuit, Aer, execute
from qiskit.tools.visualization import plot_histogram
from IPython.core.display import display

# 建立包含兩個量子位元和兩個經典位元的量子線路
qc = QuantumCircuit(2,2)

# 在量子線路中新增阿達馬門
qc.h([0,1])

# 新增測量門
qc.measure([0,1],[0,1])

# 顯示量子線路圖
display(qc.draw('mpl'))

# 將後端設定為本地模擬器
backend = Aer.get_backend('qasm_simulator')

# 執行一次作業
counts = execute(qc, backend, shots=1).result().get_counts(qc)

# 將傳回結果視覺化
display(plot_histogram(counts))

內容解密:

  1. 建立量子線路:我們首先建立了一個包含兩個量子位元和兩個經典位元的量子線路。這兩個量子位元用於表示兩枚硬幣的狀態,而兩個經典位元用於儲存測量結果。
  2. 新增阿達馬門:我們對兩個量子位元都應用了阿達馬門,使它們處於量子疊加態。這意味著每枚“硬幣”都有50%的機率正面或反面朝上。
  3. 測量:我們對兩個量子位元進行了測量,將結果儲存在經典位元中。
  4. 執行和視覺化:我們使用Qiskit的模擬器執行了量子線路,並將結果視覺化為直方圖。

4.6.4 知識拓展

你可以嘗試在自己的量子線路中新增更多的量子位元。你會發現可以使用這種簡單的方法建立任何型別的隨機數。量子線路的輸出將是一個二進位制數,其長度與線路中量子位元的數量相同。

實際操作

  1. 建立一個具有20個量子位元的量子線路。
  2. 執行一次,可能會得到類別似{'00101011101110011011':1}的輸出結果。
  3. 將其轉化為十進位制數,得到179099。

應用場景

這種方法可以用於建立不同大小的隨機數生成器。例如,使用n個量子位元,可以建立一個可以表示2^n種可能狀態的隨機數生成器。這可以用於模擬各種隨機事件,如擲骰子。