Qiskit 作為 IBM 開發的開源量子程式設計 SDK,提供 Python 環境下的量子電路建構、操作和執行工具。理解物理閘操作是建構複雜量子電路的基礎,本文以 u2 和 u3 閘操作為例,示範如何在 Qiskit 中實作量子位元旋轉和測量。此外,文章也介紹了 IBM Q Experience 平台及其 REST API,包含 Jobs API 和 Execute API 的使用方法,讓開發者能以程式化方式提交和管理量子實驗。QASM 作為量子組譯語言,在量子程式的編譯和執行過程中扮演關鍵角色,文章解析了 QASM 的語法、電路生命週期,以及如何在 QASM 中直接編碼,並列出常用的單量子位元閘和多量子位元閘。最後,文章探討了量子隨機數生成的原理和實作方式,包含 Hadamard 閘的應用和 Qiskit Python 程式碼範例,展現量子計算在實際應用中的潛力。

Qiskit:Python 中的量子程式設計SDK

Qiskit 是 IBM 開發的一個開源 SDK,用於在 Python 中進行量子程式設計。它提供了一個強大的工具,用於建立、操縱和執行量子電路。

物理閘(Basis Gates)的重要性

物理閘是構成更複雜邏輯閘的基礎。在 Qiskit 中,物理閘用於建立量子電路。清單 4-6 展示了一個範例電路,該電路使用物理閘對第一個量子位元進行一系列旋轉,並將結果儲存在經典暫存器中。

清單 4-6:範例電路 #2

import sys, time, math
import qiskit
import logging
from qiskit import QuantumProgram
import Qconfig

def main():
    qp = QuantumProgram()
    quantum_r = qp.create_quantum_register("qr", 5)
    classical_r = qp.create_classical_register("cr", 5)
    circuit = qp.create_circuit("Circuit", [quantum_r], [classical_r])
    qp.enable_logs(logging.DEBUG)

    # 對第一個量子位元進行一系列旋轉
    circuit.u2(-4 * math.pi / 3, 2 * math.pi, quantum_r[0])
    circuit.u2(-3 * math.pi / 2, 2 * math.pi, quantum_r[0])
    circuit.u3(-math.pi, 0, -math.pi, quantum_r[0])
    circuit.u3(-math.pi, 0, -math.pi / 2, quantum_r[0])
    circuit.u2(math.pi, -math.pi / 2, quantum_r[0])
    circuit.u3(-math.pi, 0, -math.pi / 2, quantum_r[0])

    # 將量子位元的測量結果儲存在經典暫存器中
    circuit.measure(quantum_r[0], classical_r[0])
    circuit.measure(quantum_r[1], classical_r[1])
    circuit.measure(quantum_r[2], classical_r[2])

    backend = 'ibmqx4'
    circuits = ['Circuit']
    qp.set_api(Qconfig.APItoken, Qconfig.config['url'])
    result = qp.execute(circuits, backend, shots=512, max_credits=3, timeout=240)

    print("Job id=" + str(result.get_job_id()) + " Status:" + result.get_status())

