量子笔记:量子计算 toy python implementation from scratch

news2024/10/7 6:42:30

目录

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 np

bra0 = 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 kron

M = 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 kron

bra0 = np.array([[1,0]])
bra1 = np.array([[0,1]])
ket0 = bra0.T
ket1 = bra1.T

ket00 = 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系统有2^n个基。对于标准正交基,各个基向量的one-hot表示是一个长度为2^n的向量,其中只有一个元素为1。基的one-hot表示是一个长度为2^n的向量,其中只有一个元素为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 representation
    num_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_binstr
    return 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 qbits
    k: 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) \mathbb{C}^{2\otimes n}表示.

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

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

def basis_generator(nbit=5):
    """
    Generate binary string representation of hilbert space basis, and return a generator.
    """
    nspace = 2**nbit
    for 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. 构造任意量子叠加态

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

                |\psi\rangle = \sum_i c_i | \phi_i\rangle

        量子(叠加)态必须满足幺正性,即各复系数绝对值平方和必须等于1。以下函数中最后进行了幺正性检查。其中 s.H 计算了 |𝑠〉 的转置共轭 〈𝑠| ,也称 |𝑠〉 的厄密特,也即右矢对应的左矢(或左矢对应的右矢)。

5.1 superposition1

def superposition1(coef, nbits):
    '''返回n量子系统中由所有基向量构成的任意量子叠加态。其系数由coef数组指定
       input: 
           seqs: sequence of binary string representation of basis vector, shoule be converted to one-hot representation before being used.
       output: 
           The linear combination of basis vectors
    '''
    res = 0
    for k, basis in enumerate(basis_generator(nbits)):
        res += coef[k] * basis
        
    np.testing.assert_almost_equal(res.H * res , 1) # unitarity check, 幺正性检验
    return np.matrix(res)

        使用该函数可以通过指定系数生成任意n比特量子系统的叠加态(基于计算基底):

# Test of superposition1()
coef = [1j/np.sqrt(2), np.sqrt(1/2)]
nbits = 1
s = superposition1(coef, nbits)
print(s)

coef = [1j/2, 0, 1/2, np.sqrt(1/2)]
nbits = 2
s = superposition1(coef, nbits)
print(s)

        运算结果如下:

[[0.        +0.70710678j]
 [0.70710678+0.j        ]]
[[0.        +0.5j]
 [0.        +0.j ]
 [0.5       +0.j ]
 [0.70710678+0.j ]]

5.2 superposition2

        superposition1()是针对N比特量子系统针对所有的基指定系数序列(即便为0也指定)。但是当N比较大时,如果非零系数个数比较少,可能仅指定非零系数更加方便。以下这个函数用于这种方式的实现,其中basis_vecs指定与coef对应的具有非零系数的基向量序号(以整数方式表示)。

def superposition2(coef, basis_vecs, nbits):
    '''返回n量子系统中由指定基向量构成的任意量子叠加态。其系数由coef数组指定
       input: 
           seqs: sequence of binary string representation of basis vector, shoule be converted to one-hot representation before being used.
       output: 
           The linear combination of basis vectors
    '''
    res = 0
    for k, basis in enumerate(basis_vecs):
        res += coef[k] * multi_qbits_basis(basis,nbits)
        
    np.testing.assert_almost_equal(res.H * res , 1) # unitarity check, 幺正性检验
    
    return np.matrix(res)

 调用示例代码如下:

# Test of superposition2()
coef = [1j/np.sqrt(2), np.sqrt(1/2)]
nbits = 2
s = superposition2(coef, [1,3], nbits)
print(s)

coef = [1j/2, 1/2, np.sqrt(1/2)]
nbits = 3
s = superposition2(coef, [1,3,5], nbits)
print(s, s.H * s)

        运行结果如下所示(第2个中,coef包含三个系数,basis_vec=[1,3,5],表示coef指定的系数分别对应于|001\rangle, |011\rangle, |101\rangle ): 

[[0.        +0.j        ]
 [0.        +0.70710678j]
 [0.        +0.j        ]
 [0.70710678+0.j        ]]
