Sample-Based Krylov Quantum Diagonalization (SKQD)
Build a Krylov subspace by repeatedly time-evolving and sampling a state, then diagonalize classically — scaling to many qubits with sparse linear algebra.
The problem it solves
Finding the ground-state energy of a many-body Hamiltonian means extracting the lowest eigenvalue of a matrix whose dimension is 2N — hopelessly large to diagonalize directly. The classical workhorse for this is the Krylov subspace method (Lanczos): rather than touch the full matrix, build a small subspace {|ψ⟩, H|ψ⟩, H2|ψ⟩, …} from a reference state and diagonalize H restricted to it. Krylov spaces converge to the extremal (lowest and highest) eigenvalues remarkably fast, so a handful of basis vectors usually suffices.
The catch is that applying powers of H — Hk|ψ⟩ — is not something a quantum
computer does naturally. What it does do naturally is real-time evolution
e−iHt, implemented by Trotterization. The two are closely related:
e−iHt expands as a power series in H, so the time-evolved states
{e−iH·k·dt|ψ⟩} at several times capture the spectral information that the
Hk|ψ⟩ exploration probes — but one does not explicitly construct each
Hk|ψ⟩ term by term, and the numerical stability and the correlation between
basis vectors depend on the time step and the chosen sampling times. So you can build a Krylov-type
basis purely from circuits the device can run.
Intuition — a Krylov basis from time evolution and sampling
Each Trotterized evolution nudges the reference state further along its own dynamics, exploring different parts of the Hilbert space. Measure each evolved state in the computational basis and you collect the configurations (bitstrings) that carry significant amplitude at that evolution time. Taking the union of these dominant configurations across all the sampled times yields a compact set that spans a subspace rich in the ground state — the quantum device proposes the basis, and nothing more is asked of it.
Generating Krylov states
The loop below evolves the reference state for k Trotter steps, samples it, and adds the
observed bitstrings to a growing pool of basis configurations.
import qalgora
# repeatedly evolve and sample, keeping only the dominant, valid configurations
configs = set()
for k in range(krylov_dim):
counts = qalgora.sample(trotter_evolve, k, dt, shots_count=5000)
# keep the top-k most frequent bitstrings above a frequency threshold,
# restricted to the valid symmetry sector (e.g. fixed particle number)
ranked = sorted(counts.items(), key=lambda kv: kv[1], reverse=True)
for bitstring, freq in ranked[:top_k]:
if freq >= freq_threshold and in_valid_sector(bitstring):
configs.add(bitstring)
if len(configs) >= max_subspace_dim: # cap the subspace size
break
Solving the projected eigenproblem
It helps to separate two distinct subspaces. (A) The time-evolved Krylov basis
{e−iH·k·dt|ψ0⟩} is in general non-orthogonal, so one solves a
generalized eigenproblem H c = E S c; here both H and the
overlap matrix S must be obtained from quantum overlap / matrix-element
measurements. (B) The sampled-bitstring basis — the union of computational-basis
configurations collected at several evolution times — is treated as an orthogonal computational
basis, so S = I and the problem collapses to an ordinary sparse eigenvalue problem; this
variant is closer to a Krylov-guided selected CI, and its matrix elements
Hij are constructible classically from the bitstrings. The code below
uses variant (B), solving the S = I problem with a Lanczos-type routine such as
eigsh.
Sparse classical diagonalization
from scipy.sparse.linalg import eigsh
H_sparse = build_sparse_hamiltonian(list(configs)) # CSR matrix on GPU
ground_energy = eigsh(H_sparse, k=1, which="SA")[0][0]
print("SKQD ground-state energy:", ground_energy)
Conditioning and noise — the central caveat
The price of fast Krylov convergence is ill-conditioning. As the Krylov dimension grows, the time-evolved states become nearly linearly dependent — they start to point in almost the same direction — so the overlap matrix S becomes badly conditioned. Once you estimate the matrix elements by sampling, statistical noise on those entries gets amplified by the inverse of a near-singular S, which can throw up spurious eigenvalues below the true ground state — these below-ground-state pseudo-eigenvalues are an artifact of a noisy, ill-conditioned S, not the result of an exact variational diagonalization over the subspace. Practical SKQD therefore caps the Krylov dimension, regularizes or thresholds the overlap matrix, and takes enough shots to keep the matrix-element error small. Trotter error in the evolution adds a second, separate source of bias.
Seeing it in code
Read the two snippets against the theory. In the first, the loop over k performs the
repeated time-evolve-and-sample step, and the filtering — top-k by frequency, a frequency threshold, a
valid-sector check, and a cap on the subspace size — selects the dominant configurations that define the
subspace, rather than blindly accumulating every sampled bitstring. In the second,
build_sparse_hamiltonian(list(configs)) projects H onto that subspace, and
eigsh(..., k=1, which="SA") is the sparse Lanczos solve that returns the lowest
("smallest algebraic") eigenvalue.
eigsh) — these sections
document the intended interface, not shipping software.
基于采样的 Krylov 量子对角化(SKQD)
反复对量子态做时间演化并采样,由此张成 Krylov 子空间,再交给经典对角化——靠稀疏线性代数把多量子比特系统的规模做大。
它解决的问题
求多体哈密顿量的基态能量,就是要提取一个维数为 2N 的矩阵的最低本征值——直接对角化根本不可行。经典上的主力是 Krylov 子空间方法(Lanczos):不去触碰整个矩阵,而是从一个参考态出发构造一个小子空间 {|ψ⟩, H|ψ⟩, H2|ψ⟩, …},并把 H 限制在其中对角化。Krylov 空间收敛到极端(最低与最高)本征值的速度极快,因此通常只需少数几个基矢就够了。
难点在于:作用 H 的幂——Hk|ψ⟩——并不是量子计算机天然会做的事。它天然会做的是实时演化 e−iHt,由 Trotter 分解实现。两者密切相关:e−iHt 可展开为 H 的幂级数,多个时刻的演化态 {e−iH·k·dt|ψ⟩} 能捕捉 Hk|ψ⟩ 探索的谱信息;但不逐项显式构造 Hk|ψ⟩,数值稳定性与基矢之间的相关性取决于时间步与采样时刻。于是你可以完全用设备能运行的线路来构造 Krylov 型基。
直觉 由时间演化与采样得到 Krylov 基
每一次 Trotter 演化都把参考态沿着它自身的动力学再推进一步,探索希尔伯特空间的不同区域。在计算基下测量每个演化态,便能收集到在该演化时刻承载显著振幅的组态(比特串)。把所有采样时刻的主导组态取并集,就得到一个张成富含基态子空间的紧凑集合——量子设备只负责提议这组基,别无他求。
生成 Krylov 态
下面的循环把参考态演化 k 个 Trotter 步、采样,并把观测到的比特串加入不断扩充的基组态池中。
import qalgora
# repeatedly evolve and sample, keeping only the dominant, valid configurations
configs = set()
for k in range(krylov_dim):
counts = qalgora.sample(trotter_evolve, k, dt, shots_count=5000)
# keep the top-k most frequent bitstrings above a frequency threshold,
# restricted to the valid symmetry sector (e.g. fixed particle number)
ranked = sorted(counts.items(), key=lambda kv: kv[1], reverse=True)
for bitstring, freq in ranked[:top_k]:
if freq >= freq_threshold and in_valid_sector(bitstring):
configs.add(bitstring)
if len(configs) >= max_subspace_dim: # cap the subspace size
break
求解投影本征问题
这里要区分两个不同的子空间。(A)时间演化 Krylov 基 {e−iH·k·dt|ψ0⟩} 一般并不正交,因此要求解广义本征问题 H c = E S c;此时 H 与交叠矩阵 S 都需通过量子重叠/矩阵元测量获得。(B)采样比特串基——在多个演化时刻收集的计算基组态之并集——被当作正交的计算基,于是 S = I,问题退化为普通的稀疏本征值问题;该变体更接近 Krylov 引导的选择性组态相互作用(selected CI),其矩阵元 Hij 可由比特串在经典端构造。下面的代码采用变体(B),用 Lanczos 类例程(如 eigsh)求解 S = I 的问题。
稀疏经典对角化
from scipy.sparse.linalg import eigsh
H_sparse = build_sparse_hamiltonian(list(configs)) # CSR matrix on GPU
ground_energy = eigsh(H_sparse, k=1, which="SA")[0][0]
print("SKQD ground-state energy:", ground_energy)
条件数与噪声 核心警告
Krylov 快速收敛的代价是病态。随着 Krylov 维数增大,时间演化态会变得近乎线性相关——它们开始几乎指向同一方向——于是交叠矩阵 S 的条件数急剧恶化。一旦你用采样去估计矩阵元,这些元素上的统计噪声便会被近奇异的 S 的逆放大,可能在真实基态以下抛出伪本征值——这些低于基态的伪本征值是噪声与病态 S 的产物,而非对该子空间做精确变分对角化的结果。因此实用的 SKQD 会限制 Krylov 维数、对交叠矩阵做正则化或阈值处理,并采足够多的样以使矩阵元误差保持很小。演化中的 Trotter 误差还会带来另一个独立的偏差来源。
对照代码理解
请对照原理来读这两段代码。第一段中,对 k 的循环执行了反复的时间演化加采样步骤,而其后的筛选——按频次取 top-k、设频率阈值、校验有效扇区、并对子空间规模设上限——挑选出定义子空间的主导组态,而非盲目累积每一个采样到的比特串。第二段中,build_sparse_hamiltonian(list(configs)) 把 H 投影到该子空间上,而 eigsh(..., k=1, which="SA") 即返回最低("最小代数值")本征值的稀疏 Lanczos 求解。
eigsh)——以上章节描述的是预期接口,而非已发布的软件。