11  第十一章 量子计算

本章是个篇外,因为有意思的东西很多,就当是切换视角了。

11.1 单量子比特

类似计算里的基本比特0和1,量子计算机的基本单元是量子比特,记为\(|0 \rangle\)\(|1 \rangle\)。想象空间里有一个半径为1的球,我们将球心放在原点,把\(|0 \rangle\)\(|1 \rangle\)分别放在球的北极和南极:

图 11.1: 布洛赫球

这个球被称为布洛赫球,其x轴指向页面外,y轴指向侧面,z轴朝上,\(| 0 \rangle\)\(| 1 \rangle\)分别对应坐标 \((0,0,1)\)\((0,0,-1)\)

对经典比特而言,0、1是其唯一的两个状态,在计算机里通常表示成高低电平。但量子力学允许一个量子比特处于\(| 0 \rangle\)\(| 1 \rangle\)的叠加态,即:

\[ \alpha |0 \rangle + \beta |1 \rangle \]

其中\(\alpha\)\(\beta\)分别为\(|0 \rangle\)\(|1 \rangle\)的概率幅,满足:

\[ |\alpha|^2 + |\beta|^2 = 1 \]

正如量子力学领域的经典“寓言”薛定谔的猫那样,处于叠加态的量子比特相当于盒子里的那只猫,在没有用任何仪器、设备或某种手段观测它的时候,猫处于生与死的叠加态,但是一旦我们打开盒子尝试去“看”时,猫只表现出了一种状态,要么是活的,要么已经死亡,不存在既生亦死的中间形式。

这种现象被称为量子态的“坍缩”,对于单个量子比特而言,其坍缩到\(| 0 \rangle\)\(| 1 \rangle\)的概率由概率幅模长的平方描述。

例如记

\[ | + \rangle = \frac{1}{\sqrt{2}} | 0 \rangle + \frac{1}{\sqrt{2}} | 1 \rangle \]

在这种状态下,\(| 0 \rangle\)\(| 1 \rangle\)的概率幅模长都为\(\frac{1}{\sqrt{2}}\),在布洛赫球上,它的位置位于赤道上:

图 11.2: |+⟩态在布洛赫球上的位置

注意\(\alpha |0 \rangle + \beta |1 \rangle\)不满足三维坐标的向量合。

为了定位\(\alpha |0 \rangle + \beta |1 \rangle\)在球上的位置,令:

\[ |\psi\rangle = \cos\frac{\theta}{2} |0\rangle + e^{i\phi}\sin\frac{\theta}{2} |1\rangle \]

其中\(\theta \in [0, \pi]\)为极角(状态向量与\(z\)轴正方向的夹角),它决定了测量时坍缩为\(|0\rangle\)\(|1\rangle\)的概率分配,\(\phi \in [0, 2\pi)\)为方位角(在\(x-y\)赤道平面上投影与\(x\)轴的夹角),代表两基态之间的相对相位:

图 11.3: 布洛赫球上的极角 θ 与方位角 ϕ

因此\(\alpha=\cos\frac{\theta}{2}\)\(\beta=e^{i\phi}\sin\frac{\theta}{2}\)

对量子比特而言,它的位置可以是球面上任意一点,其中z轴的基态被称为z基,是\(| 0\rangle\)\(| 1\rangle\)

x基则是\(| +\rangle\)\(| -\rangle\),满足:

\[ | +\rangle = \frac{1}{\sqrt{2}} | 0 \rangle + \frac{1}{\sqrt{2}} | 1 \rangle\\ | -\rangle = \frac{1}{\sqrt{2}} | 0 \rangle - \frac{1}{\sqrt{2}} | 1 \rangle \]

y基则是\(| i \rangle\)\(| -i \rangle\),满足:

\[ | i \rangle = \frac{1}{\sqrt{2}} | 0 \rangle + \frac{i}{\sqrt{2}} | 1 \rangle\\ | -i \rangle = \frac{1}{\sqrt{2}} | 0 \rangle - \frac{i}{\sqrt{2}} | 1 \rangle \]

这3组基在布洛赫球上的位置分别对应三维空间中 3 根相互垂直的坐标轴与球面的交点,而任意一组基都能完整描述一个量子比特在布洛赫球上的位置:

图 11.4: 布洛赫球上的 3 组正交基(Z基、X基、Y基)

一个很有意思的东西是,对于量子态\(\alpha |+\rangle + \beta |-\rangle\),当我们在x基上测量时,它有\(\left|\alpha\right|^2\)的概率坍缩为\(|+\rangle\)\(|\beta|^2\)的概率坍缩为\(|-\rangle\)

假设坍缩到了\(|+\rangle\),因为\(| + \rangle = \frac{1}{\sqrt{2}} | 0 \rangle + \frac{1}{\sqrt{2}} | 1 \rangle\),所以当我们用z基再次测量这个量子比特时,它分别有\(\frac{1}{2}\)的概率坍缩到\(|0\rangle\)\(|1\rangle\)

这表明在不同的基之间进行连续测量或读取,量子比特的信息会丢失并无法复原。

11.2 量子门

量子门之于量子比特,就像逻辑门之于数字比特那样用于转换状态。对于单量子门\(U\),考虑z基上的变化,假设:

\[ U |0\rangle = \alpha_1 |0\rangle + \beta_1 |1\rangle\\ U |1\rangle = \alpha_2 |0\rangle + \beta_2 |1\rangle \]

则对任意单量子比特\(| \psi \rangle = \alpha |0\rangle + \beta |1\rangle\)\(U | \psi \rangle\)为:

\[ \begin{aligned} U |\psi \rangle &= U(\alpha |0\rangle + \beta |1\rangle)\\\ &= \alpha U|0\rangle + \beta U|1\rangle\\[2mm] &= \alpha (\alpha_1 |0\rangle + \beta_1 |1\rangle) + \beta (\alpha_2 |0\rangle + \beta_2 |1\rangle)\\[2mm] &= (\alpha \alpha_1 + \beta \alpha_2) |0\rangle + (\alpha \beta_1 + \beta \beta_2) |1\rangle \end{aligned} \]

为了保障\(U\)是一个合法的量子门,\(U |\psi \rangle\)必须同样是布洛赫球上的一个点。考虑到\(| \psi \rangle\)可以写为\(\alpha |0\rangle + \beta |1\rangle\)的形式,我们可以用向量\(\begin{pmatrix} 1 \\ 0 \end{pmatrix}\)\(\begin{pmatrix} 0 \\ 1 \end{pmatrix}\)来表示\(|0\rangle\)\(|1\rangle\)。同样地,将\(U\)表示为一个2x2的矩阵:

\[ U = \begin{pmatrix} \alpha_1 & \alpha_2 \\ \beta_1 & \beta_2 \end{pmatrix} \]

定义\(\langle \psi |\)\(| \psi \rangle\)的共轭转置(\(\alpha \begin{pmatrix} 1 \\ 0 \end{pmatrix} + \beta \begin{pmatrix} 0 \\ 1 \end{pmatrix} = \begin{pmatrix} \alpha \\ \beta\end{pmatrix}\)),即: \[ \langle \psi | = \begin{pmatrix} \alpha^* & \beta^* \end{pmatrix} \]

则有:

\[ \langle \psi | \cdot | \psi \rangle = \langle \psi | \psi \rangle = \alpha^*\alpha + \beta^*\beta = \left|\alpha\right|^2+\left|\beta\right|^2 = 1 \]

定义 \(U\) 的共轭转置为\(U^\dagger\),先计算\(U | \psi \rangle\)

\[ U | \psi \rangle = \begin{pmatrix} \alpha_1 & \alpha_2 \\ \beta_1 & \beta_2 \end{pmatrix} \begin{pmatrix} \alpha \\ \beta \end{pmatrix} = \begin{pmatrix} \alpha_1 \alpha + \alpha_2 \beta \\ \beta_1 \alpha + \beta_2 \beta \end{pmatrix} \]

为了保障\(U\)是一个合法的量子门,类似地必须满足:

\[ {(U | \psi \rangle)}^\dagger {(U | \psi \rangle)} = 1 \]

根据矩阵的转置公式:

\[ {(U | \psi \rangle)}^\dagger {(U | \psi \rangle)} = \langle \psi | U^\dagger U | \psi \rangle = 1 \]

因此必须满足\(U^\dagger U = I\),即\(U\)是一个酉矩阵,例如:

\[ U = \begin{pmatrix} \frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}} \\ \frac{1}{\sqrt{2}} & -\frac{1}{\sqrt{2}} \end{pmatrix} \]

当然这个\(U\)门只是把z基换成x基,然后每个基前面的概率幅保持不变。

\[ \begin{aligned} \begin{pmatrix} \frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}} \\ \frac{1}{\sqrt{2}} & -\frac{1}{\sqrt{2}} \end{pmatrix} \cdot \begin{pmatrix} \alpha \\ \beta \end{pmatrix} &= \begin{pmatrix} \frac{1}{\sqrt{2}} \\ \frac{1}{\sqrt{2}}\end{pmatrix}\alpha + \begin{pmatrix}\frac{1}{\sqrt{2}} \\ -\frac{1}{\sqrt{2}}\end{pmatrix}\beta \\ \Rightarrow U(\alpha|0\rangle + \beta|1\rangle) &= \alpha| + \rangle + \beta| - \rangle \end{aligned} \]

其实任意酉矩阵\(U\)的每一列都可以看成是一组可以用于描述量子比特的基,同时也可以注意到\(U^\dagger\)就是\(U\)的逆操作。

11.2.1 单位门

单位门\(I\)就是保持不变,把\(| 0 \rangle\)映射成\(| 0 \rangle\),把\(| 1 \rangle\)映射成\(| 1 \rangle\),它实际上啥也没变。

11.2.2 泡利\(X\)

泡利\(X\)门也叫非门,它把\(| 0 \rangle\)映射成\(| 1 \rangle\),把\(| 1 \rangle\)映射成\(| 0 \rangle\)。因为量子门矩阵的每一列都是变换后的新基,很容易写出\(X\)等于\(\begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix}\)

在布洛赫球里\(X\)门等价于绕着x轴旋转180度。

图 11.5: X门绕x轴旋转180度

\(x\) 轴的旋转使得非门不会改变位于 \(x\) 轴上的 \(| + \rangle\)\(| - \rangle\),但会交换位于 \(y\) 轴上的 \(| i \rangle\)\(| -i \rangle\)

