量子傅里叶变换

背景介绍

傅里叶变换(Fourier Transform,傅立叶变换),是将函数表示成一组三角函数的线性组合的过程,是一种信号分析的重要方法。傅里叶变换有离散傅里叶变换和连续傅里叶变换等多种变体形式。本节将会从离散傅里叶变换出发,重点讨论其量子版本量子傅里叶变换

离散傅里叶变换

离散傅里叶变换(Discrete Fourier Transform, DFT)是分析有限长序列的重要工具,在诸多领域,比如频谱分析,信号处理,数据压缩,偏微分方程,长整数与多项式乘法等中,有着广泛的应用。

维)离散傅里叶变换是一个 的线性映射,其将复列向量 映射为相同维数的复列向量 ,其中

如果记傅里叶变换在计算基 下的矩阵表示为 ,那么有:

此时 是一个 的方阵,也称离散傅里叶变换矩阵,它的第 行第 列元素为

快速傅里叶变换

基于矩阵乘法的定义,给定输入复向量 ,计算输出其离散傅里叶变换的像 所需的时间复杂度为 。库利和图基充分利用变换中的对称性和周期性,在 1965 年提出了一种复杂度低至 的计算傅里叶变换的算法,它和其它高效、快速计算离散傅里叶变换的方法被统称为快速傅里叶变换(Fast Fourier Transform, FFT)。我们需要注意的是,在经典计算机上,即使采用快速傅里叶变换,所需的时间复杂度依然跟维数 是多项式相关的。

量子傅里叶变换原理

量子傅里叶变换(Quantum Fourier Transform, QFT)是离散傅里叶变换的量子对应版本,在量子算法设计中也扮演着重要角色,经常作为关键的子程序出现在各种量子算法中。已有的应用包括整数分解问题,隐子群问题(Hidden Subgroup Problem)等。

基本原理

维希尔伯特空间中的计算基,量子傅里叶变换 定义为:

因为要使用量子比特来编码,我们假设 ,这里 是编码需要使用的量子比特的数量。

习题 1. 证明式 定义的矩阵 是一个酉矩阵,即

证明. 由式 定义可知, 的矩阵形式为

其共轭转置矩阵为

因此有

其中 是克罗内克 函数,其值为 当且仅当 ,否则为 。式 中第二行到第三行利用了一个数学中常用的公式:

该公式可以由等比数列求和公式推导得到,感兴趣的同学可以自己动手试下。

对比离散傅里叶变换矩阵的定义,即式 ,我们可以注意到

即如果我们将离散傅里叶变换中的 编码到计算基 对应的概率幅上,那么作用量子傅里叶变换之后,输出态中的计算基 对应的概率幅即为 ,从而清楚地看到 DFT 和 QFT 在矩阵表达上的一致性。

习题 2. 证明式 成立。

证明. 的定义我们有

证毕。

量子电路实现方法

由上一小节可知量子傅里叶变换的本质就是酉矩阵 ,因此,接下来我们将详细地介绍 的量子电路的构造过程。通过将量子傅里叶变换的输出态做张量积分解,再逐个量子比特构建便可得到 的量子电路。

注: 为了与符号对应、便于阅读,本小节中量子比特的编号从 开始。

量子傅里叶变换输出态的张量积分解。先约定整数和小数的二进制表示。给定整数 ,记 二进制展开,即 ,其中 。类似地,记 为小数 的二进制展开,即 ;同样地,我们也可以定义

例 1.,由 ,有

基于二进制表示,我们就可以给出量子傅里叶变换输出态的张量积表示,其对量子傅里叶变换的量子电路构造有直接的指导意义。

首先,注意到由 个量子比特表示的量子态 即对应于 的二进制表示,故我们可以将量子傅里叶变换,即式 中的输出态 二进制展开为

中指数上的求和式展开为乘法,再连同量子态关于 做变量分离(即将与不同 相关的变量放在一起作为整体),便得到了量子态的张量积形式:

交换张量积和求和的顺序(这点值得读者去亲自验证),再将只有两项的求和形式展开便可得到

然后,我们把 二进制展开为 ,那么输出态的第 个量子比特就可以表示为

