qalgora-Q Docs Hub量子文档 ✦ Ask AI✦ 问问文档

ADAPT-VQE Algorithm

◐ Design-level API
This page documents qalgora-Q API design, architecture, or adaptation workflows. Code examples illustrate intended usage and are not guaranteed to run in the current reference implementation.

Grow the ansatz adaptively: at each step add the operator from a pool with the largest energy gradient, building a compact, problem-tailored shallow circuit. Understand first why it works this way, then see how qalgora-Q runs the whole loop in a single call.

The problem it solves — fixed ansätze are either too big or too small

A fixed ansatz like UCCSD crams every single and double excitation into the circuit, whether or not they actually matter for the molecule in front of you. The result is usually a circuit that is far too deep — many of those parameters contribute almost nothing, yet they still burn through precious coherence time. But pruning excitations by hand is hard, because you have no way of knowing in advance which ones to keep and which to throw away. ADAPT-VQE takes a different tack: instead of building the ansatz all at once, it grows it on demand, adding only the single most useful operator at each step.

The intuition — lay one brick at a time, always downhill

Lay out a pool of candidate excitation operators and ask one question: if I were to wire a given operator into the circuit right now, how fast could it push the energy down? The answer is that operator's energy gradient. Each round, ADAPT-VQE picks the operator with the largest gradient — the steepest available descent direction — adds it, re-optimizes all the parameters, and asks the question again. Building up brick by brick this way, the circuit contains only operators that genuinely drive the energy downward, which keeps it both shallow and accurate.

The math — measuring the gradient with a commutator

In the current state |ψ⟩, wiring in operator Ai with a parameter θi, the derivative of the energy with respect to that parameter (evaluated at θi=0) is given by the expectation value of a commutator:

∂E/∂θi|0 = ⟨ψ| [H, Ai] |ψ⟩

This formula assumes a specific generator convention. If the candidate unitary is written e(θ Ai) with Ai an anti-Hermitian excitation generator, then ∂E/∂θi|0 = ⟨ψ|[H, Ai]|ψ⟩. If instead a Hermitian generator Gi is used with e(−iθ Gi), the gradient is −i⟨ψ|[H, Gi]|ψ⟩. Different packages adopt different generator conventions, so follow the specific ansatz definition.

This quantity tells us directly which direction, and how fast, the energy would move if we added Ai. The larger its absolute value, the more "valuable" that operator is right now. When the gradients of every operator in the pool have dropped below some threshold, adding any further operator would barely help — that is convergence, and the loop stops.

The mechanism — the adaptive growth loop

  1. For every operator Ai in the pool, measure the gradient ⟨[H, Ai]⟩.
  2. Pick the operator with the largest gradient magnitude and append it to the circuit ansatz.
  3. Re-optimize all parameters so far together with VQE.
  4. Return to step one, until the largest gradient falls below the threshold.

Each additional round grows the circuit by exactly one operator and one parameter. What you end up with is not a generic template, but a compact circuit custom-built for this particular Hamiltonian.

Honest boundaries — the measurement cost of gradient screening

  • Screening isn't free. Every round you have to measure the gradient of each operator in the pool before you can crown a winner. The larger the pool, the more expensive this screening becomes — it buys you a shallower circuit, but at the price of more measurements.
  • It is a greedy strategy. Taking the steepest direction at every step does not guarantee the globally shortest circuit, and it can stall in a local minimum.
  • Re-optimization gets pricier as the circuit grows. Every added operator means re-optimizing all the parameters again, so each round's optimization cost keeps rising late in the run.
  • The choice of operator pool is critical. Too small a pool lacks expressive power; too large a pool makes screening explode — designing the pool is itself a trade-off.

Reading the code against the theory

Read the code below against the discussion above. get_operator_pool("uccsd", ...) pulls out the pool of candidate excitation operators — exactly the batch whose gradients get evaluated one by one. solvers.adapt_vqe(...) wraps the entire loop: internally gradient="parameter_shift" estimates each candidate's energy gradient via the parameter-shift rule; in ADAPT-VQE's theory this same gradient can equivalently be expressed through the commutator expectation ⟨[H, Ai]⟩. Both target the same selection criterion, but the measurement implementation need not be identical. It then picks the largest to wire in, re-optimizes with LBFGS, and stops only once the largest gradient drops below threshold=1e-3. The returned len(ops) is the number of operators ultimately selected and actually used — usually far fewer than the whole pool, which is precisely why the circuit stays compact.