[[0.        +0.j ]
 [0.        +0.5j]
 [0.        +0.j ]
 [0.5       +0.j ]
 [0.        +0.j ]
 [0.70710678+0.j ]
 [0.        +0.j ]
 [0.        +0.j ]] [[1.+0.j]]

5.3 纠缠态 vs 可分离态

        可以分解为各单量子态的张量积形式的多量子态称为可分离态,反之,不能分离的就是纠缠态。 比如说,以下这个三量子系统状态就是一个可分离态:

        以下这个双量子态也是可分离态:

                |\psi\rangle=\frac{1}{2}(|00\rangle+|01\rangle+|10\rangle+|11\rangle)=\frac{1}{2}(|0\rangle+|1\rangle) \otimes (|0\rangle+|1\rangle))|

        而下面这个双量子态就不能展开为张量积形式,所以是纠缠态:

                |\psi\rangle = \frac{1}{\sqrt{2}}(|01\rangle+|10\rangle)

        量子力学中两个费米子的纠缠态就可以用以上这个双量子态来表示。费米子的量子态由自旋决定,有两种自旋,一种是向上spin up,另一种是向下spin down。两个纠缠在一起的费米子构成的双量子系统的总自旋为0。但是,没有人知道哪个自旋向上,哪个自旋向下。系统处于纠缠的叠加态。对其中任何一个进行测量,如果得到的结果是自旋向上,那么另一个也必定坍缩到自旋向下(因为自旋守恒);反之如果得到的结果是自旋向下,则另一个必定坍缩到自旋向上。

        无论是对哪个进行测量,结果都是这样(测量了其中一个导致其状态坍缩,同时也就知道了另外一个的状态),无论两者相距多远,似乎它们能够跨越遥远的空间以超光速的方式心灵感应。这就是爱因斯坦说的鬼魅般的超距相互作用。

        

量子系统纠缠与否的判定        

        前面章节中介绍过双量子系统的叠加态是否是纠缠态的简易判断准则(量子笔记:量子纠缠祛魅,贝尔纠缠态):

        

        对于形如双量子叠加态是不是属于纠缠态,有一个简单的判决准则是:gif.latex?rt%20%3D%20su%20%3F

        如果以上这个等式成立,则该式子是可以进行张量积分解的,即代表可分离态;反之,如果不成立,则说明这个式子是不能进行张量积分解的,也就是属于纠缠态。

        

        那多量子比特(n>=3)的量子系统状态有没有以上这样简易的判决准则呢?

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

        通常情况下我们都是以计算基底下的坐标向量的形式来表示量子态(波函数)。

        但是有时候也会需要变换到其它基底下去。

6.1 投影和分解

        波函数投影到某个指定基底所得的振幅系数可以通过波函数的左矢与该基底的右矢的内积运算而得。如下所示:

                c_i=\langle \phi_i|\psi \rangle

        进一步,针对一组基底,分别求得波函数投影到各基底的振幅系数,即得到波函数在该组基底下的分解。如下所示:

        ​​​​​​​        |\psi\rangle = \sum_i c_i |\phi_i\rangle = \sum_i \langle \phi_i | \psi \rangle \cdot |\phi_i \rangle

        注意,也有写做c_i = \langle \psi | \phi_i \rangle,但是将波函数变为左矢(右矢的复共轭转置)使得对应的系数也变成的复共轭,所以计算出来的投影系数为原来的系数的共轭。

        我们定义以下函数来实现投影和分解。

def project(psi, basis):
    '''<Psi | basis> to get the projected coefficient '''
    return basis.H * psi

def decompose(psi, basis_mat):
    '''
    将叠加态波函数针对指定的基底进行分解.
    psi: 输入叠加态波函数
    basis_mat: 
        np.matrix类型。指定的基底集合,以矩阵的形式表示,每一列表示一个基向量
        注意,由于需要利用*.H的运算,所以必需是np.matrix类型,普通的np.ndarray没有.H的属性。
    
    psi和basis_mat都是相对计算基底的表示
    '''
    coefs = []
    for k in range(basis_mat.shape[1]):
        #print(k,basis_mat[:,k].H)
        coefs.append(project(psi,basis_mat[:,k]))
        
    return coefs

        以下测试中,先用superposition()函数生成叠加态,然后再用decompose()进行分解。两个函数互为逆处理,两者都工作正确的话,最后应该恢复出原始的系数coef。 当然,这个只是