\[ \begin{pmatrix}0 & 1 \\ 1 & 0 \end{pmatrix} \begin{pmatrix} \bbox[border: 2px solid #0d6efd; border-radius: 22px; padding: 4px 6px;]{\begin{matrix} \frac{1}{\sqrt{2}} \\ \frac{i}{\sqrt{2}} \end{matrix}} & \bbox[border: 2px solid #e76f51; border-radius: 22px; padding: 4px 6px;]{\begin{matrix} \frac{1}{\sqrt{2}} \\ -\frac{i}{\sqrt{2}} \end{matrix}} \end{pmatrix} = \begin{pmatrix} \bbox[border: 2px solid #e76f51; border-radius: 22px; padding: 4px 6px;]{\begin{matrix} \frac{i}{\sqrt{2}} \\ \frac{1}{\sqrt{2}} \end{matrix}} & \bbox[border: 2px solid #0d6efd; border-radius: 22px; padding: 4px 6px;]{\begin{matrix} -\frac{i}{\sqrt{2}} \\ \frac{1}{\sqrt{2}} \end{matrix}} \end{pmatrix} \]

11.2.3 泡利\(Y\)

泡利\(Y\)门将\(|0\rangle\)映射成\(i|1\rangle\),将\(|1\rangle\)映射成\(-i|0\rangle\),在布洛赫球上,它是绕y轴旋转180度。

图 11.6: Y门绕y轴旋转180度

虽然在布洛赫球上看起来是\(|0\rangle\)变到了\(|1\rangle\),但实际上它到了\(i|1\rangle\),其中\(i|1 \rangle\)\(-i |0 \rangle\)\(i\)是全局相位,不同的全局相位在布洛赫球上都被映射为同一个点,所以在球上看不到全局相位信息,但全局相位不影响测量概率,真正重要的是相对相位。

11.2.4 泡利\(Z\)

\(Z\)门就是绕z轴旋转180度,\(Z\)门保持\(| 0 \rangle\)不变,将\(| 1 \rangle\)映射到\(-| 1 \rangle\)

图 11.7: Z门绕z轴旋转180度

\(Z\)门可以理解为在\(| 0 \rangle\)\(| 1 \rangle\)之间引入了一个相对相位。

这里需要区分两个容易混淆的概念:全局相位和相对相位。

全局相位(如 \(e^{i\gamma}|\psi\rangle\))是整体乘一个相位因子,在布洛赫球上是同一个点。

相对相位(如 \(a|0\rangle + e^{i\phi}b|1\rangle\))只改变基态之间的相位差。在布洛赫球上,z基的相对相位 \(\phi\) 正好对应绕 \(z\) 轴旋转的方位角。因为 \(-1 = e^{i\pi}\),所以 \(Z\) 门是给 \(|1\rangle\) 引入了 \(\pi\)(180度)的相对相位。

如果对上文介绍的\(X,Y,Z\)门的操作感到不好理解,是因为都是站在z基的角度来说的。对x基而言,\(X\)门只是在x基上引入相对相位,对y基而言,\(Y\)门只是在y基上引入相对相位。然后另外两个基只是\(非门+相对相位\)的形式。

图 11.8: 量子门操作

11.2.5 \(S\)

\(S\)门满足\(S^2 = Z\),在布洛赫球上,它是绕z轴旋转90度,因此也满足\(S^4 = I\)

11.2.6 \(T\)

绕z轴旋转45度,满足\(T^2=S\)

11.2.7 \(H\)

\(H\)门叫哈达玛门,它把z基映射到x基,也把x基映射到z基,因为它就是上文\(U\)门的例子,它的共轭转置就是它自己。

11.3 运行一个量子门

如果空有概念,但没法去“试一下”,那其实是会感到相当失落的。虽然量子计算听起来离我们很远,但并非遥不可及。

IBM为我们提供了使用量子计算机的可能,可以访问IBM Quantum页面。对于普通用户,IBM提供了每个月10分钟的真实量子处理器(QPU)免费使用时间,以及开源的Qiskit开发套件用于实验。

可以从一个简单的单量子比特实验开始:把处于基态\(|0\rangle\)的量子比特通过一个\(H\)门,使其进入等概率叠加态\(|+\rangle = \frac{1}{\sqrt{2}}|0\rangle + \frac{1}{\sqrt{2}}|1\rangle\),然后对其进行测量。

首先,构建单量子比特电路并绘制电路图:

代码
from qiskit import QuantumCircuit

qc = QuantumCircuit(1)# 初始化一个量子比特
qc.h(0)            # 施加 Hadamard 门
qc.measure_all()   # 测量所有量子比特(自动生成名为 meas 的经典寄存器)

# 绘制电路图
qc.draw('mpl', style={'name': 'bw', 'backgroundcolor': 'none'})
图 11.9: 使用Hadamard门创建单量子比特电路

在量子电路图中,量子比特用一条水平线表示,方框代表施加在量子比特上的量子门,右侧的仪表符号则代表测量操作,测量的结果会存储在自动生成的相同位宽的经典比特寄存器中(用双横线表示)。

考虑到单次测量无法体现概率分布,因此我们需要通过多次重复实验(称为Shots)来积累统计数据。

接下来定义一个通用的执行辅助函数 run_circuit_and_get_counts,并使用本地模拟器 AerSimulator 进行 1000 次采样:

代码
from qiskit_aer import AerSimulator # 本地模拟器
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager # 用于电路转译成QPU可执行的指令集,包含优化和适配等过程
from qiskit_ibm_runtime import SamplerV2 as Sampler # 量子电路采样执行器
from qiskit.visualization import plot_histogram

# 定义运行辅助函数
def run_circuit_and_get_counts(circuit, backend, shots=1000):
    """运行电路并获取统计结果

    Args:
        circuit: 量子电路
        backend: 执行后端
        shots: 采样次数

    Returns:
        统计结果
    """
    pm = generate_preset_pass_manager(backend=backend, optimization_level=1) # 定义转译器,默认优化等级为1
    isa_circuit = pm.run(circuit) #转译电路
    sampler = Sampler(mode=backend) # 初始化采样执行器
    job = sampler.run([isa_circuit], shots=shots) # 执行采样
    result = job.result() # 获取结果
    return result[0].data.meas.get_counts() # 返回统计结果

# 使用本地模拟器 AerSimulator 运行
backend = AerSimulator()
counts = run_circuit_and_get_counts(qc, backend, shots=1000)

# 绘制统计直方图
fig = plot_histogram(counts, color='#0d6efd')
fig.patch.set_alpha(0.0)
fig.axes[0].patch.set_alpha(0.0)
fig
图 11.10: 电路仿真统计直方图

直方图展现了波函数坍缩的统计特性,在1000次采样中,\(|0\rangle\)\(|1\rangle\) 各以约 \(50\%\) 的几率出现。

如果希望把任务提交给IBM云端真实的量子芯片运行,只需切换后端即可:

from qiskit_ibm_runtime import QiskitRuntimeService

# 保存个人凭据(只需在首次配置时执行一次)
QiskitRuntimeService.save_account(
     channel="ibm_quantum_platform",
     token="<YOUR_API_KEY>",
     overwrite=True,
     set_as_default=True
)

# 寻找当前最空闲的物理量子芯片
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False, min_num_qubits=127)
print("选中物理量子芯片:", backend.name)

# 使用同一个辅助函数直接在物理芯片上运行
counts_qpu = run_circuit_and_get_counts(qc, backend, shots=1000)
plot_histogram(counts_qpu)

除了用Qiskit,IBM也提供了图形化的操作界面用于测试量子电路,点击IBM composer

11.4 多量子比特

对于多量子比特而言,它所有的基是所有量子位的基的张量积,例如两个量子比特,其基是\(\{| 0 \rangle \otimes | 0 \rangle, | 0 \rangle \otimes | 1 \rangle, | 1 \rangle \otimes | 0 \rangle, | 1 \rangle \otimes | 1 \rangle \}\)

\(| 0 \rangle \otimes | 1 \rangle\)\(| 0 1 \rangle\),张量运算操作如下:

\[ \begin{pmatrix} 1 \\ 0 \end{pmatrix}\otimes\begin{pmatrix} 0 \\ 1 \end{pmatrix}=\begin{pmatrix}1 \begin{pmatrix} 0 \\ 1 \end{pmatrix} \\ 0 \begin{pmatrix} 0 \\ 1 \end{pmatrix}\end{pmatrix}=\begin{pmatrix}0 \\ 1 \\ 0 \\ 0 \end{pmatrix} \]

这样就能很自然地用矩阵的方式表示出每个基所对应的向量了。

对于两个量子比特,其叠加态是所有基的混合:

\[ c_0 | 00 \rangle + c_1 | 01 \rangle + c_2 | 10 \rangle + c_3 | 11 \rangle \]

同样满足概率和为1,即:

\[ |c_0|^2 + |c_1|^2 + |c_2|^2 + |c_3|^2 = 1 \]

对于多量子比特,按照量子比特位从右到左的顺序排列,记\(q_i\)为第\(i\)个量子比特,如\(|q_{n-1} \cdots q_1 q_0 \rangle\)代表\(n\)量子比特的一个基,其任意\(q_j\)只能取值0或1。

为了简洁记录,定义十进制数\(m = 2^{n-1}q_{n-1}+\cdots+q_0\),令\(| m \rangle\)等于\(| q_{n-1} \cdots q_1 q_0 \rangle\)

换句话说,就是用十进制数表示二进制数字,例如三比特的量子叠加态可以记为:

\[ c_0 |0 \rangle + c_1 |1 \rangle + c_2 |2 \rangle + \cdots + c_7 |7 \rangle \]

11.4.1 测量单量子比特

对于两个量子比特,假设处于叠加态:

\[ \frac{1}{2}| 00 \rangle + \frac{1}{\sqrt{2}}| 01 \rangle + \frac{\sqrt{3}}{4}| 10 \rangle + \frac{1}{4}| 11 \rangle \]

首先可以验证它是个“合法”的叠加态,也就是概率和为1。然后先测量最左边的量子比特,可以计算出其为\(| 0 \rangle\)的概率为:

\[ (\frac{1}{2})^2 + (\frac{1}{\sqrt{2}})^2 = \frac{1}{4} + \frac{1}{2} = \frac{3}{4} \]

\(| 1 \rangle\)的概率则为\(\frac{1}{4}\),假设先测得左量子比特为\(|0\rangle\),那右量子比特的概率又应该是多少呢?

因为左量子比特已经是\(|0\rangle\)了,所以最终结果只会是\(|00\rangle\)\(|01\rangle\),为了保证右比特满足概率和为1,我们需要对\(|00\rangle\)\(|01\rangle\)的系数进行归一化:

\[ \begin{aligned} A(\frac{1}{2}|00 \rangle + \frac{1}{\sqrt{2}}| 01 \rangle) \\ \text{s.t.} |A \frac{1}{2}|^2 + |A \frac{1}{\sqrt{2}}|^2 = 1 \end{aligned} \]

计算到\(A=\frac{2}{\sqrt{3}}\),并可得右比特为\(|0\rangle\)的概率为\(\frac{1}{3}\),为\(| 1 \rangle\)的概率为\(\frac{2}{3}\)

11.4.2 纠缠态

对某些叠加态,可以分解成单个量子态的张量积,例如:

\[ \begin{aligned} &\ \ \ \ \ \ \frac{1}{2}(|00\rangle - |01\rangle+|10\rangle-|11\rangle)\\ &=\frac{1}{\sqrt{2}}(|0\rangle+|1\rangle)\otimes\frac{1}{\sqrt{2}}(|0\rangle-|1\rangle)\\ &=|+\rangle \otimes |-\rangle = |+\rangle|-\rangle \end{aligned} \]

但存在一些无法分解为张量积形式的量子态。这些被称为纠缠态,例如贝尔态:

\[ \left\{ \begin{aligned} |\Phi^+\rangle &= \frac{1}{\sqrt{2}}(|00\rangle + |11\rangle) \\ |\Phi^-\rangle &= \frac{1}{\sqrt{2}}(|00\rangle - |11\rangle) \end{aligned} \right. \qquad \left\{ \begin{aligned} |\Psi^+\rangle &= \frac{1}{\sqrt{2}}(|01\rangle + |10\rangle) \\ |\Psi^-\rangle &= \frac{1}{\sqrt{2}}(|01\rangle - |10\rangle) \end{aligned} \right. \]

对任一贝尔态的任意一个量子进行测量,测量出来后另一个量子一定会坍缩到对应的状态。

通常认为这种“同步”是瞬时的,无论两个量子相距多远,然而纠缠量子无法用于超光速传递信息,主要原因有两个:首先对于任一量子,都有50%的概率坍缩到\(|0\rangle\)\(|1\rangle\),这是随机的,我们没办法人为地控制它到某个状态。其次是就算我们能控制它的坍缩状态,对于远端的接收方,在没测量之前,他看到的始终是叠加态的单量子,在他测量后也没法分辨坍缩是来自发送方测量后的“同步”坍缩还是没测量的随机坍缩。而发送方是否测量的信号必须依赖经典信道,如电磁波等传输,这些经典信道的通信速度没法超越光速。

11.4.3 单量子比特门

如果有多个量子比特,但只想对其中一个进行操作,例如\(|00\rangle\)对第一个量子比特应用\(H\)门,另一个保持不变。操作可以写成这样的形式:

\[ (H\otimes I)(|0\rangle \otimes |0\rangle)=H|0\rangle \otimes I|0\rangle = |+\rangle \otimes |0\rangle \]

绘制电路时,让最右边的量子比特绘制在最上方,然后依次往下排:

代码
from qiskit import QuantumCircuit

qc = QuantumCircuit(2)
qc.h(1)  # 对1号量子比特施加H门
qc.measure_all()
qc.draw('mpl', style={'name': 'bw', 'backgroundcolor': 'none'})
图 11.11: 单量子比特门电路

可以计算一下:

\[ H|0\rangle\otimes|0\rangle = \frac{1}{\sqrt{2}}(|0\rangle + |1\rangle)\otimes|0\rangle = \frac{1}{\sqrt{2}}(|00\rangle + |10\rangle) \]

注意它不是一对纠缠量子哦,因为右量子比特始终都是\(|0\rangle\),同样地用仿真器采样1000次,结果如下:

代码
counts = run_circuit_and_get_counts(qc, backend, shots=1000)

# 绘制统计直方图
fig = plot_histogram(counts, color='#0d6efd')
fig.patch.set_alpha(0.0)
fig.axes[0].patch.set_alpha(0.0)
fig
图 11.12: 单量子比特门电路采样统计直方图

11.4.4 多量子比特门

多量子比特门就是作用于两个及以上量子的量子门,接下来将列举一些常见的多量子比特门。

11.4.4.1 \(CNOT\)

\(CNOT\)门被称为受控非门,它在左量子比特为\(|1\rangle\)时,翻转右量子比特,为\(|0\rangle\)时保持不变:

\[ \text{CNOT}|00\rangle = |00\rangle \\ \text{CNOT}|01\rangle = |01\rangle \\ \text{CNOT}|10\rangle = |11\rangle \\ \text{CNOT}|11\rangle = |10\rangle \]

\(CNOT\)门的电路如下图所示:

代码
from qiskit import QuantumCircuit

qc = QuantumCircuit(2)
qc.cx(1, 0)

qc.draw('mpl', style={'name': 'bw', 'backgroundcolor': 'none'})
图 11.13: CNOT门电路

其中带有“加号”的量子位是目标位,圆点的量子位是控制位。\(CNOT\)门结合\(H\)门可以用来制备纠缠量子:

代码
from qiskit import QuantumCircuit

qc = QuantumCircuit(2)
qc.h(1)
qc.cx(1, 0)
qc.measure_all()

qc.draw('mpl', style={'name': 'bw', 'backgroundcolor': 'none'})
图 11.14: 纠缠量子电路

同样使用本地模拟器采样 1000 次,统计测量结果:

代码
counts = run_circuit_and_get_counts(qc, backend, shots=1000)

fig = plot_histogram(counts, color='#0d6efd')
fig.patch.set_alpha(0.0)
fig.axes[0].patch.set_alpha(0.0)
fig
图 11.15: 纠缠量子电路采样统计直方图

其实就是把\(H|0\rangle\otimes|0\rangle\)计算的\(|10\rangle\)换成了\(|11\rangle\)

根据\(CNOT\)门的特点,可以很容易地写出其矩阵形式:

\[ \text{CNOT} = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \end{pmatrix} \]

为了加深理解,尝试手动计算\(CNOT(H\otimes I)(|0\rangle\otimes|0\rangle)\)

图 11.16: 矩阵计算

\(CNOT\)门也可以翻转控制,用右量子比特控制左量子比特,你可以自己证明一下这个等价于\((H\otimes H)CNOT(H\otimes H)\)

代码
from qiskit import QuantumCircuit

qc = QuantumCircuit(2)
qc.h([0,1])
qc.cx(1, 0)
qc.h([0,1])

qc.draw('mpl', style={'name': 'bw', 'backgroundcolor': 'none'})
图 11.17: 翻转CNOT门电路

11.4.4.2 \(CU\)

\(CU\)门就是受控任意单量子门,满足:

\[ \begin{aligned} CU|00\rangle&=|00\rangle \\ CU|01\rangle&=|01\rangle \\ CU|10\rangle&=|1\rangle \otimes U|0\rangle \\ CU|11\rangle&=|1\rangle \otimes U|1\rangle \end{aligned} \]

其电路图如下:

代码
from qiskit import QuantumCircuit
from qiskit.circuit.library import UnitaryGate
import numpy as np

qc = QuantumCircuit(2)

# 创建一个标签为U的单量子门并将其设为受控门
U = UnitaryGate(np.eye(2), label='U')
cU = U.control(1)# 设置为单控制位量子门
qc.append(cU, [1, 0])# [控制位,目标位]

qc.draw('mpl', style={'name': 'bw', 'backgroundcolor': 'none'})
图 11.18: 受控U门电路图

\(U\)满足:

\[ U|0\rangle = a|0\rangle+b|1\rangle\\ U|1\rangle = c|0\rangle+d|1\rangle \]

\(CU\)可以写成:

\[ CU = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & a & c \\ 0 & 0 & b & d \end{pmatrix} \]

\(U\)为泡利\(X\)门时,就变成了\(CNOT\)门。

\(U\)为泡利\(Z\)门时,就变成了\(CZ\)门,\(CZ\)门满足\(CZ∣ab\rangle=(−1)^{ab}∣ab\rangle\)

11.4.4.3 \(\text{SWAP}\)

\(\text{SWAP}\)门用于交换两个量子比特,定义为:

\[ \text{SWAP}|00\rangle=|00\rangle \\ \text{SWAP}|01\rangle=|10\rangle \\ \text{SWAP}|10\rangle=|01\rangle \\ \text{SWAP}|11\rangle=|11\rangle \]

其电路图如下:

代码
from qiskit import QuantumCircuit

qc = QuantumCircuit(2)
qc.swap(0, 1)

qc.draw('mpl', style={'name': 'bw', 'backgroundcolor': 'none'})
图 11.19: SWAP门电路图

11.4.4.4 \(\text{Toffoli}\)

\(\text{Toffoli}\)门是一个三量子比特门,它是受控-受控非门,只有当左边和中间的两个量子比特都为\(|1\rangle\)时,右边的量子比特才会翻转。其定义如下:

\[ \text{Toffoli}|000\rangle=|000\rangle \\ \text{Toffoli}|001\rangle=|001\rangle \\ \text{Toffoli}|010\rangle=|010\rangle \\ \text{Toffoli}|011\rangle=|011\rangle \\ \text{Toffoli}|100\rangle=|100\rangle \\ \text{Toffoli}|101\rangle=|101\rangle \\ \text{Toffoli}|110\rangle=|111\rangle \\ \text{Toffoli}|111\rangle=|110\rangle \]

其电路图如下:

代码
from qiskit import QuantumCircuit

qc = QuantumCircuit(3)
qc.ccx(2, 1, 0)

qc.draw('mpl', style={'name': 'bw', 'backgroundcolor': 'none'})
图 11.20: Toffoli门电路图

\(\text{Toffoli}\)门的一个作用是,它可以模拟经典逻辑门。

大多数经典逻辑门是不可逆的,例如与门,其真值表如下:

\[ \begin{array}{cc|c} A & B & A \land B \\ \hline 0 & 0 & 0 \\ 0 & 1 & 0 \\ 1 & 0 & 0 \\ 1 & 1 & 1 \end{array} \]

可以看到,当输出为 \(0\) 时,我们无法反推出最初的输入究竟是 \((0,0)\)\((0,1)\) 还是 \((1,0)\),这意味着信息丢失。

而所有量子门必须都是酉矩阵,其共轭转置是它的逆变换,否则概率将不守恒。

为了让经典逻辑门可逆,假设输入\(A\)\(B\),输出为\(f(A,B)\),让辅助输入\(C\)\(f(A,B)\)进行异或运算,就能将不可逆门变成可逆门:

图 11.21: 不可逆门转换为可逆门

对二进制而言,由于任何数与 \(0\) 异或保持不变(\(x \oplus 0 = x\)),与 \(1\) 异或相当于取反(\(x \oplus 1 = \overline{x}\)),其真值表如下:

\[ \begin{array}{ccc|ccc} A & B & C & A & B & f(A,B) \oplus C \\ \hline 0 & 0 & 0 & 0 & 0 & f(0,0) \\ 0 & 0 & 1 & 0 & 0 & \overline{f(0,0)} \\ 0 & 1 & 0 & 0 & 1 & f(0,1) \\ 0 & 1 & 1 & 0 & 1 & \overline{f(0,1)} \\ 1 & 0 & 0 & 1 & 0 & f(1,0) \\ 1 & 0 & 1 & 1 & 0 & \overline{f(1,0)} \\ 1 & 1 & 0 & 1 & 1 & f(1,1) \\ 1 & 1 & 1 & 1 & 1 & \overline{f(1,1)} \end{array} \]

可以看到此时输入与输出保持一一对应的映射关系,因此无论输出是什么,我们都能倒推得到输入。

当然这种方式能推广到更多输入或输出的情况:

图 11.22: 不可逆门变可逆门的推广

那为什么说\(\text{Toffoli}\)门可以用于模拟任何经典逻辑门呢?因为当右量子比特取\(| 1\rangle\)时(相当于输入\(C=1\)),\(\text{Toffoli}\)输出的右量子比特是左边和中间量子比特的与非运算。而与非门自身就是完备的逻辑门,利用与非门可以实现任意经典逻辑门。

11.5 量子预言机

量子预言机中的“预言机”(oracle)指的是黑盒或一个布尔函数,它可以通过真值表或逻辑门定义,对量子比特来说,量子预言机必须是一个量子门才能满足幺正性。

假设预言机的逻辑是\(f(x)\),定义实现逻辑的量子门为\(U_f\),让\(f(x)\)与一个额外的辅助输入异或,可以将不可逆的逻辑转换成量子电路上的可逆变换:

图 11.23: 量子预言机

\(U_f|xy\rangle=|x\rangle\otimes|y\oplus f(x)\rangle\),考虑想要实现一个量子或门,其真值表如下:

\[ \begin{array}{cc|c} x_1 & x_2 & f(x_1, x_2) \\ \hline 0 & 0 & 0 \\ 0 & 1 & 1 \\ 1 & 0 & 1 \\ 1 & 1 & 1 \end{array} \]

其中输入\(x\)\(x_1,x_2\),下一步就是给真值表添加辅助输入\(y\)

\[ \begin{array}{ccc|c} x_1 & x_2 & y & y \oplus f(x_1, x_2) \\ \hline 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 1 \\ 0 & 1 & 0 & 1 \\ 0 & 1 & 1 & 0 \\ 1 & 0 & 0 & 1 \\ 1 & 0 & 1 & 0 \\ 1 & 1 & 0 & 1 \\ 1 & 1 & 1 & 0 \end{array} \]

之后根据量子门的特性,即量子门的每一列都对应一个原始输入基变换后输出的新的基,可以写出\(U_f\)等于:

\[ \begin{pmatrix} |00\rangle\otimes|0\oplus f(0,0)\rangle & |00\rangle\otimes|1\oplus f(0,0)\rangle & \dots & | 11\rangle\otimes|1\oplus f(1,1)\rangle \end{pmatrix} \]

展开后为:

\[ U_f=\begin{pmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \\ \end{pmatrix} \]

能发现什么规律吗?考虑把\(U_f\)对角线分块为\(2\times2\)的矩阵:

\[ \begin{pmatrix} \bbox[border: 2px solid #e76f51; border-radius: 8px; padding: 4px 6px;]{\begin{matrix} 1 & 0 \\ 0 & 1 \end{matrix}} & 0 & 0 & 0 \\ 0 & \bbox[border: 2px solid #e76f51; border-radius: 8px; padding: 4px 6px;]{\begin{matrix} 0 & 1 \\ 1 & 0 \end{matrix}} & 0 & 0 \\ 0 & 0 & \bbox[border: 2px solid #e76f51; border-radius: 8px; padding: 4px 6px;]{\begin{matrix} 0 & 1 \\ 1 & 0 \end{matrix}} & 0 \\ 0 & 0 & 0 & \bbox[border: 2px solid #e76f51; border-radius: 8px; padding: 4px 6px;]{\begin{matrix} 0 & 1 \\ 1 & 0 \end{matrix}} \end{pmatrix} = \begin{pmatrix} \mathbf{I} & 0 & 0 & 0 \\ 0 & \mathbf{X} & 0 & 0 \\ 0 & 0 & \mathbf{X} & 0 \\ 0 & 0 & 0 & \mathbf{X} \end{pmatrix} \]

然后再对照\(f(x_1,x_2)\)的输出,发现当输出为0时,对角矩阵是单位门,输出为1时,对角矩阵是\(X\)门。

11.6 相位预言机

在量子计算中,除了量子预言机,还有相位预言机。相位预言机会给\(|x\rangle\)加上一个相位因子。

考虑这样一个初始状态:

\[ |x\rangle\otimes |-\rangle \]

展开后可以写为:

\[ \begin{aligned} |x\rangle |-\rangle &= |x\rangle \frac{1}{\sqrt{2}}(|0\rangle - |1\rangle) \\ &=\frac{1}{\sqrt{2}}(|x\rangle|0\rangle - |x\rangle |1\rangle) \end{aligned} \]

令相位预言机的量子门为\(O_f\),我们希望\(O_f\)满足:

\[ \begin{aligned} O_f|x\rangle|-\rangle &= \frac{1}{\sqrt{2}}\Big(|x\rangle|0\oplus f(x)\rangle - |x\rangle|1\oplus f(x)\rangle\Big) \\ &= \begin{cases} \frac{1}{\sqrt{2}}(|x\rangle|0\rangle - |x\rangle|1\rangle), & f(x) = 0 \\ \frac{1}{\sqrt{2}}(|x\rangle|1\rangle - |x\rangle|0\rangle), & f(x) = 1 \end{cases} \\ &= \begin{cases} |x\rangle|-\rangle, & f(x) = 0 \\ -|x\rangle|-\rangle, & f(x) = 1 \end{cases} \\ &= (-1)^{f(x)} |x\rangle|-\rangle \end{aligned} \]

可以看到,辅助量子比特 \(|-\rangle\) 在整个过程中完全没有变化,但却将相位因子 \((-1)^{f(x)}\) 添加到了输入\(|x\rangle\) 上,这被称为相位回踢。

通常我们会忽略辅助比特,因此有:

\[ O_f|x\rangle = (-1)^{f(x)}|x\rangle \]

同样考虑将或门转化为相位预言机,根据\(O_f|x\rangle = (-1)^{f(x)}|x\rangle\),很容易写出\(O_f\)等于: \[ \begin{pmatrix} (-1)^{f(0,0)} & 0 & 0 & 0 \\ 0 & (-1)^{f(0,1)} & 0 & 0 \\ 0 & 0 & (-1)^{f(1,0)} & 0 \\ 0 & 0 & 0 & (-1)^{f(1,1)} \end{pmatrix} \]

可以看到,相位预言机是一个纯粹的对角矩阵,最终\(f(x)\)输出的信息就包含在了量子态的概率幅中。

问题是怎么提取出来呢?因为无论是\(|00\rangle\)还是\(-|00\rangle\),测量后结果都是00。

11.7 扩散算子

要将隐藏在概率幅正负号里的信息提取出来,就必须借助量子干涉,如扩散算子(通常记作\(D\))。

扩散算子的几何操作非常直观,被称为关于平均值翻转:先计算出当前所有基态概率幅的平均值,然后让每一个基态的概率幅以该平均值为对称轴进行翻转。

假设量子态共有 \(N\) 个基态,各基态的概率幅为 \(\alpha_i\),则平均值为:

\[ \mu = \frac{1}{N} \sum \alpha_i \]

每个概率幅 \(\alpha_i\) 与平均值 \(\mu\) 的偏差为 \(\alpha_i - \mu\)。以平均值为中心翻转后,新的概率幅 \(\alpha_i^\prime\) 满足:

\[ \alpha_i^\prime = \mu - (\alpha_i - \mu) = 2\mu - \alpha_i \]

以 2 个量子比特为例:

  • 初始化:通过对初始量子比特施加\(H\)门进入均匀叠加态: \[ |s\rangle = \frac{1}{2}|00\rangle + \frac{1}{2}|01\rangle + \frac{1}{2}|10\rangle + \frac{1}{2}|11\rangle \] 此时 4 个状态的概率幅全部为 \(\frac{1}{2}\),测量得到每个状态的概率均为 \(\frac{1}{4}\)

  • 相位预言机标记:假设我们要寻找的目标解是 \(|11\rangle\)(即只有 \(f(11) = 1\),其余均为 \(0\))。经过相位预言机 \(O_f\) 作用后,只有目标态被赋予了负号:

    • \(|00\rangle\) 的概率幅:\(\frac{1}{2}\)
    • \(|01\rangle\) 的概率幅:\(\frac{1}{2}\)
    • \(|10\rangle\) 的概率幅:\(\frac{1}{2}\)
    • \(|11\rangle\) 的概率幅:\(-\frac{1}{2}\)

    此时如果直接测量,各状态的概率全是 \(0.25\),我们无法区分谁是目标。

  • 扩散算子翻转:

    • 首先计算 4 个概率幅的平均值 \(\mu\)\[ \mu = \frac{0.5 + 0.5 + 0.5 + (-0.5)}{4} = \frac{1.0}{4} = 0.25 \]
    • 接下来,利用公式 \(\alpha' = 2\mu - \alpha\) 对每个状态执行均值翻转:
      • 对于非目标态: \[ \alpha' = 2(0.25) - 0.5 = 0.5 - 0.5 = \mathbf{0} \]
      • 对于目标态 \(|11\rangle\)\[ \alpha' = 2(0.25) - (-0.5) = 0.5 + 0.5 = \mathbf{1.0} \]

经过扩散算子的翻转,非目标态的概率幅被削减为0,而目标态 \(|11\rangle\) 的概率被放大到了1。

此时再去测量量子比特,便能以 \(100\%\) 的概率直接测出目标态 \(|11\rangle\)

对于量子电路,扩散算子的矩阵形式为:

\[ D = 2|s\rangle\langle s| - I \]

其中 \(|s\rangle\) 为均匀叠加态。\(\langle s|\)\(|s\rangle\)的共轭转置,\(|s\rangle\langle s|\)是外积(目前关于\(\langle \psi|\phi \rangle\)为内积,\(|\psi\rangle |\phi\rangle\)为张量积)。

外积满足:

\[ |a\rangle \langle b| = \begin{pmatrix}a_1\\a_2\end{pmatrix} \begin{pmatrix}b_1^* & b_2^*\end{pmatrix}=\begin{pmatrix}a_1 b_1^* & a_1 b_2^* \\ a_2 b_1^* & a_2 b_2^*\end{pmatrix} \]

其实外积就是一种特殊的矩阵乘法。

使用扩散算子需要注意一点,当目标态数量超过总状态数的一半时,结果会出现反转,非目标项反而被放大,目标项反而被削弱。

11.8 代码里自定义门

在 Qiskit 中,如果已经推导出了某个量子门的矩阵形式,可以直接通过 UnitaryGate 将该矩阵封装为自定义量子门。

以刚才寻找目标态 \(|11\rangle\) 为例:

  • 构造相位预言机门\(O_f\)\[ O_f = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & -1 \end{pmatrix} \]

  • 构造扩散算子门 \(D\)

    \[ D = \begin{pmatrix} -0.5 & 0.5 & 0.5 & 0.5 \\ 0.5 & -0.5 & 0.5 & 0.5 \\ 0.5 & 0.5 & -0.5 & 0.5 \\ 0.5 & 0.5 & 0.5 & -0.5 \end{pmatrix} \]

在代码中,将这两个矩阵封装为带有名称标签的 UnitaryGate,即可直接挂载到电路上:

代码
import numpy as np
from qiskit import QuantumCircuit
from qiskit.circuit.library import UnitaryGate

# 构造相位预言机矩阵
oracle_matrix = np.diag([1, 1, 1, -1])
oracle_gate = UnitaryGate(oracle_matrix, label='Of')

# 构造扩散算子矩阵
s = 0.5 * np.ones((4, 1))
diffusion_matrix = 2 * (s @ s.T) - np.eye(4)
diffusion_gate = UnitaryGate(diffusion_matrix, label='D')

# 组合电路
qc = QuantumCircuit(2)
qc.h([0, 1])
qc.append(oracle_gate, [0, 1])
qc.append(diffusion_gate, [0, 1])

qc.measure_all()

qc.draw('mpl', style={'name': 'bw', 'backgroundcolor': 'none'})
图 11.24: 基于自定义门的电路

构建好完整的量子电路后,同样使用本地模拟器采样 1000 次,统计测量结果:

代码
counts = run_circuit_and_get_counts(qc, backend, shots=1000)

fig = plot_histogram(counts, color='#0d6efd', figsize=(3, 2))
fig.patch.set_alpha(0.0)
fig.axes[0].patch.set_alpha(0.0)
fig
图 11.25: 自定义门电路采样直方图

可以看到输出全部变成了11。

11.9 更多阅读资料

一个是托马斯·王写的《Introduction to Classical and Quantum Computing》,关于量子计算在音乐创作方面的书,可以查看《Quantum Computer Music》