量子机器学习

量子计算概论

量子位元的布洛赫球表示

布洛赫球表面上的任何一点都代表一个量子位态。因此,量子位的任何广义状态|ψ〉可由三个参数γ、θ和φ表示,如下所示:|\psi >=e^{i\gamma }(cos\frac{\theta }{2}|0>+sin\frac{\theta }{2}e^{i\varphi }|1>)

我们已经看到的量子位的状态可以表示为|ψ〉= α|0〉+ β|1〉,其中α和β为复数。我们可以将任意复数α在笛卡尔坐标系中表示为α = a + ib
或者,我们可以选择将极坐标中的任何复数 α 表示为\alpha =re^{i\phi }其中r=\sqrt{a^2+b^2}

如果我们取\alpha =r_\alpha e^{i\phi_\alpha }\beta =r_\beta e^{i\phi _\beta },那么我们有以下结果: 

如果忽略全局相位因子,状态的Bloch球表示可表示为:

布洛赫球面上有无数个点,每个点对应一个量子位态。然而,在测量量子位时,如果测量在标准0−1基础上完成,我们仅观察到两种状态之一|0〉或|1〉。随后对量子位的测量继续展示被测状态。因此,如果我们测量量子位状态为∣0〉,连续的后测量将继续揭示状态∣0〉。所以,测量改变了量子位的状态。

Stern-Gerlach实验

斯特恩-格拉赫实验是最早用来理解量子位特性的实验之一。这个实验是斯特恩在1921年构想出来的,1922年他和格拉赫合作进行了这个实验。在实验装置中,向各个方向发射的热银原子通过一个准直器,以使银原子束在水平方向上排列。下一阶段,银原子束通过磁铁的两个磁极。

磁铁有一个特殊的设置,南极是平的,北极有锋利的边缘。这使得从准直器出来的银原子由于该区域的不均匀磁场而发生偏转。随后,偏转的银原子被收集到探测器屏幕上。磁铁的设计是这样的,沿着z方向的磁场,因此B\approx B_z\hat{k}一般来说,非均匀磁场B检测到原子的方式是,它们应该撞击到探测器中两个极端之间的任何位置,但它们撞击的是两个不同的位置,A和B。
银原子在穿过磁场时,受到一个力F,由势能U的负梯度给出,如图所示:F=-\triangledown U
势能是银原子的磁矩μ与斯特恩格拉赫装置的不均匀磁场B的点积的负数。因此,势能U可以写成:U=-\mu .B
将方程代入,我们将银原子所受的力的表达式简化为:

因此,我们看到当原子沿z方向的磁矩为负时,施加在原子上的力为正。正的力将把原子推到偏转屏上O点以上,而负的力将把原子推到偏转屏上O点以下的任何一点。同样,经典的z方向上的磁矩μz可以用原子的磁矩表示为:\mu _z=|\mu |cos\theta
参数θ是μ与z轴的夹角。根据上面的公式,\mu _z取+|μ|和−|μ|之间的连续值。因此,所有的原子都应该分布在这两个值之间。然而,正如前面所讨论的,这并没有发生,原子出现在两个离散的点上。让我们从一个角度来解释这个现象,以及它与角动量量子化的关系。
一个银原子有47个电子,46个电子的总角动量是零。原子的总角动量由轨道角动量和自旋角动量组成。此外,第47个电子的轨道角动量为零。因此,与银原子相关的唯一角动量是来自第47个电子的自旋角动量。我们应该能在偏转屏上得到第47个电子的自旋角动量的信号。原子核对原子角动量的贡献不大,因此可以忽略。所以,银原子的磁矩,实际上是由于第47个电子的自旋角动量。所有原子撞击的两个离散区域应该对应于固有自旋角动量,它可以取两个离散值-\frac{\bar{h}}{2},对应于O以上的离散区域,以及-\frac{\bar{h}}{2}对应于O以下的离散区域。通常,-\frac{\bar{h}}{2}对应的状态被表示为∣0〉状态。-\frac{\bar{h}}{2}被表示为∣1〉状态。因此,Stern-Gerlach实验确立了角动量是量子化的事实。Stern-Gerlach上下状态完美地匹配Bloch球表示,因此|+z〉=∣0〉,且|−z〉=∣1〉。事实上,原子的自旋角动量和轨道角动量是在这个实验中首先想到的。在这个Stern Gerlach装置中,如果原子只有轨道角动量,那么由于银原子的轨道角动量为零,人们可以预期原子束在磁场的影响下不会偏转。这个事实让物理学家相信除了轨道角动量之外,还有自旋角动量的存在。
在下图中A的Stern-Gerlach实验的示意图中,模型已大大简化,其中来自烘炉的输入束流输出两束原子∣+ Z〉和∣−Z〉。

在上图B中,我们将两个Stern-Gerlach装置串联在一起。第一装置使原子沿z方向偏转,第二装置使原子沿x方向偏转。对应于∣+ Z〉状态的原子仅通过沿着x轴的第二个设备被发送。与预期相反,我们看到在x方向有两束原子,我们可以方便地称为状态∣+ x〉和∣−x〉。只是要清楚的是,尽管x、y和z轴互相正交,状态向量∣+ z〉并不垂直于∣−x〉或∣+ x〉。

多量子

用两个经典比特,我们可以有四种状态:00 01 10和11。一个有两个量子位A和B的量子系统可以是4种状态的叠加,这些状态对应于计算基态00、01、10和11。我们可以将双量子位系统的状态表示为:
在形式∣ij〉的计算基状态中,i表示第一个量子位的基状态,j表示第二个量子位的基状态。因此,概率振幅aij表示联合状态∣ij〉。这些概率振幅属于复平面,这些振幅的平方之和应该是1。
现在让我们看看态∣ψ〉AB将发生什么,如果我们碰巧测量一个量子比特,说量子A,我们观察态|0〉。由于我们已经观察到量子位A处于|0〉态,在|1〉态中与量子位A对应的计算基态将消失。量子位A和B的新合并状态∣ψ’〉AB将如下:
当然,为了确保新状态的概率和为1,我们需要对新状态的组成振幅进行归一化。

贝尔态

最有趣的双量子位态之一是如下所示的状态:
这个态是态∣00〉和∣11〉同等比例的叠加。如果我们观察量子位A并测量其态为∣0〉,那么双量子位坍塌为态∣00〉。如果我们现在测量量子位元B的状态,那么我们只能找到量子位B一个状态就是∣0〉。类似地,如果我们测量量子位A处于状态∣1〉,双量子位状态坍塌为∣11〉。在这种状态下,如果我们对量子位B进行测量,我们将发现它在状态∣1〉中具有100%的确定性。方程中两个纠缠量子位元的叠加态也被称为贝尔态。在这个贝尔态中,我们可以观察到,两个量子位的状态是完全相关的,这种量子现象被称为量子纠缠。想象一下,我们用两个电子之间的量子纠缠来创造Bell态,然后我们把这两个电子分开一段距离。现在,如果我们测量一个电子并观察它处于状态∣0〉,那么另一个电子如果被测量也将处于状态∣0〉,即使它们被很远的距离分开。贝尔状态引起了包括爱因斯坦在内的研究人员的极大兴趣。

多量子态



狄拉克符号

在量子力学中,量子系统的状态存在于复希尔伯特空间中。希尔伯特空间是一个具有内积范数的向量空间。它也是一个完全的矢量空间,在那里量子态序列的收敛不会是一个问题。在这里,我们不打算过多地讨论完全向量空间的定义。不熟悉完全向量空间的读者可以把它们想象成量子系统可以获得的所有可能状态的空间。

右矢

根据Dirac向量符号,与量子状态相关的列向量表示为∣ψ〉。向量的这种符号表示称为Ket表示。

左矢


观察列向量被转置为行向量,振幅被转换为它们的共轭复数。对于一个复数(a + i b),它的共轭复数由(a - i b)给出。如果一个Ket向量只有实数的概率振幅,那么相应的Bra向量就是它的转置。

内积

矢量的级数

希尔伯特空间中一个向量的大小也称为这个向量的l^2范数,它被定义为向量与自身的内积的平方根。就Ket和Bra符号而言,向量|ψ〉的范数如下:

ci∗是ci的复共轭,向量|ψ〉∈\mathbb{C}^n的第i个分量。一个量子状态|ψ〉的内积〈ψ|ψ〉等于1。振幅|c_i|^2的平方属于状态∣ψ〉坍塌到状态∣i〉测量的概率。由于计算基础是互斥和穷举的,因此它们对应的概率之和应为1,因此由式1-37和1-38可得:

外积

张量积


张量积为我们提供了一种从两个或多个现有向量空间创建更大向量空间的便捷方法。如果我们有一个向量空间 V ∈\mathbb{R}^m,其基为 { |v_1〉, ∣v_2〉… ∣v_m〉} 和另一个向量空间 U ∈\mathbb{R}^n,其基为 { |u_1〉, ∣u_2〉… ∣u_n〉} ,然后通过使用张量积,我们可以得到一个更大的向量空间 W ∈\mathbb{R}^{m\times n},其中 m × n 个基集元素,形式为 ∣v_i〉 ⊗ ∣u_j〉。为了方便起见,我们将基向量∣v_i〉 ⊗ ∣u_j〉 写为 ∣v_iu_j〉。
张量积在量子计算中很重要,因为它们允许我们从几个量子比特的单个状态中创建量子态。为了便于说明,我们考虑由 |\psi _1〉 = \alpha _1|0〉 + \beta _1∣1〉 给出的量子位 A 的状态,以及由 |\psi _2〉 = \alpha _2|0〉 + \beta _2∣1〉 给出的量子位 B 的状态。它们的组合状态可以表示为两个状态的张量积,如下所示:
需要注意的一点是,并非所有的多量子比特状态都可以表示为单个量子比特状态的张量积。一个经典的例子是贝尔态\frac{1}{\sqrt{2}}|00>+\frac{1}{\sqrt{2}}|11>,它不能被分解为单个量子比特态的张量积。这发生在量子位处于纠缠态时。

单量子比特门

在量子计算中,人们应该能够操纵量子系统的状态。就像在经典系统中一样,我们通过不同的门来操纵比特的状态,如OR,AND,NOT,XOR等。在量子计算中,我们使用量子门来操纵量子比特的状态。让我们先来看看非门的量子等价物。

量子非门

经典的NOT门在现有状态为0时将位的状态更改为1,反之亦然。量子门做类似的事情,但在量子位计算基础状态的振幅方面。它将∣0〉态的概率振幅分配给∣1〉态,反之亦然。量子NOT门作为算子X工作,如下图所示:X:\alpha|0>+\beta |1>\rightarrow \beta |0>+\alpha|1>
如果我们在计算的基础上把量子位的状态表示为矢量,那么我们有:X:\begin{bmatrix} \alpha \\ \beta \end{bmatrix}=\begin{bmatrix} \beta \\ \alpha \end{bmatrix}

现在让我们试着解码X的矩阵表示形式。从公式可以看出,X将一个向量变换成另一个相同维数的向量,因此X可以表示为一个方阵。一个方阵将二维向量的分量倒转就是矩阵X,如下所示。X=\begin{bmatrix} 0 & 1\\ 1 & 0 \end{bmatrix}
在量子门的变换下,总概率应该是守恒的。对于NOT门,我们可以看到概率是守恒的。一般来说,为了保证概率守恒,任何量子门只需要遵守一个性质即可:它们应该是酉矩阵。
当且仅当下列关系式成立时,具有实数项的矩阵U称为酉矩阵:UU^T=U^TU=I
矩阵U^T是矩阵U的转置,而I是单位矩阵。在量子力学中,酉算子和状态空间分量都可以是复数。对于具有复数项的酉矩阵 U,UU^{*T}=U^{*T}U=I,其中U^{*T}是矩阵 U 的复共轭转置。

任何可逆矩阵 U 乘以它的逆矩阵U^{-1}都会得到单位矩阵,并且矩阵乘法是可交换的。UU^{-1}=U^{-1}U=I

比较上面两个方程,我们可以看到任何酉矩阵 U 的逆U^{-1}都是其复共轭转置U^{*T}。既U^{-1}=U^{*T}
矩阵U^{*T}通常用U^\dagger表示,因此对于酉矩阵,一般可以写出以下形式:U^{-1}=U^\dagger

现在让我们做一些数学计算,看看在量子系统的状态下,概率之和是否真的守恒。
当应用幺正变换U时,让量子系统的状态∣u_1〉变为状态∣v_1〉(参见图1-6)。
每个计算基状态对应的概率总和为1,因此我们可以写〈u_1|u_1〉= 1。对量子态 ∣u_1〉 应用酉变换 U 后,新状态为 |v_1〉 = U ∣u_1 〉。 ∣v_1 〉 的左矢表示为 〈v_1∣ = 〈u_1U^\dagger。现在状态 |v_1〉 中每个计算基础状态的概率之和如下:
由于对于酉矩阵U^\dagger U=I,公式简化为:
由于两个向量的点积在幺正变换下是不变的,因此两个向量之间的距离也保持不变,因为两个向量之间的距离只不过是点积的线性和。

Hadamard门

Hadamard 门作用于状态 |0〉 的量子位,并将其带到\frac{1}{\sqrt{2}}|0>+\frac{1}{\sqrt{2}}|1>的等叠加状态。它还将状态 |1〉 转换为状态 \frac{1}{\sqrt{2}}|0>-\frac{1}{\sqrt{2}}|1>。哈达马门对应的酉矩阵如下:H=\frac{1}{\sqrt{2}}\begin{bmatrix} 1 & 1\\ 1 & -1 \end{bmatrix}

就布洛赫球体表示而言,哈达马门将沿 z 轴对齐的状态 |0〉 变为沿正 x 轴对齐的状态 \frac{1}{\sqrt{2}}|0>+\frac{1}{\sqrt{2}}|1>。 (见图 1-7。)

需要注意的一件事是,如果我们连续两次应用阿达玛门,量子位元的状态保持不变。这是因为阿达玛矩阵H^2的平方等于单位矩阵。

量子Z门

量子Z门使状态∣0〉没有变化,而它将状态∣1〉改变为−|1〉。量子Z门的变换表示如下:Z=\begin{bmatrix} 1 & 0\\ 0 & -1 \end{bmatrix}
因此,给定任意状态 |ψ〉 = α|0〉 + β∣1〉,Z 门会发生变化并将其转换为 α|0〉 − β∣1〉。量子 Z 门可以用计算基础状态的外积写成如下:

多量子比特门

当我们想到2位经典门时,我们会想到AND,XOR,NAND和NOR门。事实上,在经典计算范式中,NAND门被称为通用门,因为任何其他位上的门都可以通过组合NAND门来构建。帮助我们构建通用量子门的两种量子比特门之一是条件非门,或CNOT门,下一节将介绍。

CNOT门

CNOT门作用在两个量子位上:量子位A,被称为控制量子位,量子位B,是目标量子位。在应用一个CNOT门,控制量子位状态保持不变。如果控制量子位处于状态∣1〉,目标量子位状态被翻转。
两个量子位的计算基础状态是它们对应的基础状态的张量积。例如,当两个量子位都处于零状态时的双量子位状态由|0>_A\otimes |0>_B给出。我们简化符号,将状态|0>_A\otimes |0>_B写为 ∣00〉。表 1-2 显示了应用 CNOT 门时量子位计算基础状态如何变化。
学习量子门如何转换计算基态的想法是有用的,因为量子门是线性算子。这使得我们可以线性累加对应于计算基态的转换态,以理解叠加态上量子门的转换。因此,对于作用于量子位状态α|0〉+ β|1〉的幺正算子U(适用于任何线性算子),我们可以这样写:
现在,如果我们仔细看表1-2,我们可以看到,应用CNOT门后的目标量子位的状态是什么都没有,但在应用CNOT门之前,两个量子位的状态的模2相加。因此,对两个量子位的CNOT操作可以表示如下(见图1-8):

CNOT门U_{CN}的矩阵表示是4×4方阵。
U_{CN}=\begin{bmatrix} 1 & 0 & 0 &0 \\ 0 & 1 & 0 &0 \\ 0 & 0 & 0 & 1\\ 0 & 0 & 1& 0 \end{bmatrix}

如果我们只考虑目标量子位的输出,在某种意义上,异或门可以被认为是量子CNOT门的经典对应物。异或门的输出只不过是它的两个输入位A和b的模相加。然而,与CNOT门不同的是,异或门是不可逆的。任何幺正的量子门操作都是可逆的,因此通过应用幺正门的逆变换,我们可以恢复量子系统的原始状态。应该注意的是,酉变换的逆也是酉变换。
经典的异或门是不可逆的,因为给定异或门的输出,我们无法确定它的两个输入。然而,我们可以传递其中一个位,比如位A,作为一个额外的输出,使异或门可逆。(如图1-9所示)
在几种多量子位门中,CNOT门的特殊之处在于任何量子门都可以用CNOT门和一个或多个单量子位门来构建。换句话说,CNOT和单量子位门形成了一个通用的量子门集合,我们可以用它构造任意精度水平的任意给定量子门。

受控U门

另一个值得特别提到的多量子位门是受控u门(见图1-10)。假设我们有一个幺正算子U作用于n个量子位的量子系统。我们可以把受控U门想象成一种基于控制量子位的状态将酉算子U应用到n个目标量子位的系统上的门。当控制量子位处于状态∣1〉,幺正算子应用于n目标量子位的系统,而当控制量子位处于∣0〉状态,没有在n目标位的系统上应用转换。实际上,CNOT门是受控u门的一种特殊情况,其中幺正算子是单量子位X门。

复制量子位:不可克隆定理