if __name__ == '__main__':
    start_time = time.time()
    main()
    print("--- %s seconds 
---
" % (time.time() - start_time))

程式碼解析:

  1. 建立量子程式和暫存器:首先,建立一個 QuantumProgram 物件,然後建立一個包含 5 個量子位元的量子暫存器和一個包含 5 個經典位元的經典暫存器。
  2. 建立電路:使用建立的暫存器建立一個名為 “Circuit” 的量子電路。
  3. 啟用日誌記錄:啟用日誌記錄以便於除錯。
  4. 應用物理閘:對第一個量子位元應用一系列的 u2u3 閘,以實作特定的旋轉操作。
    • u2u3 閘是 Qiskit 中的基礎閘,用於實作各種單量子位元操作。
    • u2 閘需要兩個引數,而 u3 閘需要三個引數,這些引數決定了旋轉的角度和軸。
  5. 測量:將第一、二、三個量子位元的測量結果儲存在對應的經典位元中。
  6. 執行:設定後端為 ibmqx4,並使用 execute 方法執行電路。引數 shots=512 表示重複執行 512 次,以收集統計結果。

Composer 中的量子電路

Qiskit 程式也可以使用 IBM Q Experience Composer 的拖曳介面建立。只需將閘拖到量子位元直方圖中,設定閘的引數,然後儲存並在模擬器或真實裝置上執行。

使用 REST API 執行實驗

IBM Q Experience 提供了一個 REST API,允許使用者以程式設計方式與其互動。使用 REST API,使用者可以列出後端裝置、取得硬體或校準引數、查詢作業執行佇列、取得作業狀態、推播或取消作業等。

使用 Jobs API 提交實驗

要使用 Jobs API 提交實驗,需要建構一個 HTTP POST 請求到指定的端點,並在請求體中包含一個 JSON 檔案,該檔案描述了要執行的實驗。

請求範例:
{
  // JSON 檔案內容,描述實驗細節
}

程式碼解析:

  1. 建構 HTTP POST 請求:使用瀏覽器的 REST 客戶端(如 Chrome 的 YARC)建構一個 HTTP POST 請求到 https://quantumexperience.ng.bluemix.net/api/Jobs?access_token=ACCESS_TOKEN
  2. 取得存取令牌:需要先進行身份驗證以取得存取令牌。存取令牌用於授權對 Q Experience API 的存取。
  3. JSON 檔案內容:請求體中的 JSON 檔案描述了實驗的細節,包括要執行的電路、後端裝置等。

使用 Q Experience API 進行量子程式設計

本章節將探討如何利用 IBM 的 Q Experience 平台提供的 API 進行量子程式設計。Q Experience 提供了一個強大的工具,用於執行量子電路模擬和真實量子處理器上的實驗。

Jobs API 與 Execute API

Q Experience 提供了兩種主要的 API 用於執行量子實驗:Jobs API 和 Execute API。這兩種 API 在功能和使用方式上有所不同。

Jobs API

Jobs API 用於提交和管理量子作業。要使用 Jobs API,首先需要獲得一個存取令牌(access token)。獲得存取令牌後,可以構建一個 HTTP 請求,將量子電路以 QASM 格式提交給指定的後端處理器。

請求格式

Jobs API 的請求格式如表 4-2 所示。請求主體包含了一個 QASM 程式的陣列、執行的次數(shots)、後端裝置名稱以及最大信用點數(maxCredits)。

{
  "qasms": [{
    "qasm": "\n\ninclude \"qelib1.inc\";\nqreg q[5];\ncreg c[5];\nu2(-4*pi/3,2*pi) q[0];\nu2(-3*pi/2,2*pi) q[0];\nu3(-pi,0,-pi) q[0];\nu3(-pi,0,-pi/2) q[0];\nu2(pi,-pi/2) q[0];\nu3(-pi,0,-pi/2) q[0];\nmeasure q -> c;\n"
  }],
  "shots": 1024,
  "backend": {
    "name": "ibmqx4"
  },
  "maxCredits": 3
}

#### 內容解密:

  • qasms:包含一個或多個 QASM 程式,每個程式都必須寫在一行中,並使用換行符號(\n)分隔。
  • shots:指定實驗的重複次數。
  • backend:指定要使用的量子處理器或模擬器。
  • maxCredits:指定願意為此作業消耗的最大信用點數。
回應格式

提交作業後,API 將傳回一個包含作業狀態、執行 ID 等資訊的回應,如列表 4-8 所示。

{
  "qasms": [
    {
      "qasm": "\n\ninclude \"qelib1.inc\";\nqreg q[5];\ncreg c[5];\nu2(-4*pi/3,2*pi) q[0];\nu2(-3*pi/2,2*pi) q[0];\nu3(-pi,0,-pi) q[0];\nu3(-pi,0,-pi/2) q[0];\nu2(pi,-pi/2) q[0];\nu3(-pi,0,-pi/2) q[0];\nmeasure q -> c;\n",
      "status": "WORKING_IN_PROGRESS",
      "executionId": "e9d758c3480a54a6455f72c84c5cc2a6"
    }
  ],
  "shots": 1024,
  "backend": {
    "id": "c16c5ddebbf8922a7e2a0f5a89cac478",
    "name": "ibmqx4"
  },
  "status": "RUNNING",
  "maxCredits": 3,
  "usedCredits": 3,
  "creationDate": "2018-04-24T00:12:07.847Z",
  "deleted": false,
  "id": "33d58594fcb7204e4d2ccdb65cd3c88c",
  "userId": "ef072577bd26831c59ddb212467821db"
}

#### 內容解密:

  • status:作業的整體狀態,例如 RUNNINGCOMPLETEDFAILED
  • usedCredits:實際消耗的信用點數。
  • creationDate:作業建立的日期和時間。

Execute API

Execute API 與 Jobs API 的主要區別在於,它會將實驗註冊到 Composer 中。使用 Execute API 需要構建一個 HTTP POST 請求,並將請求主體中的 QASM 程式碼提交給指定的裝置。

請求格式

Execute API 的請求格式如列表 4-9 所示。請求主體包含實驗名稱、程式碼型別(QASM2)、以及 QASM 程式碼。

{
  "name": "Experiment #20180410193125",
  "codeType": "QASM2",
  "qasm": "\n\ninclude \"qelib1.inc\";\nqreg q[5];\ncreg c[5];\nu2(-4*pi/3,2*pi) q[0];\nu2(-3*pi/2,2*pi) q[0];\nu3(-pi,0,-pi) q[0];\nu3(-pi,0,-pi/2) q[0];\nu2(pi,-pi/2) q[0];\nu3(-pi,0,-pi/2) q[0];\nmeasure q -> c;\n"
}

#### 內容解密:

  • name:實驗的名稱。
  • codeType:程式碼型別,必須是 QASM2
  • qasm:QASM 程式碼,必須寫在一行中,並使用 \n 表示換行。

重點提示

在使用 Q Experience API 時,請務必注意以下幾點:

  1. 裝置狀態:在提交作業前,請確保目標裝置是線上狀態。
  2. QASM 程式碼格式:QASM 程式碼必須寫在一行中,使用 \n 表示換行。
  3. API 回應格式:API 的回應格式可能會隨著時間而變化,請留意官方檔案的更新。

量子組譯(QASM):幕後強大力量

當在 Composer 或 REST 客戶端中執行實驗時,您可能已經意識到幕後發生的事情。電路被轉換成量子組譯(QASM),然後在真實裝置或模擬器中執行。量子組譯是高階 Python 程式碼的中間表示,是 IBM Q Experience 與開源社群合作的結果。

QASM 的由來與特性

QASM 根據其經典的表親,儘管經典組譯已成絕學,但 QASM 並不那麼令人望而生畏。事實上,它根據經典組譯文法的一個子集。

QASM 在量子計算中的角色

您的 Python 程式或 Q Experience 電路的生命週期可以描述為量子和經典計算部分的混合,具有以下步驟:

編譯(Compilation)

這是在經典電腦上離線進行的步驟。當 Python 或 Composer 電路執行時,經典編譯器將高階表示(例如 Python)轉換為 QASM 中間表示。此步驟具有以下特點:

  • 尚未知道特定的問題引數。
  • 不需要與量子電腦互動。
  • 可以將經典程式編譯成目的碼並進行初始最佳化。

例如,列表 4-6 中的 Python 程式和對應的 Composer 電路被轉換成列表 4-11 中的組譯程式碼。

清單 4-11:列表 4-6 中 Python 程式的 QASM 程式碼

include "qelib1.inc";
qreg qr[5];
creg cr[5];
u2(-4.18879020478639,6.28318530717959) qr[0];
u2(-4.71238898038469,6.28318530717959) qr[0];
u3(-3.14159265358979,0,-3.14159265358979) qr[0];
u3(-3.14159265358979,0,-1.57079632679490) qr[0];
u2(3.14159265358979,-1.57079632679490) qr[0];
u3(-3.14159265358979,0,-1.57079632679490) qr[0];
measure qr[0] -> cr[0];
measure qr[1] -> cr[1];
measure qr[2] -> cr[2];

電路生成(Circuit Generation)

來自前一步驟的 QASM 被饋送到電路生成階段。此步驟在經典電腦上進行,特定的問題引數已知,並且可能與量子電腦發生一些互動。此步驟具有以下特點:

  • 這是線上階段(發生在量子電腦上)。
  • 輸出是一組量子電路,或量子基本區塊,以及相關的經典控制指令和在執行時所需的經典目的碼。

執行(Execution)

此步驟在物理量子電腦上進行。輸入是以量子電路中間表示表達的一組量子電路。這些在低階控制器上執行,輸出是從高階控制器傳回的一組測量結果。

後處理(Postprocessing)

此步驟在經典電腦上進行,並接收一組已處理的測量結果。輸出是量子計算的最終結果(參見圖 4-10)。

直接使用 QASM 的優勢

總而言之,量子組譯語法並不像其經典對應物那樣令人望而生畏;事實上,直接使用量子組譯進行程式設計比使用 Python 更簡單、更快。下一節將介紹一些簡單的技巧,如果您決定直接在 QASM 中編碼:

總是先包含標頭 include "qelib1.inc"

它包含了 Q Experience 硬體原語(量子閘)。該函式庫中提供的閘在表 4-5(單量子位元閘)和表 4-6(多量子位元閘)中描述。

單量子位元閘與多量子位元閘

表 4-5:量子組譯提供的單量子位元閘

名稱描述
u3(theta,phi,lambda)3引數2脈衝單量子位元閘。
u2(phi,lambda)2引數1脈衝單量子位元閘。
u1(lambda)1引數1脈衝單量子位元閘。
Id等同於單位矩陣或 u(0,0,0)。
Xpauli X 或 σx(sigma-x)或位元翻轉。
Ypauli Y 或 σy(sigma-y)。
Zpauli Z 或 σz(sigma-z)。
rx(theta)繞 X 軸旋轉 theta 度。
ry(theta)繞 Y 軸旋轉 theta 度。
rz(phi)繞 Z 軸旋轉 theta 度。
hHadamard:將單一量子位元置於狀態疊加。
SZ 的平方根:sqrt(Z) 相位閘。
SdgS-dagger:S 的複共軛。代數上定義為 sqrt(Z) 的轉置矩陣的複共軛。
Tsqrt(S) 相位閘。
TdgT-dagger 或 sqrt(S) 的複共軛。

表 4-6:量子組譯提供的多量子位元閘

名稱描述
cx c,t受控非門(CNOT):僅當控制量子位元(c)為 1 時,才翻轉第二個量子位元(t)。用於糾纏 2 個量子位元。
cz a,b受控相位:僅當控制量子位元(a)為 1 時,才應用相位旋轉。
cy a,b受控 Y:僅當控制量子位元(a)為 1 時,才應用 pauli Y 旋轉。
ch a,b受控 Hadamard:僅當控制量子位元(a)為 1 時,才將量子位元(b)置於疊加狀態。
ccx a,b,c3量子位元 Toffoli 閘:僅當量子位元 a 和 b 都為 1 時,才翻轉量子位元 c。

量子隨機數生成:從機率性到實作

量子計算的一個基本特性是其機率性質,這使得量子電腦能夠生成真正的隨機數。本章將探討如何利用量子力學的隨機性來生成隨機數,並介紹相關的量子電路設計和實作。

使用Hadamard門生成隨機位元

Hadamard門是量子資訊系統中的一個基本門,用於將量子位元(qubit)置於疊加態。其矩陣表示為:

H = 1/√2 * [[1, 1], [1, -1]]

將Hadamard門應用於基本態 |0⟩ 和 |1⟩,可得到:

H|0⟩ = 1/√2 (|0⟩ + |1⟩) H|1⟩ = 1/√2 (|0⟩ - |1⟩)

這表明Hadamard門將基本態轉換為疊加態,使得測量結果具有機率性。

實作:隨機位元生成電路

在IBM Q Experience Composer中,可以建立一個簡單的電路來生成隨機位元:

  1. 新增一個量子位元(qubit)和一個經典位元(classical bit)。
  2. 對量子位元應用Hadamard門。
  3. 測量量子位元並將結果儲存在經典位元中。

執行此電路後,將獲得一個隨機的0或1結果,每個結果的機率為1/2。

使用QISKit Python產生多個隨機數

雖然上述方法可以生成單個隨機位元,但效率較低。更好的方法是使用QISKit Python指令碼以程式設計方式建立電路來生成多個隨機數。

from qiskit import QuantumCircuit, execute, Aer

def qrng(n, x):
    # 建立量子電路
    qc = QuantumCircuit(x, x)
    
    # 對所有量子位元應用Hadamard門
    for i in range(x):
        qc.h(i)
    
    # 測量量子位元並將結果儲存在經典位元中
    for i in range(x):
        qc.measure(i, i)
    
    # 執行電路
    simulator = Aer.get_backend('qasm_simulator')
    job = execute(qc, simulator, shots=n)
    result = job.result()
    counts = result.get_counts(qc)
    
    # 將測量結果轉換為隨機數
    random_numbers = []
    for i in range(n):
        binary_string = bin(i)[2:].zfill(x)
        random_numbers.append(int(binary_string, 2))
    
    return random_numbers

# 生成10個8位元隨機數
n = 10
x = 3
random_numbers = qrng(n, x)
print(random_numbers)

內容解密:

  1. qrng函式:此函式接受兩個引數:n(要生成的隨機數數量)和x(量子位元數量)。它建立一個具有x個量子位元和x個經典位元的量子電路。
  2. Hadamard門應用:對所有x個量子位元應用Hadamard門,使它們處於疊加態。
  3. 測量:測量所有量子位元並將結果儲存在對應的經典位元中。
  4. 執行電路:使用QISKit的execute函式在模擬器上執行電路,並取得測量結果。
  5. 結果處理:將測量結果轉換為二進位制字串,然後轉換為十進位制隨機數。

本章介紹瞭如何利用量子力學的機率性質生成真正的隨機數,並展示了使用Hadamard門和QISKit Python指令碼的實作方法。這種方法可以用於生成高品質的隨機數,在密碼學和模擬等領域具有重要應用價值。