目录

0. 概要

1. 量子比特表示:用二维张量表示

2. 张量积的实现

2.1 用scipy.linalg.kron()实现张量积

2.2 用张量积计算双量子系统的基

3. 多量子系统基向量表示和生成

3.1 Helper function: bin_ext

3.2 多量子系统的基的生成

3.3 numpy.matrix

numpy.matrix.A, getA(), numpy.matrix.A1, getA1()

4. 基向量生成器

5. 构造任意量子叠加态

5.1 superposition1

5.2 superposition2

5.3 纠缠态 vs 可分离态

量子系统纠缠与否的判定

6. 波函数投影和分解、基底变换

6.1 投影和分解

6.2 基底变换


0. 概要

量子计算、量子信息、量子编程自学笔记系列。

用自己能看懂的方式来表述对于量子计算基础知识的理解。

不求体系完备和逻辑严谨、但求通俗易懂。或能顺便给路过的小伙伴一些参考和启发那是纯属巧合概不认账^-^。当然,这里仅限于轮廓的勾勒和要点的连接,对逻辑体系性和完备性以及细节感兴趣的话还是要自行正儿八经地啃正经的参考书。

到目前为止已经介绍了一大堆理论知识,一直有浮在云端的感觉(我一个老实巴交的码农程序狗整那么多数学干嘛呢^-^)。所以,这一篇来上点代码,看看如何用python来模拟实现量子计算中的处理。这是python实现的第一篇,先介绍一些python实现量子计算的基本编程实现,整到哪算哪。。。

1. 量子比特表示:用二维张量表示

单量子系统的计算基底如下所示:

  • qbit[0] = |0〉
  • qbit[1] = |1〉

在量子态表示中,我们需要区分左矢量和右矢量,也就是行向量和列向量。当我们在谈论行向量和列向量,其实已经是在谈论二维张量或者说矩阵了(只有把向量当作矩阵来考虑时才产生了所谓的行向量和列向量之分)。由于在量子态的表示中,需要区分左矢(行向量)和右矢(列向量),因此需要用二维张量来表示。另外一个原因是后面要用到的实现张量积的函数scipy.linalg.kron()不接受向量(1阶张量类型的参数),必需是2阶及以上的张量数据类型。

import numpy as npbra0 = np.array([[1,0]])
bra1 = np.array([[0,1]])
ket0 = bra0.T
ket1 = bra1.T
print(bra0)
print(bra1)
print(ket0)
print(ket1)# ket0,1的正交性和幺正性检验
np.testing.assert_almost_equal(np.squeeze(np.dot(bra0,ket0)), 1)
np.testing.assert_almost_equal(np.squeeze(np.dot(bra1,ket1)), 1)
np.testing.assert_almost_equal(np.squeeze(np.dot(bra1,ket0)), 0)
np.testing.assert_almost_equal(np.squeeze(np.dot(bra0,ket1)), 0)

如上所示,用numpy中的2维数组来表示bra0,1和ket0,1。其中bra是shape(1,2) 的2维数组,ket是shape(2,1) 的2维数组,分别对应于行向量和列向量。运行以上代码可以得到:

[[1 0]] (1, 2)
[[0 1]] (1, 2)
[[1][0]] (2, 1)
[[0][1]] (2, 1)

最后4条语句是用于进行幺正性检查的,即检查是否满足正交性以及是否满足“长度”为1。

2. 张量积的实现

2.1 用scipy.linalg.kron()实现张量积

scipy中提供kron()函数用于实现克罗内克积,也就是直积或者说张量积(scipy.linalg.kron(), numpy.kron())。

scipy.linalg.kron(a, b). The same as numpy.kron()

Parameters

a(M, N) : shape为(M,N)的多维输入数组

b(P, Q):  shape为(P,Q)的多维输入数组

输出为shape=((MP,NQ))的多维数组