在经典的计算范式中,复制一点信息是微不足道的。我们可以有一个经典的CNOT门,它把要复制的输入位作为控制位,把一个被初始化为零的位作为目标位来完成一个位复制机制。换句话说,一个经典的CNOT门只不过是XOR门,就像我们之前建立的那样。参见图1- 11。
现在让我们看看我们是否可以使用CNOT门复制一个量子位|ψ〉的状态。两个量子位的输入状态可以写为:
在应用CNOT时,双量子比特系统的新状态改变为α|00〉+ β∣11〉。现在让我们看看我们是否能够复制量子位的状态∣ψ〉。如果我们成功复制了量子位,那么两个量子位的输出状态将是
比较CNOT α|00〉+ β∣11〉的双量子比特输出状态和方程1-64,我们看到,CNOT不可能复制状态∣ψ〉,除非αβ = 0。条件αβ = 0仅当α或β为0时才满足。条件α = 0适用于状态|ψ〉=∣1〉,而条件β = 0适用于条件|ψ〉= |0〉。这告诉我们,我们不能复制量子态,除非它处于计算的基本态之一。事实上,我们可以将一个量子位的观测推广到任意数量的量子位的量子系统。这种量子位元的未知叠加态不能被复制的特性被称为不可克隆定理。
如前所述,如果量子位状态处于计算基状态之一,我们可以复制量子位。假设量子位处于状态|ψ〉=∣1〉。那么CNOT gate的输出将为∣11〉,这将等于状态|ψ〉|ψ〉=∣11〉。

不同基的测量

到目前为止,在讨论量子位状态的测量时,我们仅研究了规范计算基础状态|0〉和∣1〉。更准确地说,我们已经将量子比特的状态表示为|ψ〉= α|0〉+ β∣1〉。当我们在计算基础上进行测量时,要么我们得到一个0,具有概率|α|2,使量子位的测量后状态为∣0〉,要么我们得到一个1,具有概率|β|2,使量子位的∣1〉的测量后状态。我们可以在其他正交基状态以及例如∣+〉和∣−〉基状态表示量子位,其中

或者,我们可以根据∣+〉和∣−〉状态表示状态∣0〉和∣1〉,如下:

现在,如果我们在| +〉的基础上测量量子比特的状态,或者我们将观察+状态,且有概率|α + β|2使测量后状态为∣−〉,或者我们将观察-状态,且有概率|α−β|2使测量后状态为∣−〉。一般情况下,我们可以将量子位的状态写在任何线性独立的基中表示|ϕ1〉,∣ϕ2〉,比如|ψ〉= α1 |ϕ1〉+ α2 |ϕ2〉。
在图1-12中,我们说明了测量量子状态∣ψ〉的电路表示。在测量时,量子态会坍缩到用于测量的计算基态之一。例如,对于一个量子位状态,我们可能选择在|0〉,∣1〉中测量,因此测量输出将是0或1状态。类似地,如果我们选择在|+〉,∣−1〉中测量量子位状态,输出状态将是+状态或-状态。

贝尔态量子门

当两个量子位A和B像贝尔态一样相互纠缠时,就不可能分离单个的量子位态。换句话说,我们不能将贝尔态表示为各个量子位态的张量积,如下所示:
如果我们对量子比特A进行测量,我们得到一个0,有0.5概率使测量后状态为∣00〉,或者我们得到一个1,有0.5概率使测量后状态为∣11〉。在随后的量子位B的测量中,如果量子位A的状态为0,我们得到0的概率为1。类似地,如果量子位A处于状态1,我们就有1的概率得到量子位B的状态1。所以,在贝尔态的量子位元的状态是相互关联的。

现在让我们看看我们如何从量子门创建贝尔态。我们可以通过在∣0〉状态初始化的两个量子位x和y来创建Bell状态。我们通过第一个量子位通过Hadamard gate(见图1-13),它将量子位x转换为|+〉状态,

量子比特上的Hadamard gate变换(H)表示∣0〉和∣1〉可被推广如下:


将x, y∈{0,1}的不同值代入方程1-71,可以得到不同的Bell态,如表1-3所示。

量子隐形传态

量子隐形传态是一种不需要任何通信通道就能在发送端和接收端之间传输量子态的量子计算技术。
为了说明量子隐形传态,我们将量子态的发送方称为爱丽丝,量子态的接收方称为鲍勃。我们将用一个故事来说明量子隐形传态。Alice 和 Bob 在童年时期共享贝尔状态 |\beta _{00}〉,其中第一个量子位 Q_2属于 Alice,量子位 Q_3属于 Bob。由于工作原因,鲍勃不得不搬到另一个城市。现在爱丽丝想与鲍勃分享一些信息:第三个量子位 Q_1状态∣ψ〉。
图1-15所示为量子隐形传态电路。需要注意的一件事是,单电路线不是物理线。它们仅仅描述了不同量子位门运行所相对的时间的流逝。测量后的双线用于描述测量量子位状态后继承的经典信息。
Alice 和 Bob 使用最初处于状态 |0〉 的量子位 Q_2Q_3,通过使用哈达玛门的量子电路,然后在时间t=t_0时应用 CNOT 门,达到贝尔状态 |\beta _{00}〉。现在Alice想要将量子位Q_1状态∣ψ〉发送给Bob。
如果我们观察任意时刻 t 的三量子位状态 ∣\psi _0〉,其中t_0<t<t_1,则可以写成如下:

在时间t=t_1时,Alice 的量子位 Q_1Q_2分别是 CNOT 门的控制量子位和目标量子位。 CNOT 门会改变叠加态 ∣\psi _0〉 中不同的计算基础状态,如下所示:

因此,任意时刻 t 的状态∣\psi _1〉,其中t_1<t<t_2,可以写成如下:

现在,在时间t=t_2时,Hadamard 门应用于第一个量子位,因此在任何时间 t(其中t_2<t<t_3),三个量子位的组合状态 |\psi _2〉 可以表示如下:

展开公式中的项,我们得到状态 ∣\psi _2〉,如下所示:

由于在时间t=t_3时我们将测量 Alice 的量子位,因此根据 Alice 量子位的计算基础状态来排列状态 |\psi _2〉 是有意义的,即 |00〉、|01〉、|10〉、| 11〉。重新排列公式 1-79 中的各项,我们得到:

现在,一旦我们在时间t=t_3对 Alice 的量子位进行测量,我们将测量它们处于四种计算基础状态之一,而 Bob 的量子位的状态将是与之纠缠的状态。例如,如果我们测量 Alice 的两个量子位均为 0,即 M_1=0M_2=0,那么 Bob 的量子位的状态就是与状态 ∣00〉 相关的状态,即 (α|0〉 + β) ∣1〉)。这是 Alice 希望发送给 Bob 的状态。
现在,假设我们测量M_1=1M_2=1。那么 Bob 的状态就是与状态 ∣11〉 相关的状态,即 (α|1〉 − β∣0〉)。这并不是理想的状态。然而,这些变换在鲍勃的量子比特上排列起来;即,X^{M_2}Z^{M_1}将负责将 (α|1〉 − β∣0〉) 转换为所需状态 (α|0〉 + β∣1〉)。
在这种情况下,X^{M_2}=X只不过是具有以下矩阵表示的量子非门:X=\begin{bmatrix} 0 &1 \\ 1 & 0 \end{bmatrix}
这会翻转概率幅度,因此在应用 X 门时,状态 (α|1〉 − β∣0〉) 将转换为 (α|0〉 − β∣1〉)。接下来,Bob 的量子位将通过Z^{M_1} = Z门,这只会翻转与状态 |1〉 相关的相位。这会将量子位状态 (α|0〉 − β∣〉) 转换为所需的量子位状态 (α|0〉 + β∣1〉)。
表 1-4 列出了与 Alice 量子位测量相对应的所有四种可能性。它们每个都产生 Bob 量子位的最终状态为 (α|0〉 + β∣1〉)。

量子并行算法

量子并行性允许人们同时评估多个不同输入值的函数。假设我们有一个函数 f(x),其中 x 接受 n 个不同的值。通过开发适当的酉变换,人们可以使用量子计算机同时计算 x 的所有可能值的 f (x)。许多量子算法利用量子并行性。参见图 1-16。
假设我们要计算一个具有二元定义域和值域的函数 f(x),即 f : X ∈ {0, 1} → {0, 1}。
评估该函数的一种便捷方法是从相等叠加态|x>=\frac{1}{\sqrt{2}}|0>+\frac{1}{\sqrt{2}}|1>作为数据输入,并以初始化为状态 |y〉 = ∣0〉 的量子位作为目标。使用适当的酉门U_f,我们将联合状态 ∣x, y〉 转换为 ∣x, y ⊕ f(x)〉,其中 ⊕ 表示模 2 加法。
应用酉门U_f后的输出状态可以展开如下:
方程 1-81 中的状态是一个有用的状态,其中 f (0) 和 f(1) 作为分量,与其相应的输入纠缠在一起。就好像我们通过为函数域中的所有值创建叠加状态来在其整个域上立即评估该函数。这种量子现象称为量子并行性。
现在的问题是,我们如何从这个叠加状态∣ψ〉得到函数评估?
正如我们已经建立的,为了能够从给定的状态中提取任何信息,我们需要执行度量。如果我们将数据量子位测量为0,我们将状态崩溃为∣0,f(0)〉。现在,如果我们对第二个量子位进行测量,我们肯定能得到f(0)的值,这是百分之百确定的。类似地,如果我们在第二个量子位上测量到第一个量子位为1,我们肯定会测量f(1)的值。
我们可以将这种方法推广到其域中具有多个输入值的函数。假设我们有一个函数,其域中有N=n^2个值,使得f:X\in \left \{ 0,1,2,...,2^n-1 \right \}\rightarrow \left \{ 0,1 \right \}
我们可以通过在 n 个量子位系统上使用 Hadamard 门来创建所有2^n个值的相等叠加状态作为计算基础状态。为了说明这个想法,我们从最初处于 ∣0〉 状态的两个量子位开始(见图 1-17)。对它们中的每一个应用 Hadamard 门,我们得到以下结果:



因此,我们可以看到,通过在 ∣0〉 状态初始化的 2 个量子位上使用 Hadamard 门,我们能够获得四个计算基础状态的相等叠加。我们可以用整数表示来表示计算基础状态的“二进制字符串”表示,如下所示:
现在,如果我们从初始化为 ∣0〉 状态的 n 个量子位开始,而不是两个量子位,那么通过对每个量子位应用哈达玛变换,我们得到以下叠加状态:


因此,我们可以看到,通过使用 n 个量子位,我们可以同时评估一个函数在其域中的 2n 个输入。当然,为了得到函数值,我们必须对状态 |ψ〉 进行测量,每次测量都会产生输入 x 及其对应的函数值 f(x)。

量子干涉

如前所述,在量子计算算法中,目标是使量子系统状态给出的概率分布偏向于一个或多个结果。让我们用一个例子来讨论量子干涉。

总结

至此,我们进入了第一章的结尾。在本章中,我们介绍了量子位(量子计算的基本单位)的大量基础知识。此外,我们还讨论了纠缠和叠加的重要量子力学性质。此外,我们还研究了几个重要的单量子位和多量子位门,它们对于操纵量子位的状态非常重要。在本章末尾,我们讨论了贝尔态、与量子隐形传态相关的概念以及量子并行性。
您将在接下来的章节中看到,量子并行性是多个量子计算和量子机器学习应用中的重要组成部分。在下一章中,我们将讨论量子计算和量子机器学习背景下所需的线性代数的重要思想,研究量子力学的假设,然后更详细地研究量子系统中的测量。最后,我们将以一些重要的量子计算算法来结束本章,以进一步了解量子计算及其相关算法的强大功能。

量子计算的数学基础和假设

量子力学比经典力学更基础,它在微观和宏观层面上都起作用。然而,对于高速运动的微观域中的粒子和系统,量子力学的表现变得更加重要。关于量子力学的解释方面仍然存在问题。然而,在操作层面上,它可以高精度地处理各种现象。量子力学的数学比经典力学简单得多,而且作为一种计算装置,量子力学已经取得了巨大的成功。在本章中,我们将讨论线性代数中的一些主题,然后转向量子力学的假设。

线性代数主题

由于量子系统的状态存在于希尔伯特空间中,并且状态上的算子是线性的,因此线性代数在量子力学的研究中变得至关重要。在第一章中,我们讨论了线性代数中的一些主题,以了解量子力学和量子计算。然而,更严格的线性代数知识对于理解量子力学和量子计算至关重要。在本章中,我们将研究线性代数中的具体思想,这些思想是量子态、量子演化和量子测量思想的核心。

向量的线性独立性

如果一个向量不能表示为另一个向量的线性缩放,则这两个向量 |v1〉 和 |v2 〉 被称为线性无关。从数学上来说,如果 |v1〉 ≠ k|v2 〉 对于某个常数 k,|v1〉 和 |v2 〉 是线性无关的。一组 n 个向量 |v1 〉,|v2 〉…。 |vn〉 \in \mathbb{R}^m 如果它们中没有一个可以表示为其他的线性组合,则称它们是线性无关的。要确定给定的 n 个向量集是否线性无关,当且仅当每个线性系数 c1 到 cn 为零时 c1 |v1〉 + c2 |v2〉 + …cn |vn〉 = 0。如果我们将向量 |v1〉 到 |vn 〉 排列为矩阵 A 的向量,我们可以将 c1|v1〉 + c2 |v2〉 + … + cn |vn〉 = 0 表达如下:
仅当系数向量 [c1, c2....cn]T 为零,如果通过列向量 |v1〉 到 |vn 〉 形成的矩阵是满秩的,则这是可能的。如果维度为 m × n 的矩阵 A 的秩等于 m 和 n 中的最小值,则称其为满秩。为了使公式 2-1 中的矩阵成为满秩,其秩必须为 n(假设 m > n)。如果矩阵是 n × n 方阵,我们可以通过确保矩阵的行列式非零来验证该矩阵是满秩的。
如果一组 n 个向量 |v1 〉, |v2 〉, . 。 |vn 〉 ε ℝn 是线性无关的,向量跨越整个 n 维向量空间。跨越n个向量意味着可以通过n个向量的线性组合来产生不同的其他向量。因此,使用一组 n 个线性无关向量,可以产生\mathbb{R}^n中所有可能的向量。如果向量 |v1 〉, |v2 〉, . 。 |vn 〉 不是线性独立的,那么它们将跨越\mathbb{R}^n内的更小的子空间\mathbb{R}^k。让我们尝试用一个例子来说明向量跨度的概念。
假设我们有一个向量|v1〉= [1,2,3]T。使用这个,我们可以在三维空间中只跨越一个维度,因为所有向量都将是a∣v1〉的形式,其中a是标量乘数。
现在,如果我们采用另一个向量|v2〉= [5 9 7]T,它不是∣v1〉的标量乘数,我们可以采用a|v1〉+ b∣v2〉的形式的线性组合,在三维向量空间中跨越一个二维子空间,如图2-1所示。
现在,如果我们将另一个向量|v3〉= [4 8 1]T到我们的向量集,我们可以跨越整个ℝ3向量空间,因为|v1〉,∣v2〉,和∣v3〉是线性独立的。如果我们将∣v3〉视为∣v1〉和∣v2〉的线性组合,那么它不可能跨越整个三维空间。我们将被限制在由∣v1〉和∣v2〉跨越的二维子空间。

基向量

一组n个线性独立的向量|v1〉,|v2〉,....|vn〉形成了表示n维向量空间中任何给定向量的基础。使用n个基向量的线性组合一次就可以在n维向量空间中创建任何向量。

标准正交基

当一个向量空间的基集合中的向量元素彼此正交时,我们就说它有一组标准正交基。一组基向量|ϕ1〉,|ϕ2〉......∣ϕn〉被认为形成一个标准正交基,如果以下情况成立:\left \langle \phi _i|\phi _j \right \rangle=\delta _{ij}

我们不需要明确地引用线性无关性作为正交基的条件,因为向量的正交性总是保证向量的线性无关。
在量子力学中,我们总是用标准正交基来表示希尔伯特空间中的量子态。

线性算子

量子态存在于复杂的希尔伯特空间中。在线性和酉算子的作用下,量子态从一种态演化到另一种态。
由于任何向量都可以表示为其基向量的线性和,因此要理解线性算子如何变换向量空间中的任何给定向量,只需知道线性算子如何变换其基向量就足够了。当向量 |v〉 和 |w〉 的维度匹配时,我们可以将 A 视为从 V 到 V 的线性算子。
向量空间上的两个平凡算子是使向量保持不变的单位I算子和将任意向量变换为0向量的零算子。
如果A是一个从向量空间V到向量空间W的线性算子,如果B是一个从向量空间W到向量空间Y的线性算子,那么可以通过组合来定义一个线性算子BA,该组合将向量|v〉∈V映射到向量| Y〉∈Y,如下所示:

将线性算子解释为矩阵




因此,方程2-9描述了基元素与线性算子Aˆ或它对应的矩阵A关于这两个基底的关系。一般来说,线性算子也可以看作是关于通常基的一个矩阵。在本书中,我们不会对线性算子及其相应的矩阵作任何区别。除非另有说明,否则矩阵变换是关于通常的基的。在量子力学中,线性算符是方阵,因此向量空间V上的线性算符可以被认为是从V到V的变换。此外,对于形式为a: V→V的线性算符,在没有明确规定的情况下,我们将假设通常的基。
既然我们在定义线性算子和它们对应的矩阵时特别注意基,让我们花点时间来学习量子位态的通常基。对于单量子比特系统,通常的基向量为|0〉= [1 0]T且|1〉= [0 1]T。
类似地,对于两个量子比特系统,通常的基向量将是单个量子比特通常基状态的张量积,即,|i〉⊗∣j〉,其中i表示量子比特1的通常基状态,j表示量子比特2的通常基状态。我们可以有四种这样的组合:|0〉⊗|0〉,|0〉⊗|1〉,|1〉⊗∣0〉,且|1〉⊗∣1〉。它们的列向量表示可以通过展开张量积得到。示例:|1〉⊗|0〉= [0 1]T⊗[1 0]T = [0 0 1 0]T。通常,对于一个n-量子比特系统,将存在2n个基状态向量,其形式为|ko〉⊗|k1〉⊗|k2〉…⊗∣kn−1〉,其中ki表示第i个量子比特的基向量。

外积形式的线性算子




Pauli 算子及其外积表示

我们在第一章中简要地讨论了泡利矩阵。四个泡利矩阵是线性运算符,相对于计算基∣0〉和∣1〉。

