核心线路接口
概述
本章介绍 UnitaryLab 量子线路的核心数据结构与操作方法,适合希望构建和操作量子线路的用户。读完本章,你将能够:
- 使用多种方式创建
Circuit对象 - 添加单量子比特门、受控门和旋转门
- 添加测量操作
- 执行模拟并读取结果
- 使用线路变换方法(复制、反转、追加等)
- 了解 UnitaryLab 的量子比特排序规则
模块索引
| 模块 | 主要类 |
|---|---|
unitarylab.core.circuit | CircuitBase、Circuit |
unitarylab.core.register | Register |
unitarylab.core.classical_register | ClassicalRegister |
unitarylab.backend.gatesequence.gatesequence | GateSequenceBase、GateSequence |
unitarylab.backend.gate.gatebase | QuantumGate |
1. 创建 Circuit
from unitarylab.core import Circuit
# 方式一:直接指定量子比特数(最常用)
qc = Circuit(4)
# 方式二:传入初始状态向量(用于从已知量子态开始模拟)
import numpy as np
state = np.array([1, 0, 0, 0], dtype=complex) # 对应 |00⟩
qc = Circuit(state)
# 方式三:传入 Register 和 ClassicalRegister 对象(需要命名寄存器或测量时使用)
from unitarylab.core import Register
from unitarylab.core.classical_register import ClassicalRegister
qr = Register('q', 3)
cr = ClassicalRegister('c', 3)
qc = Circuit(qr, cr)说明:
- 方式一适合快速构建线路,不需要测量时推荐使用。
- 方式三在需要进行测量并读取经典比特结果时使用。
Circuit内部会自动维护一个GateSequence,每次调用门方法时会向其中追加QuantumGate。
2. 添加单量子比特门
所有单比特门的第一个参数均为目标量子比特索引(从 0 开始)。
qc = Circuit(3)
qc.x(0) # Pauli-X(NOT)门
qc.y(1) # Pauli-Y 门
qc.z(2) # Pauli-Z 门
qc.h(0) # Hadamard 门
qc.s(1) # S 门(π/2 相位)
qc.sdag(1) # S† 门
qc.t(2) # T 门(π/4 相位)
qc.tdag(2) # T† 门
qc.i(0) # 恒等门(no-op,可用于占位)常用单量子比特门速查表:
| 方法 | 门名称 | 说明 |
|---|---|---|
x(target) | Pauli-X | 量子 NOT 门,将 翻转为 |
y(target) | Pauli-Y | Y 轴旋转 π |
z(target) | Pauli-Z | 将 相位翻转 |
h(target) | Hadamard | 创建叠加态 |
s(target) | S | 相位门,等价于 |
t(target) | T | 相位门,等价于 |
sqrtx(target) | √X | 门 |
sqrty(target) | √Y | 门 |
3. 添加旋转门
旋转门需要指定旋转角度(以弧度为单位):
import numpy as np
qc = Circuit(2)
# RX(θ):绕 X 轴旋转 θ 角度
qc.rx(np.pi / 2, 0)
# RY(θ):绕 Y 轴旋转
qc.ry(np.pi / 4, 1)
# RZ(θ):绕 Z 轴旋转
qc.rz(np.pi, 0)
# 相位门 P(θ):仅对 |1⟩ 施加 e^{iθ} 相位
qc.p(np.pi / 2, 1)
# 通用单比特门 U3(θ, φ, λ)
qc.u3(np.pi / 2, 0, np.pi, 0)| 方法 | 参数 | 说明 |
|---|---|---|
rx(angle, target) | 角度(弧度) | 绕 X 轴旋转 |
ry(angle, target) | 角度(弧度) | 绕 Y 轴旋转 |
rz(angle, target) | 角度(弧度) | 绕 Z 轴旋转 |
p(angle, target) | 角度(弧度) | 相位门 |
u1(lmb, target) | λ | U1(λ) 门 |
u2(phi, lmb, target) | φ, λ | U2(φ, λ) 门 |
u3(theta, phi, lmb, target) | θ, φ, λ | 通用单比特门 |
gp(angle) | 角度(弧度) | 全局相位门 |
4. 添加受控门
qc = Circuit(3)
# CNOT:控制比特 0,目标比特 1
qc.cx(0, 1)
qc.cnot(0, 1) # cx 的别名
# 多控制 X(Toffoli):控制比特列表,目标比特
qc.mcx([0, 1], 2)
# 受控 Z
qc.cz(0, 1)
# 受控 Hadamard
qc.ch(0, 1)
# 受控相位门
qc.cp(np.pi / 2, 0, 1)
# 受控旋转门
qc.crx(np.pi / 2, 0, 1)
qc.cry(np.pi / 2, 0, 1)
qc.crz(np.pi / 2, 0, 1)
# SWAP 门
qc.swap(0, 1)
# 任意酉矩阵门(传入 2x2 或更大的酉矩阵)
import numpy as np
mat = np.array([[0, 1], [1, 0]], dtype=complex) # Pauli-X 矩阵
qc.unitary(mat, 0)
# 带控制状态的受控门(control_state=0 表示控制比特为 0 时触发)
qc.cx(0, 1, control_state=0)常用受控门速查表:
| 方法 | 说明 | 示例 |
|---|---|---|
cx(ctrl, tgt) | CNOT | qc.cx(0, 1) |
mcx(ctrls, tgt) | 多控制 X | qc.mcx([0, 1], 2) |
cy(ctrl, tgt) | 受控 Y | qc.cy(0, 1) |
cz(ctrl, tgt) | 受控 Z | qc.cz(0, 1) |
ch(ctrl, tgt) | 受控 H | qc.ch(0, 1) |
cs(ctrl, tgt) | 受控 S | qc.cs(0, 1) |
cp(angle, ctrl, tgt) | 受控相位 | qc.cp(np.pi/2, 0, 1) |
swap(tgt1, tgt2) | SWAP | qc.swap(0, 1) |
unitary(mat, tgt) | 任意酉矩阵 | qc.unitary(mat, 0) |
5. 添加测量
测量需要先创建经典寄存器:
from unitarylab.core import Register
from unitarylab.core.classical_register import ClassicalRegister
qr = Register('q', 2)
cr = ClassicalRegister('c', 2)
qc = Circuit(qr, cr)
qc.h(0)
qc.cx(0, 1)
# 将量子比特 0 测量到经典比特 0,量子比特 1 测量到经典比特 1
qc.measure([0, 1], [0, 1])
# 也可以单个测量
# qc.measure(0, 0)测量说明:
measure(qubit, clbit)中,qubit和clbit均可以是整数或列表。- 测量操作在执行时会对量子态进行投影,并将结果写入
ExecutionResult.classical_results_map。
6. 执行线路
result = qc.execute()
# 指定后端和设备
result = qc.execute(
backend='torch', # 'torch'(默认)或 'numpy'
device='cpu', # 'cpu' 或 'gpu'
dtype=np.complex128 # 精度,默认 complex64
)7. 绘图与分析
# 绘制线路图(弹出 Matplotlib 图窗)
qc.draw()
# 保存为文件
qc.draw(filename='circuit.png', title='My Circuit')
# 获取线路分析(返回 CircuitInfo 对象)
info = qc.analyze()
info.show() # 打印门数、深度、层结构等
# 计算线路酉矩阵(适用于小线路)
matrix = qc.get_matrix()8. 线路变换
UnitaryLab 支持多种线路结构变换,这些变换均返回新的 Circuit 对象(不修改原线路):
qc = Circuit(2)
qc.h(0)
qc.cx(0, 1)
# 复制线路
qc2 = qc.copy()
# 反转门顺序(并对每个门取共轭转置),等价于整个线路的 U†
qc_inv = qc.inverse()
qc_dag = qc.dagger() # inverse() 的别名
# 量子比特索引镜像翻转(比特 0 ↔ 比特 n-1)
qc_rev = qc.reverse()
# 重复整个线路 3 次
qc_rep = qc.repeat(3)
# 展开块门(n=1 展开一层)
qc_dec = qc.decompose(n=1)
# 添加控制比特,使整个线路变为受控线路
qc_ctrl = qc.control(num_control_qubits=1)
# 追加子线路到当前线路末尾
sub = Circuit(2)
sub.z(0)
qc.append(sub, target=[0, 1])
# 前置子线路
qc.prepend(sub, target=[0, 1])
# 将目标比特初始化为指定状态向量
import numpy as np
v = np.array([1/np.sqrt(2), 1/np.sqrt(2)])
qc.initialize(v, target=0)线路变换速查表:
| 方法 | 说明 |
|---|---|
copy() | 返回线路的独立拷贝 |
inverse() / dagger() | 反转顺序并取共轭转置 |
reverse() | 量子比特索引镜像翻转 |
repeat(times) | 重复整个线路 |
decompose(n, name) | 展开块门 |
control(n, control_state) | 将线路包装为受控线路 |
append(other, target, control, control_state) | 追加子线路 |
prepend(other, target, control, control_state) | 前置子线路 |
initialize(v, target) | 初始化目标比特为指定态 |
寄存器接口
Register
量子寄存器,支持 Python 风格索引:
from unitarylab.core import Register
qr = Register('q', 3)
# 单比特访问
print(qr[0])
# 切片访问
print(qr[1:3])
# 列表访问
print(qr[[0, 2]])ClassicalRegister
经典寄存器,接口与 Register 对称,values 属性存储测量结果,-1 表示未测量:
from unitarylab.core.classical_register import ClassicalRegister
cr = ClassicalRegister('c', 2)常见注意事项
- 线路复用:
Circuit对象可以通过append/prepend嵌套,这在构建模块化算法(如 QPE、QFT + 算法主体)时非常有用。 - 不可变门对象:
QuantumGate是 frozen dataclass,一旦创建不可修改。线路变换方法均返回新对象。 - 块门展开:通过
append添加的子线路会以块门(block)形式存储。执行时会自动展开,但绘图和分析时可能需要先调用decompose()展开才能看到细节。
最后更新于