scipy.linalg.kron的输入数组必需为2阶或2阶以上的张量(关于张量的介绍请参考量子笔记:张量、张量的阶数与向量的维数、外积、张量积)。以下为几个张量积计算例,有兴趣的小伙伴可以先笔算一下,然后再运行以下程序段看看计算结果是否一致,这样可以有效地检验对于张量积运算的理解是否正确。

import numpy as np
from scipy.linalg import kronM = kron(np.array([[1,2],[3,4]]), np.array([[1,1,1]]))
print(M)
M = kron(np.array([[1,2],[3,4]]), np.array([[1,1,1],[2,2,2]]))
print(M)
M = kron(np.array([[1,2],[3,4]]), np.array([[[1,1,1],[2,2,2]]]))
print(M)

前两个例子都是2阶张量之间的张量积,应该还是比较容易手写出来。但是第3个例子是一个2阶张量与一个3阶张量之间的张量积,这个要写出来就比较费劲了。更不用说涉及到更高阶张量的张量积运算了。

2.2 用张量积计算双量子系统的基

以下示例用kron()函数计算双量子系统的4个基向量。

import numpy as np
from scipy.linalg import kronbra0 = np.array([[1,0]])
bra1 = np.array([[0,1]])
ket0 = bra0.T
ket1 = bra1.Tket00 = kron(ket0,ket0)
ket01 = kron(ket0,ket1)
ket10 = kron(ket1,ket0)
ket11 = kron(ket1,ket1)
print(ket00.T) # 为了显示方便,打印成其转置形式,即对应的bra
print(ket01.T)
print(ket10.T)
print(ket11.T)

最后的结果出于打印的遍历经过了转置处理后打印成行向量的形式,打印结果如下。但是严格地来说,用*.T进行转置处理在处理一般的量子态时是不合理的,必需要用*.H(复共轭转置),这个后面会谈到。

[[1 0 0 0]]
[[0 1 0 0]]
[[0 0 1 0]]
[[0 0 0 1]]

用同样的方式可以计算更多量子比特构成的多量子比特系统的状态空间的基。

3. 多量子系统基向量表示和生成

以下函数实现中,从string的最后1比特开始往前数。但是这个不是必然的。正序往后数也可以得到一组合法的基。但是当前这种实现可以得到比较符合直觉的基的表示。在所生成的基的one-hot表示中,1的位序号恰好等于对应的Qubits的二进制表示的值。比如说|00〉|00〉对应的[1,0,0,0], |01〉|01〉对应的[0,1,0,0],etc

n-Qubits系统有个基。对于标准正交基,各个基向量的one-hot表示是一个长度为的向量,其中只有一个元素为1。基的one-hot表示是一个长度为的向量,其中只有一个元素为1。

3.1 Helper function: bin_ext

为了方便后面的实现,先写一个基于python的bin()函数扩展实现的bin_ext函数。Python bin()用于将十进制数转换为二进制字符串,带0b前缀,不保留头上的零(leading zeros)。如下所示:

Python bin() function returns the binary string of a given integer.

Syntax: bin(a)

Parameters : a : an integer to convert

Return Value : A binary string of an integer or int object.

print(bin(100))
print(bin(26))
print(bin(26007))

运行结果:

0b1100100
0b11010
0b110010110010111

本扩展函数bin_ext()通过参数控制是否保留leading zeros,以及是否保留“0b”前缀。

def bin_ext(num, keep_leading_zeros = True, N=16, keep_prefix = True):# Convert num to binary representationnum_binstr        = bin(num)[2:] #print(num_binstr)if keep_leading_zeros:num_binstr        = '0'*(N - len(num_binstr)) + num_binstr#print(num_binstr)                if keep_prefix:num_binstr = '0b'+num_binstrreturn num_binstr
print(bin_ext(10))
print(bin_ext(140, keep_leading_zeros = True, N=10))
print(bin_ext(10, True, 16, False))

运行结果如下:

0b0000000000001010
0b0010001100
0000000000001010