将泡利矩阵表示为外积的最简单方法是确定计算基础状态向量在泡利矩阵运算时的变换。例如,如果我们采用泡利矩阵 σz ,它将基础状态 ∣0〉 转换为 ∣0〉 ,并将基础状态 ∣1〉 转换为 − ∣1〉。因此,根据公式 2-11,我们可以写出以下内容:

线性算子的特征向量和特征值

向量空间 V 上的线性算子 A 的特征向量是向量 ∣v〉,使得 A∣v〉 = λ∣v〉。这里,λ是特征值,∣v〉是特征值λ对应的特征向量。图 2-2 显示了特征向量的变换。
我们可以通过求解det| a−λI| = 0给出的特征方程来求得线性算子a的特征值。线性算子A的特征方程对应的特征函数定义为c(λ) = det∣A−λ i∣。特征方程自然地来自于特征向量方程,如下所示:
公式2-17可以有两个解,微不足道的一个是|v〉= 0。然而,更有趣的解是当(A−λI)的列向量不是线性无关时。在这种情况下,矩阵(A - λI)不是满秩的,因此它的行列式det(A - λI)应该是零。这就给出了特征值解的著名特征方程如下:

算子的对角线表示

如果∣k〉表示的算子A的特征向量是正交的,其对应的特征值用λk表示,则算子A可以表示为:
这种表示法称为算子的对角线表示法。对应于算子A的矩阵是对角线的如果算子以特征向量作为基用对角线矩阵的形式表示的话。并不是所有的矩阵或运算符都有对角线表示。这里所示的线性算子A对于通常的计算基础具有对角线表示:
在这种情况下,特征向量∣0〉和∣1〉对应于特征值3和4。我们再看另一个算子它关于通常基的表示是由泡利矩阵σx表示的。

算子的伴随


伴随算子也称为厄米共轭算子。在第一章中,我们将伴随算子称为算子的共轭转置,因为如果我们引用算子的矩阵表示法,那么它正是如此。向量 |v〉 的共轭转置,我们表示为 〈v|也可以用伴随符号 |v〉† 来表示。
伴随算子的一些性质在这里概述:
对于两个线性算子A和B, (AB)†= B†A†。
一个算子的伴随子的伴随子返回同一个算子。换句话说,(A†)†= A
一般情况下,算子A与其伴随的A†是不相等的。类似地,在一般情况下,算子A和它的伴随算子不是可换的;即通常AA†不等于A†A。

自伴或厄米算子

当运算符 A 等于其伴随运算符时,即 A = A+,则该运算符被称为自伴随运算符或 Hermitian 运算符。 Hermitian 算子的一些相关属性如下:
厄米算子总是具有实数特征值。
对于非简并的厄米算子,即每个特征值仅对应于一个特征向量,厄米算子的特征向量彼此正交。

普通运算符

如果线性算子 A 与其伴随 A† 可交换,则称其为正规算子 A。因此,对于普通算子来说,AA† = A†A。这里概述了普通运算符的一些重要属性:
厄米算符A自然是一个正规的算符,因为对于厄米算符A = A+,因此关系AA†= A†A总是成立的。然而,正规算子不一定是厄米特算子。
正规算子可以进行谱分解。在谱分解形式中,可以将一个正规算子A表示为。其中,λk表示特征向量∣k〉对应的特征值。我们将在后面的章节中更详细地讨论谱分解。

酉算子

我们在第一章详细讨论了酉算子,因为量子系统状态上允许的所有变换本质上应该是酉算子。对于任何酉算子 U,我们知道 UU† = U†U = I,它自动满足正规算子的条件:UU† − U†U = 0。因此,所有酉算子都是正规算子。因此,正规算子族同时包含厄米算子和酉算子,如图 2-3 所示。此外,多个酉算子可以是Hermitian算子,反之亦然。例如,Hadamard 矩阵既是酉矩阵又是 Hermitian 矩阵。

线性算子的谱分解


这称为线性算子的谱分解,其中正规算子的特征值和相应的特征向量分别为λk和|k〉。我们在第 1 章中广泛使用的 Hadamard 门是一个普通算子。


线性算子的迹

线性算子的迹可以定义为其对角线项的总和。矩阵迹的一些性质如下:
线性算子的特征值之和等于算子的迹。
如果 ∣u〉 和 ∣v〉 是向量空间 V 中的两个向量,并且 A 是 V 上的运算符,那么我们有:

向量张量积的线性算子

如果 A 和 B 分别是向量空间 V 和 W 中向量 ∣v〉 和 ∣w〉 上的线性算子,则向量 |v〉 ⊗ ∣w〉 上的线性算子由 A ⊗ B 给出。 线性算子 A ⊗ B 对 |v〉 ⊗ |w〉 的作用如下:
因此,A ⊗ B 可以被认为是由 V ⊗ W 给出的向量空间 V 和 W 的张量积的线性算子。



普通算子的功能


指数函数在量子力学中至关重要,正如我们将在本章后面的量子力学假设中看到的那样。我们可以如下定义普通算子 A 上的指数函数,其中 c ∈ ℂ 是任意常数。根据公式 2-38,我们可以将 exp(cA) 写成如下:





换向器和反换向器算子


对于两个可交换的算子,换向算子为零。如果两个运算符交换,则可以同时对它们进行对角化。

量子力学假设

在本节中,我们将介绍量子力学的基本假设。这些假设充当了物理量子世界和量子力学数学公式之间的桥梁。

假设 1:量子态

量子系统的状态由复希尔伯特空间中的向量 |ψ〉 表示。希尔伯特空间是配备有由内积导出的范数的完全向量空间。
状态向量∣ψ〉包含给定时间量子系统的所有信息。

根据我们选择的基础,状态可以代表不同的物理可观测值。例如,我们可以查看相对于 ∣0〉 和 ∣1〉 计算基础状态的量子位状态,并将量子位表示为 |ψ〉 = α|0〉 + β ∣1〉。这里α和β是状态|0〉和|1〉对应的概率幅,量子位处于∣0〉和|1〉的叠加。

假设 2:量子进化


在方程 2-49 中,U(t1 , t0) 是将量子系统从状态 |ψ(to)〉 带到 |ψ(t1 )〉 的酉算子。

量子态时间演化的薛定谔方程

让我们尝试看看酉算子 U(t1 , t0) 与量子力学最重要的方程之一:薛定谔方程的关系。

在上式中, ℏ 是归一化普朗克常数,等于 h/2π ,其中 h 是普朗克常数。这里的术语 H 指的是封闭量子系统的哈密顿量,不要与哈达玛变换混淆。

特征值特意表示为 Ek 以表示能量。我们用 ∣Ek〉 表示相应的本征态。处于最低能量状态的量子系统将处于对应于最小能量本征值 Emin 的本征态 ∣Emin〉 。由于哈密顿算子是厄米算子,因此我们只能有真实的能级。

表达式 e^###是酉算子,它将具有哈密顿量 H 的量子系统从时间 t0 的状态 |ψ(t0)〉 转变为时间 t1 的 |ψ(t1 )〉。它正是方程 2-49 中的酉算子 U(t1 , t0),因此我们可以说:

基本上,U(t1, t0)与H具有相同的特征向量∣Ek〉与特征值e^###是哈密顿特征值Ek的指数版本。

假设 3:量子测量

我们之前已经确定,我们可以用代表某些可测量物理量的合适正交基来表达状态。状态|ψ〉一般可以表示为这些正交基状态的叠加。如果我们尝试测量 ∣0〉 和 |1〉 基本状态中量子位的状态,假设量子位为 |ψ〉 = α|0〉 + β ∣ 1〉,则测量将产生状态 0 或 1 之一。
测量产生状态 0 的概率为 |α|2,而状态 1 的概率为 |β|2。
量子位的测量后状态是测量的基础状态。例如,如果我们再次测量量子位状态为∣0〉,我们将得到相同的状态∣0〉。
当我们进行测量时,量子系统不再封闭,因为它与测量过程相互作用。因此,在测量时,量子态不再根据薛定谔方程演化。

一般测量算子



该完整性方程来自这样一个事实:与集合 {Mk} 中不同测量算子相关的概率之和应为 1。可以通过对方程 2-55 所示的不同结果的概率求和来证明这一点。


到目前为止,我们还没有对这些测量算子{Mk}的结构做出任何假设。只要它们满足完整性方程并产生有效的正概率值,它们就是有效的测量算子。现在让我们看看当您计划对不同的计算基础状态进行测量时如何定义这些测量运算符。如果您使用正交计算基础状态 {| ψk 〉},则可以将测量算子定义为 Mk = |ψk〉〈ψk |。

测量算子的一些重要属性如下:
测量算子是厄米算子。


投影测量算子

投影测量是一种组合各个测量算子 P0 、 P1 、PN − 1 对应于正交基向量 |ψ0〉, |ψ1 〉, 。 。 ∣ ψN − 1 〉等的方法。投影测量算子 M 是 Hermitian 算子,其表示形式如下:

请注意,虽然与各个基态相关的运算符 P0、P1、...PN − 1 是酉的,投影测量算子 M 不是酉算子。







投影测量算子可用于计算可由正交基表示的结果的统计属性。例如,我们可以根据量子系统的状态 |ψ〉 计算其平均结果,如下所示:


如果要制作量子态 ∣ψ〉 的多个相同副本并相对于测量算子 M 基向量进行测量,则射影算子 M 的标准差是结果分布的度量。投影测量算子的标准偏差导致了著名的海森堡不确定性原理,如下一节所示。

海森堡测不准原理

海森堡不确定性原理给出了两个投影测量算子(例如 M 和 N)的标准差乘积的下界,给定量子态 ∣ψ〉。
假设我们有两个测量算子M和N,并且我们在精确状态下复制量子系统的多个副本,比如2n,∣ψ〉。现在,如果我们对算子M进行n次测量,对算子N进行n次测量,我们会看到M和N结果的标准差遵循以下关系:
方程2-74称为一般海森堡测不准原理。为了证明海森堡测不准原理,我们将用一个数学小插曲来研究柯西-施瓦茨不等式。如图2-4所示。




这是复向量空间中向量的柯西-施瓦茨不等式,我们将用它来证明海森堡不确定性原理。
首先,M 和 N 是投影测量算子,是 Hermitian 算子。让我们采用两个状态 ∣Φ1 〉 和 ∣Φ2 〉,它们是在系统状态 |ψ〉 上应用投影测量算子 M 和 iN 的结果,定义如下:





现在我们已经接近证明海森堡测不准原理了。可以被认为是运算符 M 和 N 的标准差,其期望 〈M〉 和 〈N〉 为零。我们可以将公式 2-86 中的 M 和 N 分别替换为 (M − 〈M〉) 和 (N − 〈N〉),以用运算符 M 和 N 的标准差来表达同样的事情。 ,我们可以将公式 2-86 重写如下:

方程 2-88 中的不等式是海森堡不确定性原理对于两个测量算子 M 和 N 的最一般版本。如果将算子 M 和 N 选择为位置算子 x ˆ 和动量算子 p ˆ ,则交换算子将其代入公式 2-88,可得到与位置和动量相关的海森堡测不准原理:

POVM 算子

一般测量算子和投影测量算子不仅给出了测量各种结果的概率的规则,而且还给出了测量后状态的清晰表述。然而,在各种应用中,测量后的状态对于实验来说并不那么重要。衡量各种结果的概率的能力是唯一重要的事情。在这种情况下,POVM 测量方案被证明是一种方便的公式。我们可以定义一个正算子Ek,使得当测量状态∣ψ〉时k的结果的概率如下:
希尔伯特空间 V 中的正算子 A 是对于每个 |ψ〉 ∈ V 满足 〈ψ|A|ψ〉 ≥ 0 的算子。因此,确保算子 Ek 为正将确保我们具有由 P( 表示的概率k) ≥ 0。如果我们有 N 个我们感兴趣的结果,我们必须以满足完整性方程的方式构建正算子 Ek;即。算子 Ek 称为 POVM 元素,而完整集合 {Ek } 称为 POVM。与投影测量算子{Pk}不同,POVM算子{Ek}不需要满足关系。因此,正测量算子{Ek}不限于仅测量与一组正交基态有关的结果。因此,从这个意义上说,POVM 比投影测量算子更通用,而后者实际上是前者的特例。让我们看看 POVM 与投影测量不同的更有趣的情况,而不是将投影测量视为 POVM 的特殊情况。假设我们想要检测两个不一定正交的状态。我们可以将这两个状态记作。不用说,由于状态 ∣ψ1 〉 和 ∣ψ2〉 之间的重叠,我们不可能完全确定地测量这两个状态。让我们定义三个 POVM 元素,如下所示,看看如何最好地检测这两个事件:如果测量状态为 |ψ1〉 = |0〉,则永远不会观察到 E1,因为它对应于正交状态 ∣1〉。然而,如果检测到 E1,我们可以安全地推断出正在测量的状态必须是状态。类似的,如果检测到 E2,那么它必须是状态 |ψ1〉 = ∣ 0〉。它不可能是状态因为它与 (| 0〉−| 1〉) 正交。当检测到 E3 时,我们无法确定所测量的状态。这里的中心点是,使用 POVM,我们永远不会错误地识别我们要测量的状态。只是有时我们无法确定我们所面临的实际状态。

密度算子

到目前为止,我们一直使用状态向量 |ψ〉 来表示量子系统。量子系统也可以用密度算子 ρ 来表示。对于我们目前所研究的与周围环境隔离且处于纯量子态的量子系统,密度算子只不过是状态向量∣ψ〉与其自身的外积。因此,我们有这个:

混合量子态的密度算子

有时很难确定量子系统所处的确切量子态。我们可以以经典概率 pi 获得 n 个纯量子态 ∣ψi 〉 中任意一个的量子态。在这种情况下,密度算子就派上用场了,我们可以为这种混合量子态系统定义密度算子,如下所示:
因此,混合量子态的密度算子只不过是其每个组成纯态的密度算子的平均值。
混合态的密度算子的迹也是 1。请参见以下内容:

混合量子态密度算子的演化