# test project() and decompose()
coef = [1j/np.sqrt(2), 1j/np.sqrt(2)]
nbits = 2
s = superposition2(coef, [1,3], nbits)
print(s)
computation_basis = np.matrix([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]).H
coef1 = decompose(s,computation_basis)
print(coef1)

        运行结果如下: 

[[0.+0.j        ]
 [0.+0.70710678j]
 [0.+0.j        ]
 [0.+0.70710678j]]
[matrix([[0.+0.j]]), matrix([[0.+0.70710678j]]), matrix([[0.+0.j]]), matrix([[0.+0.70710678j]])]         
# random test of project() and decompose()
nbits = 3
# 生成2**nbits个随机复系数
coef  = np.random.random([2**nbits,]) + 1j * np.random.random([2**nbits,])
# 归一化
norm_factor = np.sqrt(np.sum(np.conj(coef) * coef))
print(norm_factor)
coef = coef / norm_factor
np.testing.assert_almost_equal(1, np.sum(np.conj(coef) * coef)) # 归一化后满足概率和等于1
print(coef, type(coef))

# 生成叠加态
s = superposition1(coef, nbits)

# 分解
computation_basis = np.zeros([2**nbits, 2**nbits])
for k, basis_k in enumerate(basis_generator(nbits)):
    #print(k,basis_k)
    computation_basis[:,k] = np.squeeze(basis_k)
print(computation_basis)

coef1 = decompose(s, np.matrix(computation_basis))
print(coef1)

        运行以上测试代码可以得到:

(2.165212496837334+0j)
[0.26504767+0.32357524j 0.35633515+0.11254125j 0.26048141+0.33595667j
 0.18204604+0.386526j   0.23181745+0.26564862j 0.34037746+0.10183365j
 0.18917889+0.07431278j 0.14806314+0.09153582j] <class 'numpy.ndarray'>
[[1. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0.]
 [0. 0. 1. 0. 0. 0. 0. 0.]
 [0. 0. 0. 1. 0. 0. 0. 0.]
 [0. 0. 0. 0. 1. 0. 0. 0.]
 [0. 0. 0. 0. 0. 1. 0. 0.]
 [0. 0. 0. 0. 0. 0. 1. 0.]
 [0. 0. 0. 0. 0. 0. 0. 1.]]
[matrix([[0.26504767+0.32357524j]]), matrix([[0.35633515+0.11254125j]]), matrix([[0.26048141+0.33595667j]]), matrix([[0.18204604+0.386526j]]), matrix([[0.23181745+0.26564862j]]), matrix([[0.34037746+0.10183365j]]), matrix([[0.18917889+0.07431278j]]), matrix([[0.14806314+0.09153582j]])]

        当然,以上测试代码中叠加态的生成以及投影分解都是在相同的计算基底下进行的,叠加态生成和投影分解(在同一基底下)是互逆的,分解的结果与最初用于生成叠加态的系数应该是相同的。这个当然并不是什么很有趣的事情,其目的只是对代码进行一个sanity check。投影分解的更有趣的应用应该是在当基底发生变换时的情况。

6.2 基底变换

        如上节的波函数的新的基底下的分解所示,[〈𝜓|𝜙0〉,〈𝜓|𝜙1〉,...].𝑇相当于就是波函数在该新的基底下的坐标向量。从该波函数在原基底下的坐标向量到在新基底下的坐标向量的变换就称为基底变换。同一个波函数在不同基底下的坐标向量是不同的,所以严格地来说,将波函数写成坐标向量的形式是需要表明它对应的基底的。但是一般来说,缺省地认为是采用计算基底,在计算基底下的坐标向量不必特意标明基底,但是在其它基底下的坐标向量表示则需要注明对应基底。

        根据线性代数理论,我们知道向量空间的基地变换可以用矩阵来表示。

        未完待续。。。coming soon。。。