3.2 多量子系统的基的生成

以下函数用于计算由N个量子比特构成的量子系统的序号为k(从0开始)的计算基的坐标向量(one-hot)表示。当然,所谓序号是人为指定的,如下所述,只不过恰好是表示张量积的二进制字符串所对应的十进制数。虽然,不是必然的,但是却是使用起来最方便的。

以下函数实现中,从bibstr的最后1比特开始往前数(binstr[::-1]表示将字符串倒序)。但是这个不是必然的。正序往后数也可以得到一组合法的基。但是这种实现方式可以得到比较符合直觉的基的表示。在所生成的基的one-hot表示中,1的位序号恰好等于对应的Qubits的二进制表示的数值。比如说|000〉对应的[1,0,0,0,0,0,0,0], |001〉对应的[0,1,0,0,0,0,0,0],|010〉对应的[0,0,1,0,0,0,0,0],...比如说"010"是十进制数2的二进制表示,它的one-hont表示中恰好是bit[2]为1,其余为0,余者以此类推。

def multi_qbits_basis(k,N):"""N: number of qbitsk: integer representation of the basis vector"""binstr = bin_ext(k, True, N, False)res = np.array([[1]])# 从最后一位开始往前数,做直积for idx in binstr[::-1]:    # for idx in string:    # print(idx, bit[int(idx)], res)res = kron(bit[int(idx)],res)return np.matrix(res)
print(multi_qbits_basis(3,4).T)
print(multi_qbits_basis(13,5).T)N = 3
for k in range(2**N):print('basis{0} = {1}'.format(k,multi_qbits_basis(k,N).T))

运行结果如下:

[[0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]]
[[0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]]
basis0 = [[1 0 0 0 0 0 0 0]]
basis1 = [[0 1 0 0 0 0 0 0]]
basis2 = [[0 0 1 0 0 0 0 0]]
basis3 = [[0 0 0 1 0 0 0 0]]
basis4 = [[0 0 0 0 1 0 0 0]]
basis5 = [[0 0 0 0 0 1 0 0]]
basis6 = [[0 0 0 0 0 0 1 0]]
basis7 = [[0 0 0 0 0 0 0 1]]

3.3 numpy.matrix

在以上multi_qbits_basis实现中,最后输出结果转换成numpy.matrix输出了。那numpy matrix是个什么东东呢?

numpy matrix是numpy ndarray的一个子类。其目的其实就是提供一个matlab matrix的对应物,提供更为直观的矩阵运算,包括矩阵数据的处理,矩阵的计算,以及基本的统计功能,转置,可逆性等等,包括对复数的处理,均在matrix对象中。

关于numpy中矩阵和二维数组的取舍

numpy matrix和numpy array在很多时候都是通用的,matrix的优势就是相对直观的运算处理方式(更符合线性代数课上学到的东西),但官方建议如果两个可以通用,那就选择array,因为array更灵活,速度更快。事实上官网上甚至建议不要使用numpy matrix(numpy.matrix — NumPy v1.23 Manual):

Note

It is no longer recommended to use this class, even for linear algebra. Instead use regular arrays. The class may be removed in the future.

但是本文中还是使用了numpy matrix,原因在于numpy matrix提供了numpy.matrix.H property(Returns the (complex) conjugate transpose of self.),(对于复数域的矩阵运算来说)使用比较方便。

numpy.matrix.A, getA(), numpy.matrix.A1, getA1()

使用属性A或者函数getA()可以将numpy matrix变换为numpy ndarray对象。进一步属性A1和函数getA1()则将矩阵转换为ndarray的同时还将其展平(flattern)为1-D。

如以下代码所示:

x = np.matrix(np.arange(12).reshape((3,4)));
print(x, type(x))
print(x.A, type(x.A))
print(x.getA(), type(x.getA()))
print(x.A1, type(x.A1))
print(x.getA1(), type(x.getA1()))
[[ 0  1  2  3][ 4  5  6  7][ 8  9 10 11]] <class 'numpy.matrix'>
[[ 0  1  2  3][ 4  5  6  7][ 8  9 10 11]] <class 'numpy.ndarray'>
[[ 0  1  2  3][ 4  5  6  7][ 8  9 10 11]] <class 'numpy.ndarray'>
[ 0  1  2  3  4  5  6  7  8  9 10 11] <class 'numpy.ndarray'>
[ 0  1  2  3  4  5  6  7  8  9 10 11] <class 'numpy.ndarray'>

4. 基向量生成器

n个Qbits的系统状态空间可以用希尔伯特空间(Hilbert Space) 表示.

该希尔伯特空间维数为,换句话说,它是由个基向量张成的空间。

因为希尔伯特空间的维数为,随Qubit的个数n呈指数增长,所以直接生成所有的基向量保存下来使用,需要巨大的内存。为了避免内存问题,实际运算处理时,可以如以下实现方式所示,用yield返回一个generator。不一次性生成和保存数组,而是实际使用循环中按需生成。

def basis_generator(nbit=5):"""Generate binary string representation of hilbert space basis, and return a generator."""nspace = 2**nbitfor i in range(nspace):yield multi_qbits_basis(i,nbit)# Test of basis_generator()
for k, mi in enumerate(basis_generator(nbit=3)):print('basis[{0}] = {1}'.format(k,mi.T), end='\n')

以上测试代码运行结果如下:

basis[0] = [[1 0 0 0 0 0 0 0]]
basis[1] = [[0 1 0 0 0 0 0 0]]
basis[2] = [[0 0 1 0 0 0 0 0]]
basis[3] = [[0 0 0 1 0 0 0 0]]
basis[4] = [[0 0 0 0 1 0 0 0]]
basis[5] = [[0 0 0 0 0 1 0 0]]
basis[6] = [[0 0 0 0 0 0 1 0]]
basis[7] = [[0 0 0 0 0 0 0 1]]

5. 构造任意量子叠加态

任意量子系统状态(也称波函数)是各个基向量的线性叠加,系数为复数,称为振幅。复振幅系数的平方则代表坍缩到各基态的概率。

量子(叠加)态必须满足幺正性,即各复系数绝对值平方和必须等于1。以下函数中最后进行了幺正性检查。其中 s.H 计算了 |