对于封闭量子系统,状态向量的演化由 |ψ(t2 〉 = U(t2 , t1)|ψ(t1 )〉 给出。让我们看看当系统处于混合状态时密度算子如何演化。请注意,在混合量子态中,n 个不同的可能状态 ∣ψi 〉 就像纯态一样演化。因此,如果系统在酉演化后以概率 pi 处于状态 ∣ψi(t1 )〉 ,则系统将处于状态 U (t2, t1) ∣ ψi(t1 )〉 具有相同的概率 pi. 因此,酉演化后混合态的密度算子 ρ2 可以写为酉演化后纯态密度算子的平均值,为此处显示:

使用密度算子进行测量

假设我们有一个与结果 m 相对应的测量算子 Mm。测量算子 Mm = ∣ Φm〉〈Φm ∣ 对应于基向量 ∣ Φm〉。假设我们知道量子系统处于纯态 ∣ψi〉,结果 m 的概率由条件概率 P(m/i) 给出。

测量后的密度算子




密度算子的混合状态与纯状态

我们在前面的章节中看到了混合状态与纯状态在表示方面有何不同。然而,给定一个密度算子,我们可以通过检查密度算子的平方迹来检查它是纯态还是混合态。对于纯状态,tr(ρ^2) = 1,而对于混合状态,tr(ρ^2) < 1。鼓励读者进行数学计算来验证这一说法。

多量子系统的联合密度算子

约化密度算子


贝尔态的部分迹






这意味着量子位 A 处于混合状态。这是一个有趣的观察,因为两个量子位的联合状态处于纯状态,而各个量子位处于混合状态。这种奇怪的行为与量子纠缠现象有关。

延迟测量原理

在许多量子电路中,测量常常在电路的中间部分进行,测量结果用于有条件地控制后续的量子门。例如,在第一章中,我们在量子隐形传态电路中观察到,爱丽丝的两个量子位上的测量用于控制鲍勃量子位上的酉算子。图2-5显示了供参考的量子隐形传态电路,其中前两个量子位Q1和Q2属于Alice,而量子位Q3属于Bob。

实际上,在图 2-5 的量子隐形传态电路中,在测量 Alice 的量子位时,我们得到了经典信息 M1 和 M2 ,它们用于有条件地控制相继应用于 Bob 量子位的酉算子 X 和 Z。我们在图 2-6 中的量子隐形传态中所做的不同之处在于,将 Bob 量子位上的 X 和 Z 运算符设置为 Alice 量子位的量子信息(状态),然后测量 Alice 量子位到电路末端。
人们可能会说图 2-5 中的量子电路更加直观和可解释,因为它需要将经典信息从 Alice 传递给 Bob;然而,中心思想是图 2-5 和图 2-6 中的电路是等效的。这种将测量推到电路末端的方法称为延迟测量原理
总结延迟测量状态的原理,可以将电路中间部分的测量移至电路末端。此外,如果电路中间部分中的测量用于经典地控制电路其他部分中的酉运算,则它们可以被条件量子运算取代。延迟测量原理的结果是测量与调节操作进行交换。

近似酉算子

在经典计算体系中,一小组门(例如 AND、OR 和 NOT 门)可用于实现任何经典函数。因此,这样一组门被认为对于经典计算是通用的。在量子计算范式中,如果任何给定的酉算子可以通过由通用集中的门组成的量子电路近似到任意精度,则一组门被认为是通用的。在第一章中,我们在实现一些量子算法时接触了 CNOT 和 Hadamard 门。这两个门以​​及相位门和 π/8 门被认为是通用的,因为使用这些门可以将任何单一门逼近到任意精度。图 2-7 显示了四个门及其酉变换以供参考。

现在让我们看看使用一组离散量子门来近似酉变换意味着什么。让我们采用在相同状态 ∣ψ〉 上运行的两个酉变换 U 和 V,其中 U 是我们想要实现的酉变换,V 是我们能够使用离散门集实现的酉变换。我们可以定义用 V 逼近 U 的误差如下:
正如我们在公式 2-114 中看到的,误差 E(U, V) 是当使用 V 而不是 U 作为酉算子时期望变换状态与实际变换状态之间差异的最大范数。还要注意变换 E(U, V) 中的误差与测量变换状态时的误差之间的关系。如果我们有一组 n 个测量算子 M1 , M2 …。 。 , Mn 属于正交集 |ψ1 〉, |ψ2 〉, …. ,|ψn〉,则每个测量元素Mk给出测量状态的概率为|ψk〉。如果可以模拟所需的酉算子 U,那么在状态 ∣ψ〉 变换之后对基 ∣ψk〉 的测量将产生概率 pk(U),如下所示:
类似地,如果我们使用 V 作为 ∣ψ〉 上的酉变换而不是 U,然后使用测量算子 Mk 对基本状态 ∣ψk〉 进行测量,那么测量状态 ∣ψk〉 的概率可以为写成如下:





公式2-121中的不等式告诉我们,如果用E(U, V)给出的V来近似算子U的误差很小,那么测量概率和实际概率的差异也很小。事实上,误差范数的上限是以 V 逼近 U 时的误差为上限,即 2E(U, V)。
该不等式概括为由 n 个酉算子 U1 、 U2 、…、Un 组成的序列,由 n 个酉算子 V1、V2、…、Vn 的序列近似。通过归纳可以看出,与 n 个酉运算序列的近似相关的误差遵循以下关系:



因此,我们看到该关系对于 n = 2 成立。通过归纳,我们可以将此关系扩展到由 V1 、 V2 .. Vn 近似的酉算子 U1 、 U2…、 Un 的任意序列。

索洛维-基塔耶夫定理

每当我们查看空间 U 中的近似元素时,我们都会查看该空间中元素的较小子集 W,这很容易实现。通过组合使用较小子集 W 中的元素,我们形成一个在 U 中稠密的空间 V。在拓扑中,如果 V 的闭包等于集合 U,则子集 V 被称为 U 的稠密子集。非正式地,每个稠密集 V 中的元素任意接近于集合 U 中的元素。稠密集的最佳示例是由 ℚ 表示的有理数集合,作为由 ℝ 表示的实线的子集。每个实数要么是有理数,要么任意接近于一。 U 的密集子集 V 可用于使用 V 的元素以任意精度表示 U 的元素。例如,由于位的二进制表示,经典计算机只能使用有理数。然而,由于有理数形成实线 ℝ 的稠密子集,因此我们可以高精度地逼近实无理数。类似地,在量子计算的情况下,可能的门的集合形成一个连续体,并且并不总是可以用 SU(d) 中的元素精确地构造一个门。
设 SU(d) 表示 d 维希尔伯特状态空间中的酉算子群。
因此,Solovay-Kitaev 定理根据可接受的误差 ϵ 给出了通用集合 V(或者通用集合 V 的元素的函数)所需门的近似数量的估计。逼近酉算子时可接受的误差越低,构建这种酉门所需的通用集中的门数量就越大。

ERP悖论、局部现实主义和贝尔不等式

在经典世界中,每当我们想到任何物体时,我们都会假设该物体的物理属性存在,无论我们是否观察到它。对此类物体的任何测量都只能揭示物理特性。然而,根据量子力学,物体不具有任何与其测量无关的物理属性。事实上,只有在系统上进行测量时,这些物理特性才会存在。这种对仅通过测量而具有物理特性的物体的解释被称为哥本哈根解释。例如,根据量子力学,除非测量到特定的能级,否则电子不具有任何特定的能级,例如基态或激发态。量子力学给我们提供的是一组假设,告诉我们给定电子状态,测量时电子处于特定状态的概率是多少。
从1920年到1930年,包括爱因斯坦在内的几位物理学家都不相信量子力学所提供的这个新观点。著名论文《物理现实的量子力学描述能否被认为是完整的?》由爱因斯坦、罗森和波多尔斯基(统称EPR)所写,详细描述了一个思想实验,以反驳哥本哈根的解释。他们的论点基于量子纠缠的概念。假设我们有一个角动量为0的量子系统,同时发射两个光子P1和P2。由于光子有自旋和角动量必须守恒,如果一个光子有自旋向上的状态,另一个光子必须有自旋向下的状态,以确保系统的角动量为零。我们表示自旋上升状态为∣0〉,而自旋下降状态为∣1〉。这种现象被称为纠缠,其中两个光子不是独立的。假设每个光子粒子具有相同的自旋向上和向下的倾斜度,两个粒子的联合状态由给出。如果一个光子的自旋已知,那么另一个光子的自旋就立即已知。假设我们把光子分开1光年的天文距离,大约是9.46 × 10^12千米。如果我们测量一个光子P1,我们有50%的机会测量自旋向上,50%的机会测量自旋向下。现在让我们假设我们测量P1处于一个自旋状态∣0〉,然后我们快速测量,比方说在1秒内,P2的状态。光子P2总是会测量自旋向上。量子力学表明,粒子的状态不是预先确定的,只有在测量之后才可用。这意味着P1的测量信息必须比光传播得快得多,才能在1秒内到达P2,这样P2才能根据测量时的休眠状态调整状态。EPR认为,根据特殊相对规则,没有任何物体的速度能超过光速,因此哥本哈根的解释应该是无效的。这种特殊相对的理论违背被称为ERP悖论
相反,ERP提出了另一种可能的量子纠缠理论,该理论指出,两个光子的状态从一开始就被预先确定了,光子P1是一个自旋向上的状态,而光子P2是一个自旋向下的状态。这个信息隐藏在光子粒子的局部内,所以当它们分开时,就不会发生通信。这叫做局部隐变量理论
这就好像两个光子粒子是一对手套,如果一个是左手,另一个就是右手。一旦我们发现了左手,我们就知道另一个无论它在宇宙中的哪个位置都一定是右手。从1935年到1964年,近30年来,局部隐变量理论一直是对量子力学的有效解释,直到爱尔兰物理学家约翰·贝尔(John Bell)的出现,他根据著名的贝尔方程提出了一个验证局部隐变量理论是否正确的实验。
要推翻ERP的主张,我们需要理解贝尔不等式。贝尔不等式不涉及量子力学。我们做了一个思想实验,用相似的感觉来推断贝尔不平等,即普通世界是如何运作的,或者爱因斯坦、波多尔斯基和罗森认为自然应该如何服从。我们用量子力学分析来跟进普通世界分析,以证明它与普通世界分析是不一致的。
我们进行了如图2-8所示的实验,裁判Colin为Alice和Bob准备了两个粒子,并将粒子发送给他们进行测量。
一旦爱丽丝接收到她的粒子,她可以选择测量与可观测Q相关的物理性质PQ,或者她可以选择测量与可观测R相关的物理性质PR。爱丽丝在接收到她的粒子时,抛一个均匀硬币来决定她想要测量的性质。
如图2-8所示,每一项物理性质的测量都有两个结果:+1或−1。与Alice类似,Bob在接收到粒子时,会测量与可观测S和T有关的两个物理性质PS或PT中的一个。Bob在接收到粒子之前不会选择要测量的性质。爱丽丝和鲍勃同时进行测量,这样一个人的测量结果不会改变另一个人的测量结果。
现在我们来看简单量(QS + RS + RT - QT),并试着计算它的期望。对表达式进行简化,得到:
从公式2-126中,我们可以很容易地看出,在某一时刻,S(Q + R)或T(R−Q)中的任何一个都是非零的,而非零的值是+2或- 2。因此:
对于由Q = q, R = r, S = s, T = t给出的Alice和Bob粒子的任何广义测量态,我们有QS + RS + RT - QT的期望如下:
现在,由于和的期望等于期望的和,我们可以将公式2-128改写为:
方程2-129被称为贝尔不等式。这个结果也被称为CHSH不等式,以四位发明者的姓名首字母命名。
现在我们来分析一下贝尔不等式在量子系统中是否成立。这里Colin准备了两个量子位的纠缠量子态如下:
科林把第一个量子位给爱丽丝,第二个给鲍勃进行测量。Alice对可观测值Q和R进行了测量,我们将其赋值如下:
在方程2-131和2-132中,Z和X是泡利矩阵。
很像之前,我们计算关于纠缠态∣ψ〉在量子力学意义上的期望例如,关于状态|ψ〉的E[QS]可以表示为:


在方程2-129中,我们可以看到,利用感知普通世界如何运作,或者ERP如何感知世界给了我们期望的上限2。然而,我们可以看到量子力学给出的期望值是2√2,这违反了贝尔不等式。这意味着我们在推导贝尔不等式时所做的一个或多个假设必定是错误的。贝尔不等式或爱因斯坦、罗森和波多尔斯基在这方面做出的可能错误的假设可以总结如下:
现实主义假设:物理属性具有独立于观察或测量的确定值的假设
局部性假设:假设 Alice 执行测量不会影响 Bob 的测量结果
这两个假设一起被称为局域实在论,而贝尔不等式的违反证明它们中至少有一个是错误的。因此,我们从贝尔不等式的违反中学到的是,尽管局部现实主义符合我们的日常经验,但它并不适用于世界在最基本层面上的运作方式。根据最近的实验证据,物理学家得出的结论是,为了对量子力学有深入直观的理解,应该从我们对世界的常识性观点中放弃局域性和实在论中的一个或两者。

哈密​​顿模拟和Trotterization

常数哈密顿量 H 下量子系统的演化由薛定谔方程给出。薛定谔方程的解给出了时间 t0 和 t 之间状态向量 ∣ψ〉 的酉演化为 |ψ(t1)〉 = U(t1 , t0) ∣ ψ(t0 )〉,其中
在哈密顿模拟中,给定哈密顿算子 H 和演化时间 t,我们需要组合一系列门来实现酉算子 。哈密​​顿量模拟是使用绝热计算的算法的重要组成部分,例如我们将在第 7 章中研究的量子近似优化算法(QAOA)。大多数物理系统中的哈密顿量可以表示为仅很少的颗粒。因此,对于 n 体量子系统,我们可以将哈密顿量写如下:
每个 Hk 哈密顿主义者通常都像两个身体相互作用一样简单。这里要强调的一点是更容易用量子门构造,因为它比酉算子工作在更小的局部子系统上。如果我们能够表达,那么轻松构造 的能力就会很有用。然而,一般来说,因为一般情况下各个局部哈密顿量不会交换,即 Hk Hl ≠ Hl Hk 。事实证明,即使两个哈密顿量 H1 和 H2 不交换,我们也可以利用特罗特(Trotter)公式模拟单个哈密顿量来模拟整体哈密顿量。

上式中的O(.)表示Big O的计算复杂度。




如果哈密顿量 H1 和 H2 比 H = H1 + H2 更容易模拟,那么应用 2-142 中的酉算子序列就证明是有用的命题。
Trotter 公式可以扩展到两个以上哈密顿量的和。例如,如果我们有 H = H1 + H2 + H3,我们可以通过酉算子序列来 Trotterize H 的酉演化,如下所示:

总结

至此,我们结束了第二章。在这一章中,我们主要介绍了量子力学的数学和它的假设,以更好地帮助我们理解和实现不同的基于量子的算法以及量子机器学习。我们详细研究了测量及其不同的变体,如射影测量和POVM,因为测量是基于量子的算法的组成部分。此外,我们涵盖了特定的重要主题线性代数是中心的量子力学表示。
在下一章中,我们将从前两章中学习并实现几个基于量子计算的算法,如量子隐形传态、Deutsch-Jozsa、Grover的算法和Bernstein-Vazirani等。我们将在谷歌的Cirq和IBM的Qiskit中实现这些量子算法。

量子算法概论

1981年,理查德·费曼提出了这样的想法:由遵守量子力学定律的量子力学元件构建的计算机可以对量子系统进行有效的模拟。量子计算基于叠加、纠缠和干涉等量子力学特性定律。与经典计算不同,在量子计算机中,由于其叠加特性,寄存器可以同时存在于所有可能的状态。只有当测量量子系统时,我们才能观察到一种可能的状态。这样的系统是有利的,因为当测量时,每个状态可以以在测量之前的状态中编码的特定概率出现。量子计算的工作原理是将所需状态的概率增加到足够高的值,以便可以通过最少数量的测量以高置信度获得所需状态。在这方面,由量子叠加产生的量子干涉发挥着重要作用,因为它允许与给定状态相对应的概率幅度相互干扰和抵消。量子干涉的这一特性使测量结果偏向于我们希望作为量子算法结果的一组状态。同样,量子纠缠允许人们在量子对象(尤其是量子位)之间创建强相关性,从而发挥量子算法的优势,正如您将在本章中看到的那样。

在本章中,我们将研究量子算法,旨在了解这些算法相对于经典算法的量子霸权。我们已经在第一章中了解了量子隐形传态算法以及使用量子并行性制定算法的方法。在本章中,我们将实现其他几种量子计算算法,例如 Deutsch Jozsa、贝尔不等式、Bernstein-Vajirani 算法和 Grover 算法,以扩大我们理解的量子算法的范围。对于这些新算法,我们将首先研究它们的技术推导,然后再进行实现。我们将使用 Google 的 Cirq 作为实现这些算法的首选量子计算框架。然而,我们将在 IBM 的 Qiskit 中实现其中一些算法,以获得多个量子计算框架的经验。在这些量子计算框架中实现这些量子计算算法将为我们提供不同的视角,并有助于填补我们在研究其技术细节时可能存在的任何空白。

Cirq

Cirq 是 Google Research 于 2018 年发布的开源量子计算软件库。开发人员可以构建和运行包含所有相关一元、二元和三元门的量子算法。 Cirq 目前不提供对谷歌量子计算机的访问。我们将使用 Cirq 的量子计算模拟器(称为 Simulator)在本地执行量子算法。

使用 Hadamard 门进行 Cirq 仿真

让我们首先通过简单的量子电路模拟来熟悉 Cirq 语言。 Cirq 语言中的量子位通常使用 LineQubit 或 GridQubit 选项来定义。 LineQubit 允许您在一维晶格上定义量子位,而 GridQubit 允许您在二维晶格上定义量子位。

使用 Cirq 的 GridQubit 功能,我们定义一个在基本状态 |0〉 处初始化的量子位,并应用 Hadamard 变换H=\frac{1}{\sqrt{2}}\begin{bmatrix} 1 &1 \\ 1&-1 \end{bmatrix}就可以了。Cirq 中的 Hadamard 变换定义为 H 本身。然后,我们使用 Cirq 中的测量功能测量来测量计算基础中的新状态。测量不需要您像许多其他量子计算包中所要求的那样显式定义用于存储测量结果的经典寄存器。所有对量子位的操作都在 Cirq 中以量子电路的形式定义。定义电路后,您可以使用 Cirq Simulator 对同一电路运行 100 次模拟并测量结果。Cirq 具有直方图工具来获取每个测量结果的计数。量子电路中的任何状态测量都可以与密钥绑定。一旦模拟器运行,就可以通过键访问结果,如清单 3-1 中的示例所示。

清单 3-1. 使用 Cirq 对量子位进行 Hadamard 变换后的测量

# Import the Package cirq 
import cirq 
# Define a Qubit 
qubit = cirq.GridQubit(0,0) 

# Create a Cirquit in cirq 
circuit = cirq.Circuit([cirq.H(qubit), 
                        cirq.measure(qubit,key='m')]) 
print("Circuit Follows") 
print(circuit) 
sim = cirq.Simulator() 
output = sim.run(circuit,repetitions=100) 
print("Measurement Output:") 
print(output) 
print("Histogram stats follow") 
print(output.histogram(key='m')

  Out put

Circuit Follows 
(0, 0): ───H───M('m')─── 
Measurement Output: m=1000111111111101111011100101000101011000010000110110101000101100111011101001001001000000010000001000 
Counter({0: 54, 1: 46})

从清单 3-1 的输出中可以看到,在相等叠加状态\frac{1}{\sqrt{2}}(|0>+|1>)下测量量子位的相同副本时,我们在状态 0 下获得 54 个测量值,在状态 1 下获得 46 个测量值,如图3-1所示。

正如预期的那样,在两个计算基础状态 0 和 1 上的分布几乎是均匀的。如果我们增加进行测量的副本数量,每个状态的概率将趋于 1/2 。如果 n 是我们进行测量的量子态的副本数,并且 Pn(0) 和 Pn (1) 是根据这 n 个副本的测量确定的概率,则以下情况成立:

现在让我们针对不同的 n 值模拟前面的代码,看看概率序列如何收敛到理想值。

我们创建一个名为 hadamard_state_measurement 的函数来计算不同 n 值的概率,如清单 3-2 所示。

# Import the Package cirq 
import cirq 
import matplotlib.pyplot as plt 

def hadamard_state_measurement(copies): 
    # Define a Qubit 
    qubit = cirq.GridQubit(0, 0) 
    # Create a Circuit in cirq 
    circuit = cirq.Circuit([cirq.H(qubit) 
            ,cirq.measure(qubit, key='m')]) 
    print("Circuit Follows") 
    print(circuit) 
    sim = cirq.Simulator() 
    output = sim.run(circuit, repetitions=copies) 
    res = output.histogram(key='m') 
    prob_0 = dict(res)[0] / copies print(prob_0) 
    return prob_0 

def main(copies_low=10, copies_high=1000): 
    probability_for_zero_state_trace = [] 
    copies_trace = [] 
    for n in range(copies_low, copies_high): 
        copies_trace.append(n) 
        prob_0 = hadamard_state_measurement(n)
        probability_for_zero_state_trace.append(prob_0)                                                  
    plt.plot(copies_trace, probability_for_zero_state_trace) 
    plt.xlabel('No of Measurements') 
    plt.ylabel("Probability of the State 0") 
    plt.title("Convergence Sequence of Probability for State 0") plt.show() 
if __name__ == '__main__': 
    main()

在清单 3-2 中,我们通过对状态 |\psi >=\frac{1}{\sqrt{2}}(|0>+|1>) 的相同副本的不同测量来计算状态 ∣0〉 的概率。从图 3-2 中的图表可以看出,随着副本数量从 100 增加到 500,状态 ∣0〉 的概率逐渐向理论值 1/2 收敛,并且振荡逐渐减小。

Qiskit

Qiskit 是 IBM 于 2017 年发布的开源量子计算软件库。Qiskit 代表量子信息科学套件,其量子计算堆栈中有四个主要组件,如下所列:
        1. Qiskit Terra:它提供了构建量子电路的所有基本组件。
        2. Qiskit Aer:您可以使用 Aer 工具开发噪声模型来模拟真实量子计算设备中可能发生的真实 噪声模拟。 Aer 还提供了 C++ 模拟器框架。
        3. Qiskit Ignis:这是一个用于分析和最小化量子电路中的噪声的框架。
        4. Qiskit Agua:包含跨域算法和在量子真实设备或模拟器上运行这些算法的逻辑。

在本书中,您将不时使用 Qiskit 编程语言。为了熟悉 Qiskit 的基本编码语法,您将实现与前面在 Cirq 中所示相同的程序:测量 Hadamard 变换后的量子位。参见清单 3-3。

清单 3-3。使用 Qiskit 对量子位进行 Hadamard 变换后的测量

""" 
Measure a qubit after Hadamard Transform 
""" 
import numpy as np 
from qiskit import QuantumCircuit, execute, Aer 
from qiskit.visualization import plot_histogram 

# Use Aer's qasm_simulator 
simulator = Aer.get_backend('qasm_simulator') 

# Create a Quantum Circuit with 1 Qubit 
circuit = QuantumCircuit(1, 1) 

# Add a H gate on Qubit 0 
circuit.h(0) 

# Map the quantum measurement to the classical register 
circuit.measure([0], [0]) 

# Execute the circuit on the qasm simulator 
job = execute(circuit, simulator, shots=100)

# Grab results from the job 
result = job.result() 

# Returns counts 
counts = result.get_counts(circuit) 
print("\nTotal count for 0 and 1 are:",counts) 

# Draw the circuit 
print(circuit.draw(output='text'))

 

在 Qiskit 中,我们使用 QuantumCircuit 选项定义量子电路。此外,我们还通过 QuantumCircuit 选项定义电路本身时所需的量子位。 QuantumCircuit 选项的其他输入是存储测量结果所需的经典位。由于我们正在测量等叠加的量子位的状态,因此我们将需要一个经典位来进行测量。与 Qiskit 中的 Cirq 不同,我们必须明确定义经典寄存器或位来存储测量结果。 Qiskit 中的 Hadamard 变换 H 是通过使用 QuantumCircuit 创建的电路来定义的。我们使用 Circuit.h(0) 在唯一的量子位上定义 Hadamard 变换。需要注意的一件事是,用于保存测量结果的经典位并不隐式地与 Qiskit 上的量子位相关联,我们必须在使用电路的测量功能进行测量时对此映射进行编码。我们使用的模拟器是从 Qiskit 中的 Aer 框架导入的。与 Cirq 中模拟量子电路的 run 命令非常相似,我们在 Qiskit 中使用执行命令。

贝尔态的创建和测量

我们在第一章中讨论了贝尔态,同时讨论了量子纠缠和量子隐形传态等算法。两个量子位 A 和 B 的贝尔状态由下式给出:

在清单 3-4 中,我们首先对在状态 |ψ〉_A= ∣0〉 初始化的量子位 A 应用哈达玛变换 H,以创建叠加态来创建贝尔态 。然后,我们将受控非门(通常称为 CNOT)应用到基于量子位 A 作为控制位的状态 |ψ〉_B = ∣0〉 初始化的量子位 B 上。

清单 3-4。使用 Cirq 创建和测量贝尔状态

import cirq 
# Define the two qubits using LineQubit 
q_register = [cirq.LineQubit(i) for i in range(2)] 
# Define the Cirquit with a Hadamard Gate on the qubit 0 
# followed by CNOT operation 
cirquit = cirq.Circuit([cirq.H(q_register[0]), cirq.CNOT(q_register[0], q_register[1])]) 
# Measure both the qubits 
cirquit.append(cirq.measure(*q_register,key='z')) 
print("Circuit") 
print(cirquit) 
# Define the Simulator 
sim = cirq.Simulator() 
# Simulate the cirquit for 100 iterations 
output = sim.run(cirquit, repetitions=100) 
print("Measurement Output") 
print(output.histogram(key='z'))

 在清单 3-4 中,我们使用 Cirq 的 LineQubit 选项来定义参与贝尔状态的两个量子位。清单 3-4 的输出显示量子电路是 cirq。在贝尔状态的测量中,我们得到几乎相等比例的整数结果:0和3。整数结果0代表状态|00〉,而结果3代表状态∣11〉。我们现在在 Qiskit 中实现贝尔状态的创建和测量,如清单 3-5 所示。

清单 3-5。使用 Qiskit 创建和测量贝尔状态

""" 
Quantum Entanglement Example with Qiskit 
""" 
import numpy as np 
from qiskit import QuantumCircuit, execute, Aer 
from qiskit.visualization import plot_histogram 

# Use Aer's qasm_simulator 
simulator = Aer.get_backend('qasm_simulator') 

# Create a Quantum Circuit acting on the q register 
circuit = QuantumCircuit(2, 2) 

# Add a H gate on Qubit 0 
circuit.h(0) 

# Add a CX (CNOT) gate on control qubit 0 and target qubit 1 
circuit.cx(0, 1) 

# Map the quantum measurement to the classical bits 
circuit.measure([0,1], [0,1])

# Execute the circuit on the qasm simulator 
job = execute(circuit, simulator, shots=100) 

# Grab results from the job 
result = job.result() 

# Returns counts 
counts = result.get_counts(circuit) 
print("\nTotal count for 00 and 11 are:",counts) 

# Draw the circuit 
print(circuit.draw(output='text'))

从清单 3-5 的输出中我们可以看到,Qiskit 在测量 Bell 状态时几乎同等地采样了状态 ∣00〉 和 ∣11〉。

量子隐形传态 

量子隐形传态是在不使用任何通信信道的情况下在发送者和接收者之间传输量子态的方法。与第一章一样,我们将量子态的发送者命名为 Alice,将量子态的接收者命名为 Bob,以保持引用一致。图 3-3 显示了量子隐形传态电路的高级电路。

我们在本章开头指出,量子算法通过在量子位之间创建有意义的相关性来受益于量子纠缠。这些相关性的本质比经典系统所能实现的要强得多,因为即使相隔无限大的距离,量子粒子也可以表现出高相关性。

在量子隐形传态中,爱丽丝和鲍勃让他们的控制量子位通过量子纠缠共享贝尔态。 Alice 想向 Bob 发送一个量子位状态 |ψ〉 。我们将此用于传输的量子位称为 Q1,将 Alice 和 Bob 用于共享贝尔状态的控制量子位称为 Q2 和 Q3。

以下是与量子隐形传态算法相关的步骤:
1. 将控制量子位 Q2 和 Q3 初始化为状态∣0〉,将量子位 Q1 初始化为要传输的状态 |ψ〉。
2. 在Q2和Q3之间创建Bell状态\frac{1}{\sqrt{2}}(|00>+|11>),首先在Q2上应用Hadamard变换H,然后在Q3上进行CNOT操作,其中Q2充当控制量位。
3. 一旦 Alice 和 Bob 的控制量子位 Q2 和 Q3 之间建立了贝尔状态,就对 Alice 的双量子位 Q1 和 Q2 应用 CNOT 算子,其中 Q1 充当控制量子位,Q2 充当目标量子位。
4. 对量子位 Q1 应用 Hadamard 变换,然后测量 Alice 的量子位 Q1 和 Q2。我们将Q1和Q2的测量状态表示为M1和M2。
5. 基于测量状态 M2 作为控制量子位,在 Bob 的量子位 Q3 上应用 CNOT 算子。最后,对 Bob 的量子位 Q3 测量的状态 M1 应用条件 Z 运算符。
6. 在此阶段,Bob 的量子位 Q3 具有 Alice 传输的状态∣ψ〉。

我们在 Cirq 中实现量子隐形传态算法,并通过传输相等的叠加态|\psi >=\frac{1}{\sqrt{2}}(|0>+|1>)来说明它。一般情况下,要传输的状态∣ψ〉可以通过将∣0〉状态转换为所需状态∣ψ〉所需的电路来指定。为此,我们在Quantum_ teleportation 例程中使用qubit_to_send_op 变量。例如,传输等叠加状态变量|\psi >=\frac{1}{\sqrt{2}}(|0>+|1>),我们通过变量 qubit_to_send_op 将 cirq.H 运算符发送到Quantum_teleportation 例程。 Hadamard 算子将在状态 ∣0〉 初始化的量子位 Q1 转换为等叠加状态。建议读者尝试使用 qubit_to_send_op 传输不同的状态。一旦量子位状态被传输,我们就测量 Bob 的量子位 Q3,看看测量值的分布是否等于传输波形的概率分布。清单 3-6 显示了量子隐形传态算法的详细实现。

清单 3-6。模拟量子隐形传态

import cirq 
def quantum_teleportation(qubit_to_send_op='H', 
    num_copies=100): 
    Q1, Q2, Q3 = [cirq.LineQubit(i) for i in range(3)] 
    cirquit = cirq.Circuit() 
    """ 
    Q1 : Alice State qubit to be sent to Bob 
    Q2: Alices control qubit 
    Q3: Bobs control qubit
    Set a state for Q1 based on qubit_to_send_op : 
    Implemented operators H,X,Y,Z,I 
    """ 
    if qubit_to_send_op == 'H': 
        cirquit.append(cirq.H(Q1)) 
    elif qubit_to_send_op == 'X': 
        cirquit.append(cirq.X(Q1)) 
    elif qubit_to_send_op == 'Y': 
        cirquit.append(cirq.X(Q1)) 
    elif qubit_to_send_op == 'I': 
        cirquit.append(cirq.I(Q1)) 
    else: 
        raise NotImplementedError("Yet to be implemented") 
    # Entangle Alice and Bob's control qubits : Q2 and Q3 
    cirquit.append(cirq.H(Q2)) 
    cirquit.append(cirq.CNOT(Q2, Q3)) 
    # CNOT Alice's data Qubit Q1 with control Qubit Q2 
    cirquit.append(cirq.CNOT(Q1, Q2)) 
    # Transform Alice's data Qubit Q1 
    # on +/- basis using Hadamard Transform 
    cirquit.append(cirq.H(Q1)) 
    # Measure Alice's qubit Q1 and Q2 
    cirquit.append(cirq.measure(Q1, Q2)) 
    # Do a CNOT on Bob's qubit Q3 using Alice's 
    # control qubit Q2 after measurement 
    cirquit.append(cirq.CNOT(Q2, Q3)) 
    # Do a Conditioned Z Operation on Bob's qubit Q3 
    # using Alice's control qubit Q1 after measurement 
    cirquit.append(cirq.CZ(Q1, Q3)) 
    # Measure the final transmitted state to Bob in Q3 
    cirquit.append(cirq.measure(Q3, key='Z')) 
    print("Circuit") 
    print(cirquit) 
    sim = cirq.Simulator()
    output = sim.run(cirquit, repetitions=num_copies) 
    print("Measurement Output") 
    print(output.histogram(key='Z')) 
if __name__ == '__main__': 
    quantum_teleportation(qubit_to_send_op='H')

从测量结果中,我们看到Alice将等叠加状态传输给了Bob。

量子随机数发生器

经典计算机中的大多数随机数生成器并不是真正随机的,因为它们是通过算法以确定性方式生成的,因此遵守可再现性规范。准确地说,经典的随机数生成器从初始种子状态开始,并且使用种子状态生成的随机数序列始终是相同的。因此,我们看到这些随机数生成器生成的数字序列模仿了随机数序列的属性,同时是确定性的。这些确定性随机数生成器例程称为伪随机生成器。伪随机数具有可重复性和速度的优点,但不能安全地用于诸如使用随机密钥来安全传输数据的密码学等应用。

与伪随机数生成器相反的是硬件随机数生成器,它利用量子过程、光电效应等物理过程生成随机数。由于这些物理过程高度不可预测,因此它们为真随机数奠定了良好的基础可用于密码学等安全应用的生成器。

在本节中,我们将说明使用多个量子位的随机整数生成器例程。这个想法很简单,如下所示:
1. 确定表示要采样的整数值范围所需的量子位数量。例如,如果我们必须从 0 到 7 的八个整数中进行采样,则需要 log2 (8) = 3 个量子位。
2. 通过对最初处于 ∣0〉 状态的每个量子位应用 Hadamard 变换来创建相等的叠加态。等叠加状态由下式给出:这里∣x〉代表计算基础状态∣x0 x1… xn − 1〉 的整数值。其中每个 xi ∈ {0, 1}。
3. 将计算基础状态映射到实际整数并将映射存储在字典 s2n_map 中。如果要采样的整数范围从零开始,则从计算基础状态到实际整数的字典可以只是二进制到十进制的转换,如下所示:如果范围从偏移量 b 开始,我们可以将计算基础状态映射到要采样的整数值,如下所示:
4. 一旦定义了映射,我们就可以对等叠加状态 |ψ〉 进行测量,并使用字典映射 s2n_map 将测量的计算基础状态映射到整数值。

在清单 3-7 中,我们使用 10 个量子位生成 0 到 210 之间的随机数。由于我们从 0 开始采样,因此我们算法的偏移量 b 为 0。

清单 3-7。量子随机数发生器

import cirq 
import numpy as np 

def random_number_generator(low=0,high=2**10,m=10): 
    """ 
    :param low: lower bound of numbers to be generated 
    :param high: Upper bound of numbers to be generated 
    :param number m : Number of random numbers to output 
    :return: string of random numbers 
    """ 
    # Determine the number of Qubits required 
    qubits_required = int(np.ceil(np.log2(high - low))) 
    print(qubits_required) 
    # Define the qubits 
    Q_reg = [cirq.LineQubit(c) for c 
                in range(qubits_required)] 
    # Define the circuit 
    circuit = cirq.Circuit() 
    circuit.append(cirq.H(Q_reg[c]) for c 
                      in range(qubits_required)) 
    circuit.append(cirq.measure(*Q_reg, key="z")) 
    print(circuit) 
    # Simulate the circuit 
    sim = cirq.Simulator() 

    num_gen = 0 
    output = [] 
    while num_gen <= m : 
        result = sim.run(circuit,repetitions=1) 
        rand_number = result.data.get_values()[0][0] + low
        if rand_number < high : 
            output.append(rand_number) 
            num_gen += 1 
    return output 
if __name__ == '__main__': 
    output = random_number_generator() 
  print(output)

从随机数生成器电路中,我们可以看到它包括对每个量子位应用 Hadamard 算子,然后进行测量。从量子随机数生成器的输出中,我们看到它生成的 20 个数字的样本均值是 510.95。这接近随机数采样的数字的平均值,即假设均匀分布的 0 到 2^10。

Deutsch–Jozsa 算法实现

Deutsch-Jozsa 算法使用我们在第 1 章中简要讨论过的量子并行性。Deutsch-Jozsa 算法评估二元函数是否平衡或恒定。如果函数 f(x) 的定义域中一半值的计算结果为 0,另一半计算结果为 1,则函数 f(x) 被称为平衡函数。常数函数对于其定义域中的所有值始终计算为相同的二进制值 0 或 1。例如,如果我们使用三个量子位的系统,我们可以有 2^3 = 8 个计算基础状态,其形式为 ∣x1 x2x3〉,其中每个 xi ∈ {0, 1}。如果我们在这八个计算基础状态上定义一个函数 f (x) = f (x1 , x2, x3) ,并且其中一半计算结果为 1,另一半计算结果为 0,我们就说该函数是平衡的。图 3-4 显示了 Deutsch-Jozsa 算法的高级图。

 Deutsch-Jozsa 算法的步骤可以总结如下:
1.基于函数的域的大小,我们定义输入量子比特的数量。例如,如果f(x)的域有四个值,那么我们需要log2(4)= 2个量子位。所以一般来说,如果我们在函数的定义域中有2^n个值,我们需要使用n个输入量子比特。此外,该算法需要一个目标量子位来保持f(x)的值。
2. 通过对每个输入量子位应用 Hadamard 变换 H,将状态 |0〉^⊗n 初始化的输入量子位变换为相等叠加状态。
3. 通过连续应用 NOT 变换 X 和 Hadamard 变换 H,将在状态 |0〉 初始化的目标量子位变换为负状态 |−〉,如下所示:这为我们提供了输入和目标量子位的组合状态,如下所示:
4. 我们有一个预言机 Uf,它将每个计算基础状态二进制字符串 x 作为输入,并在目标量子位中输出 f(x),如下所示:因此,对于任意计算基状态 ∣x〉,|x〉 ⊗ (| 0〉−| 1〉) 上的酉变换 Uf 可以表示为:
当 f(x) = 0 时,我们有以下结果:
当 f(x) = 1 时,我们有以下结果:

对于 f(x) 的任何二进制值进行推广,我们有以下结果:

基于此,我们可以说,预言变换Uf在所有量子位的组合状态∣ψ1〉上的应用可以表达如下:

这里要进行的一个有趣的观察是,通过在叠加中对目标量子位应用酉变换,我们可以获得在全局阶段中显示的函数值 f(x)。这通常被称为相位反冲技巧。
5. 接下来,我们对每个输入量子位应用哈姆达变换 H,这改变了输入量子位的计算基础。新状态 |ψ3 〉 如下所示:
新的计算基础 ∣z〉 是对应于 n 个输入量子位的二进制字符串 ∣z0 , z1…zn − 1〉 的整数表示。术语 x ⊙ z 指的是 x 和 z 模 2 的二进制串之间的点积。
6. 我们对 |ψ3〉 的几个相同副本进行测量,并将注意力集中在所有输入量子位测量为零状态的实例上,即 z0 = z1 = … = zn − 1 = 0。此时我们可以忽略目标量子位,因为它的状态不与输入量子位纠缠。该输入量子位状态的幅度如下:
从公式 3-13 中我们可以看出,如果函数 f(x) 是平衡函数,则幅度将为零,因为 f(x) = 0 对应的 +1 会抵消 f(x) = 1对应的 −1 。这意味着对于平衡状态,我们将无法观察到对应于 z0 = z1 = … = zn − 1 = 0 的状态 |z〉 = ∣0〉。另一方面,如果我们有一个常数函数,概率幅值为 1,我们最终会以 100% 的概率在测量中观察到状态 |z〉 = ∣0〉。

我们对函数 f(x) 的域大小为 4 实现 Deutsch-Jozsa 算法,这意味着我们需要两个量子位用于输入寄存器,一个量子位用于目标寄存器。清单3-6显示了详细的代码。预言机改造是通过预言机函数来实现的。

我们通过不对状态∣ψ1〉应用任何变换来定义常量函数的预言。对状态不应用任何变换可以被认为是通过预言机 Uf 实现常数函数 f(x) = 0 作为恒等变换。因此,恒等变换后的输出状态∣ψ2〉等于输入状态∣ψ1〉。

我们通过基于输入量子位的状态作为控制量子位对目标量子位应用 CNOT 变换来定义平衡函数 f(x) 的预言。通过连续的CNOT变换,我们实现了带有真值表的平衡函数的预言机,如表3-1所示。

清单 3-8 显示了 Deutsch-Jozsa 算法的详细实现。

清单 3-8。 Deutsch-Jozsa 实施

import cirq
import numpy as np
The oracle function implements the oracle for the balanced function as well as for the constant function. For the constant function, we do not apply any transformation, and hence it ends up implementing the constant function f(x) = 0 . Alternately, we implement the balanced function of four computational basis states using a CNOT transform on the target qubit based on the 2 input qubit states in succession. For the computation basis state given by |x1x2⟩ for the two-qubit input, the balanced function
implemented can be written as f(x) = f(x0, x1) = x0 ⊕ x1.

def oracle(data_reg, y_reg, circuit, is_balanced=True): if is_balanced:
    circuit.append([cirq.CNOT(data_reg[0],y_reg)
                 ,cirq.CNOT(data_reg[1], y_reg)])

    return circuit
def deutsch_jozsa(domain_size: int,
    func_type_to_simulate: str = "balanced", 
    copies: int = 1000):
    """
    :param domain_size: Number of inputs to the function
    :param oracle: Oracle simulating the function
    :return: whether the function is balanced or constant
    """
    #	Define the data register and the target qubit
    reqd_num_qubits = int(np.ceil(np.log2(domain_size))) #Define the input qubits
    data_reg = [cirq.LineQubit(c) for c
    in range(reqd_num_qubits)] # Define the Target qubits
    y_reg = cirq.LineQubit(reqd_num_qubits) # Define cirq Circuit
    circuit = cirq.Circuit()
    # Define equal superposition state for the input qubits circuit.append(cirq.H(data_reg[c]) for c
in range(reqd_num_qubits)) # Define Minus superposition state circuit.append(cirq.X(y_reg)) circuit.append(cirq.H(y_reg))
# Check for nature of function : balanced/constant # to simulate and implement Oracle accordingly
if func_type_to_simulate == 'balanced': is_balanced = True
else:
is_balanced = False
circuit = oracle(data_reg, y_reg, circuit, is_balanced=is_balanced)
# Apply Hadamard transform on each of the input qubits circuit.append(cirq.H(data_reg[c]) for
c in range(reqd_num_qubits)) # Measure the input qubits
circuit.append(cirq.measure(*data_reg, key='z')) print("Circuit Diagram Follows")
print(circuit)
sim = cirq.Simulator()
result = sim.run(circuit, repetitions=copies) print(result.histogram(key='z'))
 

