qdk_chemistry.algorithms.time_evolution.builder package

QDK/Chemistry time evolution constructor module.

class qdk_chemistry.algorithms.time_evolution.builder.PartiallyRandomized(weight_threshold=-1.0, trotter_order=2, num_random_samples=100, seed=-1, tolerance=1e-12, merge_duplicate_terms=True, commutation_type='general')

Bases: QDrift

Partially randomized product formula builder.

Implements a hybrid Hamiltonian simulation method that combines deterministic Trotter decomposition with randomized sampling. The Hamiltonian is split as:

\[H = H_D + H_R = \sum_{l=1}^{L_D} H_l + \sum_{m=1}^{M} h_m P_m\]

where: - \(H_D\) contains the \(L_D\) largest-weight terms, treated with Trotter - \(H_R\) contains the remaining terms, treated with qDRIFT-style sampling

The method is effective when: - \(\lambda_R = \sum_m |h_m| \ll \lambda\) (random part has small total weight) - \(L_D \ll M\) (few deterministic terms, many random terms)

For a second-order Trotter formula, each step applies the deterministic part \(H_D\) with half-angles in a symmetric (palindromic) sweep, with the randomized part \(H_R\) sandwiched in between. The first-order variant applies \(H_D\) at full angle followed by \(H_R\).

The total cost scales as \(O(\lambda_R^2 / \epsilon^2)\) Pauli rotations for the randomized part, where \(\lambda_R = \sum_m |h_m|\) is the 1-norm of \(H_R\) (Theorem 2 of [GuntherWS+25]).

Examples

>>> from qdk_chemistry.algorithms import create
>>> # Create a partially randomized builder
>>> builder = create(
...     "time_evolution_builder",
...     "partially_randomized",
...     weight_threshold=0.1,  # Terms with |h_j| >= 0.1 treated deterministically
...     num_random_samples=200,
...     trotter_order=2,
... )
>>> time_evolution = builder.run(qubit_hamiltonian, time=1.0)

References

Günther, J., Witteveen, F., et al. Phase estimation with partially randomized time evolution.

Parameters:
  • weight_threshold (float)

  • trotter_order (int)

  • num_random_samples (int)

  • seed (int)

  • tolerance (float)

  • merge_duplicate_terms (bool)

  • commutation_type (str)

__init__(weight_threshold=-1.0, trotter_order=2, num_random_samples=100, seed=-1, tolerance=1e-12, merge_duplicate_terms=True, commutation_type='general')

Initialize partially randomized builder with specified settings.

Parameters:
  • weight_threshold (float) – Terms with |h_j| >= threshold are treated deterministically with Trotter. Use -1.0 for automatic determination (top 10% of terms by weight).

  • trotter_order (int) – Order of Trotter formula for deterministic part. 1 = first order, 2 = second order (symmetric). Defaults to 2.

  • num_random_samples (int) – Number of random samples for the qDRIFT-style treatment of H_R. Defaults to 100.

  • seed (int) – Random seed for reproducibility. Use -1 for non-deterministic. Defaults to -1.

  • tolerance (float) – Threshold for filtering negligible coefficients. Defaults to 1e-12.

  • merge_duplicate_terms (bool) – If True, identical Pauli terms within consecutive mutually-commuting runs in the random block are fused to reduce circuit depth. Distinct commuting terms are kept separate. Defaults to True.

  • commutation_type (str) – Commutation check used when merging duplicate terms. "qubit_wise" requires every single-qubit pair to commute individually — stricter but always safe. "general" (default) uses standard Pauli commutation (even number of anti-commuting positions), which allows larger merge groups.

name()

Return the name of the time evolution unitary builder.

Return type:

str

type_name()

Return time_evolution_builder as the algorithm type name.

Return type:

str

class qdk_chemistry.algorithms.time_evolution.builder.PartiallyRandomizedSettings

Bases: Settings

Settings for partially randomized product formula builder.

The partially randomized method splits the Hamiltonian into: - H_D: Large-weight terms treated deterministically (Trotter) - H_R: Small-weight terms treated randomly (qDRIFT-style)

This hybrid approach benefits from: - Better ε-scaling from deterministic treatment of dominant terms - Reduced circuit depth from random sampling of the long tail

__init__()