Using the Solvers library

import qalgora
import qalgora_solvers as solvers
from qalgora import spin

hamiltonian = spin.z(0) + spin.z(1) - 0.5 * spin.x(0) * spin.x(1)
pool = solvers.get_operator_pool("uccsd", num_qubits=2, num_electrons=2)

energy, params, ops = solvers.adapt_vqe(
    hamiltonian, pool,
    optimizer=qalgora.optimizers.LBFGS(),
    gradient="parameter_shift",
    threshold=1e-3,
)
print("ground-state energy:", energy)
print("operators selected:", len(ops))
Specification API — not in the open reference build yet
This example shows a qalgora-Q specification API (or a third-party library) that the open reference build does not bundle today. It documents the intended interface; to run code now, use the reference build’s supported core API.

This UCCSD pool is a teaching-interface example; a real molecular calculation also needs the orbitals, electron count, fermion-to-qubit mapping, and Hamiltonian-generation pipeline specified.

The same idea, extended
ADAPT-QAOA carries this "adaptively select operators by gradient" idea over to QAOA: instead of fixing the mixer layers, it picks the mixer operator with the largest gradient at every layer.

References

  • H. R. Grimsley, S. E. Economou, E. Barnes, N. J. Mayhall, "An adaptive variational algorithm for exact molecular simulations on a quantum computer," Nat. Commun. 10, 3007 (2019). doi:10.1038/s41467-019-10988-2
  • A. Peruzzo, J. McClean, P. Shadbolt, M.-H. Yung, X.-Q. Zhou, P. J. Love, A. Aspuru-Guzik, J. L. O'Brien, "A variational eigenvalue solver on a photonic quantum processor," Nat. Commun. 5, 4213 (2014). doi:10.1038/ncomms5213

ADAPT-VQE 算法

◐ 设计接口
本页描述的是 qalgora-Q 的接口设计、架构设计或适配工作流。相关代码用于说明预期用法,当前参考实现不保证可以直接运行。

自适应生长线路拟设:每一步从算符池中选取能量梯度最大的算符加入,从而搭出一条紧凑、贴合具体问题的浅层线路。先理解它为什么要这么做,再看 qalgora-Q 如何用一次调用跑完整个循环。

它解决的问题 固定拟设要么太大要么太小

像 UCCSD 这样的固定拟设把所有单、双激发一股脑塞进线路,无论它们对眼前这个分子是否真有用。结果往往是线路过深——大量参数其实贡献甚微,却照样吃掉宝贵的相干时间。可如果手动砍掉一些激发,又很难事先知道哪些该留、哪些能扔。ADAPT-VQE 的思路是:别一次性把拟设建满,而是按需逐个生长,每次只添真正最有用的那一个算符。

直觉 沿最陡的方向逐个添砖

把一池候选激发算符摆在面前,问一个问题:如果现在把某个算符接进线路,能量最快能往下掉多少?答案就是该算符对应的能量梯度。ADAPT-VQE 每一轮都挑梯度最大的那个算符加进去——也就是当前最陡的下坡方向——然后重新优化全部参数,再问一遍。如此一砖一瓦地搭,线路只会包含确实推动能量下降的算符,自然又浅又准。

数学 用对易子衡量梯度

在当前态 |ψ⟩ 下,把算符 Ai 以参数 θi 接入后能量对该参数的导数(在 θi=0 处)由一个对易子的期望给出:

∂E/∂θi|0 = ⟨ψ| [H, Ai] |ψ⟩

这条公式依赖于具体的生成元约定。若候选幺正写成 e(θ Ai),其中 Ai反厄米的激发生成元,则 ∂E/∂θi|0 = ⟨ψ|[H, Ai]|ψ⟩;若改用厄米生成元 Gi 并写成 e(−iθ Gi),则梯度为 −i⟨ψ|[H, Gi]|ψ⟩。不同软件包采用不同的生成元约定,因此应遵循具体拟设的定义。