if name == ' main ':
print("Execute Deutsch Jozsa for a Balanced Function of Domain size 4") deutsch_jozsa(domain_size=4, func_type_to_simulate='balanced', copies=1000)
print("Execute Deutsch Jozsa for a Constant Function of Domain size 4") deutsch_jozsa(domain_size=4,
func_type_to_simulate='', copies=1000)

 从平衡函数的输出中,我们看到所有状态都是 3,对应于∣11〉的二进制量子位状态。由于我们的测量中没有任何与 ∣00〉 相对应的状态,因此它证实了该函数确实是平衡的。

类似地,对于常数函数,我们看到所有测量值都是 0,对应于预期的二进制量子位状态 ∣00〉。

Bernstein-Vajirani算法 

Bernstein-Vajirani 算法可以被认为是 Deutsch-Jozsa 算法的扩展。与 Deutsch-Jozsa 算法非常相似,我们面临一个未知函数,该函数将 0 和 1 的二进制字符串作为输入,并输出 0 或 1 的二进制值。此外,假设函数输出可以写为如下:

Bernstein-Vajirani 算法的目标是找出秘密二进制字符串 定义函数 s = s0, s1…sn − 1。由于该函数是由其秘密字符串 s 定义的,因此我们将黑盒函数称为 fs(x)。