回到本系列主目录:

量子笔记:量子计算祛魅https://chenxiaoyuan.blog.csdn.net/article/details/127251274        

参考:

用 Python 写个玩具级量子计算机 (1)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1409.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于多尺度注意力网络单图像超分(MAN)

引言 Transformer的自注意力机制可以进行远距离建模&#xff0c;在视觉的各个领域表现出强大的能力。然而在VAN中使用大核分解同样可以得到很好的效果。这也反映了卷积核的发展趋势&#xff0c;从一开始的大卷积核到vgg中采用堆叠的小卷积核代替大卷积核。 上图展现了MAN网络在…

使用T0,方式2,在P1.0输出周期为400µs,占空比为4:1的矩形脉冲,要求在P1.0引脚接有虚拟示波器,观察P1.0引脚输出的矩形脉冲波形

大家学过一段时间的单片机了&#xff0c;今天我们来说说单片机里的定时器&#xff0c;又叫计数器。首先&#xff0c;我们通过案例来了解一下什么是定时器。 【例】使用T0&#xff0c;方式2&#xff0c;在P1.0输出周期为400s&#xff0c;占空比为4&#xff1a;1的矩形脉冲&…

如何编写优秀的测试用例,建议收藏和转发

1、测试点与测试用例 测试点不等于测试用例&#xff0c;这是我们首先需要认识到的。 问题1&#xff1a;这些测试点在内容上有重复&#xff0c;存在冗余。 问题2&#xff1a;一些测试点的测试输入不明确&#xff0c;不知道测试时要测试哪些。 问题3&#xff1a;总是在搭相似…

串口通信协议【I2C、SPI、UART、RS232、RS485、CAN】

&#xff08;1&#xff09;I2C 集成电路互连总线接口(Inter IC)&#xff1a;同步串行半双工传输总线&#xff0c;连接嵌入式处理器及其外围器件。 支持器件&#xff1a;LCD驱动器、Flash存储器 特点&#xff1a; ①有两根传输线&#xff08;时钟线SCL、双向数据线SDA&#…

python基础19-36题

题目&#xff1a; 代码十九二十二十一二十二二十三二十四二十五二十六二十七二十八二十九三十三十一三十二三十三三十四三十五三十六十九 birthday int(input(“请输入生日日期&#xff1a;”)) Set1 [1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31] Set2 [2,3,6,7,10,11,…

【CV】第 7 章:目标检测基础

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

几何等变图神经网络综述

许多科学问题都要求以几何图形&#xff08;geometric graphs&#xff09;的形式处理数据。与一般图数据不同&#xff0c;几何图显示平移、旋转和反射的对称性。研究人员利用这种对称性的归纳偏差&#xff08;inductive bias&#xff09;&#xff0c;开发了几何等变图神经网络&a…

SpringMVC | 快速上手SpringMVC

&#x1f451; 博主简介&#xff1a;    &#x1f947; Java领域新星创作者    &#x1f947; 阿里云开发者社区专家博主、星级博主、技术博主 &#x1f91d; 交流社区&#xff1a;BoBooY&#xff08;优质编程学习笔记社区&#xff09; 前言&#xff1a;在上一节中我们了解…

多分类评估指标计算

文章目录混淆矩阵回顾Precision、Recall、F1回顾多分类混淆矩阵宏平均&#xff08;Macro-average&#xff09;微平均&#xff08;Micro-average&#xff09;加权平均&#xff08;Weighted-average&#xff09;总结代码混淆矩阵回顾 若一个实例是正类&#xff0c;并且被预测为正…

Linux(Nginx)

目录 一、Nginx简介 二、Nginx使用 Nginx安装 tomcat负载均衡 Nginx配置 三、Nginx部署项目 项目打包前 将前端项目打包&#xff08;测试本地项目打包后没问题&#xff09; ip/host主机映射 完成Nginx动静分离的default.conf的相关配置 将前台项目打包(配合Nginx动静…

