量子計算中,準確模擬量子系統行為至關重要。Qiskit 提供了多樣工具來探索量子噪聲及量子線路的麼正矩陣表示。本文將示範如何使用 Qiskit 模擬量子噪聲,並利用麼正模擬器與態向量模擬器理解量子線路行為,也涵蓋瞭如何取得 IBM Quantum 後端資訊、建構噪聲模型、執行 GHZ 態量子線路並比較不同模擬器結果。文章也提供程式碼片段說明如何取得量子線路的麼正矩陣及使用態向量模擬器診斷量子線路,觀察量子位元狀態變化,並輔以布洛赫球和 Q 球圖表呈現。最後,簡要介紹了 Ignis 工具在降低量子操作噪聲和誤差方面的作用,為讀者提供更全面的量子計算實務理解。

參考資料

  • “An Open High-Performance Simulator for Quantum Circuits”, IBM Research Blog, 2018年5月1日。
  • “Get to the heart of real quantum hardware”, IBM Research Blog, 2019年12月12日。
  • “Quantum Computing in the NISQ era and beyond”, John Preskill, 2018。

使用Qiskit探索量子噪聲與麼正模擬器加深對量子線路的理解

在量子計算領域,理解和模擬量子系統的行為至關重要。Qiskit作為一個強大的開源量子開發環境,提供了多種工具來探索量子噪聲和量子線路的麼正矩陣表示。本文將探討如何使用Qiskit來模擬量子噪聲,並利用麼正模擬器來理解量子線路的行為。

7.4 模擬量子噪聲

量子噪聲是量子計算中的一個重要問題,它會影響量子電腦的效能和準確性。Qiskit提供了模擬量子噪聲的功能,使得研究人員能夠更好地理解和緩解噪聲的影響。

7.4.1 取得可用的IBM Quantum後端

首先,我們需要取得可用的IBM Quantum後端,並選擇一個合適的後端來執行我們的量子線路。

def get_backend(provider):
    available_backends = provider.available_backends()
    print("{0:20} {1:<10} {2:<10}".format("Name", "#Qubits", "Pending jobs"))
    print("{0:20} {1:<10} {2:<10}".format("----", "-------", "------------"))
    for n in range(0, len(available_backends)):
        backend = provider.get_backend(str(available_backends[n]))
        print("{0:20} {1:<10} {2:<10}".format(backend.name(), backend.configuration().n_qubits, backend.status().pending_jobs))
    select_backend = input("Select a backend ('exit' to end): ")
    if select_backend != "exit":
        backend = provider.get_backend(select_backend)
    else:
        backend = select_backend
    return backend

#### 內容解密:

此函式首先列出所有可用的IBM Quantum後端,包括它們的名稱、量子位元數量和待處理任務數。使用者可以根據這些資訊選擇一個合適的後端。如果使用者輸入’exit’,函式將傳回’exit’。

7.4.2 構建噪聲模型並執行量子線路

一旦選擇了後端,我們就可以構建一個噪聲模型,並使用它來模擬量子線路的行為。

def build_noise_model(backend):
    noise_model = NoiseModel.from_backend(backend)
    print(noise_model)
    return noise_model

#### 內容解密:

此函式使用NoiseModel.from_backend(backend)方法從選定的後端提取噪聲模型。這個噪聲模型將用於模擬量子線路在真實量子裝置上的行為。

7.4.3 執行GHZ態量子線路

我們將建立一個GHZ態的量子線路,並在不同的後端上執行它,包括本地QASM模擬器、帶有噪聲模型的本地QASM模擬器、IBM Quantum QASM模擬器和真實的IBM Quantum後端。