在经典的计算体系中,可以通过查询黑盒函数 n 次来找出秘密字符串。在n次中,每次只能将一个输入位设置为1,其余设置为0,然后观察输出。例如,通过评估输入模式 10000..0 的函数,它将输出秘密位 s0,因为以下情况成立:

在量子计算范式中,我们可以像 Deutsch-Jozsa 一样使用量子并行性,只需调用一次定义黑盒函数的预言机即可找出秘密字符串 s。我们将参考 Deutsch-Jozsa 电路中的图 3-4,同时参考 Bernstein-Vajirani 算法中的不同中间状态,因为两者的高级电路图是相同的。

以下是Bernstein-Vajirani算法的详细步骤:
1. 根据函数 f(x) 的定义域,定义所需的输入量子位数量。例如,如果函数有 2n 个输入,那么我们将需要 n 个量子位。我们将所有输入量子位初始化为状态∣0〉。我们还定义了一个在状态 ∣0〉 初始化的目标量子位。
我们对输入量子位应用 Hadamard 变换 H 来定义相等叠加态。
通过连续应用 NOT 变换 X 和 Hadamard 变换 H,将目标量子位变换为负状态。
这为我们提供了输入和目标量子位的组合状态 |ψ1〉(参见图 3-4),如下所示:

2. 未知函数 fs(x) 在计算基础上的预言机 Uf 输入量子位的状态 ∣x〉 和目标量子位状态 ∣y〉 应该像这样工作:
使用与 Deutsch-Jozsa 相同的方法,我们得到新的状态 |ψ2〉(见图 3-4),如下所示:
请参阅 Deutsch-Jozsa 算法,了解如何通过相位反冲技巧让 f(x) 值显示在全局相位中。
3. 与 Deutsch-Jozsa 算法一样,我们对组合状态 ∣ψ2 〉 中的每个输入量子位应用 Hadamard 变换 H,以获得状态 ∣ψ3〉,如下所示:
在上式中,∣z〉 表示 n 个输入量子位的新计算基础。术语 x ⊙ z 表示 x 和 z 模 2 的二进制字符串表示形式之间的点积。
4. 我们知道函数 fs(x) = s ⊙ x,因此我们可以重写 |ψ3 〉,如下所示:

如果我们忽略目标量子位并查看任何输入计算基础状态 ∣z〉 的振幅,则振幅由以下公式给出:

5. 当输入计算基础状态 z 等于秘密字符串 s 时,其幅度由下式给出:
由于 2 × s ⊙ x 可被 2 整除,因此 2 × s ⊙ x mod 2 始终等于 0。这给出了计算基础状态 ∣z〉 = ∣s〉 的幅度,如下所示:
6. 由于秘密字符串 s 对应的计算基础状态的幅度为 1,因此如果我们测量输入量子位,我们将以 100% 的概率得到状态 ∣s〉。

我们以通用方式针对任意数量的输入量子位实现 Bernstein-Vajirani 算法,并针对六个输入量子位执行该算法。六个量子位的函数域中的输入数量为 2^6 = 64。对于相应秘密位设置为 1 的每个输入量子位,我们对目标量子位应用 CNOT 变换,并将输入量子位作为控制量子位。该变换确保每当秘密字符串 s 和计算基础状态字符串 x 之间的点积为偶数时,目标量子位上的结果变换为零。另一方面,当该点积为奇数时,目标量子位将进行 NOT 运算。总结一下,这个转换实现了Oracle转换:

当秘密字符串 s 和计算基础状态字符串 x 之间的点积为偶数时,则 fs(x) = 0,因此 |fs (x) ⊕ y〉 = ∣y〉。正如我们在这种情况下看到的,目标量子位 ∣y〉 的状态保持不变。当点积为奇数时,fs(x) = 1,因此 |fs(x) ⊕ y〉 = ∣1 ⊕ y〉。在这种情况下,我们可以看到 NOT 运算被应用于目标量子位的状态。清单 3-9 显示了 Bernstein-Vajirani 算法的详细实现。

清单 3-9。实施 Bernstein–Vajirani 算法

import cirq import numpy as np def func_bit_pattern(num_qubits): """ Create the Oracle function Parameters :param num_qubits: :return: """ bit_pattern = [] for i in range(num_qubits): bit_pattern.append(np.random.randint(0, 2)) print(f"Function bit pattern: \ {''.join([str(x) for x in bit_pattern]) }") return bit_pattern def oracle(input_qubits,target_qubit,circuit, num_qubits,bit_pattern): """ Define the oracle
:param input_qubits: :param target_qubit: :param circuit: :param num_qubits: :param bit_pattern: :return: """ for i in range(num_qubits): if bit_pattern[i] == 1: circuit.append(cirq.CNOT(input_qubits[i], target_qubit)) return circuit def BV_algorithm(num_qubits, bit_pattern): """ :param num_qubits: :return: """ input_qubits = [cirq.LineQubit(i) for i in range(num_qubits)] target_qubit = cirq.LineQubit(num_qubits) circuit = cirq.Circuit() circuit.append([cirq.H(input_qubits[i]) for i in range(num_qubits)]) circuit.append([cirq.X(target_qubit) , cirq.H(target_qubit)]) circuit = oracle(input_qubits,target_qubit, circuit,num_qubits,bit_pattern) circuit.append([cirq.H(input_qubits[i]) for i in range(num_qubits)]) circuit.append(cirq.measure(*input_qubits,key='Z')) print("Bernstein Vajirani Circuit Diagram") print(circuit) sim = cirq.Simulator() results = sim.run(circuit, repetitions=1000)
:param input_qubits: :param target_qubit: :param circuit: :param num_qubits: :param bit_pattern: :return: """ for i in range(num_qubits): if bit_pattern[i] == 1: circuit.append(cirq.CNOT(input_qubits[i], target_qubit)) return circuit def BV_algorithm(num_qubits, bit_pattern): """ :param num_qubits: :return: """ input_qubits = [cirq.LineQubit(i) for i in range(num_qubits)] target_qubit = cirq.LineQubit(num_qubits) circuit = cirq.Circuit() circuit.append([cirq.H(input_qubits[i]) for i in range(num_qubits)]) circuit.append([cirq.X(target_qubit) , cirq.H(target_qubit)]) circuit = oracle(input_qubits,target_qubit, circuit,num_qubits,bit_pattern) circuit.append([cirq.H(input_qubits[i]) for i in range(num_qubits)]) circuit.append(cirq.measure(*input_qubits,key='Z')) print("Bernstein Vajirani Circuit Diagram") print(circuit) sim = cirq.Simulator() results = sim.run(circuit, repetitions=1000)

 从输出中我们可以看到,Bernstein-Vajirani 算法在测量输入量子位时以 100% 的概率正确识别了秘密字符串 111011。建议读者针对较大的域大小执行该算法,并查看该算法是否按预期工作。

贝尔不等式检验 

贝尔的不等式检验说明​​了这样一个事实:通过使用量子纠缠,人们可以实现比无法相互通信的两方或多方之间经典的相关性更强的相关性。尽管纠缠可以在两个量子物体之间产生强相关性,但它本身在通信中并没有什么用处,因为仅对一个量子物体进行纠缠态测量就可以使另一个量子物体的测量完全确定性。例如,对于 Alice 和 Bob 共享的 Bell 状态,Alice 对 ∣0〉 或 ∣1〉 的测量完全决定了 Bob 量子位的状态,反之亦然。然而,如果Alice和Bob都可以在纠缠后进行测量并影响测量的最终结果,那么Alice和Bob之间就可以创建有用的相关性,这在经典设置中是不可能的。我们将通过爱丽丝和鲍勃之间的合作游戏来激发贝尔不等式检验。然而,在我们进行贝尔不等式测试之前,让我们推断出如果 Alice 在|α〉正交基 , ∣α⊥ 〉 中测量她的量子位,而 Bob 在|β〉 正交基 ∣β⊥ 〉 中测量他的量子位,则得出不同结果的概率, 假设它们共享贝尔状态.需要了解这些概率才能提出合作博弈的获胜策略。

我们将 Alice 基的一般测量基础表示为 ∣α〉 和 ∣α⊥ 〉,其中 α 是基态 ∣α〉 与 ∣0〉 状态所成的角度。因此,我们可以将它们表示如下:

计算基础状态∣0〉在基础状态∣α〉和∣α⊥〉上的投影为〈0| α〉 = cos α 和 〈0| α⊥〉 = − sin α。类似地,计算基础状态∣1〉在∣α〉上的投影为〈1| α〉 = sin α 且 |α⊥ 〉 为 〈1|α⊥ 〉 = cos α。利用这些信息,我们可以在基础 {|α〉, |α⊥〉} 中写出 ∣0〉 和 ∣1〉,如下所示:

类似地,我们可以在另一个基组 {|β 〉, |β⊥〉} 中表示 |0〉 和 |1〉,其中 β 是基状态 |β 〉 与 |0〉 状态所成的角度,如下所示:

现在,如果 Alice 在 {|α〉, |α⊥ 〉} 基础上测量她的量子位,而 Bob 在 {|β〉, |β⊥〉} 基础上测量他的量子位,则纠缠贝尔态可以用以下形式表示下列的:

表 3-2 显示了 Alice 的测量基础状态(即 {|α〉, |α⊥〉})和 Bob 的测量基础状态(即 {|β〉, |β)的每个结果的概率⊥〉}。

现在让我们讨论 Alice 和 Bob 之间的合作博弈来说明贝尔不等式检验。游戏由两名玩家(爱丽丝和鲍勃)和一名裁判组成。 Alice和Bob相隔很远,他们之间没有任何沟通渠道。在每一轮中,裁判向 Alice 发送一个 x1 位,向 Bob 发送一个 x2 位。根据接收到的位,Alice 和 Bob 应该分别返回位 a(x1) 和 b(x2 )。如果满足以下条件,爱丽丝和鲍勃将赢得本轮:

表 3-3 显示了所有 x1 和 x2 对赢得比赛的真值表。

在经典世界中,Alice 和 Bob 能够想出的最佳策略最多 75% 的情况下会赢得比赛。这里,这些策略类似于 Alice 和 Bob 用于发回比特的决策函数 a(x1 ) 和 b(x2 )。人们可以验证爱丽丝和鲍勃在经典意义上玩的最佳策略是发回相同的位。因此,成功概率为 75% 的两种最佳策略如下:

现在让我们看看 Alice 和 Bob 是否可以通过量子策略做得更好,因为他们共享贝尔态。这是一种这样的策略:

1. 如果 Alice 收到位 x1 = 0,她会在与 α = 0 相关的 { ∣0〉, ∣π/2〉} 基础上测量她的量子位,这给了我们标准 {|0〉,| 1〉}计算基础。如果她收到位 x1 = 1,她会在 { ∣π/4 〉, ∣3π/4〉} 基础上测量她的量子位。
2. Bob 选择类似的策略,根据他是否收到位 x2,他在 { ∣π/8 〉, ∣5π/8〉} 或 { ∣− π/8 〉, ∣3π/8〉} 中测量量子位= 0 或 x2 = 1。

对于每个测量的基础 {|k〉, | k⊥ 〉} Alice 和 Bob 会发回 0(表示 |k〉)和 1(表示 ∣k⊥〉)。这是很重要的一点,因为它将确定 Alice 和 Bob 返回的 a(x1 ) 和 b(x2 ) 的值。

当x1=0时,x2=0

现在 |α = 0〉 ⊗ ∣β = π/8〉 对应于 a(x1 ) = 0, b(x2 ) = 0。因此,我们有 a(x1) ⊕ b(x2 ) = 0 ⊕ 0 = 0 = xy = 0 × 0 = 0 当 (x1 = 0, x2 = 0) 时,概率为

相似地

另外,|α⊥, α = 0〉 ⊗ ∣β⊥, β = π/8〉 对应于 a(x1 ) = 1, b(x2 ) = 1。因此,我们有 a(x1 ) ⊕ b(x2 ) = 1 ⊕ 1 = 0 = xy = 0 × 0 = 0 当 (x1 = 0, x2 = 0) 时,概率为

结合上面两个公式,我们可以说,当 (x1 = 0, x2 = 0) 时,Alice 和 Bob 有获胜概率。

当x1 = 0,x2 = 1时:

现在 |α = 0〉 ⊗ ∣β = − π/8〉 对应于 a(x1 ) = 0, b(x2 ) = 0。因此,a(x1) ⊕ b(x2 ) = 0 ⊕ 0 = 0 = xy = 0 × 1 = 0 当 (x1 = 0, x2 = 1) 时,概率为

相似地,

状态 |α⊥, α = 0〉 ⊗ ∣β⊥, β = − π/8〉 对应于 a(x1 ) = 1, b(x2 ) = 1。因此,a(x1 ) ⊕ b(x2 ) = 1 ⊕ 1 = 0 = xy = 0 × 1= 0 当 (x1 = 0, x2 = 1) 概率为

结合公式,我们可以说,当 (x1 = 0, x2 = 1) 时,Alice 和 Bob 有获胜概率。

类似地,使用所采用的策略可以推断出,对于其余两个条件 (x1 = 1, x2 = 0) 和 (x1 = 1, x2 = 1),Alice 和 Bob 的获胜概率为。建议读者对这两个条件进行数学计算,并验证该说法是否正确。

因此,对所有可能的位 x1 和 x2 组合使用所采用的策略,Alice 和 Bob 设法发回 a(x1) 和 b(x2 ),以确保 a(x1 ) ⊕ b(x2 ) = x1 x2 的概率。这高于经典设置中可实现的最大获胜概率 0.75。

我们通过对清单 3-10 中 Alice 和 Bob 之间的合作博弈进行建模,在 Cirq 中实现贝尔不等式。合作博弈就是使用我们刚才讨论的策略。

清单 3-10。贝尔不等式

import cirq import numpy as np def bell_inequality_test_circuit(): """ Define 4 qubits 0th qubit - Alice 1st qubit - contains the bit sent to Alice by the referee 2nd qubit - Bob's qubit 3rd qubit - contains the bit sent to Bob by the referee :return: cirq circuit """ qubits = [cirq.LineQubit(i) for i in range(4)] circuit = cirq.Circuit() # Entangle Alice and Bob to the Bell state circuit.append([cirq.H(qubits[0]), cirq.CNOT(qubits[0], qubits[2])]) # Apply X^(-0.25) on Alice's Qubit circuit.append([cirq.X(qubits[0])**(-0.25)]) # Apply Hadamard transform to the referee Qubits # for Alice and Bob # This is done to randomize the qubit circuit.append([cirq.H(qubits[1]), cirq.H(qubits[3])]) # Perform a Conditional X^0.5 on Alice and Bob # Qubits based on corresponding referee qubits circuit.append([cirq.CNOT(qubits[1], qubits[0])**0.5]) circuit.append([cirq.CNOT(qubits[3], qubits[2])**0.5]) # Measure all the qubits circuit.append(cirq.measure(qubits[0], key='A')) circuit.append(cirq.measure(qubits[1], key='r_A')) circuit.append(cirq.measure(qubits[2], key='B')) circuit.append(cirq.measure(qubits[3], key='r_B')) return circuit
def main(iters=1000): # Build the Bell inequality test circuit circuit = bell_inequality_test_circuit() print("Bell Inequality Test Circuit") print(circuit) #Simulate for several iterations sim = cirq.Simulator() result = sim.run(circuit, repetitions=iters) A = result.measurements['A'][:, 0] r_A = result.measurements['r_A'][:, 0] B = result.measurements['B'][:, 0] r_B = result.measurements['r_B'][:, 0] win = (np.array(A) + np.array(B)) % 2 == (np.array(r_A) & np.array(r_B)) print(f"Alice and Bob won {100*np.mean(win)} % of the times") if __name__ == '__main__': main()

