{ "cells": [ { "cell_type": "markdown", "id": "c2b3a1a8", "metadata": {}, "source": [ "# 使用量子化学工具箱高效模拟VQE算法\n", "\n", "[![下载Notebook](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r2.7.0rc1/resource/_static/logo_notebook.svg)](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/r2.7.0rc1/mindquantum/zh_cn/advanced/mindspore_mqchem_tutorial.ipynb) \n", "[![下载样例代码](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r2.7.0rc1/resource/_static/logo_download_code.svg)](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/r2.7.0rc1/mindquantum/zh_cn/advanced/mindspore_mqchem_tutorial.py) \n", "[![查看源文件](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r2.7.0rc1/resource/_static/logo_source.svg)](https://gitee.com/mindspore/docs/blob/r2.7.0rc1/docs/mindquantum/docs/source_zh_cn/advanced/mqchem_tutorial.ipynb)\n", "\n", "## 1. 引言\n", "\n", "`mqchem` 是一个专为解决量子化学问题而设计的集成工具箱。它的核心优势在于基于 **组态相互作用(Configuration Interaction, CI)** 的模拟方法。与在整个 $2^{N}$ 维希尔伯特空间中操作的通用模拟器不同,`mqchem` 的模拟器在一个由固定电子数(`n_electrons`)定义的子空间中进行演化。这种方法极大地减少了运行时间,使得我们可以在极短的时间内模拟20比特或更大规模的化学体系。\n", "\n", "`mqchem` 模块主要包含三个协同工作的核心组件:\n", "\n", "- **`CIHamiltonian`**: 用于高效表示化学问题的哈密顿量。\n", "- **`UCCExcitationGate`**: UCCSD 等变分 ansatz 的基本构建块。\n", "- **`MQChemSimulator`**: 在 CI 空间中执行量子线路演化和测量的高性能模拟器。\n", "\n", "在本教程中,您将学习如何遵循自然的工作流程,使用 `mqchem` 模块的组件来解决化学问题:\n", "\n", "1. 了解 `mqchem` 的核心组件及其各自的职责。\n", "2. 学习如何将这些组件组合起来,以应用量子线路并计算期望值。\n", "3. 利用高阶函数 `prepare_uccsd_vqe` 快速搭建一个完整的 VQE 流程。\n", "4. 亲手完成一个 H₆ 线性链分子的基态能量计算。\n", "\n", "**前置依赖**:\n", "在开始之前,请确保您已经安装了 MindQuantum 以及用于化学计算的 `openfermion` 和 `openfermionpyscf`。\n", "\n", "```bash\n", "pip install mindquantum openfermion openfermionpyscf\n", "```" ] }, { "cell_type": "markdown", "id": "38052e40", "metadata": {}, "source": [ "---\n", "\n", "## 2. `mqchem` 核心组件\n", "\n", "在解决一个量子化学问题时,我们通常需要定义问题本身(哈密顿量)、构建求解方案(ansatz 线路),并在一个模拟环境中执行它。`mqchem` 的三个核心组件正好对应这几个步骤。\n", "\n", "### 2.1 `CIHamiltonian`:定义问题\n", "\n", "`CIHamiltonian` 是 `FermionOperator` 的一个包装类,它将费米子哈密顿量转换为一种适合在 CI 空间中进行高效计算的格式。它是我们 VQE 计算的目标函数。" ] }, { "cell_type": "code", "execution_count": 1, "id": "2134121b", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CI 哈密顿量:\n", "1 [0^ 0] +\n", "1 [1^ 1]\n" ] } ], "source": [ "from mindquantum.core.operators import FermionOperator\n", "from mindquantum.simulator import mqchem\n", "\n", "# 任何一个费米子算符都可以被包装\n", "# 例如,我们定义一个简单的粒子数算符 H = n_0 + n_1\n", "ham_op = FermionOperator('0^ 0') + FermionOperator('1^ 1')\n", "\n", "# 将其包装为 CIHamiltonian\n", "ci_ham = mqchem.CIHamiltonian(ham_op)\n", "\n", "print(\"CI 哈密顿量:\")\n", "print(ci_ham)" ] }, { "cell_type": "markdown", "id": "99ee7a5a", "metadata": {}, "source": [ "### 2.2 `UCCExcitationGate`:构建解法\n", "\n", "`UCCExcitationGate` 是构建UCC(Unitary Coupled-Cluster)ansatz 的基本单元。它代表了酉算符 $U(\\theta) = e^{\\theta(T - T^\\dagger)}$,其中 $T$ 是一个费米子激发算符(例如 $a_p^\\dagger a_q$),而 $\\theta$ 是一个可训练的参数。\n", "\n", "`mqchem` 模块中的模拟器经过特殊优化,可以极高效地应用这种门。" ] }, { "cell_type": "code", "execution_count": 2, "id": "081a6207", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "创建的 UCC 门:\n", "exp{(theta)([2^ 0] + [2 0^])}\n" ] } ], "source": [ "# 创建一个从轨道 0 激发到轨道 2 的激发算符 T = a_2^\\dagger a_0\n", "# 'theta' 是一个可训练的参数名\n", "t_op = FermionOperator('2^ 0', 'theta')\n", "\n", "# 从该算符创建 UCC 激发门\n", "ucc_gate = mqchem.UCCExcitationGate(t_op)\n", "\n", "print(\"创建的 UCC 门:\")\n", "print(ucc_gate)" ] }, { "cell_type": "markdown", "id": "c4f2c7e2", "metadata": {}, "source": [ "### 2.3 `MQChemSimulator`:提供执行环境\n", "\n", "`MQChemSimulator` 是执行模拟的引擎。它维护着一个 CI 基矢上的量子态,并提供了应用 `UCCExcitationGate` 和计算 `CIHamiltonian` 期望值的方法。\n", "\n", "初始化时,需要指定系统的 `n_qubits`(总自旋轨道数)和 `n_electrons`(总电子数)。模拟器默认从 **哈特里-福克(Hartree-Fock, HF)** 态开始,这是量子化学计算中最常用的参考态。" ] }, { "cell_type": "code", "execution_count": 3, "id": "db8bc9ac", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "模拟器量子比特数: 4\n", "模拟器电子数: 2\n", "\n", "初始 Hartree-Fock 态:\n", "1¦0011⟩\n" ] } ], "source": [ "from mindquantum.core.circuit import Circuit\n", "\n", "# 初始化一个4量子比特、2电子的模拟器\n", "sim = mqchem.MQChemSimulator(n_qubits=4, n_electrons=2, seed=42)\n", "\n", "print(f\"模拟器量子比特数: {sim.n_qubits}\")\n", "print(f\"模拟器电子数: {sim.n_electrons}\")\n", "\n", "# 默认的 HF 态是 |0011> (比特从右到左编号 0, 1, 2, 3)\n", "print(\"\\n初始 Hartree-Fock 态:\")\n", "print(sim.get_qs(ket=True))" ] }, { "cell_type": "markdown", "id": "8cd31303", "metadata": {}, "source": [ "---\n", "\n", "## 3. 组合应用:模拟与计算\n", "\n", "了解了三大组件后,我们来看看如何将它们组合起来,执行一个完整的模拟流程。\n", "\n", "### 3.1 应用门与线路\n", "\n", "我们可以使用 `apply_gate` 或 `apply_circuit` 方法,在 `MQChemSimulator` 维护的量子态上作用 `UCCExcitationGate`。" ] }, { "cell_type": "code", "execution_count": 4, "id": "6accd81d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "应用单个门之后的状态:\n", "0.99500417¦0011⟩\n", "-0.09983342¦0110⟩\n", "\n", "应用线路后的状态:\n", "0.97517033¦0011⟩\n", "-0.0978434¦0110⟩\n", "0.19767681¦1001⟩\n", "0.01983384¦1100⟩\n" ] } ], "source": [ "# 重置模拟器到 HF 态\n", "sim.reset()\n", "\n", "# 应用之前创建的 ucc_gate,并为参数 'theta' 赋值 0.1\n", "sim.apply_gate(ucc_gate, pr={'theta': 0.1})\n", "\n", "print(\"应用单个门之后的状态:\")\n", "print(sim.get_qs(ket=True))\n", "\n", "# 也可以应用包含多个门的线路\n", "sim.reset()\n", "t_op2 = FermionOperator('3^ 1', 0.2) # 使用常数作为参数\n", "ucc_gate2 = mqchem.UCCExcitationGate(t_op2)\n", "circuit = Circuit([ucc_gate, ucc_gate2])\n", "\n", "# 应用线路,并为参数 'theta' 赋值\n", "sim.apply_circuit(circuit, pr={'theta': 0.1})\n", "\n", "print(\"\\n应用线路后的状态:\")\n", "print(sim.get_qs(ket=True))" ] }, { "cell_type": "markdown", "id": "08e91d20", "metadata": {}, "source": [ "### 3.2 计算期望值\n", "\n", "`get_expectation` 方法用于计算当前量子态下,某个 `CIHamiltonian` 的期望值 $\\langle\\psi|H|\\psi\\rangle$。\n", "\n", "例如,我们来验证 HF 态 $|0011\\rangle$ 下,哈密顿量 $H = n_0 + n_1$ 的期望值。由于轨道 0 和 1 都被占据,我们期望结果为 $1+1=2$。" ] }, { "cell_type": "code", "execution_count": 5, "id": "50b73472", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 的期望值为: 2.0\n" ] } ], "source": [ "sim.reset()\n", "\n", "# 使用之前创建的 ci_ham\n", "expectation = sim.get_expectation(ci_ham)\n", "print(f\" 的期望值为: {expectation}\")" ] }, { "cell_type": "markdown", "id": "bed49038", "metadata": {}, "source": [ "---\n", "\n", "## 4. VQE 实战:计算 H₆ 分子基态能量\n", "\n", "现在,我们将运用所学知识,通过 VQE 算法计算 H₆ 线性链分子的基态能量。这是一个展示 `mqchem` 模块强大功能的典型案例。\n", "\n", "### 4.1 准备工作:定义分子\n", "\n", "我们使用 `openfermion` 和 `openfermionpyscf` 来获取 H₆ 分子的数据。`run_pyscf` 会执行经典的量子化学计算(如 HF 和 CCSD),这些结果将作为我们量子算法的输入。\n", "\n", "**关键**:我们必须设置 `run_ccsd=True`,因为 `prepare_uccsd_vqe` 函数需要 CCSD 的计算结果来为 VQE 提供高质量的初始参数。" ] }, { "cell_type": "code", "execution_count": 6, "id": "74667a61", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "分子: H₆ 线性链\n", "量子比特数 (自旋轨道数): 12\n", "电子数: 6\n", "精确基态能量 (FCI): -3.23606628 Hartrees\n" ] } ], "source": [ "from openfermion import MolecularData\n", "from openfermionpyscf import run_pyscf\n", "\n", "# 定义 H₆ 分子,键长为 1 埃\n", "geometry = [(\"H\", (i, 0, 0)) for i in range(6)]\n", "basis = \"sto-3g\"\n", "multiplicity = 1 # 自旋多重度 (2S+1),单重态 S=0\n", "charge = 0\n", "\n", "# 创建分子对象并运行 PySCF\n", "# 注意:run_ccsd=True 对于获取初始振幅至关重要\n", "molecule = MolecularData(geometry, basis, multiplicity, charge)\n", "mol = run_pyscf(molecule, run_ccsd=True, run_fci=True)\n", "\n", "print(f\"分子: H₆ 线性链\")\n", "print(f\"量子比特数 (自旋轨道数): {mol.n_qubits}\")\n", "print(f\"电子数: {mol.n_electrons}\")\n", "print(f\"精确基态能量 (FCI): {mol.fci_energy:.8f} Hartrees\")" ] }, { "cell_type": "markdown", "id": "0e845f1a", "metadata": {}, "source": [ "### 4.2 使用 `prepare_uccsd_vqe` 一键准备 VQE\n", "\n", "`prepare_uccsd_vqe` 是 `mqchem` 模块的一大亮点。这个高阶工厂函数为我们自动完成了 VQE 准备中最繁琐的步骤,它将我们之前学到的组件创建过程自动化了:\n", "\n", "1. 从分子数据生成费米子哈密顿量,并包装成 `CIHamiltonian`。\n", "2. 基于 UCCSD(Unitary Coupled-Cluster Singles and Doubles)理论,生成一个参数化的 `Circuit`,其中包含一系列 `UCCExcitationGate`。\n", "3. 从经典的 CCSD 计算结果中提取耦合簇振幅,作为 VQE 优化的**初始参数**。这通常是一个非常好的起点。" ] }, { "cell_type": "code", "execution_count": 7, "id": "af7559fb", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CI 哈密顿量 (部分项):\n", " 4.6038 [] +\n", "-2.2818 [0^ 0] +\n", "-0.1459 [4 0^] +\n", " 0.0642 [8 0^] +\n", "-2.2818 [1^ 1] +\n", "-0.1459 [5 1^] +\n", " 0.0642 [9 1^] +\n", "-2.0409 [2^ 2] +\n", "-0.2111 [6 2^] +\n", " 0.0417 [10 2^] +\n", "-2.0409 [3^ 3] +\n", "-0.2111 [7 3^] +...\n", "\n", "生成的 Ansatz 线路包含 59 个门。\n", "线路参数名称: ['d1_0', 's_1', 'd1_1', 'd1_2', 's_3', 'd1_3', 'd1_4', 's_5', 'd1_5', 'd1_6', 's_7', 'd1_7', 'd1_8', 'd2_1', 'd2_3', 'd2_9', 'd2_5', 'd2_18', 'd2_7', 'd2_11', 'd2_16', 'd2_13', 'd2_20', 'd2_22', 'd2_24', 'd2_27', 'd2_29', 'd2_31', 'd2_34']\n", "\n", "从 CCSD 提取的初始振幅 (共 29 个):\n", "[-0.02172895 -0.00966027 -0.03288994 -0.10380602 0.0028648 -0.0143801\n", " -0.03201595 -0.00681583 -0.02420889 -0.01695636 -0.00239016 -0.01001419\n", " -0.01221332 0.00432926 0.01629623 0.00904958 -0.00799714 0.01818314\n", " 0.03079327 0.04406509 0.02507472 0.01007596 -0.00356389 -0.00956368\n", " -0.01592823 -0.01108764 -0.01197809 -0.00586536 0.00582737]\n" ] } ], "source": [ "# 一键生成哈密顿量、UCCSD ansatz 线路和初始参数\n", "# threshold=1e-6 用于过滤掉 CCSD 振幅过小的激发项,简化 ansatz\n", "hamiltonian, ansatz_circuit, initial_amplitudes = mqchem.prepare_uccsd_vqe(mol, threshold=1e-6)\n", "\n", "print(\"CI 哈密顿量 (部分项):\")\n", "print(str(hamiltonian.fermion_hamiltonian)[:200] + \"...\")\n", "\n", "print(f\"\\n生成的 Ansatz 线路包含 {len(ansatz_circuit)} 个门。\")\n", "print(\"线路参数名称:\", ansatz_circuit.params_name)\n", "\n", "print(f\"\\n从 CCSD 提取的初始振幅 (共 {len(initial_amplitudes)} 个):\")\n", "print(initial_amplitudes)" ] }, { "cell_type": "markdown", "id": "83b08941", "metadata": {}, "source": [ "### 4.3 获取期望与梯度计算函数\n", "\n", "VQE 的核心是最小化能量期望值。高效的优化算法(如 L-BFGS-B)需要能量关于参数的梯度。`get_expectation_with_grad` 方法正是为此设计的。它返回一个函数,该函数接收参数值,并同时返回能量期望值和梯度。" ] }, { "cell_type": "code", "execution_count": 8, "id": "bf8b5afc", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "使用初始参数计算的能量: -3.21777544\n", "对应的梯度 (前5个): [-0.03673877 0.02322724 -0.06124962 -0.10907011 -0.00220752]\n" ] } ], "source": [ "# 初始化一个新的模拟器用于 VQE 计算\n", "vqe_sim = mqchem.MQChemSimulator(mol.n_qubits, mol.n_electrons)\n", "\n", "# 获取可以计算期望和梯度的函数\n", "# 这个函数与 scipy.optimize.minimize 的接口兼容\n", "grad_ops = vqe_sim.get_expectation_with_grad(hamiltonian, ansatz_circuit)\n", "\n", "# 我们可以测试一下这个函数\n", "energy, gradient = grad_ops(initial_amplitudes)\n", "print(f\"使用初始参数计算的能量: {energy:.8f}\")\n", "print(f\"对应的梯度 (前5个): {gradient[:5]}\")" ] }, { "cell_type": "markdown", "id": "da59e68b", "metadata": {}, "source": [ "### 4.4 运行优化器\n", "\n", "最后,我们使用经典的优化器 `scipy.optimize.minimize` 来寻找最优参数,从而得到基态能量的变分近似值。" ] }, { "cell_type": "code", "execution_count": 9, "id": "f5648912", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "--- VQE 优化完成 ---\n", "VQE 计算得到的基态能量: -3.23544945 Hartrees\n", "精确的 FCI 基态能量: -3.23606628 Hartrees\n", "误差: 6.17e-04 Hartrees\n", "运行时间: 0.03 秒\n" ] } ], "source": [ "from scipy.optimize import minimize\n", "from time import time\n", "\n", "t0 = time()\n", "\n", "# 使用 L-BFGS-B 算法进行优化\n", "# jac=True 表示我们的 grad_ops 函数同时返回期望值和雅可比矩阵(梯度)\n", "result = minimize(grad_ops, initial_amplitudes, method=\"L-BFGS-B\", jac=True)\n", "\n", "vqe_energy = result.fun\n", "\n", "print(\"\\n--- VQE 优化完成 ---\")\n", "print(f\"VQE 计算得到的基态能量: {vqe_energy:.8f} Hartrees\")\n", "print(f\"精确的 FCI 基态能量: {mol.fci_energy:.8f} Hartrees\")\n", "print(f\"误差: {abs(vqe_energy - mol.fci_energy):.2e} Hartrees\")\n", "print(f\"运行时间: {time() - t0:.2f} 秒\")" ] }, { "cell_type": "markdown", "id": "9f72d5e0", "metadata": {}, "source": [ "可以看到,VQE 的计算结果与精确的 FCI 能量非常接近,并且整个优化过程在0.02秒内就完成了!这证明了 `mqchem` 模块中各个组件协同工作的正确性和高性能。\n", "\n", "---\n", "\n", "## 5. 总结\n", "\n", "在本教程中,我们系统地介绍了 `mqchem` 模块。我们从它的三个核心组件——`CIHamiltonian`、`UCCExcitationGate` 和 `MQChemSimulator`——出发,理解了它们在量子化学模拟工作流中各自的角色。\n", "\n", "我们不仅学习了如何独立使用这些组件,更重要的是,我们看到了它们如何无缝集成,以解决实际问题。最后,通过一个计算 H₆ 分子基态能量的 VQE 实例,我们展示了如何利用 `prepare_uccsd_vqe` 等便捷工具,高效地搭建和运行一个完整的量子化学模拟流程。\n", "\n", "`mqchem` 模块为在 MindQuantum 平台上进行高性能、高精度的量子化学研究提供了强大的支持。希望本教程能帮助您快速上手,并探索更多有趣的化学问题!" ] } ], "metadata": { "kernelspec": { "display_name": "py39", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.21" } }, "nbformat": 4, "nbformat_minor": 5 }