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))
程式碼解析:
- 建立量子程式和暫存器:首先,建立一個
QuantumProgram物件,然後建立一個包含 5 個量子位元的量子暫存器和一個包含 5 個經典位元的經典暫存器。 - 建立電路:使用建立的暫存器建立一個名為 “Circuit” 的量子電路。
- 啟用日誌記錄:啟用日誌記錄以便於除錯。
- 應用物理閘:對第一個量子位元應用一系列的
u2和u3閘,以實作特定的旋轉操作。u2和u3閘是 Qiskit 中的基礎閘,用於實作各種單量子位元操作。u2閘需要兩個引數,而u3閘需要三個引數,這些引數決定了旋轉的角度和軸。
- 測量:將第一、二、三個量子位元的測量結果儲存在對應的經典位元中。
- 執行:設定後端為
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 檔案內容,描述實驗細節
}
程式碼解析:
- 建構 HTTP POST 請求:使用瀏覽器的 REST 客戶端(如 Chrome 的 YARC)建構一個 HTTP POST 請求到
https://quantumexperience.ng.bluemix.net/api/Jobs?access_token=ACCESS_TOKEN。 - 取得存取令牌:需要先進行身份驗證以取得存取令牌。存取令牌用於授權對 Q Experience API 的存取。
- 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:作業的整體狀態,例如RUNNING、COMPLETED或FAILED。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 時,請務必注意以下幾點:
- 裝置狀態:在提交作業前,請確保目標裝置是線上狀態。
- QASM 程式碼格式:QASM 程式碼必須寫在一行中,使用
\n表示換行。 - 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)。 |
| X | pauli X 或 σx(sigma-x)或位元翻轉。 |
| Y | pauli Y 或 σy(sigma-y)。 |
| Z | pauli Z 或 σz(sigma-z)。 |
| rx(theta) | 繞 X 軸旋轉 theta 度。 |
| ry(theta) | 繞 Y 軸旋轉 theta 度。 |
| rz(phi) | 繞 Z 軸旋轉 theta 度。 |
| h | Hadamard:將單一量子位元置於狀態疊加。 |
| S | Z 的平方根:sqrt(Z) 相位閘。 |
| Sdg | S-dagger:S 的複共軛。代數上定義為 sqrt(Z) 的轉置矩陣的複共軛。 |
| T | sqrt(S) 相位閘。 |
| Tdg | T-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,c | 3量子位元 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中,可以建立一個簡單的電路來生成隨機位元:
- 新增一個量子位元(qubit)和一個經典位元(classical bit)。
- 對量子位元應用Hadamard門。
- 測量量子位元並將結果儲存在經典位元中。
執行此電路後,將獲得一個隨機的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)
內容解密:
qrng函式:此函式接受兩個引數:n(要生成的隨機數數量)和x(量子位元數量)。它建立一個具有x個量子位元和x個經典位元的量子電路。- Hadamard門應用:對所有
x個量子位元應用Hadamard門,使它們處於疊加態。 - 測量:測量所有量子位元並將結果儲存在對應的經典位元中。
- 執行電路:使用QISKit的
execute函式在模擬器上執行電路,並取得測量結果。 - 結果處理:將測量結果轉換為二進位制字串,然後轉換為十進位制隨機數。
本章介紹瞭如何利用量子力學的機率性質生成真正的隨機數,並展示了使用Hadamard門和QISKit Python指令碼的實作方法。這種方法可以用於生成高品質的隨機數,在密碼學和模擬等領域具有重要應用價值。