Krylov Methods
The krylov subpackage implements sample-based Krylov quantum
diagonalization (SKQD) and basis expansion methods.
Core SKQD
- class qvartools.krylov.basis.skqd.ClassicalKrylovDiagonalization(hamiltonian, config, initial_state=None)[source]
Bases:
objectClassical Krylov subspace diagonalization via exact time evolution.
Constructs Krylov states \(|\psi_k\rangle = (e^{-iH\Delta t})^k |\psi_0\rangle\) using exact matrix exponentiation (no Trotter decomposition), samples computational-basis configurations from each via Born-rule sampling, and solves a projected generalized eigenvalue problem.
For molecular Hamiltonians the algorithm restricts to the particle-number-conserving subspace. For spin Hamiltonians the full Hilbert space is used.
- Parameters:
hamiltonian (
Hamiltonian) – The system Hamiltonian.config (
SKQDConfig) – Algorithm hyperparameters.initial_state (
np.ndarrayorNone, optional) – Initial state vector in the full (or subspace) Hilbert space. IfNone, a default Hartree–Fock-like state is constructed.
- hamiltonian
The Hamiltonian instance.
- Type:
Hamiltonian
- config
The configuration dataclass.
- Type:
- h_dense
Dense Hamiltonian matrix (in the relevant subspace).
- Type:
np.ndarray
- subspace_configs
Particle-conserving configurations, if applicable.
- Type:
torch.TensororNone
Examples
>>> skqd = ClassicalKrylovDiagonalization(hamiltonian, SKQDConfig()) >>> eigenvalues, info = skqd.run() >>> info["krylov_dim"] 10
- extract_projected_submatrix(configs)[source]
Extract projected H and S from the precomputed dense Hamiltonian.
Maps each configuration in configs to its index in the full particle-conserving subspace and extracts the corresponding submatrix of
self.h_dense. Falls back to_build_projected_matrices()if any configuration is not found in the subspace.- Parameters:
configs (
torch.Tensor) – Basis configurations, shape(n_basis, num_sites).- Returns:
h_proj (
np.ndarray) – Projected Hamiltonian, shape(n_basis, n_basis).s_proj (
np.ndarray) – Overlap matrix (identity), shape(n_basis, n_basis).
- Return type:
- run()[source]
Execute the full SKQD algorithm.
Constructs Krylov states iteratively, samples configurations from each, builds projected Hamiltonian and overlap matrices in the sampled basis, and solves the generalized eigenvalue problem.
- Returns:
eigenvalues (
np.ndarray) – Lowest eigenvalues from the projected problem, shape(num_eigenvalues,).info (
dict) – Diagnostic information with keys:"basis_size": int — final number of basis configurations."krylov_dim": int — number of Krylov vectors constructed."energies_per_step": list of float — ground-state energy estimate after each Krylov expansion step."basis_configs": torch.Tensor — final basis configurations.
- Return type:
- class qvartools.krylov.basis.skqd.SKQDConfig(max_krylov_dim=10, time_step=0.1, total_evolution_time=1.0, shots_per_krylov=1000, use_cumulative_basis=True, num_eigenvalues=1, which_eigenvalues='SA', regularization=1e-08, use_gpu=False)[source]
Bases:
objectHyperparameters for Sample-Based Krylov Quantum Diagonalization.
- Parameters:
max_krylov_dim (
int) – Maximum number of Krylov vectors to construct.time_step (
float) – Time step for real-time evolutione^{-iH dt}.total_evolution_time (
float) – Total evolution time budget (informational; the algorithm usesmax_krylov_dim * time_stepKrylov vectors).shots_per_krylov (
int) – Number of measurement shots per Krylov state for sampling computational-basis configurations.use_cumulative_basis (
bool) – IfTrue, retain samples from all previous Krylov states (cumulative union). IfFalse, only keep the latest set.num_eigenvalues (
int) – Number of lowest eigenvalues to compute from the projected problem.which_eigenvalues (
str) – Eigenvalue selection criterion passed to the eigensolver."SA"= smallest algebraic (default).regularization (
float) – Tikhonov regularization added to the overlap matrix diagonal to stabilise the generalized eigenvalue problem.use_gpu (
bool) – IfTrue, attempt to use GPU-accelerated linear algebra.
Examples
>>> cfg = SKQDConfig(max_krylov_dim=5, time_step=0.05) >>> cfg.max_krylov_dim 5
Flow-Guided SKQD
- class qvartools.krylov.basis.flow_guided.FlowGuidedKrylovDiag(hamiltonian, config, nf_basis, nf_basis_weights=None, initial_state=None)[source]
Bases:
objectSKQD with normalizing-flow basis seeding.
Combines configurations obtained from a normalizing-flow sampler with the Krylov subspace to accelerate convergence. The NF basis provides an informed starting set of configurations, and Krylov expansion systematically enriches it.
- Parameters:
hamiltonian (
Hamiltonian) – The system Hamiltonian.config (
SKQDConfig) – Algorithm hyperparameters.nf_basis (
torch.Tensor) – Configurations from the normalizing-flow sampler, shape(n_nf, num_sites).nf_basis_weights (
torch.TensororNone, optional) – Importance weights for the NF configurations. IfNone, uniform weights are assumed.initial_state (
np.ndarrayorNone, optional) – Initial state for the Krylov expansion. IfNone, a default Hartree–Fock-like state is constructed.
Examples
>>> skqd = FlowGuidedKrylovDiag(hamiltonian, SKQDConfig(), nf_basis=nf_configs) >>> results = skqd.run_with_nf(progress=True) >>> results["energy"] -1.137
- run_with_nf(progress=False)[source]
Run SKQD with NF basis seeding.
- Parameters:
progress (
bool, optional) – IfTrue, log progress at each Krylov expansion step.- Returns:
Results dictionary with keys:
"energy": float — best stable ground-state energy estimate."eigenvalues": np.ndarray — all computed eigenvalues from the final projection."basis_size": int — final number of basis configurations."krylov_dim": int — number of Krylov vectors used."energies_per_step": list of float — ground-state energy estimate after each expansion step."nf_energy": float — energy from the NF-only basis."basis_configs": torch.Tensor — final basis configurations.
- Return type:
Basis Expansion
- class qvartools.krylov.expansion.residual_config.ResidualExpansionConfig(max_configs_per_iter=100, residual_threshold=0.0001, max_iterations=10, max_basis_size=5000, min_energy_improvement_mha=0.05, stagnation_patience=3)[source]
Bases:
objectHyperparameters for residual-based and selected-CI basis expansion.
- Parameters:
max_configs_per_iter (
int) – Maximum number of new configurations to add per iteration.residual_threshold (
float) – Minimum absolute residual component for a configuration to be considered for inclusion.max_iterations (
int) – Maximum number of expansion iterations.max_basis_size (
int) – Hard upper limit on the total basis size.min_energy_improvement_mha (
float) – Minimum energy improvement in milliHartree per iteration. If the improvement drops below this forstagnation_patienceconsecutive iterations, expansion terminates.stagnation_patience (
int) – Number of consecutive iterations with insufficient energy improvement before early stopping.
Examples
>>> cfg = ResidualExpansionConfig(max_configs_per_iter=50) >>> cfg.max_configs_per_iter 50
- class qvartools.krylov.expansion.residual_expander.ResidualBasedExpander(hamiltonian, config)[source]
Bases:
objectIterative basis expansion driven by residual analysis.
Given a current basis and its ground-state eigenpair \((E, |\Phi\rangle)\), computes the residual \(r_x = \langle x | (H - E) | \Phi \rangle\) for candidate configurations \(|x\rangle\) and adds those with the largest \(|r_x|\) to the basis.
- Parameters:
hamiltonian (
Hamiltonian) – The system Hamiltonian.config (
ResidualExpansionConfig) – Expansion hyperparameters.
- hamiltonian
The Hamiltonian instance.
- Type:
Hamiltonian
- config
The configuration dataclass.
- Type:
ResidualExpansionConfig
Examples
>>> expander = ResidualBasedExpander(hamiltonian, ResidualExpansionConfig()) >>> expanded, stats = expander.expand_basis(basis, energy, eigvec) >>> stats["iterations"] 3
- expand_basis(current_basis, energy, eigenvector)[source]
Iteratively expand the basis using residual analysis.
- Parameters:
current_basis (
torch.Tensor) – Starting basis configurations, shape(n_basis, num_sites).energy (
float) – Current ground-state energy estimate.eigenvector (
np.ndarray) – Current eigenvector in the basis representation.
- Returns:
expanded_basis (
torch.Tensor) – Expanded basis configurations.stats (
dict) – Expansion statistics with keys:"iterations": int — number of expansion iterations."initial_energy": float — energy before expansion."final_energy": float — energy after expansion."energy_improvement_mha": float — total improvement in mHa."basis_sizes": list of int — basis size at each iteration."energies": list of float — energy at each iteration."configs_added": list of int — configs added per iteration.
- Return type:
- class qvartools.krylov.expansion.selected_ci_expander.SelectedCIExpander(hamiltonian, config)[source]
Bases:
objectCIPSI-style selected-CI basis expansion.
Uses second-order perturbative importance to select the most significant configurations for basis enrichment:
\[\varepsilon_x = \frac{|\langle x | H | \Phi \rangle|^2}{|E - E_x|}\]where \(E_x = \langle x | H | x \rangle\) is the diagonal Hamiltonian element and \(E\) is the current variational energy.
- Parameters:
hamiltonian (
Hamiltonian) – The system Hamiltonian.config (
ResidualExpansionConfig) – Expansion hyperparameters (shared with residual expansion).
- hamiltonian
The Hamiltonian instance.
- Type:
Hamiltonian
- config
The configuration dataclass.
- Type:
ResidualExpansionConfig
Examples
>>> expander = SelectedCIExpander(hamiltonian, ResidualExpansionConfig()) >>> expanded, stats = expander.expand_basis(basis, energy, eigvec) >>> "pt2_corrections" in stats True
- expand_basis(current_basis, energy, eigenvector)[source]
Iteratively expand the basis using CIPSI-style selection.
- Parameters:
current_basis (
torch.Tensor) – Starting basis configurations, shape(n_basis, num_sites).energy (
float) – Current ground-state energy estimate.eigenvector (
np.ndarray) – Current eigenvector in the basis representation.
- Returns:
expanded_basis (
torch.Tensor) – Expanded basis configurations.stats (
dict) – Expansion statistics with keys:"iterations": int — number of expansion iterations."initial_energy": float — energy before expansion."final_energy": float — energy after expansion."energy_improvement_mha": float — total improvement in mHa."basis_sizes": list of int — basis size at each iteration."energies": list of float — energy at each iteration."configs_added": list of int — configs added per iteration."pt2_corrections": list of float — Epstein–Nesbet PT2 correction at each iteration.
- Return type:
Basis Sampling
- class qvartools.krylov.basis.sampler.KrylovBasisSampler(hamiltonian, num_qubits, shots=1000, time_step=0.1)[source]
Bases:
objectInterface for sampling configurations from Krylov-evolved states.
Computes time-evolved states \(|\psi_k\rangle = e^{-iH \Delta t \cdot k} |\psi_0\rangle\) and samples computational-basis configurations from the resulting probability distribution \(p(x) = |\langle x | \psi_k \rangle|^2\).
Currently provides a classical simulation backend. The interface is designed to accommodate future quantum-hardware backends (e.g., via Qiskit or CUDA-Q) without changing the calling code.
- Parameters:
- Raises:
ValueError – If
num_qubitsdoes not match the Hamiltonian’s site count, or ifshotsortime_stepare invalid.
Examples
>>> from qvartools.hamiltonians import TransverseFieldIsing >>> ham = TransverseFieldIsing(num_sites=4, J=1.0, h=0.5) >>> sampler = KrylovBasisSampler(ham, num_qubits=4, shots=500) >>> counts = sampler.sample_krylov_state(krylov_power=3) >>> type(counts) <class 'dict'>
- property h_dense: ndarray
Lazily-constructed dense Hamiltonian matrix.
- Returns:
Dense Hamiltonian of shape
(hilbert_dim, hilbert_dim).- Return type:
np.ndarray
- sample_krylov_state(krylov_power, initial_state=None)[source]
Sample configurations from a Krylov-evolved state.
Computes \(|\psi_k\rangle = e^{-iH \Delta t \cdot k} |\psi_0\rangle\) and samples
shotsbitstring configurations from the resulting probability distribution.- Parameters:
- Returns:
Mapping from bitstring (e.g.,
"0110") to the number of times it was observed acrossshotssamples.- Return type:
- Raises:
ValueError – If
krylov_poweris negative orinitial_statehas the wrong dimension.RuntimeError – If the evolved state has near-zero norm (e.g., due to numerical issues).
Krylov Expansion Utilities
krylov_expand — Basis expansion via Hamiltonian connections
Provides expand_basis_via_connections(), which grows a configuration
basis by following the off-diagonal structure of the Hamiltonian. Starting
from a set of reference configurations, the function collects all
Hamiltonian-connected states, ranks them by coupling strength, and adds
unique new configurations up to a specified cap.
Supports two-hop expansion: first hop discovers singles/doubles from seed configs, second hop expands from those to reach up to quadruples.
- qvartools.krylov.expansion.krylov_expand.expand_basis_via_connections(basis, hamiltonian, max_new=500, n_ref=None, coupling_rank=True)[source]
Expand a configuration basis by following Hamiltonian connections.
Selects
n_refreference configurations from the basis, collects all states connected to them via the Hamiltonian, ranks by coupling strength, removes duplicates and states already in the basis, and returns the expanded basis with up tomax_newnew configurations.Performs a two-hop expansion when budget allows: first hop discovers single/double excitations from seed configs, second hop expands from those to reach quadruples.
- Parameters:
basis (
torch.Tensor) – Current basis configurations, shape(n_basis, n_sites)with integer entries.hamiltonian (Any) – The system Hamiltonian. Must implement
diagonal_elementandget_connections.max_new (
int, optional) – Maximum number of new configurations to add (default500).n_ref (
intorNone, optional) – Number of reference configurations. Defaults tomin(len(basis), 50).coupling_rank (
bool, optional) – IfTrue, rank new configs by max|H_ij|coupling strength and keep topmax_new(defaultTrue).
- Returns:
Expanded basis configurations, shape
(n_basis + n_added, n_sites)wheren_added <= max_new.- Return type: