# 使用 Python 求解 H₂ 基态能量

本教程使用 ArcQML Python API 实现 H₂/STO-3G 的 VQE。任务与 [Rust H₂ VQE 教程](../rust/h2_vqe.md)相同，完整代码位于 [`examples/python/h2_vqe.py`](../../../examples/python/h2_vqe.py)。

## 问题配置

| 配置 | 数值 |
| --- | --- |
| H–H 距离 | `0.70 Å` |
| 基组 | STO-3G |
| 活性电子/轨道 | 2/2 |
| 映射 | Jordan–Wigner |
| 量子比特 | 4 |
| Hamiltonian 项数 | 15 |
| Hartree–Fock 能量 | `-1.1173490350562805 Ha` |
| 精确基态能量 | `-1.1361894542078266 Ha` |

VQE 最小化：

$$
E(\boldsymbol{\theta}) =
\langle \psi(\boldsymbol{\theta}) \rvert H \lvert \psi(\boldsymbol{\theta}) \rangle.
$$

## 从公共 JSON 构造 Hamiltonian

Python 与 Rust 示例共用 [`examples/data/h2_hamiltonian.json`](../../../examples/data/h2_hamiltonian.json)。Python 绑定通过 `PauliSum` 的公开构造接口读取其中每一项：

```python
payload = json.loads(path.read_text(encoding="utf-8"))
hamiltonian = arcqml.PauliSum(num_qubits=payload["num_qubits"])

for term in payload["terms"]:
    operations = term["paulis"]
    if not operations:
        hamiltonian.add_identity(coefficient=term["coefficient"])
    else:
        hamiltonian.add_term(
            paulis="".join(op["pauli"] for op in operations),
            qubits=[op["qubit"] for op in operations],
            coefficient=term["coefficient"],
        )
```

## Hartree–Fock 初态与 ansatz

先占据 `q0`、`q1`，制备显示为 `|0011⟩` 的 Hartree–Fock 初态：

```python
circuit = arcqml.Circuit(num_qubits=4)
circuit.x(qubit=0)
circuit.x(qubit=1)
```

随后添加 6 层 `RY-RZ + 环形 CNOT`，共 48 个可训练参数：

```python
parameter_index = 0
for _layer in range(LAYERS):
    for qubit in range(NUM_QUBITS):
        ry = 0.04 * math.sin(0.37 * (parameter_index + 1))
        parameter_index += 1
        rz = 0.04 * math.sin(0.37 * (parameter_index + 1))
        parameter_index += 1
        circuit.ry(angle=ry, qubit=qubit)
        circuit.rz(angle=rz, qubit=qubit)
    for control in range(NUM_QUBITS):
        circuit.cnot(
            control=control,
            target=(control + 1) % NUM_QUBITS,
        )
```

完整程序使用固定公式生成非零初值，因此重复运行可复现。

## 训练

```python
simulator = arcqml.StateVectorSimulator(num_qubits=NUM_QUBITS)
optimizer = arcqml.Adam(learning_rate=0.05)

for step in range(1, 101):
    energy = simulator.run(circuit=circuit, observable=hamiltonian)
    energy.backward()
    optimizer.step(circuit=circuit)
    optimizer.zero_grad(circuit=circuit)
```

训练顺序为 `run → backward → step → zero_grad`。`run` 不修改模拟器，所以同一个零态模拟器可以反复使用；Hartree–Fock 制备已经包含在线路中。

评估时关闭梯度记录：

```python
with arcqml.no_grad():
    energy = simulator.run(circuit=circuit, observable=hamiltonian).item()
```

程序最后报告与精确基态的绝对误差，并以 `1.6e-3 Ha` 判断是否达到化学精度。

## 运行

先安装本地绑定，然后在仓库根目录执行：

```bash
maturin develop --release
python examples/python/h2_vqe.py
```

数据位置由脚本自身路径计算，因此也可以从其他工作目录启动。