其中上式 成立是因为 的整数部分满足 不影响相对相位。综合式 和式 ,我们得到量子傅里叶变换输出态的张量积表示为

这个表示的重要意义在于,它给出了输出态中每个量子比特的状态和输入状态的二进制展开之间的对应关系。我们只需要从输入状态 出发,分别构造出每个量子比特的输出态,它们的张量积即是量子傅里叶变换的输出态。

量子电路实现。由量子傅里叶变换的张量积表示式 可知,我们只需要实现变换

仔细观察可以发现,输出态的第 个量子比特的状态与且只与输入态的第 到第 个量子比特的状态相关。一个简单直接的办法是将输出态倒序,即先实现

再利用 门,调整输出态各量子比特的顺序便可完整地实现 QFT:

对于式 中的变换的实现,考虑到中间输出态的第 个量子比特的状态与且只与输入态的第 到第 个量子比特的状态相关,如果我们先将第 个量子比特的状态变换为中间输出态对应量子比特的状态的话,位次在 之前的量子比特便没有直接信息 可用,所以我们应当先实现位次在前的量子比特的变换,即:

考虑到局部过程的相似性,我们只需要对任意的 实现变换

时上式 退化为单比特情形:

变换 所对应的矩阵便是

即 Hadamard 门的矩阵。也就是说单比特的变换 和 QFT 都是 Hadamard 门。

单量子比特上的 QFT

图 1:单量子比特上的 QFT

我们再来考虑稍复杂一点的情形,当 时,变换 退化为两比特情形:

因为变换 中量子比特 的状态没有变化,整个变换可以是一些在 上的单比特量子门和 做为控制比特的一些量子门的组合。受变换 的启发,我们可以先对 做一个 门:

再来考虑变换

类似于式 的方法,我们可以以遍历的方式计算出变换 的矩阵表示:

下图 2 为变换 对应的量子电路:

变换 (23) 对应的量子电路

图 2:变换 对应的量子电路

类似 ,我们可以定义量子门

及其控制形式

值得一提的是, 是不区分控制比特与受控比特的量子门,即有等价量子电路:

C(R_k) 的对称性

图 3: 的对称性

对于变换 更一般的情形可以类似地用下图 4 实现,这里就不再赘述了:

变换 (23) 对应的量子电路

图 4:变换 对应的量子电路

算法总结

综变换 - 所述, 量子比特系统的 QFT 的电路实现如下图 5:

量子傅里叶变换

图 5:一种实现量子傅里叶变换的量子电路

复杂度分析

量子傅里叶变换的复杂度,即计数图 5 所示的量子电路中所使用的量子门的个数。具体来说,总计使用了 门, 门以及 门。因此,总共使用的量子门个数为

我们可以看到这个数值与量子比特数目 是二次关系(也即多项式关系),而与矩阵的维数 呈对数关系,即图 5 给出的量子电路是复杂度为 的高效量子傅里叶变换算法。相对于经典的 FFT,是一种更高效地实现方式。

量子傅里叶逆变换

量子傅里叶逆变换 定义为:

习题 1 中我们已经证明了 ,即式 定义的矩阵 的逆矩阵。利用这个性质,我们可以根据实现 的量子电路(如图 5 所示),通过作用每个基础量子门的逆门来得到实现 的量子电路。注意到量子门 的逆都是它们自身,而量子门 的逆为

的量子电路如图 6 所示,其最开始部分一共有 量子门,然后是 门和控制 门组成的一些子电路(用于实现变换 的逆变换)。

量子傅里叶逆变换态

图 6:一种实现量子傅里叶逆变换的量子电路

由量子傅里叶逆变换的电路构造过程,我们可以看出其与量子傅里叶变换具有相同的复杂度。

例子

作为量子傅里叶变换的一个具体的例子,我们考虑三量子比特的 QFT()在量子计算机上的实现过程。假设某量子计算机支持以下量子门集合 ,并支持单量子比特控制操作。由 门的定义式 我们发现,

另外,我们可以使用三个 门实现一个 门。因此三量子比特 QFT 的量子电路为

三量子比特的QFT

图 7:一种实现三比特量子傅里叶变换的量子电路

