Python實現量子態取樣
什麼是量子態矢量?
在前面一篇量子系統模擬的部落格中,我們介紹了使用python去模擬一個量子系統演化的過程。當我們嘗試理解量子態和量子門操作時,可以通過其矩陣形式的運算來描述量子態演化的過程:
\]
這裡的狄拉克標記符號和矩陣指數運算,在這篇部落格中同樣進行了介紹。我們可以簡單的將該過程理解為:一個矩陣和一個矢量進行了一個點乘操作,得到了一個更新後的態矢量:
\]
在量子計算的框架下,由於通用的量子門操作都是酉矩陣(Unitary),因此不論是更新前還是更新後的操作,得到的態矢量總是歸一化的:
\]
因此,在本文中考慮取樣時,為了方便計算,我們將態矢量先轉換為概率幅矢量,再進行取樣。概率幅矢量的特徵表現為:
\]
這裡的\(n\)就表示該量子系統的比特數,一個量子系統的量子態元素個數,或者是概率幅的元素個數是比特數的指數倍數(跟量子比特所佔用的能級數有關,最常用的是兩能級系統,因此為\(2^n\)個元素個數)。
如何實現取樣?
在上一個章節中所表述的是量子態的形式,在轉換為概率幅矢量之後,其每一個元素都代表獲取到當前二進位量子態的概率。這樣我們獲得一個量子態的態矢量或者概率幅矢量時,其實就是獲得了該系統的概率分布。通過該概率分布,我們可以進行蒙特卡羅模擬:先在\([0,1)\)上面進行均勻隨機撒點,同時將概率幅矢量轉換為其對應的累積分布圖,最後計算隨機撒的點對應的累積分布圖的位置,即可獲得當前概率下的模擬取樣,具體實現請參考如下示例。
取樣示例一
我們先假設一個概率幅的分布,再對其進行取樣。
給定一個指數下降的概率幅分布
這裡我們先給定一個\(e^{-x}\)的概率分布函數,注意我們採取的是概率幅,因此要對其進行歸一化的話只需要計算\(y_i=\frac{y_i}{\sum_jy_j}\)即可。
import numpy as np
import matplotlib.pyplot as plt
plt.figure()
x=[i for i in range(32)]
y=[np.exp(-i) for i in range(32)]
y/=sum(y)
plt.title('Distribution of Quantum States')
plt.xlabel('Quantum States')
plt.ylabel('Probabilities')
plt.xticks(x,('0'*(7-len(str(bin(i))))+str(bin(i)).split('b')[1] for i in range(32)),rotation=70)
plt.plot(x,y,color='black')
plt.show()
在這個案例中我們還使用了一些matplotlib
的特殊繪圖技巧,這裡我們不展開介紹,後續會單獨寫一篇文章來分析常用的matploblib畫圖姿勢。
均勻隨機數
這裡我們直接使用python的random
函數,就可以生成\([0,1)\)之間的均勻隨機數,撒點數量越多,呈現的均勻分布的結果就越明顯。
import random
import matplotlib.pyplot as plt
x = [random.random() for i in range(1000)]
y = [random.random() for i in range(1000)]
plt.figure()
plt.plot(x,y,'.',color='red')
plt.show()
累積分布函數
所謂的累積分布函數,其實就是將前面獲取到的概率幅矢量做一個累積疊加的操作,對應的計算方法如下:
\]
我們很容易可以預測,在累積分布函數的終點一定是1,這是因為前面所定義的\(\sum_{i=0}^{2^n-1}p_i=1\)。
import numpy as np
import matplotlib.pyplot as plt
plt.figure()
x=[i for i in range(32)]
y=[np.exp(-i) for i in range(32)]
y/=sum(y)
for i in range(len(y)-1):
y[i+1]+=y[i]
plt.title('Cumulative Distribution Function')
plt.xlabel('Quantum States')
plt.ylabel('Cumulative Probabilities')
plt.xticks(x,('0'*(7-len(str(bin(i))))+str(bin(i)).split('b')[1] for i in range(32)),rotation=70)
plt.plot(x,y,color='black')
plt.show()
量子態取樣
這裡我們將概率分布函數和模擬取樣結果直接放在一起進行對比:
import numpy as np
import matplotlib.pyplot as plt
import random
plt.figure()
x=[i for i in range(32)]
y=[np.exp(-i) for i in range(32)]
y/=sum(y)
plt.plot(x,y,color='black',label='Real Distribution')
for i in range(len(y)-1):
y[i+1]+=y[i]
sp=np.zeros(32)
for i in range(50):
r = random.random()
for j in range(32):
if y[j]>r:
sp[j]+=1/50
break
plt.title('Sampling Results with 50 times')
plt.xlabel('Quantum States')
plt.ylabel('Probabilities')
plt.xticks(x,('0'*(7-len(str(bin(i))))+str(bin(i)).split('b')[1] for i in range(32)),rotation=70)
plt.plot(x,sp,color='red',label='Simulated Sampling')
plt.legend()
plt.show()
這裡我們可以看到結果已經是非常的接近了,如果我們繼續提高取樣次數,結果當然會更加接近真實分布:
因此,在獲得概率幅之後,我們可以根據場景對精度的要求,對該概率幅進行取樣,到這裡就完成了所有的功能實現。
取樣示例二
除了單調函數外,這裡我們再考慮另外一種形式的分布:正弦概率分布函數:
import numpy as np
import matplotlib.pyplot as plt
plt.figure()
x=[i for i in range(32)]
y=[np.sin(i/2)+1 for i in range(32)]
y/=sum(y)
plt.title('Distribution of Quantum States')
plt.xlabel('Quantum States')
plt.ylabel('Probabilities')
plt.xticks(x,('0'*(7-len(str(bin(i))))+str(bin(i)).split('b')[1] for i in range(32)),rotation=70)
plt.plot(x,y,color='black')
plt.show()
由於上面一個示例我們已經介紹完成了基本的操作流程和原理,這裡我們就不過多的贅述,直接展示累積分布函數和最終的模擬取樣效果:
累積分布函數
import numpy as np
import matplotlib.pyplot as plt
plt.figure()
x=[i for i in range(32)]
y=[np.sin(i/2)+1 for i in range(32)]
y/=sum(y)
for i in range(len(y)-1):
y[i+1]+=y[i]
plt.title('Cumulative Distribution Function')
plt.xlabel('Quantum States')
plt.ylabel('Cumulative Probabilities')
plt.xticks(x,('0'*(7-len(str(bin(i))))+str(bin(i)).split('b')[1] for i in range(32)),rotation=70)
plt.plot(x,y,color='black')
plt.show()
模擬取樣結果
import numpy as np
import matplotlib.pyplot as plt
import random
plt.figure()
x=[i for i in range(32)]
y=[np.sin(i/2)+1 for i in range(32)]
y/=sum(y)
plt.plot(x,y,color='black',label='Real Distribution')
for i in range(len(y)-1):
y[i+1]+=y[i]
sp=np.zeros(32)
for i in range(3000):
r = random.random()
for j in range(32):
if y[j]>r:
sp[j]+=1/3000
break
plt.title('Sampling Results with 3000 times')
plt.xlabel('Quantum States')
plt.ylabel('Probabilities')
plt.xticks(x,('0'*(7-len(str(bin(i))))+str(bin(i)).split('b')[1] for i in range(32)),rotation=70)
plt.plot(x,sp,color='red',label='Simulated Sampling')
plt.legend()
plt.show()
總結概要
對一個量子態矢量進行取樣的過程,主要可以分為三個步驟:
- 計算量子態對應的概率分布函數(矢量);
- 計算量子態對應的累積分布函數(矢量);
- 均勻隨機取樣,映射到累積分布函數中所對應的量子態,在足夠多的取樣次數下就可以完整的模擬出原始的量子態分布。
版權聲明
本文首發鏈接為://www.cnblogs.com/dechinphy/p/state.html
作者ID:DechinPhy
更多原著文章請參考://www.cnblogs.com/dechinphy/