def execute_circuit(backend, noise_model):
    basis_gates = noise_model.basis_gates
    coupling_map = backend.configuration().coupling_map
    print("Coupling map: ", coupling_map)
    
    circ = QuantumCircuit(3, 3)
    circ.h(0)
    circ.cx(0, 1)
    circ.cx(0, 2)
    circ.measure([0, 1, 2], [0, 1, 2])
    print(circ)
    
    counts = execute(circ, Aer.get_backend('qasm_simulator')).result().get_counts(circ)
    display(plot_histogram(counts, title='Ideal counts for 3-qubit GHZ state on local qasm_simulator'))
    
    counts_noise = execute(circ, Aer.get_backend('qasm_simulator'), noise_model=noise_model, coupling_map=coupling_map, basis_gates=basis_gates).result().get_counts(circ)
    display(plot_histogram(counts_noise, title="Counts for 3-qubit GHZ state with noise model on local qasm simulator"))
    
    # ... 其他執行和繪圖程式碼

#### 內容解密:

此函式首先設定量子線路的基礎門和耦合對映。然後,它建立一個3量子位元的GHZ態量子線路,並在不同的模擬器和後端上執行它,比較有無噪聲模型的結果。

7.5 使用麼正模擬器

Qiskit的Aer模擬器提供了unitary_simulator,可以用來取得量子線路的麼正矩陣表示。

7.5.1 取得量子線路的麼正矩陣

def show_unitary(circuit):
    backend = Aer.get_backend('unitary_simulator')
    unit = execute(circuit, backend).result().get_unitary(circuit)
    print("Unitary matrix for the circuit:\n------------------------------- \n", unit)

#### 內容解密:

此函式使用unitary_simulator後端執行量子線路,並取得其麼正矩陣。麼正矩陣描述了量子線路對輸入態向量的作用。

7.5.2 計算和比較結果

def calc_unitary(circuit, unitary):
    shots = 1000
    binary = int(pow(2, circuit.width()/2))
    bin_key = '0' + str(int(circuit.width()/2)) + 'b'
    vector = [1]
    outcomes = [format(0, bin_key) + ":"]
    
    # ... 計算預期結果和模擬結果的程式碼

#### 內容解密:

此函式計算量子線路的預期輸出結果,並與在qasm_simulator上執行的結果進行比較。它使用麼正矩陣和初始態向量來計算預期結果。

參考資料

  • IBM研究院的David C.McKay,Thomas Alexander和Luciano Bello等撰寫的“Qiskit Backend Specifications for OpenQASM and OpenPulse Experiments”,arXiv預印版(2018年9月11日)。

此文章探討了使用Qiskit進行量子噪聲模擬和麼正模擬的方法和技術,為讀者提供了對量子計算中這些重要概念的深入理解。透過實際的程式碼示例和結果比較,讀者可以更直觀地理解量子噪聲的影響和量子線路的行為。

使用態向量模擬器進行診斷

本文將介紹態向量模擬器,瞭解如何用其診斷量子線路,檢視量子位元在量子線路中的狀態。態向量模擬器本質上並不是一種量子電腦模擬器,而是一種用於一次性執行使用者的量子線路並傳回量子位元的態向量的工具。由於態向量模擬器只是“模擬器”,使用者實際上可以在不幹擾量子位元、不破壞量子狀態的前提下,用其對量子線路進行診斷性測試。

準備工作

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

操作步驟

