Skip to Content

核心线路接口

概述

本章介绍 UnitaryLab 量子线路的核心数据结构与操作方法,适合希望构建和操作量子线路的用户。读完本章,你将能够:

  • 使用多种方式创建 Circuit 对象
  • 添加单量子比特门、受控门和旋转门
  • 添加测量操作
  • 执行模拟并读取结果
  • 使用线路变换方法(复制、反转、追加等)
  • 了解 UnitaryLab 的量子比特排序规则

模块索引

模块主要类
unitarylab.core.circuitCircuitBaseCircuit
unitarylab.core.registerRegister
unitarylab.core.classical_registerClassicalRegister
unitarylab.backend.gatesequence.gatesequenceGateSequenceBaseGateSequence
unitarylab.backend.gate.gatebaseQuantumGate

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-YY 轴旋转 π
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)CNOTqc.cx(0, 1)
mcx(ctrls, tgt)多控制 Xqc.mcx([0, 1], 2)
cy(ctrl, tgt)受控 Yqc.cy(0, 1)
cz(ctrl, tgt)受控 Zqc.cz(0, 1)
ch(ctrl, tgt)受控 Hqc.ch(0, 1)
cs(ctrl, tgt)受控 Sqc.cs(0, 1)
cp(angle, ctrl, tgt)受控相位qc.cp(np.pi/2, 0, 1)
swap(tgt1, tgt2)SWAPqc.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) 中,qubitclbit 均可以是整数或列表。
  • 测量操作在执行时会对量子态进行投影,并将结果写入 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() 展开才能看到细节。
最后更新于