Skip to Content

快速开始

概述

本章将引导你在 5 分钟内完成 UnitaryLab 模拟器的上手流程。完成后,你将能够:

  • 使用 Circuit 创建量子线路
  • 添加基本量子门
  • 执行模拟并读取状态向量和概率分布
  • 添加测量并读取经典比特结果

推荐导入方式

from unitarylab import Circuit, Register, ClassicalRegister

CircuitRegisterClassicalRegisterunitarylab 包顶层直接导出的三个名称(等价写法:from unitarylab.core import Circuit, Register, ClassicalRegister),也是用户最常用的高层接口,绝大多数操作都通过它们完成。底层的 GateSequenceCircuitExecutor 等在普通使用中无需直接导入。

最小示例:Bell 态

Bell 态是量子纠缠的标准示例,由一个 Hadamard 门和一个 CNOT 门构成。

from unitarylab import Circuit # 1. 创建 2 量子比特线路 qc = Circuit(2) # 2. 对第 0 号量子比特施加 Hadamard 门 qc.h(0) # 3. 添加 CNOT 门(控制比特 0,目标比特 1) qc.cx(0, 1) # 4. 执行模拟 result = qc.execute() # 5. 查看状态向量 print(result.state)

预期输出:

[0.70710678+0.j 0. +0.j 0. +0.j 0.70710678+0.j]

查看概率分布

probs = result.probabilities print(probs)

预期输出:

{'00': 0.4999999999999999, '11': 0.4999999999999999}

probabilities 返回一个字典,键为计算基态的二进制字符串(little-endian,最低位对应 qubit 0),值为对应的测量概率。Bell 态下 |00⟩|11⟩ 各占约 50%。

添加测量

Circuit(n) 这种整数构造方式会自动创建默认量子寄存器 Register('q', n) 默认经典寄存器 ClassicalRegister('c', n),因此不需要显式创建经典寄存器也可以直接调用 measure()

from unitarylab import Circuit qc = Circuit(2) # 已自动创建名为 'q' 的 2 量子比特寄存器和名为 'c' 的 2 经典比特寄存器 qc.h(0) qc.cx(0, 1) # 将量子比特 0、1 的测量结果存入经典比特 0、1 qc.measure([0, 1], [0, 1]) result = qc.execute() print(result.classical_results_map)

只有在需要自定义寄存器命名、使用多个寄存器自定义量子/经典比特布局时,才需要显式构造 Register/ClassicalRegister 并传入 Circuit

from unitarylab import Circuit, Register, ClassicalRegister qr = Register('q', 2) cr = ClassicalRegister('c', 2) qc = Circuit(qr, cr) qc.h(0) qc.cx(0, 1) qc.measure([0, 1], [0, 1]) result = qc.execute() print(result.classical_results_map)

预期输出(默认 seed=42,结果确定不变):

{0: 1, 1: 1}

classical_results_map 是经典比特索引到测量值(01)的映射。Bell 态的测量结果总是两比特相同(0011),体现了量子纠缠。若改用 qc.execute(seed=None) 或其他种子,每次运行的结果会在 {0: 0, 1: 0}{0: 1, 1: 1} 之间随机变化。

执行参数:shots、seed、backend_options

execute() 的完整参数为:

result = qc.execute( initial_state=None, # 初始态,默认从 |0...0⟩ 开始 backend='torch', # 'torch'(默认)/ 'numpy' / 'cpp' / 'tensornet' device='cpu', # 'cpu' 或 'gpu'(仅 backend='torch' 支持 gpu) dtype=np.complex128, # 复数精度,默认 complex128;会按后端自动归一化(如整数/浮点类型会被提升为对应复数类型) shots=1, # 独立重复执行次数 seed=42, # 测量随机种子;None 表示不固定种子 backend_options=None, # 后端专属选项(tensornet 后端可传 max_bond/cutoff/routing) )
  • shots 大于 1 时,result.state / result.classical_results_map最后一次执行的结果,而 result.counts 会汇总所有 shots 的经典比特串统计(键为字符串,值为出现次数)。
  • seed 独立控制线路内测量的随机性,默认固定为 42,因此不显式传参时结果可复现;需要真正随机的采样时传 seed=None
  • backend_options 目前只在 backend='tensornet' 时生效,用于控制 MPS 的最大键维 max_bond、截断阈值 cutoff 及双比特门路由策略 routing'auto' / 'swap' / 'mpo')。
# 多次采样并统计经典比特串出现次数 qc = Circuit(2) qc.h(0) qc.cx(0, 1) qc.measure([0, 1], [0, 1]) result = qc.execute(shots=1000, seed=None) print(result.counts) # {'00': 498, '11': 502} # 具体数值每次运行不同

选择执行后端

execute() 支持 backenddevice 参数,适用于不同计算环境:

# 使用 PyTorch 后端(默认),在 CPU 上运行 result = qc.execute(backend='torch', device='cpu') # 使用 NumPy 后端 result = qc.execute(backend='numpy', device='cpu') # 使用 C++ 编译后端(需要编译扩展可用) result = qc.execute(backend='cpp', device='cpu') # 使用张量网络(MPS)后端,适合大比特数、低纠缠线路 result = qc.execute(backend='tensornet', device='cpu') # 若有 CUDA 或 Apple MPS,可切换到 GPU(仅 torch 后端支持) import torch gpu_available = torch.cuda.is_available() or torch.backends.mps.is_available() if gpu_available: # Apple MPS 不支持 complex128,因此统一显式使用 complex64 result = qc.execute(backend='torch', device='gpu', dtype=np.complex64) else: print('当前环境没有可用 GPU,跳过 GPU 示例。')

一般直接调用 qc.execute() 无需指定参数(默认 torch + cpu);比特数很大但线路纠缠有限时可尝试 tensornet 后端;有 GPU 时可用 device='gpu' 加速。

绘制线路图

qc.draw()

draw() 会弹出 Matplotlib 线路图。如需保存为文件:

qc.draw(filename='bell.png', title='Bell State')

下一步

最后更新于