real-word super resulution: real-sr, real-vsr, realbasicvsr 三篇超分和视频超分论文

real-world image and video super-resolution 文章目录real-world image and video super-resolution1. Toward Real-World Single Image Super-Resolution:A New Benchmark and A New Model&#xff08;2019&#xff09;1.1 real-world数据集制作1.2 LP-KPN网络结构1.3 拉普拉…

近八成中国程序员起薪过万人民币,你过了么?

打工者联盟为了抵抗996、拖欠工资、黑心老板、恶心公司&#xff0c;让我们组成打工者联盟。客观评价自己任职过的公司情况&#xff0c;为其他求职者竖起一座引路的明灯。https://book.employleague.cn/一项调查显示&#xff0c;近八成中国程序员本科毕业生起薪过万&#xff08;…

Oracle数据库中的数据完整性

目录 1.数据完整性约束作用 2.数据完整性约束的分类 3.完整性约束的状态 4.域完整性的实现 &#xff08;1&#xff09;check约束 ①可视化方式创建check约束 ②命令方式创建约束 ③修改表创建的约束 ④删除约束 &#xff08;2&#xff09;实体完整性约束实现 ①prim…

思科dhcp服务器动态获取ip地址

项目要求: 某公司共有网管中心、行政部、技术部、三个部门&#xff0c;分别处在一栋大楼中的两个楼层&#xff0c;为了保证公司内部主机始终能够连接Internet&#xff0c;采用双向冗余设计&#xff0c;分别使用路由器R1与路由器R2连接中国电信和中国联通。 1.首先为了避免不必要…

【算法详解】数据结构:7种哈希散列算法,你知道几个?

一、前言 哈希表的历史 哈希散列的想法在不同的地方独立出现。1953 年 1 月&#xff0c;汉斯彼得卢恩 ( Hans Peter Luhn ) 编写了一份IBM内部备忘录&#xff0c;其中使用了散列和链接。开放寻址后来由 AD Linh 在 Luhn 的论文上提出。大约在同一时间&#xff0c;IBM Researc…

项目进度管理

第3 章 项目进度管理 3.1 概述 1.项目进度管理是指在项目实施过程中&#xff0c;对各阶段的进展程度和项目最终完成的期限所进行的管理&#xff0c;是在 规定的时间内&#xff0c;拟定出合理且经济的进度计划&#xff08;包括多级管理的子汁划)&#xff0c;在执行该计划的过程…

常见的限流算法的原理以及优缺点

原文网址&#xff1a;常见的限流算法的原理以及优缺点_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍限流常用的算法及其优缺点。 常用的限流算法有&#xff1a; 计数器&#xff08;固定窗口&#xff09;算法滑动窗口算法漏桶算法令牌桶算法 下面将对这几种算法进行分别介绍…

tmux的简单使用

文章目录一、认识tmux1.1 会话1.2 tmux的作用1.3 tmux的安装二、tmux的使用2.1 会话管理2.1.1 创建会话2.1.2 退出会话2.1.3 从终端环境进入会话2.1.4 查看会话列表2.1.5 销毁会话2.1.6 重命名会话2.2 窗口管理2.3 窗格管理一、认识tmux 1.1 会话 命令行的典型使用方式是&…

rocketmq是如何消费

拉取消息的请求都在pullRequestQueue队列里&#xff0c; 拉取消息成功后设置下一次需要拉取的offset&#xff0c; boolean dispatchToConsume processQueue.putMessage(pullResult.getMsgFoundList()); 这个方法会把拉取回来的消息放进msgTreeMap里面 然后消费拉取回来的消…

MongoDB副本集成员如何复制新数据

复制是指在多台服务器上保持相同的数据副本。MongoDB 实现此功能的方式是保存操作日志&#xff08;oplog&#xff09;&#xff0c;其中包含了主节点执行的每一次写操作。oplog 是存在于主节点 local 数据库中的一个固定集合。从节点通过查询此集合以获取需要复制的操作。 每个…