Skip to Content

薛定谔化方法

概述

unitarylab_algorithms.schrodingerization 包实现了通过薛定谔化(Schrödingerization)技术将偏微分方程(PDE)求解转化为量子模拟的算法——将非厄米(非酉)动力学嵌入到满足薛定谔方程的更大量子系统中,从而在量子计算机上进行酉模拟。

核心思想:将经典偏微分方程 不一定是反厄米算符)通过坐标变换嵌入到等价薛定谔方程所描述的量子系统中。

方程模块算法类描述
一维对流方程equation_advectionAdvectionEquationAlgorithm线性输运方程
一维热方程equation_heatHeatEquationAlgorithm扩散方程
二维热方程equation_heat2dHeat2dEquationAlgorithm二维热扩散

本模块使用独立的 PDE 算法接口和 setup.json 配置。返回值中的 circuit 是线路图信息列表,plot 是解的可视化信息。对流方程支持 classicaltrotter;热方程的 block 选项当前按经典方法计算。各方法支持的参数和输出结构见对应小节。


基类:unitarylab_algorithms.schrodingerization.base

所有薛定谔化算法均继承自 unitarylab_algorithms.schrodingerization.base.BaseAlgorithm

抽象接口

class BaseAlgorithm(ABC): def __init__(self): self.color = "#DBB924" self.algo_dir = None self.logger = None @abstractmethod def run(self, params: str) -> Dict[str, Any]: """执行算法逻辑。params 为 JSON 字符串格式。""" ... def parse_params(self, params) -> Any: """解析参数:优先按 json.loads 解析,失败则回退到 ast.literal_eval, 兼容 JSON 字符串、Python 字面量字符串和已解析的 dict/list。""" ...

抽象基类声明的 run(self, params: str) 签名只是一个占位声明——Python 不检查子类重写方法的签名兼容性。三个具体子类实际实现(且被 __main__ 与外部调用方实际使用)的签名是:

def run(self, params=None, algo_dir: str = None, backend='torch', device='cpu', dtype=np.complex128) -> Dict[str, Any]:

params=None 时会自动从该算法模块目录下的 setup.json 加载默认参数;传入 dict/list 会直接使用;传入 JSON 字符串会被 parse_equation 内部解析(先 json.loads,若结果含 "params" 键则取 ["params"])。

日志工具

create_algorithm_logger 函数为每个算法创建独立的滚动文件日志记录器,写入 algo_dir/algorithm.log(及单独的 algorithm_error.log):

from unitarylab_algorithms.schrodingerization.base import create_algorithm_logger logger = create_algorithm_logger(__file__) logger.info("算法开始执行")

参数:

参数类型默认值说明
algorithm_filestr通常传入算法模块的 __file__;用于确定默认日志目录
log_namestr | NoneNone日志记录器名称(默认使用算法文件夹名)
log_dirstr | NoneNone日志目录(默认使用算法文件所在目录)
console_outputboolTrue是否同时输出到控制台
max_bytesint50 * 1024 * 1024(50 MB)单个日志文件最大字节数
backup_countint5保留的备份日志文件数量
force_reconfigureboolFalse强制重新初始化(热重载时使用)

该函数会检测沙箱环境(同时存在 TASK_IDALGO_PARAMS 环境变量时判定为沙箱),此时即使 console_output=True 也会跳过控制台 StreamHandler,仅写入文件,以避免宿主进程重复采集日志。

绘图辅助方法

BaseAlgorithm 还提供了 set_plt(color='white')(统一设置 matplotlib 文字/坐标轴配色)、_generate_solution_plot_1d(...)(一维解曲线图)、_generate_circuit_plots(name, qc, H1=None, H2=None, format='svg')(生成量子电路图,qc 对应的完整电路图始终生成,H1/H2None 时各追加一张分解电路图,因此返回列表长度在 1~3 之间)等受保护的辅助方法,供子类在 _solve_* 方法内部调用。其中 _generate_solution_plot_1d 并非每个子类都会经由自身的 _generate_solution_plot 包装调用——一维对流方程与一维热方程直接继承基类的 _generate_solution_plot(内部调用 _generate_solution_plot_1d),而二维热方程则完全覆盖了 _generate_solution_plot,改用独立实现的 3D 曲面绘图(ax.plot_surface(...)),从不调用 _generate_solution_plot_1d,详见下文各算法小节。


一维对流方程

背景

线性对流方程描述了标量场 以常速度 的输运过程:

薛定谔化方法将 编码为量子态,并在等价薛定谔方程 )下演化,从而实现对该非酉经典偏微分方程的量子酉模拟。

导入

from unitarylab_algorithms import AdvectionEquationAlgorithm

.run() 参数

def run(self, params=None, algo_dir: str = None, backend='torch', device='cpu', dtype=np.complex128) -> Dict[str, Any]
参数类型默认值说明
paramsNone | str | dict | listNoneNone 时自动加载模块内 setup.json;字符串既可以是 JSON 内容,也可以是指向 JSON 文件的路径AdvectionEquationAlgorithm 独有的文件路径分支);也可直接传入已解析的 dict/list
algo_dirstr | NoneNone结果与日志输出目录;为 None 时自动创建 ./results/schrodingerization/equation_advection/
backendstr'torch'仅在 method='trotter' 时生效,完整转发给底层 schro_trotter
devicestr'cpu'同上
dtypenumpy dtypenp.complex128同上

setup.json 中默认方程配置(equation_advection 块)的关键固定参数:

参数默认值取值范围说明
a0.1[-100, 100]对流速度;符号决定迎风格式(upwind)的方向
L16(0, 100]计算域长度,区间为
T1(0, 100]终止时间
nx4[1, 10]空间量子比特数

求解方法配置(solutionMethod_classical 块):

参数默认值说明
na8辅助量子比特数,控制薛定谔化参数 的离散精度
R4 的截断区间为
ppoint1薛定谔化后在该点恢复原方程的解

边界条件默认使用 boundaryCondition_periodic(周期边界),初值默认使用 initialCondition_discontinuous(阶跃初值: 处为 0,其余为 1);离散格式默认 discreteFormat_upwind(迎风格式,scheme='upwind'_solve_classical 会依据 a 的符号自动切换为 'forward'/'backward')。

返回值

_solve_classical / _solve_trotter 均返回:

{ "status": "ok", "message": "Advection equation solved", "grid": {"n_points": 2**nx, "dx": dx}, # trotter 分支额外含 "dt", "nt" "x": [...], # 空间网格坐标(list) "u": [...], # 终止时刻的解(list) "circuit": [{"format": "svg", "filename": "..."}], # 始终只有 1 张完整电路图,两个 `_solve_*` 分支均未向 `_generate_circuit_plots` 传入 H1/H2 "plot": {"format": "svg", "filename": "..."}, # 解的可视化图(单个 dict) }

示例

from unitarylab_algorithms import AdvectionEquationAlgorithm algo = AdvectionEquationAlgorithm() result = algo.run() # params=None,使用 setup.json 默认参数(classical 方法) print(result["status"], result["message"]) print("电路图数量:", len(result["circuit"]))

自定义参数(以 dict 形式传入,直接对应 setup.jsonparams 数组结构)时,请参照 setup.json 的完整 schema 构造 equationsolutionMethod_* 两个块;也可以先 json.load 读取默认 setup.json,修改其中的 par_fix/value 字段后再传入。


一维热方程

背景

一维热方程描述标量场的扩散过程:

其中 是热扩散系数,要求 。算符 是负半定的非哈密顿量类型,需要通过薛定谔化嵌入()才能进行酉模拟。

导入

from unitarylab_algorithms import HeatEquationAlgorithm

.run() 参数

def run(self, params=None, algo_dir: str = None, backend='torch', device='cpu', dtype=np.complex128) -> Dict[str, Any]

参数含义与对流方程一致,但不支持文件路径形式的 params 字符串,仅接受 None、已解析对象或可直接解析的配置字符串。当前版本的 Trotter 路径使用默认执行后端配置。

setup.json 中默认方程配置(equation_heat 块):

参数默认值取值范围说明
a1(0, 100]扩散系数,要求 a > 0
L17(0, 100]计算域长度
T1(0, 100]终止时间
nx5[1, 10]空间量子比特数
f(x)(源项)"a+x"由 sympy 解析,可用变量 x 及常量 aL

边界条件默认 boundaryCondition_dirichlet),初值默认 initialCondition_custom(需通过 par_func 提供自定义 )。

method='block' 目前等价于 method='classical'_solve_block(self, eq) 的完整实现是:

def _solve_block(self, eq): self.logger.info('Block encoding will be supported soon! Now falling back to classical method!') return self._solve_classical(eq)

setup.jsonmethod_list 中列出了 "solutionMethod_block",容易让人误以为块编码方法已经实现。选择该方法实际得到的是经典矩阵指数方法的结果,请勿用其性能或电路结构代表真正的块编码算法。

返回值

字段形状与对流方程一致(见上),message 字段为 "Heat equation solved",但 circuit 列表的长度取决于求解方法:method='classical' 时只生成 1 张完整线路图;method='trotter' 时会把非空的 H1H2 一并传给 _generate_circuit_plots(...),因此生成 3 张线路图(完整线路、H1H2);method='block' 当前回退到 classical,所以也是 1 张。

示例

from unitarylab_algorithms import HeatEquationAlgorithm algo = HeatEquationAlgorithm() result = algo.run() # 默认 classical 方法 print(result["status"], result["grid"])

二维热方程

背景

二维热方程将标量扩散推广到两个空间维度:

量子模拟需要 个空间量子比特( 方向各 个),薛定谔化嵌入方式与一维情形类似()。

导入

from unitarylab_algorithms import Heat2dEquationAlgorithm

注意类名大小写为 Heat2d(非 Heat2D),__init__.pyfrom .algorithm import Heat2dEquationAlgorithm 与包级 ALGORITHM_NAME = "heat2d" 均沿用此拼写。

.run() 参数

def run(self, params=None, algo_dir: str = None, backend='torch', device='cpu', dtype=np.complex128) -> Dict[str, Any]

同样不支持文件路径形式的 paramsmethod='trotter' 时可通过 device 选择执行设备,后端与数值精度使用默认配置。

setup.json 中默认方程配置(equation_heat2d 块):

参数默认值取值范围说明
a11(0, 100] 方向扩散系数
a21(0, 100] 方向扩散系数
L17(0, 100]计算域长度( 共用)
T1(0, 100]终止时间
nx4[1, 10]每个方向的空间量子比特数(总空间比特数为 2*nx

边界条件默认 boundaryCondition_dirichlet,初值默认 initialCondition_custom,默认 method_list 仅列出 ["solutionMethod_classical", "solutionMethod_trotter"]不含 block)。

尽管 setup.json 未声明 block 方法,Heat2dEquationAlgorithm.run() 的代码依然会对 method == 'block' 分派到 _solve_block(self, eq),其实现与一维热方程完全相同——记录 "Block encoding will be supported soon!..." 后直接调用 _solve_classical(eq)。因此通过自定义 params(而非默认 setup.json)显式指定 "solutionMethod_block" 时,同样只会得到经典方法的结果。

返回值

{ "status": "ok", "message": "2D Heat equation solved", "grid": {"n_points": 2**nx, "dx": dx}, # trotter 分支额外含 "dt", "nt" "x": [...], "y": [...], # 二维热方程独有:额外的 y 方向网格坐标 "u": [[...], ...], # 形状为 (2**nx, 2**nx) 的二维解,按 list of list 序列化 "circuit": [{"format": "svg", "filename": "..."}, ...], "plot": {"format": "svg", "filename": "..."}, # 3D 曲面图(plot_surface),非一维折线图 }

示例

from unitarylab_algorithms import Heat2dEquationAlgorithm algo = Heat2dEquationAlgorithm() result = algo.run() print(result["status"], "grid:", result["grid"]) print("y 方向网格点数:", len(result["y"]))

通用注意事项

  • 三个算法均没有使用 unitarylab_algorithms.algo_base.BaseAlgorithm,因此不具备 _build_return_dict()self.outputself.status 等其他包共有的机制;不要假设返回字典的字段与其他章节一致。
  • params=None 时会自动加载算法自身目录下的 setup.json 求解一次默认算例,这也是每个 algorithm.py 文件末尾 if __name__ == "__main__": result = XxxAlgorithm().run() 的行为。
  • methodsetup.json(或传入参数)中 solver 块的 type 字段决定(对应 solutionMethod_classical/solutionMethod_trotter/solutionMethod_blocktype 值去除前缀后的部分,如 'classical'/'trotter'/'block');三个算法支持的取值不完全相同,详见各自小节。
  • _solve_block 目前在 equation_heatequation_heat2d 中均是”回退到经典方法”的占位实现,equation_advection 则根本不接受 'block';三者均没有真正的块编码(block-encoding)电路实现。
  • 在处理外部输入前,可使用 algo.parse_params(params) 安全反序列化参数(先尝试 json.loads,失败则回退 ast.literal_eval)。
  • 这些算法对于细密空间网格计算量较大(矩阵维度随 2**nx 增长,二维情形为 2**(2*nx))。验证环境配置时,建议从较小的 nx(如 4–6)开始,再逐步扩大规模。
  • 每个算法内部使用 create_algorithm_logger(algo_dir) 配置日志记录,日志文件写入 algo_dir/algorithm.log(及 algorithm_error.log),沙箱环境下会自动跳过控制台输出以避免日志重复。
最后更新于