西蒙算法

在 Simon 的问题中,我们得到一个函数 f(x),其访问仅限于通过黑盒变换 Uf 进行查询,就像 Deutsch-Jozsa 和 Bernstein-Vajirani 算法中的那样。作为西蒙问题的一部分,我们需要执行以下操作:
1. 判断该函数是否是一对一函数,即输入的每个值都映射到唯一的输出。
2. 判断该函数是否为二对一函数,即输入的每个值正好映射到两个输入。当函数为二对一时,存在一个秘密二进制字符串 s 将具有相同输出的每对输入 x1 和 x2 联系起来,即 f(x1 ) = f(x2 ) 当且仅当 x1 ⊕ x2 = s。我们需要为已识别的二对一函数确定秘密字符串 s。
3.此外,假定输入函数将始终是一对一函数或二对一函数。

西蒙算法是其他重要算法的先驱,例如用于整数素因数分解的肖尔算法。图 3-5 展示了 Simon 算法的高级流程图。

以下是与西蒙算法相关的步骤:
1. 我们根据问题的领域从 n 个输入量子位开始。此外,我们定义一组 n 个量子位作为目标量子位来保存 f(x) 的值。所有量子位都初始化为零。 2n 个量子位的初始状态可以写成如下:
2. 我们对每个输入量子位应用 Hadamard 变换,为输入创建相等的叠加态。 Hadamard 变换后 2n 个量子位的组合状态由下式给出:
3. 在下一阶段,我们通过 Oracle 变换 Uf 将函数 f(x) 应用于每个计算基础状态 x = xo x1…xn − 1。因此,对于每个计算基础状态|x〉,我们有:
在上式中,|y〉 是 n 个目标量子位中每一个的初始状态,因此 y = 0。这给我们提供了新状态 |ψ2 〉,如下所示:
请注意,与之前的算法不同,Simon 算法中没有相位反冲,因为我们设置了目标量子位的初始状态 y = 0。

我们对输入量子位应用 Hadamard 变换以获得最终状态 ∣ψ3 〉,如下所示:

4. 现在让我们看看当秘密字符串 s = 0000…0 时会发生什么,即函数是一对一的。当函数是一对一函数时,f(x) 的每个值都与特定的输入字符串 x 相关联。因此,如果我们测量目标量子位并观察 ∣f(x)〉,我们将只得到一个对应的 x。对于每个输入 ∣z〉 状态,假设我们已经观察到目标量子位的状态为 ∣f(x)〉,则概率幅度由 给出。因此,给定 ∣z〉 状态的相应概率,我们观察到目标量子位的状态为 ∣f(x)〉,由 给出。由于所有 z 的概率相同,因此我们在每个目标量子位状态 f(x) 的输入状态 z 上得到均匀分布。
5. 现在我们讨论秘密字符串s不全零的情况;即,该函数是二对一函数。一旦我们测量了目标量子位并观察了状态 ∣c〉,就会有两个 x 值,例如 x1 和 x2,这将给出 f(x1 ) = f(x2 ) = c。对于目标量子位的每个测量状态 c,每个输入量子位状态 ∣z〉 的概率幅度由以下给出:
对于任何状态 ∣z〉 具有非零概率幅度,以下应该成立:
对于二对一函数,我们知道 x1 和 x2 由关系 x1 ⊕ x2 = s 绑定,这也意味着 x2 = x1 ⊕ s。现在让我们通过替换 x2 = (x1 ⊕ s) 来简化 x1 ⊙ z = x2 ⊙ z。
由于两边都有 x1 ⊙ z,因此恒等式简化为 s ⊙ z = 0。
这意味着当我们获得测量任何输入状态 z 的非零概率时,则 s ⊙ z = 0 。
我们可以测量输入量子位并观察 n 个不同的 z 值。根据观察到的 z 值,我们可以求解一组 n 个方程,如下所示,以找到秘密字符串:
这n个方程可以通过高斯消元法等算法方便地求解。
清单 3-11 说明了 Simon 算法的详细实现。秘密字符串110用于演示西蒙算法的实现。
清单 3-11。西蒙算法

import cirq import numpy as np def oracle(input_qubits, target_qubits, circuit): # Oracle for Secret Code 110 circuit.append(cirq.CNOT(input_qubits[2],target_qubits[1])) circuit.append(cirq.X(target_qubits[0])) circuit.append(cirq.CNOT(input_qubits[2], target_qubits[0])) circuit.append(cirq.CCNOT(input_qubits[0],input_qubits[1], target_qubits[0])) circuit.append(cirq.X(input_qubits[0])) circuit.append(cirq.X(input_qubits[1])) circuit.append(cirq.CCNOT(input_qubits[0], input_qubits[1], target_qubits[0])) circuit.append(cirq.X(input_qubits[0])) circuit.append(cirq.X(input_qubits[1]))
circuit.append(cirq.X(target_qubits[0])) return circuit def simons_algorithm_circuit(num_qubits=3,copies=1000): """ Build the circuit for Simon's Algorithm :param num_qubits: :return: cirq circuit """ input_qubits = [cirq.LineQubit(i) for i in range(num_qubits)] target_qubits = [cirq.LineQubit(k) for k in range(num_qubits, 2 * num_qubits)] circuit = cirq.Circuit() # Create Equal Superposition state for the # Input qubits through Hadamard Transform circuit.append([cirq.H(input_qubits[i]) for i in range(num_qubits)]) # Pass the Superposition state through the oracle circuit = oracle(input_qubits, target_qubits, circuit) # Apply Hadamard transform on the input corners circuit.append([cirq.H(input_qubits[i]) for i in range(num_qubits)]) # Measure the input and the target qubits circuit.append(cirq.measure(*(input_qubits + target_qubits), key='Z')) print("Circuit Diagram for Simons Algorithm follows") print(circuit) #Simulate Algorithm sim = cirq.Simulator() result = sim.run(circuit,repetitions=copies) out = dict(result.histogram(key='Z')) out_result = {} for k in out.keys():
new_key = "{0:b}".format(k) if len(new_key) < 2*num_qubits: new_key = (2*num_qubits – len(new_key))*'0' + new_key out_result[new_key] = out[k] print(out_result) if __name__ =='__main__': simons_algorithm_circuit()

根据 Simon 算法的输出,只需选择 f(x) 值(存储在组合 |x〉|f(x)〉 状态的最后 3 位中)的两个结果,就可以轻松找到秘密字符串。火柴。如果我们取两个结果 111010 和 001010,我们可以看到两个结果的输出位相同并且等于 010。因此,如果我们对两个输入 111 和 001 进行模 2 加法,我们将得到我们的密码。因此,密码是 111 ⊕ 001,这给我们 110,它与我们选择的密码相匹配。建议读者编写一个小函数,使用类似的逻辑自动执行密钥查找过程。 

格罗弗算法

量子计算相对于经典计算的潜在优势之一是它访问数据库元素的速度。格罗弗算法就是这样一种算法,它可以在从数据库中搜索项目时提供二次加速。 Grover 的算法使用幅度放大技巧,这不仅有助于数据库搜索任务,而且可以广泛用于多种应用。

假设数据库中有 N = 2^n 个项目,并且我们想要搜索由 k 索引的项目,我们将其称为获胜者。我们可以通过对应于 n 个输入量子位的计算基础状态 ∣x〉 来定义 N 个项目。预言机在每个计算基础状态 |x〉 ∈ {0, 1}^n 上工作,并为获胜者项目返回函数输出 f(x) = 1,为其余项目返回 0。在量子计算范式中,我们可以将预言机 Uf 视为在计算基础状态 ∣x〉 上工作的酉算子,如下所示:
对于计算基础状态∣k〉引用的获胜项,Oracle变换的效果如下所示:

现在我们已经了解了有关预言机的一些信息,让我们看看 Grover 算法的步骤:
1. 基于数据库中的项目数量 N = 2n,我们使用 Hadamard 变换定义 n 个量子位上的相等叠加状态,初始化为 |0〉⊗n,即。我们还将在 ∣0〉 处初始化的目标量子位设置为负状态,我们用它来实现相位反冲技巧。这给出了输入和目标量子位的组合状态 |ψ1 〉,如下所示:
2. 下一步,我们实现预言机 Uf,它作用于输入和目标的计算基础状态 Uf |x〉 ∣y〉 = |x〉 ∣ f(x) ⊕ y〉,其中 y 是目标量子位状态。通过我们在 Deutsch-Jozsa 算法中说明的相位反冲技巧,将 Uf 应用于 |ψ1〉 可以得到 ∣ψ2 〉。经过预言酉 Uf 变换后的状态 ∣ψ2 〉 由下式给出:
可以看到,目标量子位状态保持不变,我们能够得到每个计算基础状态∣x〉对应的阶段的函数值f(x)。因此,展望未来,我们可以丢弃目标量子位,并将预言机 Uf 在任何计算基础状态上的变换视为 Uf|x〉 = (−1)^f(x) |x〉。现在我们已经仅根据输入量子位建立了 Oracle 函数,我们将不再引用目标量子位。某种意义上,预言机实现了函数 f(x),当 x 是获胜者状态时,该函数为 1,其他地方为 0。
3. 我们可以想到等叠加态作为两个相互正交的向量的线性组合:搜索到的或获胜的项目,我们用 ∣k〉 表示,向量 ∣c〉 是通过删除向量分量获得的单位向量∣k〉 来自等叠加态 |ψin 〉。图 3-6(a) 说明了这一点。
这允许我们在两个向量 ∣k〉 和 |c〉 的范围内写 |ψin〉(见图 3-6(a)),如下所示:
4. 现在,一旦我们对状态∣ψin〉应用预言变换Uf,与获胜项状态∣k〉对应的阶段就会乘以-1,因此输出状态∣ψmid〉可以表达如下:
因此,酉预言变换 Uf 基本上具有对向量 ∣c〉 进行反射的效果,如图 3-6(b) 所示。反射具有否定获胜状态∣k〉振幅的效果。
5. 最后,我们将向量 |ψmid〉 反映在向量 |ψeq 〉 上,其中 |ψeq〉 是 n 个量子位的相等叠加状态,即 。沿向量 |ψeq〉 的反射由以下公式给出:变换。在 |c〉 和 |k〉 的二维基础上,我们可以将 |ψeq〉 写为。这使得酉变换 U eqψ 如下:
将酉变换 Uψeq 应用于 |ψmid〉,即 ∣c〉 和 ∣k〉 的二维基础中的 [cosθ − sinθ]T,我们得到 ∣ψout〉,如下所示:
因此,通过连续的酉变换 Uf 和 Uψeq ,我们已经从状态 |ψin〉 = sinθ|k〉 + cosθ ∣ c〉 变为 |ψout〉 = sin 3θ|k〉 + cos 3θ|c〉。由于sin在第一象限是单调递增的,cos是单调递减的,所以不难看出sin项给出的|k〉的幅度已经从sinθ增加到sin3θ,而其余状态的幅度由∣c给出〉 从 cosθ 减小到 cos3θ。
6. 连续迭代地应用酉变换 Uf 和 U eqψ ,使我们能够通过向获胜者状态 ∣k〉 放大幅度来收敛到该状态。我们可以将这两个变换组合为 UUeq f ψ 并将其称为 Grover 变换 G。因此,如果我们应用 Grover 变换进行 m 次迭代,则最终输出状态将非常接近∣k〉。
当我们使用属于具有四个项目(即 N = 4)的预言机的双输入量子位时,我们有以下结果:
因此,获胜项目的初始幅度为 1/2,相应的概率为 1/4。由于 sinr=1/2 ,这意味着 θ = 30°。经过酉变换 Uf 和 Ueq 后,获胜项目的新振幅为 sin3θ = sin (3 × 30°) = sin 90° = 1。这意味着起始状态 |ψin 〉 已转换为获胜项目状态∣k〉 只需一次迭代。
7. 预言机提供的 Uf 变换与 Deutsch-Jozsa 和 Bernstein-Vajirani 算法中的相同。
8. 我们需要一种方法来根据量子算子提出酉变换 Uψeq 。就Hadamard门而言,Uψeq 可以写成如下:

现在 H⊗n|0〉⊗n 什么都不是,而是 n 个量子位的相等叠加状态,因此其中 N = 2n。此外,由于 Hadamard 变换 H 是幂等的,我们有 H2 = I。使用此信息,我们可以重写公式 3-57,如下所示:
2|ψeq〉〈ψeq | − I 正是关于向量 〈ψeq | 的反射变换。
现在我们已经证明了 H⊗n(2| 0〉⊗n 〈0|⊗n − I)H⊗n 确实是关于 |ψeq〉 反射的酉变换,剩下的就是找到一种方法来实现使用标准门进行变换 (2| 0〉⊗n 〈0|⊗n − I)。
9. 为了了解如何实现 (2| 0〉⊗n 〈0|⊗n − I),让我们看看这个变换对基本状态 ∣x〉 有何作用。

因此,当基础状态不是 |0〉⊗n 时,变换会翻转相位。
这种条件相翻转算子可以通过使用 CNOT、X 和 H 门的组合来实现,正如我们将在两个量子位的 Grover 算法实现过程中看到的那样。
10. 请注意,仅在 Grover 变换的第一次迭代中,Grover 变换 |ψin 〉 的输入状态才等于 |ψeq〉。您不应该假设在每次迭代中都会出现这种情况,因为从第二次迭代开始,Grover 迭代的 ∣ψin 〉 状态会有所不同。

现在我们已经详细讨论了 Grover 算法的所有不同方面,我们可以将 Grover 算法的高级流程图放在一起,如图 3-7 所示。

如前所述,我们使用数据库大小 4 来实现 Grover 算法。此外,我们构建 oracle Uf 来搜索元素 01 以供说明。对于预言机的广义实现,我们反转获胜者元素位为零所对应的输入量子位的状态。这确保获胜者计算基础状态转换为 |1〉⊗n 给出的所有 1 状态,其中 n 是输入量子位的数量。在下一步中,我们基于所有输入量子位作为控制量子位,对目标量子位应用条件 NOT 变换。由于获胜者计算基础状态为 |1〉⊗n ,因此目标量子位上的条件 NOT 变换只会为获胜者状态设置 f(x) = 1。由于相位反冲,为获胜者计算状态设置 f(x) = 1 将在其幅度中引入所需的 -1 翻转因子。条件 NOT 变换是通过使用 Toffoli 门来实现的。一旦实现所需的翻转,我们需要撤消条件 NOT 运算,以便获胜者计算基础状态从 |1〉⊗n 恢复到其原始值。

该算法的另一个重要部分是构建反射算子 U eqψ ,它将反映在关于相等叠加状态 ∣ψeq〉 的预言变换 Uf 后获得的状态 ∣ψmid〉 。我们可以按照图 3-8 中 Grover 算法电路图所示的方式实现这一点,数据库大小为 4。预言 Uf 和弯曲算子 U eqψ 形成了 Grover 迭代器。通过 Grover 迭代器的几轮应用,人们应该能够以高概率测量获胜者状态。对于由使用两个量子位的计算基础状态索引的四个项目组成的数据库,我们在一个 Grover 迭代器中收敛到获胜者状态。

建议读者采用包括∣00〉在内的不同基态,并验证条件相位翻转算子是否按预期工作。 Grover 算法的一次迭代足以收敛到获胜者状态 01,正如我们之前在图 3-8 中看到的那样。具体实现请参见清单3-12。

清单 3-12。格罗弗算法

