什么是量子态矢量?

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

\[\left|\psi_t\right>=e^{-iHt}\left|\psi_0\right>
\]

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

\[\overrightarrow{x'}=\textbf{A}\overrightarrow{x}
\]

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

\[\left<\psi^*|\psi\right>=1
\]

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

\[\sum_{i=0}^{2^n-1}p_i=1
\]

这里的\(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()

累积分布函数

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

\[y_i=\sum_{j<=i}y_j
\]

我们很容易可以预测,在累积分布函数的终点一定是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()

总结概要

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

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

版权声明

本文首发链接为:https://www.cnblogs.com/dechinphy/p/state.html

作者ID:DechinPhy

更多原著文章请参考:https://www.cnblogs.com/dechinphy/

Python实现量子态采样的更多相关文章

  1. Python 和 C/C++ 拓展程序如何性能优化?看这一篇文就够

    作者:王璐璐 | 旷视 MegEngine 架构师 一. 背景 在 MegEngine imperative runtime 的早期开发中,我们面临着一些的性能优化问题.除了一些已知需要重构的地方(早 ...

  2. 使用开源量子编程框架ProjectQ打印编译后的量子线路与绘制线路图

    技术背景 在量子计算领域,基于量子芯片的算法设计(或简称为量子算法)是基于量子线路来设计的,类似于传统计算中使用的与门和非门之类的逻辑门.因此研究一个量子线路输入后的编译(可以简化为数量更少的量子门组 ...

  3. 昇思MindSpore全场景AI框架 1.6版本,更高的开发效率,更好地服务开发者

    摘要:本文带大家快速浏览昇思MindSpore全场景AI框架1.6版本的关键特性. 全新的昇思MindSpore全场景AI框架1.6版本已发布,此版本中昇思MindSpore全场景AI框架易用性不断改 ...

  4. python 多分类任务中按照类别分层采样

    在机器学习多分类任务中有时候需要针对类别进行分层采样,比如说类别不均衡的数据,这时候随机采样会造成训练集.验证集.测试集中不同类别的数据比例不一样,这是会在一定程度上影响分类器的性能的,这时候就需要进 ...

  5. Python中的随机采样和概率分布(二)

    在上一篇博文<Python中的随机采样和概率分布(一)>(链接:https://www.cnblogs.com/orion-orion/p/15647408.html)中,我们介绍了Pyt ...

  6. Python中的随机采样和概率分布(一)

    Python(包括其包Numpy)中包含了了许多概率算法,包括基础的随机采样以及许多经典的概率分布生成.我们这个系列介绍几个在机器学习中常用的概率函数.先来看最基础的功能--随机采样. 1. rand ...

  7. 【python实现卷积神经网络】上采样层upSampling2D实现

    代码来源:https://github.com/eriklindernoren/ML-From-Scratch 卷积神经网络中卷积层Conv2D(带stride.padding)的具体实现:https ...

  8. Python 资源大全中文版

    Python 资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列的资源整理.awesome-python 是 vinta 发起维护的 Python 资源列 ...

  9. 【原】Learning Spark (Python版) 学习笔记(二)----键值对、数据读取与保存、共享特性

    本来应该上周更新的,结果碰上五一,懒癌发作,就推迟了 = =.以后还是要按时完成任务.废话不多说,第四章-第六章主要讲了三个内容:键值对.数据读取与保存与Spark的两个共享特性(累加器和广播变量). ...

随机推荐

  1. python 虾米停服了...用python爬取虾米最近播放的1000首歌

    1. 虾米关服 在这里插入图片描述 用了5年多的音乐软件就这么说关就关了,确实让人心里不好受 ,虽然再去一个新的app里,让它们的算法熟悉你的喜好也不是很困难,可我还是习惯虾米的界面.虾米现在可以支持 ...

  2. hdfs读写删除过程解析

    一.hdfs文件读取过程 hdfs有一个FileSystem实例,客户端通过调用这个实例的open()方法就可以打开系统中希望读取的文件,hdfs通过rpc协议调用Nadmenode获取block的位 ...

  3. 风炫安全WEB安全学习第二十六节课 XSS常见绕过防御技巧

    风炫安全WEB安全学习第二十六节课 XSS常见绕过防御技巧 XSS绕过-过滤-编码 核心思想 后台过滤了特殊字符,比如说

  4. Termux键盘配置

    通过编辑~/.termux/termux.properties配置 extra-keys = [\ ['ESC', 'CTRL', '&', '$', '!', '%', '<', '& ...

  5. TCP/IP协议栈在Linux内核中的运行时序分析

    网络程序设计调研报告 TCP/IP协议栈在Linux内核中的运行时序分析 姓名:柴浩宇 学号:SA20225105 班级:软设1班 2021年1月 调研要求 在深入理解Linux内核任务调度(中断处理 ...

  6. 单线程的as-if-serial语义

    单线程的as-if-serial语义 关于指令重排序有个问题不明白的一个问题 int a = 2; int c = 1 + a; float b = 3f / 2f; 举个栗子,从CPU的设计者以及编 ...

  7. 02--Docker配置阿里云镜像加速器

    1.登录阿里云控制台,在产品与服务中收索 "容器镜像服务" 2.点击镜像加速器,CentOS 3.在路径 /etc/docker/daemon.json 下配置加速器地址 4.重新 ...

  8. 动态sql语句、逆向工程(generator)、分页助手(pagehelper)

    1.动态sql语句 if if where 配合使用 <select id="selectByWhere" resultType="com.alibaba.wlq. ...

  9. tail -f 在对文件进行动态追踪时失效的问题

    在我是用 tail -f file.txt 对这个文件进行动态追踪时: 我重新打开一个新的终端进行vim编辑这个文件并且保存 这是我们发现,tail -f file.txt'动态追踪的这个文件没有任何 ...

  10. Docker容器日志清理方案

    Docker容器在运行过程中会产生很多日志,久而久之,磁盘空间就被占满了,以下分享docker容器日志清理的几种方法 删除日志 在linux上,容器日志一般存放在 /var/lib/docker/co ...