2. 量子比特与量子门编程实践

在上一节中,我们已经建立了量子计算的基本直觉:量子比特可以处于叠加态,测量会使其坍缩。但要真正用代码操控量子比特,必须把这种直觉翻译成数学语言,再翻译成可执行的程序。本节围绕四个核心问题展开:量子比特用什么数学对象表示、量子门如何用矩阵描述、如何在代码中构造和操作这些门、以及如何通过线路可视化和状态向量模拟来验证结果。

一、量子比特的数学表示

一个量子比特的状态可以写成基态的线性组合:

|ψ⟩ = α|0⟩ + β|1⟩

其中 α 和 β 是复数,称为概率幅,满足归一化条件 |α|² + |β|² = 1。|0⟩ 和 |1⟩ 是计算基,对应二维列向量:

|0⟩ = [1, 0]ᵀ
|1⟩ = [0, 1]ᵀ

因此任意单量子比特态可以写成列向量 [α, β]ᵀ。例如,Hadamard 门作用在 |0⟩ 上得到 (|0⟩+|1⟩)/√2,对应向量 [1/√2, 1/√2]ᵀ。测量时,得到 0 的概率是 |α|²,得到 1 的概率是 |β|²。这一点在代码中非常重要:状态向量中的每个分量都是复数,模拟器通常用两个浮点数分别存储实部和虚部。

多量子比特系统用张量积组合。两个量子比特的基态有 |00⟩、|01⟩、|10⟩、|11⟩ 四个,状态向量是四维复向量。n 个量子比特对应 2ⁿ 维状态向量,这也是量子模拟在比特数增大时迅速变慢的根本原因。

二、量子门的矩阵形式

量子门是对状态向量的线性变换,必须保持归一化,因此对应酉矩阵 U,满足 U†U = I。单量子比特门是 2×2 酉矩阵,常见的有:

  • Pauli-X:[[0,1],[1,0]],相当于经典非门,交换 α 和 β。
  • Pauli-Z:[[1,0],[0,-1]],保持 |0⟩ 不变,给 |1⟩ 加一个负相位。
  • Hadamard (H):(1/√2)[[1,1],[1,-1]],把 |0⟩ 变成叠加态。
  • 相位门 S:[[1,0],[0,i]],给 |1⟩ 加 i 相位。
  • 旋转门 Rx(θ):绕 X 轴旋转 θ 角,矩阵为 [[cos(θ/2), -i sin(θ/2)], [-i sin(θ/2), cos(θ/2)]]。

多量子比特门中,最典型的是受控非门 CNOT。它有两个输入:控制位和目标位。当控制位为 |1⟩ 时,翻转目标位;否则保持不变。其 4×4 矩阵为:

CNOT = [[1,0,0,0],
        [0,1,0,0],
        [0,0,0,1],
        [0,0,1,0]]

注意基的顺序约定:这里采用 |00⟩、|01⟩、|10⟩、|11⟩,即第一个比特是高位。不同框架可能采用不同约定,编程时必须先确认,否则矩阵和线路会错位。

三、在代码中构造和操作量子门

以 Qiskit 为例,构造单量子比特门并作用到指定比特上:

from qiskit import QuantumCircuit
from qiskit.quantum_info import Statevector
import numpy as np

qc = QuantumCircuit(2)
qc.h(0)          # 在 qubit 0 上施加 H 门
qc.cx(0, 1)      # 以 qubit 0 为控制、qubit 1 为目标施加 CNOT
qc.rz(np.pi/4, 1)  # 在 qubit 1 上施加 Rz(π/4)

sv = Statevector(qc)
print(sv)
print(sv.probabilities())

这段代码先制备 Bell 态 (|00⟩+|11⟩)/√2,再对第二个比特施加 Rz 旋转。运行后状态向量会显示四个复数分量,概率数组会显示 |00⟩ 和 |11⟩ 各约 0.5,|01⟩ 和 |10⟩ 接近 0。这里的关键是:h(0) 和 cx(0,1) 的顺序不能随意交换,因为量子门一般不可对易。

如果使用 Cirq,写法略有不同:

import cirq
q0, q1 = cirq.LineQubit.range(2)
circuit = cirq.Circuit(
    cirq.H(q0),
    cirq.CNOT(q0, q1),
    cirq.rz(np.pi/4).on(q1)
)
print(circuit)
print(circuit.final_state_vector())

无论使用哪个框架,核心操作都是三步:创建线路、把门作用到指定量子比特、提取状态向量或测量结果。区别主要在于 API 命名和基顺序约定。

四、线路可视化与状态向量模拟

线路可视化帮助我们在运行前检查门的顺序和比特位置。Qiskit 中可以用 qc.draw('mpl') 或 qc.draw('text') 输出线路图。文本图会按时间从左到右排列,每一行对应一个量子比特。例如上面的线路会显示:第一列 H 在 q0 上,第二列 CNOT 连接 q0 和 q1,第三列 Rz 在 q1 上。

状态向量模拟则给出线路执行后的完整量子态。对于 2 个量子比特,状态向量有 4 个复数分量;对于 3 个量子比特,有 8 个分量。通过观察哪些分量的模长接近 1、哪些接近 0,可以判断线路是否按预期制备了目标态。如果发现概率分布与预期不符,通常需要检查三件事:门的作用顺序、控制位和目标位是否写反、以及基顺序约定是否与矩阵一致。

建议在每次修改线路后,同时打印线路图和状态向量概率。线路图检查“做了什么”,概率检查“得到了什么”,两者结合能快速定位错误。
量子比特状态向量与量子门作用链 初始态 |00⟩ [1, 0, 0, 0]ᵀ H 门 (q0) (1/√2)[[1,1],[1,-1]] 叠加态 CNOT (q0→q1) 控制位 q0,目标位 q1 纠缠态 Rz(π/4) (q1) 相位旋转 改变相对相位 状态向量演化 |00⟩ 后 [1, 0, 0, 0]ᵀ P(00)=1 H 后 [1/√2, 0, 1/√2, 0]ᵀ P(00)=P(10)=0.5 CNOT 后 [1/√2, 0, 0, 1/√2]ᵀ P(00)=P(11)=0.5 Rz 后 相位改变 概率不变 关键检查点 基顺序:|00⟩,|01⟩,|10⟩,|11⟩,第一个比特为高位 门顺序:H → CNOT → Rz,不可随意交换 控制位与目标位:cx(0,1) 表示 q0 控制 q1 概率验证:|00⟩ 和 |11⟩ 各约 0.5,其余接近 0

上图把本节的核心关系串在一起:初始态经过 H 门变成叠加态,再经过 CNOT 变成纠缠态,最后经过 Rz 改变相对相位。每一步的状态向量和概率分布都明确标出,方便对照代码输出进行验证。实际编程时,建议先在小规模线路(2 到 3 个量子比特)上反复练习这些操作,确认自己理解基顺序、门顺序和控制关系,再逐步扩展到更复杂的线路。