import cirq import numpy as np def oracle(input_qubits, target_qubit, circuit, secret_element='01'): print(f"Element to be searched: {secret_element}")
# Flip the qubits corresponding to the bits containing 0 for i, bit in enumerate(secret_element): if int(bit) == 0: circuit.append(cirq.X(input_qubits[i])) # Do a Conditional NOT using all input qubits as control # qubits circuit.append(cirq.TOFFOLI(*input_qubits, target_qubit)) # Revert the input qubits to the state prior to Flipping for i, bit in enumerate(secret_element): if int(bit) == 0: circuit.append(cirq.X(input_qubits[i])) return circuit def grovers_algorithm(num_qubits=2, copies=1000): # Define input and Target Qubit input_qubits = [cirq.LineQubit(i) for i in range(num_qubits)] target_qubit = cirq.LineQubit(num_qubits) # Define Quantum Circuit circuit = cirq.Circuit() # Create equal Superposition State circuit.append([cirq.H(input_qubits[i]) for i in range(num_qubits)]) # Take target qubit to minus state |-> circuit.append([cirq.X(target_qubit) ,cirq.H(target_qubit)]) # Pass the qubit through the Oracle circuit = oracle(input_qubits, target_qubit, circuit) # Construct Grover operator. circuit.append(cirq.H.on_each(*input_qubits)) circuit.append(cirq.X.on_each(*input_qubits)) circuit.append(cirq.H.on(input_qubits[1])) circuit.append(cirq.CNOT(input_qubits[0] ,input_qubits[1]))
circuit.append(cirq.H.on(input_qubits[1])) circuit.append(cirq.X.on_each(*input_qubits)) circuit.append(cirq.H.on_each(*input_qubits)) # Measure the result. circuit.append(cirq.measure(*input_qubits, key='Z')) print("Grover's algorithm follows") print(circuit) sim = cirq.Simulator() result = sim.run(circuit, repetitions=copies) out = result.histogram(key='Z') out_result = {} for k in out.keys(): new_key = "{0:b}".format(k) if len(new_key) < num_qubits: new_key = (num_qubits - len(new_key))*'0' + new_key out_result[new_key] = out[k] print(out_result) if __name__ =='__main__': grovers_algorithm(2)

总结

至此,我们进入了第 3 章的结尾。在本章中,我们熟悉了 Cirq 中的量子计算编程范式,并在一定程度上熟悉了 Qiskit 中的量子计算编程范式。在本章中,我们研究了各种量子计算算法,例如 Deutsch-Jozsa 算法、Bernstein-Vajirani 算法、贝尔不等式、Grover 算法和 Simon 算法。通过利用叠加、纠缠、干涉以及与量子力学相关的其他微妙之处的量子力学特性,所有这些量子算法在计算上比经典算法更高效。建议读者彻底了解不同的算法及其基础数学,以便更好地理解计算的量子范式。

在下一章中,我们将研究基于量子傅立叶变换的算法,这些算法构成了量子计算和量子机器学习范式中一组重要算法的支柱。期待您的参与!

量子傅立叶变换及相关算法

在本章中,我们将研究量子傅里叶变换及其在不同量子算法中的应用。对于经典计算机来说,将整数因式分解为素数或求周期等问题是计算上难以解决的问题,因为涉及的运算数量呈指数级增长。使用很大程度上基于量子傅立叶变换的量子相位估计算法可以有效地解决整数因式分解和周期查找。另外,由于量子相位估计的目的是找到与酉算子的特征向量相对应的特征值,因此它是优化中重要算法的支柱,例如 HHL 算法(以 Hassim、Harrow 和 Lloyd 命名),用作矩阵求逆量子计算中的例行公事。我们首先修改傅里叶变换及其离散对应物离散傅里叶变换的概念,然后继续讨论令人兴奋的量子傅里叶变换和量子相位估计算法领域。接下来我们讨论和实现一些与量子傅里叶变换相关的算法,例如分解数字和周期查找。在本章的最后,我们简要介绍了群论的基础知识,试图解释隐藏子群问题以及它与几种基于傅里叶变换的算法的关系。

傅立叶级数

实数变量的周期函数可以展开为正弦和余弦形式的傅立叶级数,或者一般而言复指数函数的形式。我们可以将这样一个在长度为 L 的周期后重复自身的周期函数 f(x) 用傅立叶级数展开形式表示如下:

任何函数 f(x) 都可以被视为其域中不同 x 值的函数值向量。如果 x 是实数,则在任何给定区间内 x 的值有无数个,并且该函数可以被视为无限维向量。式4-1中代入不同k值得到的指数函数e^{\frac{2\pi ikx}{L}}充当基函数,就像矢量基一样。对于域区间 [a, b] 上的任意两个函数 f 和 g,该函数空间中的点积(其中 L = b − a)由以下给出:

其中 f(x)* 表示 f(x) 的复共轭函数。让我们计算对应于 k = k1 和 k = k2 值的两个复指数函数 gk1 和 gk2 的点积。

由于 k1 、 k2 是实数离散值,因此对于 k1 和 k2 的所有可能值,k2 − k1 = t 始终是整数。这里强调了两种可能性。
情况 1:当 k2 ≠ k1 时,k2 − k1 是非零整数。对于 k2 − k1 的任何非零整数值,e^{\frac{2\pi i(k_{2}-k_{1}))}{L}}=1。这使得上式 4-3 中的点积表达式为零。
情况 2:当 k2 = k1 时,k2 − k1 = 0。我们不能直接代入公式 4-3 中的 k2 − k1 = 0,因为用 0 代入分母 k2 − k1 会使表达式不确定。我们可以评估的是 <g_{k_{1}},g_{k_{2}}> 的极限,因为 k1 − k2 → 0。

我们可以从公式 4-4 和公式 4-6 推断,复指数函数 g_{k}(x)=e^{\frac{2\pi ikx}{L}} 构成所有具有基本周期长度 L 的周期函数的正交基。另外,我们从方程 4-6 中注意到,由 <g_k, g_k> = \left \| g_k \right \|^2 给出的 gk 范数的平方是 L。我们可以通过其范数 \sqrt{L}对 gk(x) 进行归一化,以便给出指数基函数由h_{k}(x)=\frac{1}{\sqrt{L}}e^{\frac{2\pi ikx}{L}}具有单位范数,因此形成正交基。

k 项可以解释为某种形式的频率。不同的 k 值会导致具有多个频率的周期函数中的不同谐波。

对应于不同频率 k 的每个谐波的系数可以计算为 f(x) 与单位基向量 hk(x) 的点积,如下所示:

傅里叶变换

傅里叶变换是傅里叶级数的自然扩展,我们尝试用复指数函数来表示非周期函数。您可以将非周期函数视为周期长度 L → ∞ 的函数,因此由 a 和 b 表示的一个周期 L 的下限和上限分别趋向于 −∞ 和 +∞。类似地,非周期函数中的谐波不再是离散的,而是占据连续的频率。非周期函数的傅里叶变换表示可以写成傅里叶级数的极限情况,如下所示:

可以将\frac{K}{L}n \to m  代入得到傅里叶变换表示如下:

为了在不同的变换中用 k 一致地引用频率变量,让我们再次将变量 m 更改为 k 并将非周期函数 f(x) 的傅里叶变换表示如下:

谐波\widetilde{f}(k)的系数函数现在处于连续域,它与 f(x) 的关系如下:

一般而言,系数\widetilde{f}(k)称为函数 f(x) 的频率响应。从 f(x) 到其频率响应\widetilde{f}(k)的变换称为傅里叶变换 F,表示如下:

类似地,可以应用傅里叶逆变换从函数的频率响应到函数本身,如下所示。

需要注意的一件事是,周期函数的傅里叶变换将成为其傅里叶级数表示。

离散傅里叶变换

我们之前定义的傅里叶变换仅适用于连续函数。如果我们有一个针对离散输入变量的函数 f_n,我们可以使用离散傅立叶变换。任何函数f_0,f_1,f_2...,f_{n-1}都可以用其离散傅里叶变换 (DFT) 展开表示如下:

离散傅里叶变换的频率响应函数\widetilde{f}_k如下所示:

克罗内克德尔塔函数

克罗内克增量\delta_{nm}(见图 4-1)是一个仅当离散变量 n 的值 m 时才等于 1 的函数。对于 n 的所有其他值,该函数的值为 0。

克罗内克德尔塔函数可以被认为是 N 维向量,仅在 n 的一个离散值时才假设值为 1。当 m ≠ 0时,两个克罗内克 delta 函数\delta_{nm}\delta_{n0}的点积为 0,而克罗内克 delta 的范数,即\delta_{nm}与其自身的点积为 1。因此,克罗内克 delta 函数可用于定义正交在非频域中表示离散函数的基础。例如,离散函数f_n可以表示为其代表性 Kronecker delta 函数的线性和,如下所示:

现在,如果我们想检索任意 n = j 处的函数值,只需\delta_{nj}= 1,因此我们就可以得到f_j的函数值。

事实上,我们可以将克罗内克德尔塔函数\delta_{nj}写为单位向量 |j〉。这将公式 4-16 中离散函数f_n的表示简化为以下形式:f_n=\sum_{j=0}^{N-1}f_i|j>

克罗内克增量的这种矢量表示将在量子傅里叶变换公式中派上用场。

使用 Kronecker Delta 函数激发量子傅立叶变换

克罗内克 delta 函数的频率响应可使用公式 4-15 计算如下:

根据频率响应,我们可以使用离散傅立叶变换展开式(参见公式 4-14)将\delta_{nm}写成如下:
与傅里叶级数一样,即使在不同 k 值的离散傅里叶变换的情况下,复指数函数h_k=\frac{1}{\sqrt{N}}e^{\frac{2\pi ikn}{N}}也会形成标准正交基。我们可以将这些复指数函数h_k表示为单位范数的 N 维基向量,并使用狄拉克符号将它们表示为 |k〉。换句话说,我们有这个:
复指数函数的这种向量表示允许我们将公式 4-19 中的函数\delta_{nm}表示简化如下:
或者,我们可以将\delta_{nm}表示为克罗内克 delta 基中的 |m〉,因此方程 4-21 可以写成全基方程,如下所示:
量子傅立叶变换被视为两组基函数之间的变换:空间或时域基函数由 Kronecker delta\delta_{nm}= |m〉 给出,频率基函数由指数\frac{1}{\sqrt{N}}e^{\frac{2\pi ikn}{N}}=|k>给出。
在这方面,方程 4-22 是一个重要的表示,因为量子傅立叶变换是酉变换 U,它采用 |m〉 给出的任何广义空间或时域基函数,并用频域基 |k〉 表示它,所示这里:
由于傅里叶变换酉算子 U 是线性的,任何离散函数的傅里叶变换都可以计算为傅里叶级数变换在其基函数上的线性和,如下所示:
替换 U| j〉 根据4-24中的公式4-23,我们有:
现在\frac{1}{\sqrt{N}}\sum_{j=0}^{N-1}e^{\frac{-2\pi ikn}{N}}是频率 k 的傅里叶频率响应,我们可以用\widetilde{f}_k表示。替换为\widetilde{f}_k=\frac{1}{\sqrt{N}}\sum_{j=0}^{N-1}e^{\frac{-2\pi ikn}{N}},我们看到公式 4-25 可以写成如下:
通过写\sum_{j=0}^{N-1}f_j|j>。在克罗内克 delta 的基础上,我们可以将公式 4-26 重写如下:
公式 4-27 为我们提供了一种通用方法,通过了解谱/时域和频域之间的基函数关系,对任何给定的离散函数执行傅立叶变换。需要注意的一件事是,酉变换 U 只是改变了进行傅里叶变换的函数的表示基础。正如我们将在本章的其余部分中看到的那样,我们需要理解并执行量子傅里叶变换,就需要这种傅里叶变换方法。

量子傅里叶变换

在本节中,我们将研究量子傅里叶变换电路,以了解傅里叶变换在量子计算领域中到底是如何工作的。使用 n 个量子位,我们可以定义 |x1 x2…xn〉 = ∣x〉 形式的计算基础,其中 x 是二进制字符串 x1x2…xn 的十进制展开,由以下给出:x=x_12^{n-1}+x_22^{n-2}+...+x_n2^{0}

使用 n 个量子位,我们可以获得N=2^n个计算基础状态。
明确地说,每个量子位的计算基础状态由 xi ∈ {0, 1} 表示。
您需要了解图 4-2 中的傅立叶变换电路对任何广义计算基础状态 |x〉 = |x1x2…xn〉 的变换。计算基础状态|x〉只不过是克罗内克δ函数\delta _{nx}
量子电路中使用的门是哈达玛门H和旋转门R_n,如下所示:R_m=\begin{bmatrix} 1 &0 \\ 0&e^{-\frac{2\pi i}{2^m}} \end{bmatrix}

我们从第一个量子位开始,看看电路中各个门对其状态的转换。
Hadamard 门 H 将量子位的状态从 |x_1〉 更改为\frac{1}{\sqrt{2}}(|0>+(-1)^{x_1}|1>)
我们可以将 -1 的值替换为e^{-\pi i}或更方便地替换为e^{2\pi i(\frac{1}{2})}。这让我们可以重写量子位的状态,如下所示:

 现在就像我们将二进制字符串x_1x_2...x_n写成整数形式x=x_12^{n-1}+x_22^{n-2}+...+x_n2^0一样,类似地我们可以采用符号0.x_1x_2...x_n来表示二进制分数,如下所示:x=0.x_1x_2...x_n=x_12^{-1}+x_22^{-2}+...+x_n2^{-n}
使用这个符号,我们可以写成e^{-2\pi i(\frac{x_1}{2}) }作为e^{-2\pi i0.x_1}。因此,哈达玛乘积(在公式 4-31 中)之后的量子位 1 的状态可以重写如下:

 接下来,以状态 |x_m〉 的第 m 个量子位的值为条件,连续应用旋转矩阵R_m。以状态 |x_m〉 中第 m 个量子位的值为条件的R_m变换可以表示如下:\widetilde{R}_m=\begin{bmatrix} 1 &0 \\ 0 & e^{-\frac{2\pi ix_m}{2^m}} \end{bmatrix}
如果量子位 m 处于状态 |0〉,则指数项e^{-\frac{2\pi ix_m}{2^m}}变为1,因此条件变换\widetilde{R}_m变为恒等变换。使用公式 4-32,第二个量子位进行条件变换后第一个量子位的状态可以写成如下:
现在\frac{x_2}{2^2}可以写成0.0x_2。因此,0.x_1+\frac{x_2}{2_2}简化为0.x_1x_2,并且以第二个量子位为条件的旋转 R2 后第一个量子位的状态变为如下:

如此下去,经过所有条件旋转后,量子位 1 的状态可以表示为:

 现在我们将注意力转移到第二个量子位的转换上。如果观察图 4-2,我们会发现量子位 2 重复了与量子位 1 相同的变换模式。因此,通过归纳,我们可以将量子位 2 上的变换写成如下:

 一般来说,对于任何量子位m,变换可以写成如下:

结合所有量子位上的变换,我们可以在基向量 |x1x2…xn〉 上写出整体变换,如下所示:

 接下来,我们使用 SWAP 运算符交换量子位的状态,以便索引 m 表示的任何量子位与索引 n − m 的量子位交换其状态(见图 4-3)。 SWAP操作后,量子位的整体状态如下:

我们之前看到(公式 4-22),任何基向量\delta _{nx} = |x〉 上的傅里叶变换允许我们以复指数频率基表示它,如下所示: 

通过代入N=2^nx=x_1x_2...x_n,我们有以下结果:

现在k=k_12^{n-1}+k_22^{n-2}+...+k_n2^0,因此\frac{k}{2^n}=k_12^{n-1}+k_22^{n-2}+...+k_n2^0=\sum_{p=1}^{n}\frac{k_p}{2^p}。将其代入公式 4-42,我们得到以下结果:

 我们可以将状态 |k〉 = |k_1k_2...k_n〉 表示为\bigotimes ^n_{p=1}|k_p>的状态张量积,因此我们有:
公式 4-44 中的求和可以在每个量子位基本状态上进行计算,而指数项的乘积可以附加到每个量子位。这将公式 4-44 简化为:

将每个量子位的基本状态的求和展开并写出张量积的每一项,我们得到:

让我们通过在公式 4-47 中代入不同的 p 值来计算x2^{-p}

除最后一项外,所有项均大于或等于 1。将公式 4-48 中的x2^{-1}代入表达式e^{2\pi ix2^{-1}}中。 我们得到以下结果: 

由于除了最后一项x_n2^{-1}之外的所有项都大于或等于 1,因此它们将贡献因子 1,因为我们知道对于 m 的任何整数值,e^{-2\pi im}都是 1。这简化了e^{-2\pi ix2^{-1}}以下内容:

类似地,当 p = 2 时,我们将得到x2^{-2}=x_12^{n-3}+x2^{n-4} +x_{n-1}2^{-1}+x_n2^{-2},这意味着除了最后两项之外,我们将获得所有整数值。因此,我们有这个: 

利用公式 4-49 和公式 4-50 的观察结果,我们可以将公式 4-46 简化如下: 因此,我们看到从公式 4-51 中的定义导出的复指数或频率基础上的 |x1x2…xn〉 的傅里叶变换展开与通过量子傅里叶变换电路实现的傅里叶变换展开完全匹配(参见公式 4-39) 。

需要注意的一件事是,当我们谈论一般的傅里叶变换(在量子计算之外)时,我们谈论的是每个复指数基\frac{1}{\sqrt{N}}e^{\frac{2\pi ikx}{2^n}}的复系数或权重,它们由 |k〉 表示。在量子傅立叶变换电路中,这些系数与其叠加的复基态 |k〉 相关联。叠加是有利的,因为它将傅立叶系数及其基以和的形式组合在一起,这就是复指数基 |k〉 中的输入函数信号表示。因此,基于 |x1x2…xn〉 的量子变换实际上是 |x1 x2 …xn 〉 在复指数或频率基础上的傅里叶展开。函数的傅里叶变换和函数在频率基础上的傅里叶变换展开有时可以互换使用。需要记住的重要一点是,|x1 x2…xn〉 上的傅里叶变换允许我们将 |x1 x2…xn〉 本身写为复指数或频率基础上的展开式。

证明量子傅里叶电路正在做与离散傅里叶变换相同的变换是一个漫长而严格的工作。建议读者详细阅读这一推论,因为它构成了与量子傅里叶变换相关的几种算法的支柱。

QFT在Cirq中的实现

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值