另一方面,利用图 6 中构造量子傅里叶逆变换的技巧,我们也可以从上图 7 得到三量子比特的量子傅里叶逆变换的量子电路:

三量子比特的逆QFT

图 8:一种实现三比特量子傅里叶逆变换的量子电路

简例与量易伏平台演示

接下来我们展示如何在量易伏平台上实现量子傅里叶变换的电路。从其量子电路图(图 5)可知,其中最关键的步骤是我们如何实现受控 门操作。量易伏支持双量子比特受控 门,其中

易见当 时,,从而我们可以使用受控 门来实现受控 门。量易伏平台上实现 QFT 的代码如下:

from QCompute import *
import numpy as np

# 不直接给出输出,后续通过print给出需要信息
from QCompute import Define
Define.Settings.drawCircuitControl = []
Define.Settings.outputInfo = False

def qft(qreg):
    """
    实现量子傅里叶变换的量子电路
    当调用 qft(qreg) 时,对存储在 qreg 中的量子态做量子傅里叶变换 |r> -> QFT|r>
    :param qreg: |r>,量子寄存器,假设调用 qft 前处于状态 |r>
    :return: None
    """
    n = len(qreg)  # 计数 qreg 中包含量子比特的数量
    # QFT 的第一步:
    for l in range(0, n):  # 外循环,每个循环对应一次变换 (20),实现第 l 个量子比特的变换
        H(qreg[l])  # 对第 l 个量子比特做 H 门
        for k in range(2, n - l + 1):  # 内循环,每个循环对应一个 C(R_k) 门;
            # 当 l >= n - 1 时恰不需要这个内循环
            m = l + k - 1  # 计算 C(R_k) 门的控制比特的编号
            # C(R_k) 作为 CU 门 的特例直接调用,受控比特即第 l 个量子比特
            CU(0, 0, 2 * np.pi / pow(2, k))(qreg[m], qreg[l])
    # QFT 第二步:将量子比特倒序
    for l in range(0, n // 2):  # 对第 i 个和第 (n-i-1) 个量子比特做 SWAP 门
        SWAP(qreg[l], qreg[n - l - 1])
复制

我们可以用如下方式调用 QFT,这里以一个三量子比特系统为例:

def main():
    # 创建环境
    env = QEnv()
    # 选择随机数
    seed = int(2147483647*np.random.random())
    # 选择 Backend 为本地模拟器
    # 注:量易伏也支持云端模拟器和真机后端,访问 https://quantum-hub.baidu.com/ 获取更多信息。
    env.backend(BackendName.LocalBaiduSim2, '-s ' + str(seed))

    qreg = [env.Q[i] for i in range(3)]  # 生成初始化的 3 比特量子寄存器
    qft(qreg)  # 调用 qft 函数,对寄存器所储存的量子态作用 QFT
    
    shots = 1000  # 反复实验 1000 次统计结果
    MeasureZ(qreg, range(3))  # 对寄存器进行测量
    taskResult = env.commit(shots=1000, fetchMeasure=True)
    print("Shots", taskResult['shots'])
    print("Counts", taskResult['counts'])
    print("Seed", seed)


if __name__ == '__main__':
    main()
复制

测量结果如下:

Shots 1000
Counts {'100': 129, '011': 116, '101': 125, '111': 107, '000': 122, '001': 121, '110': 157, '010': 123}
Seed 1241392683
复制

在上面的演示性程序中,三量子比特的寄存器被初始化为 态,QFT 将寄存器状态演化为:

运行后可查看量易伏构造的 QFT 电路如下:

量易伏 QComposer 上的三比特 QFT

图 9:量易伏 QComposer 上的三比特 QFT

并获得相应的 QASM 代码为:

OPENQASM 2.0;
include "qelib1.inc";
qreg q[3];
creg c[3];
h q[0];
cu(0.0, 0.0, 1.5707963) q[1], q[0];
cu(0.0, 0.0, 0.7853982) q[2], q[0];
h q[1];
cu(0.0, 0.0, 1.5707963) q[2], q[1];
h q[2];
swap q[0], q[2];
measure q[0] -> c[0];
measure q[1] -> c[1];
measure q[2] -> c[2];
复制

最后更新时间:2021年12月20日

Navigated to 量易简