在本示例中,我們將搭建一個所有量子位元都處於簡單疊加態的量子線路,或所有量子位元之間都存在糾纏的量子線路。搭建該量子線路時,需要測量每個量子門的態向量,並將測量結果儲存在一個列表中。然後將程式傳回的態向量輸出,並將其繪製在布洛赫球和Q球上,以說明量子位元在量子線路執行過程中是如何來回變化的。

  1. 設定量子位元的數量
    設定量子位元的數量,並使用se作為輸入,選擇搭建一個疊加量子線路或存在糾纏的量子線路。

    def s_vec(circuit):
        backend = Aer.get_backend('statevector_simulator')
        print(circuit.num_qubits, "qubit quantum circuit:\n------------------------")
        print(circuit)
        psi = execute(circuit, backend).result().get_statevector(circuit)
        print("State vector for the", circuit.num_qubits, "qubit circuit:\n\n", psi)
        print("\nState vector as Bloch sphere:")
        display(plot_bloch_multivector(psi))
        print("\nState vector as Q sphere:")
        display(plot_state_qsphere(psi))
        measure(circuit)
        input("Press enter to continue...\n")
    

    內容解密:

    • Aer.get_backend('statevector_simulator'):選擇態向量模擬器作為後端。
    • execute(circuit, backend).result().get_statevector(circuit):執行量子線路並取得態向量。
    • plot_bloch_multivector(psi):將態向量繪製在布洛赫球上。
    • plot_state_qsphere(psi):將態向量繪製在Q球上。
  2. 使用態向量模擬器
    選定模擬器後,當使用者執行量子線路時,該模擬器會在第一時間一次性執行整個量子線路,並傳回由量子位元計算得到的態向量。

  3. 測量量子線路
    measure()函式中透過在Aer的qasm_simulator模擬器上執行10000次該量子線路而計算出的。

    def measure(circuit):
        measure_circuit = QuantumCircuit(circuit.width())
        measure_circuit += circuit
        measure_circuit.measure_all()
        backend_count = Aer.get_backend('qasm_simulator')
        counts = execute(measure_circuit, backend_count, shots=10000).result().get_counts(measure_circuit)
        print("\nOutcome:\n", {k: v / total for total in (sum(counts.values()),) for k, v in counts.items()}, "\n")
    

    內容解密:

    • QuantumCircuit(circuit.width()):建立一個與輸入線路寬度相同的量子線路。
    • measure_circuit.measure_all():對所有量子位元進行測量。
    • execute(measure_circuit, backend_count, shots=10000):在qasm_simulator上執行測量線路10000次。

知識拓展

你可能會覺得本示例中用到的方法似曾相識,你的感覺是對的,之前的示例中確實用過這種方法。翻到3.3節,看一下當時探討過的“Inspect”功能。本示例中所探討的方法與在Qiskit中檢測量子線路的方法是類別似的。

第8章 使用Ignis清理量子操作

在之前的示例中,讀者已經嘗試過在理想化的Qiskit Aer模擬器上執行量子程式,並親自動手使用真實的IBM量子裝置。我們已經知道了真實的量子位元是存在噪聲的,(目前還)不能指望量子電腦解決現實世界中的重大問題。如何降低噪聲和減少誤差將是量子電腦在未來的產業化過程中必須解決的問題,而Qiskit Ignis是降低噪聲和減少誤差的工具之一。

技術要求

本章中探討的量子程式參見本文GitHub倉函式庫中對應第8章的目錄。

主要內容

  • 探索量子位元,理解T1、T2、誤差和量子門;
  • 比較同一塊晶片上的量子位元;
  • 估算可用時間內的量子門的數量;
  • 用讀出校正來糾正預期結果;
  • 用量子糾錯減輕意外情況造成的影響。
  graph LR
    A[開始] --> B[選擇量子位元數量]
    B --> C[選擇量子線路型別]
    C --> D[執行態向量模擬器]
    D --> E[測量量子線路]
    E --> F[輸出態向量]
    F --> G[繪製布洛赫球和Q球]

圖表翻譯:
此圖示展示了使用態向量模擬器進行量子線路診斷的流程。首先選擇量子位元數量和線路型別,然後執行態向量模擬器,接著測量量子線路,最後輸出態向量並繪製布洛赫球和Q球表示。

8.2 探索量子位元,理解T1、T2、誤差和量子門

當我們將經過模擬器驗證後的量子程式傳送給真實的量子電腦實體時,需要思考其中可能出錯的環節。一旦離開了模擬的理想量子位元,開始使用按照量子力學規律運作的實體量子位元,就不得不與現實中的另一種物理特性——噪聲,進行抗衡。