Initialize PartiallyRandomizedSettings with default values.

weight_threshold

Terms with |h_j| >= threshold are treated deterministically. Use -1.0 for automatic determination (top 10% of terms by weight).

trotter_order

Order of Trotter formula for deterministic terms (1 or 2).

num_random_samples

Number of random samples for the randomized part.

seed

Random seed for reproducibility. Use -1 for non-deterministic.

tolerance

Absolute tolerance for filtering small coefficients.

class qdk_chemistry.algorithms.time_evolution.builder.QDrift(num_samples=100, seed=-1, merge_duplicate_terms=True, commutation_type='general')

Bases: TimeEvolutionBuilder

qDRIFT randomized product formula builder.

Implements the qDRIFT algorithm from Campbell (2019), which approximates the time evolution operator \(U(t) = e^{-iHt}\) using randomized sampling of Hamiltonian terms.

Instead of applying all Hamiltonian terms in a fixed sequence (as in Trotter decomposition), qDRIFT randomly samples terms with probability proportional to their coefficient magnitudes. This can achieve better gate complexity for Hamiltonians with many terms.

The algorithm works as follows:

  1. Compute \(\lambda = \sum_j |h_j|\) (1-norm of coefficients)

  2. Build probability distribution \(p_j = |h_j| / \lambda\)

  3. Sample N terms according to this distribution

  4. Each sample contributes \(e^{-i \cdot \text{sign}(h_j) \cdot \lambda t / N \cdot P_j}\)

The approximation error is bounded by \(\epsilon \leq 2\lambda^2 t^2 / N\).

Parameters:
  • num_samples (int)

  • seed (int)

  • merge_duplicate_terms (bool)

  • commutation_type (str)

num_samples

Number of random samples to draw.

seed

Random seed for reproducibility.

merge_duplicate_terms

Whether to fuse identical Pauli terms within consecutive commuting runs.

Examples

>>> from qdk_chemistry.algorithms import create
>>> # Create a qDRIFT builder with 500 samples
>>> qdrift = create("time_evolution_builder", "qdrift", num_samples=500, seed=42)
>>> # Use it to build time evolution for a Hamiltonian
>>> time_evolution = qdrift.run(qubit_hamiltonian, time=1.0)

References

Campbell, E. (2019). Random Compiler for Fast Hamiltonian Simulation. Physical Review Letters, 123(7), 070503. https://arxiv.org/abs/1811.08017 https://doi.org/10.1103/PhysRevLett.123.070503

__init__(num_samples=100, seed=-1, merge_duplicate_terms=True, commutation_type='general')

Initialize qDRIFT builder with specified settings.

Parameters:
  • num_samples (int) – Number of random samples N. More samples increase accuracy but also increase circuit depth. Error scales as O(λ²t²/N). Defaults to 100.

  • seed (int) – Random seed for reproducibility. Use -1 for non-deterministic sampling. Defaults to -1.

  • merge_duplicate_terms (bool) – If True, identical Pauli terms within consecutive mutually-commuting runs are fused to reduce circuit depth. Distinct commuting terms are kept separate. The merging is exact and preserves the Campbell (2019) error bound. Defaults to True.

  • commutation_type (str) – Commutation check used when merging duplicate terms. "qubit_wise" requires every single-qubit pair to commute individually — stricter but always safe. "general" (default) uses standard Pauli commutation (even number of anti-commuting positions), which allows larger merge groups.

name()

Return the name of the time evolution unitary builder.

Return type:

str

type_name()

Return time_evolution_builder as the algorithm type name.

Return type:

str

class qdk_chemistry.algorithms.time_evolution.builder.QDriftSettings

Bases: Settings

Settings for qDRIFT randomized decomposition builder.

The qDRIFT algorithm approximates the time evolution operator using randomized sampling of Hamiltonian terms. The error scales as O(λ²t²/N), where λ is the 1-norm of the Hamiltonian coefficients, t is evolution time, and N is the number of samples.

__init__()

Initialize QDriftSettings with default values.

num_samples

Number of random samples N. More samples = higher accuracy. Error scales as O(λ²t²/N).

seed

Random seed for reproducibility. Use -1 for non-deterministic behavior.

merge_duplicate_terms