这个量直接告诉我们:把 Ai 加进来,能量沿哪个方向、以多快的速率改变。绝对值越大,这个算符当下越"值钱"。当池中所有算符的梯度都掉到某个阈值以下时,说明再添任何算符都几乎无济于事——此时收敛,循环停止。

机制 自适应生长循环

  1. 对算符池中的每个算符 Ai,测量梯度 ⟨[H, Ai]⟩。
  2. 选梯度绝对值最大的那个算符,接到线路拟设末尾。
  3. 用 VQE 把到目前为止所有参数一并重新优化。
  4. 回到第一步,直到最大梯度低于阈值。

每多走一轮,线路只长一个算符,参数只多一个。最终得到的不是一个通用模板,而是一条专门为这个哈密顿量量身定制的紧凑线路。

诚实的边界 梯度筛选的测量开销

  • 筛选要花钱。每一轮都要把池中每个算符的梯度都测一遍才能挑出冠军。池子越大,这笔筛选测量越贵——它换来的是更浅的线路,代价却是更多的测量次数。
  • 这是一种贪心策略。每步只取当下最陡的方向,并不保证得到全局最短的线路,也可能停在局部极小。
  • 重优化随线路增长变贵。每加一个算符就要把全部参数重新优化一遍,后期每一轮的优化成本都在上升。
  • 算符池的选择很关键。池子太小则表达力不足,太大则筛选开销爆炸——池子的设计本身就是一项权衡。

对照代码理解

请对照上文来读这段代码。get_operator_pool("uccsd", ...) 取出候选激发算符池——就是上面要逐个评估梯度的那批算符。solvers.adapt_vqe(...) 把整套循环封装好:内部用 gradient="parameter_shift" 通过参数移位规则估计每个候选算符的能量梯度;在 ADAPT-VQE 的理论中,这一梯度可以等价地用对易子期望 ⟨[H, Ai]⟩ 表示。两者针对同一个选择判据,但具体的测量实现不必相同。随后挑出最大的接入,再用 LBFGS 重优化,直到最大梯度跌破 threshold=1e-3 才停。返回的 len(ops) 就是最终被选中并真正用上的算符个数——通常远少于整个池子,这正是线路得以保持紧凑的原因。

使用 Solvers 库

import qalgora
import qalgora_solvers as solvers
from qalgora import spin

hamiltonian = spin.z(0) + spin.z(1) - 0.5 * spin.x(0) * spin.x(1)
pool = solvers.get_operator_pool("uccsd", num_qubits=2, num_electrons=2)

energy, params, ops = solvers.adapt_vqe(
    hamiltonian, pool,
    optimizer=qalgora.optimizers.LBFGS(),
    gradient="parameter_shift",
    threshold=1e-3,
)
print("ground-state energy:", energy)
print("operators selected:", len(ops))
规范接口 · 参考实现暂未包含
此示例展示的是 qalgora-Q 规范中的接口(或第三方库),开放参考实现目前尚未内置,仅用于说明预期用法;如需立即运行,请使用参考实现已支持的核心 API。

这里的 UCCSD pool 是教学接口示例;实际分子计算中还需指定轨道、电子数、费米子-量子比特映射与哈密顿量生成流程。

同一思想的延伸
ADAPT-QAOA 把这套"按梯度自适应选算符"的思路搬到 QAOA 上:不再固定混合层,而是每一层都挑梯度最大的混合算符。

参考文献

  • H. R. Grimsley, S. E. Economou, E. Barnes, N. J. Mayhall, "An adaptive variational algorithm for exact molecular simulations on a quantum computer," Nat. Commun. 10, 3007 (2019). doi:10.1038/s41467-019-10988-2
  • A. Peruzzo, J. McClean, P. Shadbolt, M.-H. Yung, X.-Q. Zhou, P. J. Love, A. Aspuru-Guzik, J. L. O'Brien, "A variational eigenvalue solver on a photonic quantum processor," Nat. Commun. 5, 4213 (2014). doi:10.1038/ncomms5213