量子笔记:量子计算 toy python implementation from scratch相关推荐

  1. 量子笔记:布尔逻辑/代数、逻辑门、通用门、可逆计算

    目录 0. 前言 1. 布尔逻辑.布尔代数和布尔函数 2. 香农.开关.逻辑门.电路 3. 门与计算 4. 功能完备性与通用门 4.1 功能完备性 4.2 通用门 5. 可逆计算和可逆门 5.1 可逆 ...

  2. 量子笔记:多量子系统、叠加、量子计算并行处理能力

    目录 0. 概要 1. 张量积的狄拉克符号表示形式 2. 多量子系统的状态的表示 3. 叠加 4. 量子计算并行处理能力 0. 概要 量子计算.量子信息.量子编程自学笔记系列. 用自己能看懂的方式来表 ...

  3. 量子笔记:单比特量子门、泡利矩阵

    目录 0. 概要 1. 量子门基本性质 1.1 量子门与布洛赫球面的关系 1.2 量子门与幺正矩阵的关系 2. 泡利矩阵: 量子X,Y,Z,ID门 2.1 量子X门(量子非门) 2.2 量子Z门 2. ...

  4. 量子笔记:多比特量子门

    目录 0. 前言 2. 量子多重H门 3. 量子SWAP门 4. 量子CNOT门(CX门):受控非门 5. 量子CY和CZ门 6. 量子C*门 6.1 受控S门 6.2 受控H门 6.3 受控Z旋转门 ...

  5. 量子笔记:量子纠缠祛魅,贝尔纠缠态

    目录 0. 概要 1. 纠缠态 vs 可分离态 1.1 由张量积生成的双量子状态 1.2 无法由张量积生成的双量子状态 1.3 双量子系统状态的向量空间 2. 测量的视角 from measureme ...

  6. Python数据分析学习笔记:计算向量夹角

    Python数据分析学习笔记:计算向量夹角 通过计算两个向量夹角了解两个向量之间的相关性. # 计算向量夹角import numpy as npdef included_angle(a, b):a_n ...

  7. Python数据分析学习笔记:计算相关系数

    Python数据分析学习笔记:计算相关系数 1.相关系数概念 相关系数,或称线性相关系数.皮氏积矩相关系数(Pearson product-moment correlation coefficient ...

  8. python 编写实用小工具-toy: python平时积累的笔记以及编写的小工具

    所有人都告诉你怎么活,只有自己没有搞清楚该如何活.相信自己,我们每个人都是主角?? toy Python ?? 献给我亲爱的女朋友--如 ? 介绍 学习 python.matlab 时积累的笔记以及编 ...

  9. PYTHON 100days学习笔记001:初识python

    现在学习这个确实时间很紧,但是迟早得学,以后PYTHON自动化运维,PYTHON自动测试都需要用的到,甚至可以往数据分析方向发展,刚好最近有数据观组织的python100天计划,就参加了,做好笔记,一 ...

最新文章

  1. KOAProgressBar
  2. 创建细分客户的无监督学习项目
  3. redis服务端基本命令
  4. 全球及中国牛乳腺炎治疗系统行业发展调研及投资预测分析报告2022-2027年
  5. NYOJ 631 冬季长跑
  6. 关于linux内核模块的装载过程
  7. SAP UI5 应用开发教程之三十六 - 使用 Chrome 开发者工具 Elements 标签动态修改 CSS 类
  8. Redis悲观锁、乐观锁和调用Lua脚本的优缺点
  9. Windows 8的企业部署之路漫漫兮
  10. spring@Autowired的对象为null,非容器中的类如何调用容器中的类
  11. 解决Mac装上Jetbrain系列软件(Pycharm/Idea)破解包无效导致软件启动报错
  12. Oracle学习笔记:手工注册oracle的oledb驱动
  13. JDBC 学习笔记(三)—— 数据源(数据库连接池):DBCP数据源、C3P0 数据源以及自定义数据源技术...
  14. Spark streaming消费Kafka的正确姿势
  15. 自定义控件的构建(6)
  16. 【2019杭电多校第七场1010=HDU6655】Just Repeat(思维)
  17. win10 更新 英特尔显示器音频 后显示器音箱没有声音
  18. 微型计算机的Usb有几个,一起来侃侃USB/eSATA二合一接口
  19. 华为模拟器ENSP下载与安装详细教程(win10 LTSC系统中安装)
  20. 几分钟搞定,文件名称中文转英文

热门文章

  1. 60位演讲大师合集,错过将遗憾终生!
  2. #mac# #finder# #Iterm2# finder中打开当前路径的Iterm2终端
  3. 你的OA,坚持应用了吗?
  4. 理想汽车 x StarRocks:为 Hive 数据查询插上极速之翼
  5. 学习Linux这篇文章就够了
  6. 第七章第三题(计算数字的出现次数)(Count occurrence of numbers) - 编程练习题答案
  7. 递归实现斐波那契数列 一个人赶着鸭子去每个村庄卖,每经过一个 村子卖去所赶鸭子的一半又一只。 这样他经过了 七个村子后还剩 两只鸭子,问问他出发时共赶多少只鸭子?经过每个村子卖出多少只鸭子?
  8. win11无线网卡突然消失,U盘插入很久才会有反应的解决方法
  9. java有关线程的说法错误的是_下面关于Java主线程的说法错误的是:
  10. Vault: 基础教程之入门及使用介绍