Whether to fuse identical Pauli terms that appear in consecutive mutually-commuting runs, reducing circuit depth. Only equal operators are combined; distinct commuting terms are kept separate. The merging is exact and preserves the error bound.

class qdk_chemistry.algorithms.time_evolution.builder.TimeEvolutionBuilderFactory

Bases: AlgorithmFactory

Factory class for creating TimeEvolutionBuilder instances.

algorithm_type_name()

Return time_evolution_builder as the algorithm type name.

Return type:

str

default_algorithm_name()

Return Trotter as the default algorithm name.

Return type:

str

class qdk_chemistry.algorithms.time_evolution.builder.Trotter(order=1, *, target_accuracy=0.0, num_divisions=0, error_bound='commutator', weight_threshold=1e-12)

Bases: TimeEvolutionBuilder

Trotter decomposition builder.

Parameters:
  • order (int)

  • target_accuracy (float)

  • num_divisions (int)

  • error_bound (str)

  • weight_threshold (float)

__init__(order=1, *, target_accuracy=0.0, num_divisions=0, error_bound='commutator', weight_threshold=1e-12)

Initialize Trotter builder with specified Trotter decomposition settings.

The Trotter decomposition approximates the time evolution operator \(e^{-iHt}\) when the Hamiltonian \(H\) can be expressed as a sum of terms \(H = \sum_j \alpha_j P_j\) where \(P_j\) are Pauli strings and \(\alpha_j\) are scalar coefficients. Rather than exponentiating the full Hamiltonian at once, the Trotter method constructs an approximation by exponentiating each term separately and combining them in a product formula. For example, the first-order Trotter formula approximates the time evolution operator as

\(e^{-iHt} \approx S_1^N(t) = \left[\prod_j e^{-i\alpha_j P_j t/N}\right]^N\), where \(N\) is the number of divisions.

The number of divisions N can be determined automatically from target_accuracy, fixed explicitly via num_divisions, or both (in which case the larger value is used).

The error associated with the Trotter decomposition, \(S_k^N(t)\), can be expressted in terms of the spectral norm of the difference between the exact and approximate time evolution operators:

\(\lVert e^{-iHt} - S_k^N(t) \rVert \leq \epsilon\)

However, the cost of computing this norm is equivalent to computing the exact exponential itself. For this reason, we provide two approximate error-bound strategies to determine the number of divisions required to achieve a target accuracy at a particular Trotter order (used only when target_accuracy is set):

  • "commutator" (default, tighter): uses the commutator-based bound from Childs et al. (2021). \(N = \lceil \frac{t^{2}}{2\epsilon} \sum_{j<k}\lVert[\alpha_jP_j,\alpha_kP_k]\rVert \rceil\)

  • "naive": uses the triangle-inequality bound. \(N = \lceil (\sum_j|\alpha_j|)^{2}t^{2}/\epsilon \rceil\)

Parameters:
  • order (int) – The order of the Trotter decomposition (currently only first order is supported). Defaults to 1.

  • target_accuracy (float) – Target accuracy for automatic step computation. Must be positive to enable automatic computation. Use 0.0 (default) to disable.

  • num_divisions (int) – Explicit number of divisions within a Trotter step. When both num_divisions and target_accuracy are given the larger value is used. Use 0 (default) for automatic determination.

  • error_bound (str) – Strategy for computing the Trotter error bound when target_accuracy is set. Either "commutator" (default, tighter) or "naive".

  • weight_threshold (float) – Absolute threshold for filtering small Hamiltonian coefficients. Defaults to 1e-12.

name()

Return the name of the time evolution unitary builder.

Return type:

str

type_name()

Return time_evolution_builder as the algorithm type name.

Return type:

str

class qdk_chemistry.algorithms.time_evolution.builder.TrotterSettings

Bases: Settings

Settings for Trotter decomposition builder.

__init__()

Initialize TrotterSettings with default values.

order

The order of the Trotter decomposition (currently only first order is supported).

target_accuracy

Target accuracy for automatic step computation (0.0 means disabled).

num_divisions

Explicit number of divisions within a Trotter step (0 means automatic).

error_bound

Strategy for computing the Trotter error bound (“commutator” or “naive”).

weight_threshold

The absolute threshold for filtering small coefficients.

Submodules