8.2.1 準備工作

可以從本文 GitHub 倉函式庫中對應第8章的目錄中下載本文示例的 Python 檔案 ch8_r1_gates_data.py。本示例是根據第5章的工作編寫的,但著重研究的是量子位元的屬性,這些屬性可能導致輸出結果出錯。

示例程式碼

  1. 匯入所需的Qiskit類別並登入自己的帳號

    from qiskit import IBMQ
    print("Getting providers...")
    if not IBMQ.active_account():
        IBMQ.load_account()
    provider = IBMQ.get_provider()
    
  2. 使用 select_backend() 載入並顯示可用後端的資料,然後根據提示符選擇一個後端

    def select_backend():
        available_backends = provider.backends(filters=lambda b: not b.configuration().simulator and b.configuration().n_qubits > 0 and b.status().operational)
        print("{0:20} {1:<10}".format("Name", "#Qubits"))
        print("{0:20} {1:<10}".format("----", "-------"))
        for n in range(0, len(available_backends)):
            backend = provider.get_backend(str(available_backends[n]))
            print("{0:20} {1:<10}".format(backend.name(), backend.configuration().n_qubits))
        select_backend = input("Select a backend ('exit' to end): ")
        if select_backend != "exit":
            backend = provider.get_backend(select_backend)
        else:
            backend = select_backend
        return backend
    
  3. 使用 display_information(backend) 函式檢索後端量子位元的資訊

    def display_information(backend):
        basis_gates = backend.configuration().basis_gates
        n_qubits = backend.configuration().n_qubits
        coupling_map = backend.configuration().coupling_map if n_qubits > 1 else []
        micro = 10**6
    
        for qubit in range(n_qubits):
            print("\nQubit:", qubit)
            print("T1:", int(backend.properties().t1(qubit) * micro), "\u03BCs")
            print("T2:", int(backend.properties().t2(qubit) * micro), "\u03BCs")
            print("Readout error:", round(backend.properties().readout_error(qubit) * 100, 2), "%")
            for bg in basis_gates:
                if bg != "cx":
                    print(bg, round(backend.properties().gate_length(bg, [qubit]) * micro, 2), "\u03BCs", "Err:", round(backend.properties().gate_error(bg, [qubit]) * 100, 2), "%")
                if n_qubits > 0:
                    for cm in coupling_map:
                        if qubit in cm:
                            print("cx", cm, round(backend.properties().gate_length("cx", cm) * micro, 2), "\u03BCs", "Err:", round(backend.properties().gate_error("cx", cm) * 100, 2), "%")
    
  4. 主函式呼叫 select_backend() 函式和 display_information(backend) 函式

    def main():
        backend = select_backend()
        display_information(backend)
    if __name__ == '__main__':
        main()
    

8.2.2 操作步驟

  1. 在Python後端中執行 ch8_r1_gates_data.py
  2. 出現提示符時,輸入想要檢視的IBM Quantum後端的名稱。

8.2.3 執行原理

  • T1(退相干時間,即弛豫時間):表示量子位元從激發態自發弛豫到基態所需的時間的統計值,以μs為單位。
  • T2(退相干時間,即退相時間):用於衡量量子位元丟失相位資訊所需的時間,以μs為單位。
  • 讀出誤差(readout_error):讀取量子位元時得到錯誤值的機率,以百分比形式顯示。
  • 量子門長度(gate_length):量子門對與之對應的量子位元進行調整所需的時間,以μs為單位。
  • 量子門誤差(gate_error):執行量子門時得到預期輸出結果的準確程度的統計值,以百分比形式顯示。

8.2.4 知識拓展

還可以從IBM Quantum Experience處取得後端的量子位元資訊。具體操作步驟包括登入IBM Quantum Experience、選擇後端、點選“Download Calibrations”取得含有量子位元資訊的CSV檔案。