本网站(662p.com)打包出售,且带程序代码数据,662p.com域名,程序内核采用TP框架开发,需要联系扣扣:2360248666 /wx:lianweikj
精品域名一口价出售:1y1m.com(350元) ,6b7b.com(400元) , 5k5j.com(380元) , yayj.com(1800元), jiongzhun.com(1000元) , niuzen.com(2800元) , zennei.com(5000元)
需要联系扣扣:2360248666 /wx:lianweikj
Python实现量子态采样
iamitnan · 314浏览 · 发布于2021-02-04 +关注

什么是量子态矢量?

在前面一篇量子系统模拟的博客中,我们介绍了使用python去模拟一个量子系统演化的过程。当我们尝试理解量子态和量子门操作时,可以通过其矩阵形式的运算来描述量子态演化的过程:


|ψt⟩=e−iHt|ψ0⟩|ψt⟩=e−iHt|ψ0⟩


这里的狄拉克标记符号和矩阵指数运算,在这篇博客中同样进行了介绍。我们可以简单的将该过程理解为:一个矩阵和一个矢量进行了一个点乘操作,得到了一个更新后的态矢量:


x′→=Ax→x′→=Ax→


在量子计算的框架下,由于通用的量子门操作都是酉矩阵(Unitary),因此不论是更新前还是更新后的操作,得到的态矢量总是归一化的:


⟨ψ∗|ψ⟩=1⟨ψ∗|ψ⟩=1


因此,在本文中考虑采样时,为了方便计算,我们将态矢量先转换为概率幅矢量,再进行采样。概率幅矢量的特征表现为:


∑i=02n−1pi=1∑i=02n−1pi=1


这里的nn就表示该量子系统的比特数,一个量子系统的量子态元素个数,或者是概率幅的元素个数是比特数的指数倍数(跟量子比特所占用的能级数有关,最常用的是两能级系统,因此为2n2n个元素个数)。

如何实现采样?

在上一个章节中所表述的是量子态的形式,在转换为概率幅矢量之后,其每一个元素都代表获取到当前二进制量子态的概率。这样我们获得一个量子态的态矢量或者概率幅矢量时,其实就是获得了该系统的概率分布。通过该概率分布,我们可以进行蒙特卡罗模拟:先在[0,1)[0,1)上面进行均匀随机撒点,同时将概率幅矢量转换为其对应的累积分布图,最后计算随机撒的点对应的累积分布图的位置,即可获得当前概率下的模拟采样,具体实现请参考如下示例。

采样示例一

我们先假设一个概率幅的分布,再对其进行采样。

给定一个指数下降的概率幅分布

这里我们先给定一个e−xe−x的概率分布函数,注意我们采取的是概率幅,因此要对其进行归一化的话只需要计算yi=yi∑jyjyi=yi∑jyj即可。

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)[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()

累积分布函数

所谓的累积分布函数,其实就是将前面获取到的概率幅矢量做一个累积叠加的操作,对应的计算方法如下:


yi=∑j<=iyjyi=∑j<=iyj


我们很容易可以预测,在累积分布函数的终点一定是1,这是因为前面所定义的∑2n−1i=0pi=1∑i=02n−1pi=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()

总结概要

对一个量子态矢量进行采样的过程,主要可以分为三个步骤:

  1. 计算量子态对应的概率分布函数(矢量);

  2. 计算量子态对应的累积分布函数(矢量);

  3. 均匀随机采样,映射到累积分布函数中所对应的量子态,在足够多的采样次数下就可以完整的模拟出原始的量子态分布。


相关推荐

PHP实现部分字符隐藏

沙雕mars · 1325浏览 · 2019-04-28 09:47:56
Java中ArrayList和LinkedList区别

kenrry1992 · 908浏览 · 2019-05-08 21:14:54
Tomcat 下载及安装配置

manongba · 970浏览 · 2019-05-13 21:03:56
JAVA变量介绍

manongba · 962浏览 · 2019-05-13 21:05:52
什么是SpringBoot

iamitnan · 1086浏览 · 2019-05-14 22:20:36
加载中

0评论

评论
分类专栏
小鸟云服务器
扫码进入手机网页