3. 单量子比特门操作实战
上一节我们从数学上认识了单量子比特门,本节把这些门真正“跑起来”。目标很明确:在Qiskit中依次构造X、Y、Z、H、S、T以及它们的共轭门,用态矢量模拟器观察每个门作用前后量子态的变化,并通过布洛赫矢量与测量统计验证门的效果是否符合理论预期。本节所有数值均为示例性计算结果,用于说明判断依据,读者在自己的环境中运行会得到一致的结果。
一、搭建最小实验环境
Qiskit从1.x版本起,态矢量模拟由Statevector类承担,电路构建仍使用QuantumCircuit。先准备一个可复用的辅助函数,把任意单比特门作用到初态上并打印态矢量:
from qiskit import QuantumCircuit
from qiskit.quantum_info import Statevector, Operator
import numpy as np
def apply_and_show(gate_name, gate_method, initial="0"):
qc = QuantumCircuit(1)
if initial == "1":
qc.x(0) # 制备 |1>
qc.barrier()
getattr(qc, gate_method)(0) # 施加目标门
sv = Statevector(qc)
print(f"{gate_name:>4} on |{initial}> -> {np.round(sv.data, 4)}")
return sv
这里的关键点是:Statevector(qc)会从全零初态开始演化整条电路,因此若想研究门作用在|1⟩上的效果,必须先用X门制备|1⟩,再用barrier()把制备段与实验段在视觉上分开。这个习惯在后续多比特实验中同样重要。
二、Pauli门:翻转与相位
X门是比特翻转,作用在|0⟩上得到|1⟩,作用在|1⟩上回到|0⟩;Y门同时引入虚数相位,Y|0⟩=i|1⟩;Z门不改变计算基的测量概率,只给|1⟩加上负号。运行下面的调用即可观察:
apply_and_show("X", "x", "0") # [0.+0.j 1.+0.j]
apply_and_show("Y", "y", "0") # [0.+0.j 0.+1.j]
apply_and_show("Z", "z", "1") # [0.+0.j -1.+0.j]
判断依据很直接:态矢量的两个分量就是|0⟩与|1⟩的概率幅。X作用后分量从(1,0)变为(0,1);Y作用后第二分量是纯虚数i,说明存在不可忽略的全局相位——虽然全局相位不可观测,但它会影响后续干涉;Z作用在|1⟩上使第二分量变为−1,测量概率仍是100%的|1⟩,只有通过H门把相位差转成幅度差才能看到。
三、Hadamard门:制造叠加
H门把|0⟩变成(|0⟩+|1⟩)/√2,把|1⟩变成(|0⟩−|1⟩)/√2。执行apply_and_show("H", "h", "0"),输出约为[0.7071+0.j 0.7071+0.j],两个分量等幅同相,对应布洛赫球赤道上的+x方向。若对|1⟩施加H,则第二分量为−0.7071,对应−x方向。H门是后续所有“相位转幅度”验证的枢纽,务必先确认它的输出。
四、相位门S、T及其共轭
S门给|1⟩乘上i,T门给|1⟩乘上e^{iπ/4}。它们单独作用在计算基上时测量结果不变,因此必须组合验证。以S门为例,标准验证电路是“H → S → H”:
qc = QuantumCircuit(1)
qc.h(0); qc.s(0); qc.h(0)
print(np.round(Statevector(qc).data, 4))
# 期望 [0.5+0.5j 0.5-0.5j] 附近的结果
更直观的做法是直接读取布洛赫矢量。Qiskit提供Statevector(qc).probabilities()与Operator,但布洛赫坐标可用密度矩阵计算:
from qiskit.quantum_info import DensityMatrix
rho = DensityMatrix(qc)
bx = 2*rho.data[0,1].real
by = 2*rho.data[1,0].imag
bz = (rho.data[0,0] - rho.data[1,1]).real
print(f"Bloch = ({bx:.3f}, {by:.3f}, {bz:.3f})")
对H→S→H电路,理论结果是绕z轴旋转π/2,布洛赫矢量从+x转到+y,即(0,1,0)。若把S换成S†(qc.sdg(0)),则转到−y方向(0,−1,0)。T门对应π/4旋转,H→T→H后布洛赫矢量落在(0.707,0.707,0)附近;T†(qc.tdg(0))则落在(0.707,−0.707,0)。这组对比是判断相位门方向与角度是否正确的核心依据。
五、用测量统计做交叉验证
态矢量是“上帝视角”,而真实实验只能测量。为了确认相位门效果,可在H→S→H电路末端加测量,并在AerSimulator上跑1024次:
from qiskit import transpile
from qiskit_aer import AerSimulator
qc.measure_all()
sim = AerSimulator()
result = sim.run(transpile(qc, sim), shots=1024).result()
print(result.get_counts()) # 示例:{'0': 512, '1': 512} 附近
H→S→H后态为(0.5+0.5i, 0.5−0.5i),两分量模长相等,因此测量应接近50/50。若把S换成S†,结果同样接近50/50,单看计数无法区分方向——这正是必须借助布洛赫矢量或进一步加相位门的原因。若在H→S→H后再加一个H,则电路等价于S作用在|0⟩上,测量应稳定得到|0⟩;而H→S→H→H→S†→H这类组合可用于构造干涉条纹,验证S与S†互为逆操作。
六、共轭门的实现与核对
Qiskit中S†对应sdg,T†对应tdg,X、Y、Z均为自逆门(X†=X)。核对共轭关系最稳妥的方式是用Operator做矩阵乘法:
from qiskit.quantum_info import Operator
S = Operator(QuantumCircuit(1).compose(QuantumCircuit(1).s(0)))
Sd = Operator(QuantumCircuit(1).compose(QuantumCircuit(1).sdg(0)))
print(np.allclose((S @ Sd).data, np.eye(2))) # True
注意compose的顺序:A.compose(B)表示先A后B,与矩阵乘法B·A对应。若顺序写反,会得到看似“不互逆”的错误结论。建议把每个门的2×2矩阵打印出来与理论对照:S=diag(1,i),S†=diag(1,−i),T=diag(1,e^{iπ/4}),T†=diag(1,e^{−iπ/4})。
七、常见偏差与排查
- 态矢量出现意外全局相位:Y门和T门会引入复数相位,若只比较实部会误判。比较时用
np.allclose并允许相位因子,或直接比较布洛赫矢量。 - Z、S、T“看起来没效果”:它们只改相对相位,必须配合H门或干涉电路观察。
- 测量计数偏离50/50:先检查是否漏了
barrier导致优化器合并门,再确认shots数量足够(建议≥1024)。 - 共轭门核对失败:优先检查
compose顺序与是否误用了qc.s(0)而非sdg。
完成以上步骤后,你应当能够对任意单比特门回答三个问题:它把|0⟩和|1⟩分别映射到什么态矢量;它在布洛赫球上对应哪种旋转;它的逆门是什么、如何用Qiskit实现。这三问构成了后续多比特门与纠缠电路实验的基础。