用 Pennylane 建立量子電路

作者:
林昱誠(Yu-Cheng Lin)、張世杰
閱讀時間:
5
分鐘
# 用 Pennylane 建立量子電路 在這一節中,我們會簡要介紹 pennylane 大致的工作流程,讓讀者有個概括性的認識,接著我們會對每一個細節作獨立介紹。 首先,打開您的 colab 或是 jupyter notebook,如果您是用 colab,請按照[此前的教學](https://www.entangletech.tw/lesson/pennylane-01)安裝 pennylane,在 cell 上輸入這行並執行,將 pennylane 匯入。 ```python=+ import pennylane as qml import numpy as np ``` ## Devices 第二步要宣告你要使用的裝置(device)以及所需的 qubits 數(在這裡稱作 wires): ```python=+ dev = qml.device('default.qubit', wires=2) ``` 括號中的第一個參數 "default.qubit" 就是你選用的裝置,在這裡我們使用模擬器(stimulator),亦即用經典電腦模擬量子電腦,不是在真的量子電路上執行。你能選用其他的模擬器(視你的使用情境)、其他公司開發的模擬器(像是 IBM Qiskit),或是在真的量子電腦上執行(像是 IonQ, AQT, Google 等等,如果你有權限的話),有興趣的讀者可以參考這篇[文章](https://pennylane.ai/plugins)了解怎麼使用。 第二個參數 "wires=2",宣告你需要多少的 qubits,以這裡為例就是 2 個 qubits。除了單純的數字外,你也可以為每個 qubit 命名,以下方程式碼為例,他創建 5 個 qubits,第一個 qubit 叫 ancilla,第二個 qubit 叫 q11,以此類推。 ```python=+ dev = qml.device('default.qubit', wires=['ancilla', 'q11', 'q12', -1, 1]) ``` 走某些裝置,像是 default.qubit,是接受不寫 wires 有時候,你會需要電路執行好幾次,並統計每個測量結果出現的機率,這時候我們會添加 "shots",以下列為例,電路會執行 1000 次 ```python=+ dev = qml.device('default.qubit', wires=2, shots=1000) ``` 除了純數字外,你也能輸入一串數字(list)。以下列為例,代表會跑三輪模擬,第一輪執行五次,第二輪執行十次,第三輪執行 1000 次。 ```python=+ shots_list = [5, 10, 1000] dev_multi_shots = qml.device("default.qubit", wires=2, shots=shots_list) ``` ## 建立量子電路 Pennylane 用 python 中的 def 來建立量子電路,如下: ```python=+ def my_circuit(): #定義函數(電路)名稱 # 將所需的 gate 放進函數中 # qml.量子邏輯閘(wires = qubit 編號) qml.PauliX(wires = 0) # 在第一個 qubit 上放 X gate qml.Hadamard(wires = 0) # 在第一個 qubit 上放 H gate qml.CNOT(wires = [0,1]) # 在第一個與第二個 qubit 上放 CNOT gate # 輸出每個量子態的機率分佈 return qml.probs(wires=[0, 1]) ``` 對於有參數的量子電路,則會在 def 後的括號中加入變量: ```python=+ theta = np.pi/2 # 定義變量(參數) def my_circuit_theta(theta): #定義函數(電路)名稱與變量 # 將所需的 gate 放進函數中 # qml.有參數的量子邏輯閘(參數,wires = qubit 編號) qml.RY(theta, wires = 0) # 在第一個 qubit 放上 RY,參數為 theta # 輸出每個量子態的機率分佈 return qml.probs(wires=[0]) ``` 如果你想把電路圖示化,要先 import matplotlib ```python=+ import matplotlib.pyplot as plt ``` 接著輸入以下程式碼 ```python=+ fig,ax = qml.draw_mpl(my_circuit, show_all_wires=False, decimals = 1, style = 'sketch')() fig.show() ```
Circuit

- 第一個參數就是你的電路 - "show_all_wires" 可打可不打,預設為 False,輸入 True 的話代表沒有放 gate 的 qubit 都要畫出來 - "decimals" 可打可不打,代表參數要顯示到小數點以下幾位,沒有打的話預設不在圖上標示參數 - style 是圖片風格,可打可不打,預設為 black_white,想知道有哪些風格可以選用可以參看[官方說明](https://docs.pennylane.ai/en/stable/code/api/pennylane.drawer.draw_mpl.html) - 其他更多參數可以參看[官方說明](https://docs.pennylane.ai/en/stable/code/api/pennylane.drawer.draw_mpl.html) 對於有參數的電路,可以在第二個括號中打入參數: ```python=+ fig,ax = qml.draw_mpl(my_circuit_theta, decimals = 2)(np.pi/2) fig.show() ```
Circuit

## QNode 最後要透過 QNode 把上面定義的電路與 device 包裝在一起 ```python=+ my_qnode = qml.QNode(my_circuit, dev) ``` 最後就執行運算 ```python=+ my_qnode() # 執行後輸出 array([0.5, 0. , 0. , 0.5]) ``` 輸出結果代表測量到 $|00\rangle$ 和 $|11\rangle$ 的機率都是 50%,其他狀態則為 0%。 QNode 也可以在定義 circuit 前就先寫好,像這樣: ```python=+ @qml.qnode(dev) # 定義 qnode def my_circuit(): #定義函數(電路)名稱 # 將所需的 gate 放進函數中 # qml.量子邏輯閘(wires = qubit 編號) qml.PauliX(wires = 0) # 在第一個 qubit 上放 X gate qml.Hadamard(wires = 0) # 在第一個 qubit 上放 H gate qml.CNOT(wires = [0,1]) # 在第一個與第二個 qubit 上放 CNOT gate # 輸出每個量子態的機率分佈 return qml.probs(wires=[0, 1]) # 執行運算 my_circuit() # 輸出 array([0.5, 0. , 0. , 0.5]) ``` 由於我們舉的例子很簡單,因此看不出 pennylane 建立 qnode 的意義何在,實際上 QNode 本身有許多和機器學習有關的參數,pennylane 下了很多功夫在串接機器學習套件上,讓量子機器學習(QML)執行起來更加方便,有興趣的讀者可以參看[官方文件](https://docs.pennylane.ai/en/stable/code/api/pennylane.qnode.html)。 ## 總結 完整的程式碼長這樣,恭喜你已經用程式碼建立出第一個量子電路: ```python=+ # 安裝 pennylane,如果你是用 colab !pip install pennylane # import pennylane, numpy 和 matplotlib import pennylane as qml import numpy as np import matplotlib.pyplot as plt # 定義 device dev = qml.device('default.qubit', wires=2) # 定義 qnode 與量子電路 @qml.qnode(dev) # 定義 qnode def my_circuit(): #定義函數(電路)名稱 # 將所需的 gate 放進函數中 # qml.量子邏輯閘(wires = qubit 編號) qml.PauliX(wires = 0) # 在第一個 qubit 上放 X gate qml.Hadamard(wires = 0) # 在第一個 qubit 上放 H gate qml.CNOT(wires = [0,1]) # 在第一個與第二個 qubit 上放 CNOT gate # 輸出每個量子態的機率分佈 return qml.probs(wires=[0, 1]) # 執行運算 my_circuit() # 輸出 array([0.5, 0. , 0. , 0.5]) # 將定義的量子電路畫成圖 fig,ax = qml.draw_mpl(my_circuit, decimals = 1, style = 'sketch')() fig.show() ``` 在接下來的文章我們會針對每一部分做細節討論,像是在 "my_circuit" 這段介紹每個 quantum gate 的程式碼,以及還能輸出(return)什麼等等。
課程目錄