以 Pennylane 做測量

作者:
林昱誠(Yu-Cheng Lin)
閱讀時間:
5
分鐘
# 測量 完成量子電路後,最後要透過「測量」得知運算結果,測量結果的呈現方式不只一種,端看您想從中得知什麼訊息,Pennylane 提供不同的呈現方式,以下我們提供比較常用的語法。 以下我們以簡易的 Bell state 作為舉例,來看不同語法呈現的測量結果,本篇提及的語法都是打在 def circuit 中最後 return 的後面: ```python=+ # 定義裝置 dev = qml.device('default.qubit', wires=2) def my_circuit(): #定義函數(電路)名稱 # 將所需的 gate 放進函數中 # qml.量子邏輯閘(wires = qubit 編號) qml.Hadamard(wires = 0) # 在第一個 qubit 上放 H gate qml.CNOT(wires = [0,1]) # 在第一個與第二個 qubit 上放 CNOT gate # 本節文章主題 return 欲呈現的測量結果 my_qnode = qml.QNode(my_circuit, dev) # 執行電路 my_qnode() ``` ## qml.state() ```python=+ return qml.state() ``` 如果今天我們想知道電路的量子態,就會使用這語法,以上述 Bell state 為例,他的量子態為: \begin{split} |\psi\rangle=\frac{1}{\sqrt 2}(|00\rangle+|11\rangle)\approx 0.70710678(|00\rangle+|11\rangle) \end{split} 下列是程式的輸出結果,與上式相符: ```python=+ array([0.70710678+0.j, 0. +0.j, 0. +0.j, 0.70710678+0.j]) ``` 上面的矩陣從左到右分別對應 $|00\rangle$, $|01\rangle$, $|10\rangle$, 和 $|11\rangle$,因此只有第一個位置和最後一個位置是 $\frac{1}{\sqrt 2}$,其他則為 0。 ## qml.probs() 今天我們想要知道每個量子態出現的機率為何,就可以使用這語法,括號中要輸入 wires 編號,像是: ```python=+ def my_circuit(): #定義函數(電路)名稱 # 將所需的 gate 放進函數中 # qml.量子邏輯閘(wires = qubit 編號) qml.Hadamard(wires = 0) # 在第一個 qubit 上放 H gate qml.CNOT(wires = [0,1]) # 在第一個與第二個 qubit 上放 CNOT gate # 輸出每個量子態的機率分佈 return qml.probs(wires = [0,1]) ``` 根據你學過的量子計算,不難得知這電路在理想情況下,測量結果出現 $|00\rangle$ 和 $|11\rangle$ 的機率各 50%(0.5): ```python=+ array([0.5, 0. , 0. , 0.5]) ``` 當然,你也可以只測量一個 qubit,像是 ```python=+ def my_circuit(): #定義函數(電路)名稱 # 將所需的 gate 放進函數中 # qml.量子邏輯閘(wires = qubit 編號) qml.Hadamard(wires = 0) # 在第一個 qubit 上放 H gate qml.CNOT(wires = [0,1]) # 在第一個與第二個 qubit 上放 CNOT gate # 輸出每個量子態的機率分佈 return qml.probs(wires = 0) # 或是 wires = [0] ``` 同理,根據你學過的基礎量子計算,測量第一個 qubit 後,看到 $|0\rangle$ 和 $|1\rangle$ 各 50%: ```python=+ array([0.5, 0.5]) ``` ## qml.expval() 這語法用於輸出某個物理量的期望值,常用於凝態物理或是化學模擬中,輸出分子的能量值(能量的期望值),比方說我們今天想知道物理量 $H$ 的期望值,則: \begin{split} \langle H\rangle = \langle \psi|H|\psi\rangle \end{split} 其中,$|\psi\rangle$ 就是電路的量子態。假使我們今天要測量 X (X gate 的 X)且在第一個 qubit 的期望值,語法會這樣打: ```python=+ return qml.expval(qml.X(0)) ``` 這相當於在計算下式: \begin{split} \langle X\rangle = \langle \psi|X\otimes I|\psi\rangle, \space \text{where}\space |\psi\rangle=\frac{1}{\sqrt 2}(|00\rangle+|11\rangle) \end{split} 上式動手算出來會是 0: ```python=+ 0.0 ``` 也可以這樣寫,相當於是兩個 operator 做 tensor product: ```python=+ return qml.expval(qml.X(0)@qml.X(1)) ``` 相當於在算 \begin{split} \langle \psi|X\otimes X|\psi\rangle=1 \end{split} ## qml.counts() 以上的測量結果都是基於理想情況下,有時候我們想知道真實情況下的測量結果,就會使用這語法。 在測量之前,dev 要多加一個參數,定義你要測量幾次(shots) ```python=+ dev = qml.device('default.qubit', wires=2, shots=1024) ``` 輸出的結果為: ```python=+ {'00': 507, '11': 517} ``` 在 1024 次測量中,有 507 次測量到的結果是 $|00\rangle$,517 次是 $|11\rangle$,機率各為 49.5% 與 50.4%,接近理想 50%。 如果你希望所有量子態的出現次數都列出來,可以在括號中打上 "all_outcomes=True",即: ```python=+ return qml.counts(all_outcomes=True) ``` ```python=+ {'00': 523, '01': 0, '10': 0, '11': 501} ``` 也可以輸出每次物理量的期望值 ```python=+ return qml.counts(qml.X(0)) ``` 以下結果表示有三次測量是 $-1$,三次是 $1$,平均起來就是 $0$ ```python=+ {-1.0: 3, 1.0: 3} ``` 亦或是 ```python=+ return qml.counts(qml.X(0)@qml.X(1)) ``` ```python=+ {1.0: 6} ``` ## qml.sample() 想看每次測量的結果可以用 qml.sample() 語法 ```python=+ array([[1, 1], [0, 0], [1, 1], [0, 0], [0, 0]]) ``` 也可以測量特定的 qubit ```python=+ return qml.sample(wires = 0) ``` 就會輸出第一個 qubit 每次的測量結果 ```python=+ array([1, 1, 0, 1, 1]) ``` 同樣地,期望值也可以 ```python=+ return qml.sample(qml.X(0)@qml.X(1)) ``` ```python=+ array([1., 1., 1., 1., 1., 1.]) ```
課程目錄