Python API Reference

The object surface (PauliLCU, Walk, QSVT, Trotter, …) is re-exported from the package root (cudaq_algorithms.PauliLCU); the composable device kernels stay in their module namespaces. Symbols are documented below at their defining module.

Block encodings

class cudaq_algorithms.pauli_lcu.PauliLCU(hamiltonian, num_qubits=None, *, include_identity=True, coefficient_threshold=1e-12)

Bases: object

Block encoding of H / alpha via a linear combination of Pauli strings.

Parameters:
  • hamiltonian (HamiltonianLike) – A cudaq.SpinOperator, a mapping {"XZI...": coefficient}, or an iterable of (coefficient, word) pairs. Words use one I/X/Y/Z character per qubit, position = qubit index.

  • num_qubits (int | None) – Optional; inferred from the input when omitted, validated against it when given.

  • include_identity (bool) – Whether identity words are retained inside the encoded operator (their sum is always reported as constant_term).

  • coefficient_threshold (float) – Terms with |coefficient| below this are dropped.

  • 1 (num_ancilla is always at least)

  • ancilla (Hamiltonians get one idle)

  • uniformly (so every encoding works)

  • empty. (with Walk/QSVT and no flattened kernel argument is ever)

property alpha: float

LCU normalization (1-norm of retained coefficients).

property kernel_args: tuple[list[float], list[int], list[int], list[int], list[int]]

(angles, term_controls, term_ops, term_lengths, term_signs).

Escape hatch for composing the module-level kernels inside your own @cudaq.kernel; the factory methods below capture these for you. Returns defensive copies.

encode_kernel(state_prep=None)

A kernel applying the full block encoding.

Without state_prep: a @cudaq.kernel(state) allocating the system register from state and the ancilla register (in |0...0>) after it. With state_prep (a (qubits: qview) kernel): a zero-argument kernel that allocates the system register in |0...0>, runs state_prep on it, then applies the encoding.

Parameters:

state_prep (Kernel | None)

Return type:

Kernel

walk_kernel(power=1, state_prep=None)

A kernel running PREPARE, walk^power, UNPREPARE.

The all-zero-ancilla block of the result is T_power(-H/alpha) applied to the input state (Chebyshev polynomial of the walk block -H/alpha). Input modes as in encode_kernel: a cudaq.State-taking kernel, or a zero-argument kernel when state_prep is given.

Parameters:
  • power (int)

  • state_prep (Kernel | None)

Return type:

Kernel

prepare_kernel()

(ancilla: qview): PREPARE with this encoding’s angles.

Return type:

Kernel

unprepare_kernel()

(ancilla: qview): PREPARE dagger with this encoding’s angles.

Return type:

Kernel

apply_kernel()

(ancilla, system): the full block encoding U_A.

Return type:

Kernel

controlled_apply_kernel()

(control_and_ancilla, system): U_A controlled by qubit 0.

Uncontrolled PREPARE pairs wrap the controlled SELECT, so the circuit is the identity at control |0>.

Return type:

Kernel

walk_step_kernel()

(ancilla, system): one qubitization walk step W.

Return type:

Kernel

adjoint_walk_step_kernel()

(ancilla, system): one adjoint walk step W†.

Return type:

Kernel

controlled_walk_step_kernel()

(control_and_ancilla, system): controlled walk step.

Return type:

Kernel

controlled_adjoint_walk_step_kernel()

(control_and_ancilla, system): controlled adjoint walk step.

Return type:

Kernel

select_observable()

The odd-moment SELECT observable for this encoding.

BlockEncoding protocol hook; delegates to the module-level select_observable.

Return type:

SpinOperator

cudaq_algorithms.pauli_lcu.select_observable(encoding)

The SELECT operator sum_i sign_i |i><i|_anc x P_i as an observable.

LCU-specific: built from the encoding’s signed Pauli terms. Its expectation after PREPARE and p walk steps is the odd Chebyshev moment <T_{2p+1}(H/alpha)> (the BlockEncoding.select_observable hook).

Parameters:

encoding (PauliLCU)

Return type:

SpinOperator

class cudaq_algorithms.block_encoding.BlockEncoding(*args, **kwargs)

Bases: Protocol

A zero-flagged block encoding U_A with <0|_anc U_A |0>_anc = H / alpha.

PauliLCU is the provided implementation; double-factorized or sparse-oracle encodings plug in by satisfying the same surface.

property num_system: int

Number of system qubits the encoded operator acts on.

property num_ancilla: int

Number of ancilla (signal) qubits flagging the encoded block.

Consumers (Walk, QSVT, the walk observables) require num_ancilla >= 1: the walk’s -H/alpha sign comes from a reflection about the ancilla zero state, which is a no-op on an empty register. PauliLCU normalizes single-term inputs to one idle ancilla to satisfy this uniformly.

property alpha: float

the encoded block is H / alpha.

Type:

The block-encoding normalization

prepare_kernel()

(ancilla: qview): PREPARE the ancilla superposition.

Return type:

Any

unprepare_kernel()

(ancilla: qview): PREPARE dagger.

Return type:

Any

apply_kernel()

(ancilla: qview, system: qview): the full block encoding U_A.

Return type:

Any

controlled_apply_kernel()

(control_and_ancilla: qview, system: qview): U_A controlled by qubit 0 of the combined register.

Return type:

Any

walk_step_kernel()

(ancilla: qview, system: qview): one qubitization walk step W (block encodes -H/alpha).

Return type:

Any

adjoint_walk_step_kernel()

(ancilla: qview, system: qview): one adjoint walk step W†.

Return type:

Any

controlled_walk_step_kernel()

(control_and_ancilla: qview, system: qview): controlled W.

Return type:

Any

controlled_adjoint_walk_step_kernel()

(control_and_ancilla: qview, system: qview): controlled W†.

Return type:

Any

select_observable()

The odd-moment observable as a cudaq.SpinOperator.

Measured after PREPARE and p walk steps (no UNPREPARE), its expectation is the odd Chebyshev moment <T_{2p+1}(H/alpha)>. The construction is encoding-specific (for an LCU it is sum_i sign_i |i><i|_anc x P_i); the even-moment reflection observable 2|0..0><0..0| - I needs only the register geometry, so Walk derives it without an encoding hook.

Return type:

Any

Qubitization and QSVT

class cudaq_algorithms.qubitization.Walk(encoding)

Bases: object

Qubitization walk over a block encoding.

Generic over the BlockEncoding protocol: encoding-specific circuits and the odd-moment observable are delegated to the injected encoding (PauliLCU is the provided implementation).

Provides walk/adjoint-walk kernel factories and Chebyshev-moment measurement in the QEL even/odd convention. Requires num_ancilla >= 1 (PauliLCU always satisfies this; the guard defends against degenerate foreign encodings). The encoding is fixed at construction — kernels and observables are cached per instance.

Parameters:

encoding (BlockEncoding)

property encoding

kernels and observables are cached against it, so swapping it would serve stale circuits).

Type:

The injected block encoding (read-only

kernel(power=1, uncompute=True, state_prep=None)

PREPARE, W^power, optionally UNPREPARE.

Without state_prep the returned kernel takes one cudaq.State argument (the input state as data — the simulation-friendly form). With state_prep — a kernel with signature (qubits: cudaq.qview) — the returned kernel takes no arguments: it allocates the system register in |0...0>, runs state_prep on it, and applies the walks. state_prep must act only on that register, whose width is num_system (a documented contract; not verifiable at factory time).

Parameters:
  • power (int)

  • uncompute (bool)

  • state_prep (Kernel | None)

Return type:

Kernel

adjoint_kernel(power=1, uncompute=True, state_prep=None)

PREPARE, (W†)^power, optionally UNPREPARE (see kernel).

Parameters:
  • power (int)

  • uncompute (bool)

  • state_prep (Kernel | None)

Return type:

Kernel

roundtrip_kernel(power=1, state_prep=None)

PREPARE, W^power, (W†)^power, UNPREPARE — the identity, for tests.

Parameters:
  • power (int)

  • state_prep (Kernel | None)

Return type:

Kernel

controlled_kernel(power=1, control_state=1, uncompute=True, state_prep=None)

Controlled walks over the system register.

Input modes as in kernel: without state_prep the returned kernel takes one cudaq.State argument; with state_prep it takes no arguments and prepares the system register itself (the injected prep runs once, uncontrolled, as in QPE). Either way the system register is followed by one register holding [control, ancillas] (the control cannot share a control set with a separate register in CUDA-Q Python). The control qubit is initialized to control_state; with control |0> the circuit is the identity up to the (cancelling) PREPARE pair.

Parameters:
  • power (int)

  • control_state (int)

  • uncompute (bool)

  • state_prep (Kernel | None)

Return type:

Kernel

controlled_roundtrip_kernel(power=1, control_state=1, state_prep=None)

Controlled W^power then controlled (W dagger)^power — identity.

Parameters:
  • power (int)

  • control_state (int)

  • state_prep (Kernel | None)

Return type:

Kernel

moment(ket, order, *, state_prep=None)

Measure the Chebyshev moment <T_order(H/alpha)>.

The input state is given either as ket (array-like or an already-built cudaq.State — the simulation-friendly form) or as state_prep (a (qubits: cudaq.qview) preparation kernel composed into the measured circuit — the hardware-shaped form). Provide exactly one.

Parameters:
  • ket (ArrayLike | None)

  • order (int)

  • state_prep (Kernel | None)

Return type:

float

moments(ket, count, *, state_prep=None)

Measure moments <T_0>, …, <T_{count-1}> (see moment).

Parameters:
  • ket (ArrayLike | None)

  • count (int)

  • state_prep (Kernel | None)

Return type:

list[float]

cudaq_algorithms.qubitization.reflection_observable(encoding)

R = 2|0...0><0...0| - I on the ancilla register.

Parameters:

encoding (BlockEncoding)

Return type:

cudaq.SpinOperator

class cudaq_algorithms.qsvt.QSVT(encoding)

Bases: object

Quantum singular value transformation over a block encoding.

Generic over the BlockEncoding protocol: encoding-specific circuits are delegated to the injected encoding (PauliLCU is the provided implementation).

Parameters:

encoding (BlockEncoding)

property encoding

kernels are cached against it, so swapping it would serve stale circuits).

Type:

The injected block encoding (read-only

kernel(sequence, convention=None, state_prep=None)

A kernel applying the phase/walk sequence.

sequence may be a PhaseSequence or a plain list of phases (optionally with convention="qsp"). Without state_prep the returned kernel takes one cudaq.State argument; with state_prep — a (qubits: cudaq.qview) kernel — it takes no arguments and prepares the system register itself. The signal register is allocated in |0...0> after the system register.

Parameters:
Return type:

Kernel

controlled_kernel(sequence, convention=None, control_state=1, state_prep=None)

A kernel applying the sequence controlled.

Input modes as in kernel: a cudaq.State-taking kernel, or a zero-argument kernel when state_prep is given (the injected prep runs on the system register only, uncontrolled). Either way the system register is followed by one register holding [control, signal] (a CUDA-Q Python control set cannot mix a bare qubit with a separate register). With control |0> the sequence is the identity.

Parameters:
Return type:

Kernel

class cudaq_algorithms.qsvt.PhaseSequence(phases, walk_directions=None, convention='qsvt')

Bases: object

A validated QSVT/QSP phase sequence.

Parameters:
  • phases (tuple[float, ...]) – d + 1 phase angles for a degree-d polynomial.

  • walk_directions (tuple[int, ...]) – Optional; one direction (‘forward’/’adjoint’ or 0/1) per walk, length d. Defaults to all forward.

  • convention (str) – “qsvt” (projector phases diag(e^{i phi}, 1), the default) or “qsp” (Z-rotation phases diag(e^{i phi}, e^{-i phi}), the QSPPACK convention). qsp-tagged phases are converted automatically wherever a circuit is built; phases always stays raw.

property projector_phases: list[float]

Phases in the projector convention the circuits implement.

qsp phases are doubled (equivalent up to a global phase of exp(i * sum(phases)); see recover_real_time_evolution).

cudaq_algorithms.qsvt.recover_real_time_evolution(cos_state, sin_state, cos_phases, sin_phases)

Combine cosine/sine QSP components into exp(-i H t)|psi>.

cos_state and sin_state are good-subspace statevectors produced by running qsp-convention sequences through the QSVT circuit (which executes doubled projector phases); the per-sequence global phase exp(i * sum(phases)) is removed here. Valid for real Hamiltonians and real input states, where the cosine/sine parts live in the real/imaginary components.

Parameters:
  • cos_state (ArrayLike)

  • sin_state (ArrayLike)

  • cos_phases (Sequence[float])

  • sin_phases (Sequence[float])

Return type:

NDArray[np.complex128]

cudaq_algorithms.qsvt.FORWARD = 0

int([x]) -> integer int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.__int__(). For floating-point numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by ‘+’ or ‘-’ and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer literal. >>> int(‘0b100’, base=0) 4

cudaq_algorithms.qsvt.ADJOINT = 1

int([x]) -> integer int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.__int__(). For floating-point numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by ‘+’ or ‘-’ and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer literal. >>> int(‘0b100’, base=0) 4

Trotter

Suzuki-Trotter Hamiltonian simulation.

Product-formula time evolution for Hamiltonians expressed as sums of Pauli strings: term extraction, host-side planning and ordering, resource estimation, and the circuit primitive itself.

The typical workflow constructs a Trotter object (term extraction, validation, and ordering happen once) and either uses its kernel factories or composes the apply_trotter primitive inside a custom kernel:

from cudaq_algorithms import trotter

evolution = trotter.Trotter(hamiltonian)
kernel = evolution.kernel(time=0.8, steps=4, order=2)  # @cudaq.kernel()
resources = evolution.resources(steps=4, order=2)

Identity terms: for H = c I + H', apply_trotter implements the product formula for H' only. The omitted exp(-i c t) is an unobservable global phase for one unconditioned evolution but a real relative phase for controlled or interference-based algorithms; identity_coefficient is reported on the Trotter object so callers can account for it (the simulation helper sim_utils.evolve reintroduces it host-side).

cudaq_algorithms.trotter.FIRST_ORDER_TROTTER: int = 1

Supported product-formula orders.

cudaq_algorithms.trotter.HamiltonianLike

a cudaq.SpinOperator (or a single cudaq.SpinOperatorTerm product), a {"XZI...": coefficient} mapping, or an iterable of (coefficient, word) pairs.

Type:

Accepted Hamiltonian input forms

alias of SpinOperator | SpinOperatorTerm | Mapping[str, complex] | Iterable[tuple[complex, str]]

class cudaq_algorithms.trotter.Trotter(hamiltonian, ordering=TrotterOrdering.PRESERVE_INPUT, *, coefficient_tolerance=1e-12)

Bases: object

Suzuki-Trotter product formulas for a Pauli-sum Hamiltonian.

Term extraction, validation, and ordering happen once at construction (identity terms are split off into identity_coefficient); the evolution parameters time, steps, and order are supplied per kernel request, mirroring the other primitives (Walk.kernel(power=...), QSVT.kernel(sequence)).

The object is hardware-shaped: nothing here executes a simulator-only API (see sim_utils.evolve for statevector-based evolution).

Parameters:
property coefficients: list[float]

Retained non-identity coefficients, in application order.

property words: list[str]

Retained Pauli words, parallel to coefficients.

property identity_coefficient: float

Sum of identity-term coefficients (not realizable in circuit).

property num_qubits: int

Register width the evolution kernels act on.

property num_terms: int

Number of retained non-identity terms.

property ordering: TrotterOrdering

Term-ordering strategy fixed at construction.

kernel(time, steps=1, order=2, state_prep=None)

Return a @cudaq.kernel() applying the product formula.

(Any because CUDA-Q exposes no stable public Python type for compiled kernel objects.)

The kernel allocates num_qubits qubits in |0...0>, optionally runs state_prep (a kernel with signature (qubits: cudaq.qview)) on them, and applies the order-order formula for time over steps steps — with or without state_prep the result takes no arguments and is directly sampleable. state_prep must act only on the register it is handed (width num_qubits, arriving in |0...0>). The identity phase is not included (it cannot be, in a circuit); track identity_coefficient when it matters.

Parameters:
Return type:

Any

state_kernel(time, steps=1, order=2)

Return a @cudaq.kernel(state) evolving an arbitrary state.

Same validated product formula as kernel(), but the register is allocated from a cudaq.State argument instead of |0...0> — the input-loading path sim_utils.evolve uses. Both factories share validation and marshaling through _prepared_args.

The supplied state must have dimension 2**num_qubits: sim_utils.evolve checks this; direct callers are responsible for it themselves (the identity-only variant cannot detect a mismatch).

Parameters:
Return type:

Any

resources(steps, order)

Resource estimate for steps steps of the order formula.

Both parameters are required so the estimate can never silently describe a different circuit than the kernel you built.

Parameters:
Return type:

TrotterResourceEstimate

class cudaq_algorithms.trotter.TrotterOrdering(*values)

Bases: Enum

Term-ordering strategies for the product formula.

PRESERVE_INPUT keeps the extraction order; COEFFICIENT_MAGNITUDE_DESCENDING applies the largest-magnitude terms first, a common heuristic for reducing Trotter error.

class cudaq_algorithms.trotter.TrotterResourceEstimate(num_terms, steps, order, pauli_rotations, estimated_cx_count, identity_coefficient)

Bases: object

Lightweight circuit-cost summary for a Trotter sequence.

estimated_cx_count is a decomposition proxy: two CNOTs per additional non-identity Pauli in each rotation.

Parameters:
  • num_terms (int)

  • steps (int)

  • order (int)

  • pauli_rotations (int)

  • estimated_cx_count (int)

  • identity_coefficient (float)

cudaq_algorithms.trotter.estimate_trotter_resources(coefficients, words, steps, order, identity_coefficient=0.0)

Return a lightweight resource estimate for a Trotter sequence.

Parameters:
Return type:

TrotterResourceEstimate

cudaq_algorithms.trotter.make_trotter_terms(hamiltonian, coefficient_tolerance=1e-12)

Return flattened terms for the Suzuki-Trotter circuit primitive.

Returns (coefficients, words, identity_coefficient, num_qubits) where words are padded plain strings: readable, comparable, and accepted directly as list[cudaq.pauli_word] kernel arguments. (Only kernel-captured words need explicit cudaq.pauli_word conversion, which Trotter.kernel performs internally.)

coefficient_tolerance filters term magnitudes only: terms with |coefficient| below it (and exactly-zero terms regardless of it) are dropped — they would emit zero-angle rotations and inflate resource estimates. It does not affect complex-coefficient validation, which is fixed package-wide (see _real_coefficient).

Parameters:
Return type:

tuple[list[float], list[str], float, int]

Preprocessing

Chemistry-input bridges between classical tensors and qubit Hamiltonians.

Connects the double-factorization preprocessing to the quantum primitives: chemist-notation spatial integrals (the form the DF module consumes and reconstructs) are spin-expanded and passed through the fermion subpackage’s Jordan-Wigner transform, yielding a cudaq.SpinOperator ready for PauliLCU/Walk/QSVT.

spin_orbital_tensors is pure NumPy and always importable and usable. qubit_hamiltonian additionally uses fermion.jordan_wigner (imported lazily); importing this module never raises, and if fermion is unavailable the ImportError surfaces when qubit_hamiltonian is called, not at import.

cudaq_algorithms.chemistry.from_fcidump(contents)

Parse FCIDUMP contents into chemist-notation spatial integrals.

Takes the integral data as a string – the text of the file, already read – not a path; the caller does the file I/O:

one_body, eri, core = from_fcidump(Path("mol.fcidump").read_text())

Keeping the parse pure (no file access) lets callers and tests inject the integrals directly. Returns (one_body, eri, core_energy): the (n, n) core Hamiltonian, the dense (n, n, n, n) chemist-notation (pq|rs) two-electron tensor (all eight symmetry partners of each stored record populated), and the scalar core/constant energy – the (one_body, eri, core_energy) triple, in the exact convention qubit_hamiltonian and the block encodings consume:

one_body, eri, core = from_fcidump(text)
hamiltonian = qubit_hamiltonian(one_body, eri, scalar_offset=core)

FCIDUMP indices are Fortran 1-based; a value i j k l record with all of i,j,k,l nonzero is a two-electron integral, with k == l == 0 a one-electron integral h_ij (its transpose is filled too), and with all indices zero the core energy.

Only real (RHF/ROHF-style) FCIDUMP files are supported; unrestricted variants (Molpro’s IUHF=1 or Psi4’s UHF=.TRUE.) store a spin-resolved integral set with a different index symmetry and are rejected up front by a header guard.

Parameters:

contents (str)

Return type:

tuple[ndarray, ndarray, float]

cudaq_algorithms.chemistry.spin_orbital_tensors(one_body, eri, *, validate_symmetry=True)

Spin-expand chemist-notation spatial integrals.

one_body is the (n, n) core Hamiltonian and eri the (n, n, n, n) chemist-notation (pq|rs) two-electron tensor over real spatial orbitals — the exact convention the double-factorization module documents. Returns (one_body_so, two_body_so) over 2n spin orbitals (interleaved spins: 2p up, 2p + 1 down), where two_body_so[p, q, r, s] is the coefficient of a^dag_p a^dag_q a_r a_s as consumed by fermion.jordan_wigner.

eri must obey the real-orbital chemist permutation symmetry ((pq|rs) = (qp|rs) = (pq|sr) = (rs|pq) and their compositions) — this is what makes the resulting qubit Hamiltonian Hermitian, and it holds for reconstructed DF integrals and mean-field integrals. It is checked by default; pass validate_symmetry=False to skip the check (e.g. for genuinely complex integrals, whose symmetry differs).

Parameters:
  • one_body (ArrayLike)

  • eri (ArrayLike)

  • validate_symmetry (bool)

Return type:

tuple[ndarray, ndarray]

cudaq_algorithms.chemistry.qubit_hamiltonian(one_body, eri, *, scalar_offset=0.0, tolerance=1e-12, validate_symmetry=True)

Qubit Hamiltonian (cudaq.SpinOperator) from chemist integrals.

Spin-expands the spatial integrals (see spin_orbital_tensors, whose eri symmetry precondition and validate_symmetry flag apply here too) and applies the Jordan-Wigner transform. scalar_offset is added as an identity term (e.g. the nuclear repulsion energy); tolerance prunes negligible terms inside the transform.

Combined with the double-factorization module this closes the classical-to-quantum loop:

factorization = compressed_double_factorization(eri, num_leaves=T)
h_truncated = qubit_hamiltonian(one_body,
                                reconstruct_eri(factorization))
encoding = PauliLCU(h_truncated)   # -> Walk / QSVT
Parameters:
  • one_body (ArrayLike)

  • eri (ArrayLike)

  • scalar_offset (float)

  • tolerance (float)

  • validate_symmetry (bool)

cudaq_algorithms.chemistry.from_pyscf(mean_field)

Chemist (pq|rs) MO integrals + nuclear repulsion from PySCF.

mean_field is a converged restricted mean field (e.g. the result of pyscf.scf.RHF(mol).run()). Returns (one_body, eri, nuclear_repulsion) in the molecular-orbital basis and chemist notation – exactly the arguments qubit_hamiltonian() expects (pass nuclear_repulsion as its scalar_offset).

Restricted (single mo_coeff matrix) references only; the spin expansion downstream assumes one spatial set shared by both spins.

Return type:

tuple[ndarray, ndarray, float]

cudaq_algorithms.chemistry.from_psi4(wavefunction)

Chemist (pq|rs) MO integrals + nuclear repulsion from Psi4.

wavefunction is a converged restricted wavefunction, e.g. the second return value of psi4.energy("scf", return_wfn=True). Returns (one_body, eri, nuclear_repulsion) in the molecular-orbital basis and chemist notation – identical in meaning and convention to from_pyscf(), so either drives qubit_hamiltonian() unchanged.

Restricted references only (uses Ca); mo_eri already returns the chemist (pq|rs) ordering, matching the PySCF path.

The wavefunction must be computed in C1 symmetry (symmetry c1 in the Psi4 geometry). The extraction reads Ca as a single dense block, so an irrep-blocked (higher-symmetry) wavefunction is rejected.

Return type:

tuple[ndarray, ndarray, float]

Fermion-to-qubit transforms (pure Python, no compiled extension).

cudaq_algorithms.fermion.jordan_wigner(one_body_or_two_body, two_body=None, scalar_offset=0.0, tolerance=1e-15)

Jordan-Wigner transform of fermionic integrals to a qubit operator.

Accepts an (n, n) one-body tensor, optionally with an (n, n, n, n) two-body tensor, or a two-body tensor alone; entries are the coefficients of adag_i a_j and adag_i adag_j a_k a_l over n spin orbitals. scalar_offset is added as an identity term; input entries and compiled terms with magnitude below tolerance are dropped. Returns a cudaq.SpinOperator.

Parameters:
  • one_body_or_two_body (ArrayLike)

  • two_body (ArrayLike | None)

  • scalar_offset (float)

  • tolerance (float)

cudaq_algorithms.fermion.bravyi_kitaev(one_body_or_two_body, two_body=None, scalar_offset=0.0, tolerance=1e-15)

Bravyi-Kitaev transform of fermionic integrals to a qubit operator.

Same input conventions as jordan_wigner; the qubits store Fenwick-tree partial sums of the occupations, giving O(log n)-weight Pauli words. Returns a cudaq.SpinOperator.

Migration note: the two-body tensor is compiled literally, entry by entry as V[i,j,k,l] adag_i adag_j a_k a_l — identical to jordan_wigner. The retired compiled binding instead antisymmetrized the tensor internally before transforming; matching jordan_wigner here repairs a prior JW/BK inconsistency. A caller who passed a raw, non-antisymmetrized (e.g. chemist-ordered) two-body tensor and relied on that internal antisymmetrization must now antisymmetrize the input themselves, or they will silently get a different operator.

Parameters:
  • one_body_or_two_body (ArrayLike)

  • two_body (ArrayLike | None)

  • scalar_offset (float)

  • tolerance (float)

Double factorization of two-electron integrals (X-DF and C-DF).

Explicit (X-DF) and compressed (C-DF) double factorization following Cohn, Motta, and Parrish, PRX Quantum 2, 040352 (2021) (arXiv:2104.08957). Heavy linear algebra runs on the NVIDIA math libraries (cuSOLVER / cuBLAS via CuPy) when a GPU is available, with a NumPy/SciPy fallback selected automatically.

class cudaq_algorithms.double_factorization.DoubleFactorization(num_orbitals, leaf_rotations, leaf_cores, method, first_factorization=None, leaf_weights=None)

Bases: object

Result of a double factorization of the two-electron integrals.

leaf_rotations[t] is the orthogonal matrix U^t (shape (num_orbitals, num_orbitals)) and leaf_cores[t] is the symmetric core Z^t for leaf t. method is "X-DF" or "C-DF".

Parameters:
reconstruct_eri()

Reconstruct the (n, n, n, n) chemist-notation ERI tensor.

Return type:

ndarray

cudaq_algorithms.double_factorization.explicit_double_factorization(eri, threshold=1e-08, max_num_leaves=None, second_factor_threshold=0.0, first_factorization='cholesky', backend='auto')

Explicit double factorization (X-DF).

First factorization of the ERI supermatrix (pq|rs) = sum_t L^t_pq L^t_rs into symmetric leaves L^t:

  • first_factorization="cholesky" (default) – pivoted Cholesky of the positive-semidefinite ERI matrix. Rank-revealing: it keeps leaves while the residual-diagonal pivot exceeds threshold (the numerical null space terminates it), so it stops at the true factorization rank.

  • first_factorization="eigendecomposition" – symmetric eigendecomposition (pq|rs) = sum_t lambda_t V^t_pq V^t_rs keeping |lambda_t| > threshold. Required for indefinite inputs; the ERI is PSD so Cholesky is preferred.

max_num_leaves caps the leaf count. Second factorization: each symmetric leaf is eigendecomposed, L^t = U^t diag(gamma^t) (U^t)^T, giving the rank-one core Z^t = outer(gamma^t, gamma^t) (scaled by lambda_t in the eigendecomposition case). second_factor_threshold optionally zeros small gamma^t_k (importance-weighted, matching OpenFermion’s convention). On the eigendecomposition path the importance includes |lambda_t|, so both paths compare the same absolute quantity – the mode’s contribution to the core one-norm; on the Cholesky path the pivot scale is already carried by the leaf vector’s norm.

Returns a DoubleFactorization with NumPy arrays.

Parameters:
  • eri (ArrayLike)

  • threshold (float)

  • max_num_leaves (int | None)

  • second_factor_threshold (float)

  • first_factorization (str)

  • backend (str)

Return type:

DoubleFactorization

cudaq_algorithms.double_factorization.compressed_double_factorization(eri, num_leaves, max_iterations=2000, tolerance=1e-10, regularization=0.0, inner_solver='lstsq', cg_tolerance=1e-10, cg_max_iterations=None, cg_warm_start=True, cg_optimization_tolerance=None, initial_generators=None, backend='auto')

Compressed double factorization (C-DF) by least-squares optimization.

Minimizes O = 1/2 || eri - sum_t U^t Z^t (U^t)^T (congruence) ||_F^2 over a fixed number of leaves. Uses the two-step scheme of arXiv:2104.08957: the leaf rotations are parameterized as U^t = exp(X^t) with antisymmetric X^t and optimized with L-BFGS (warm-started from X-DF), while the symmetric cores Z^t are solved exactly in closed form at each step.

regularization (rho) enables RC-DF (arXiv:2212.07957, Eq. 17): the L2 penalty rho * sum_{t,k,l} (Z^t_kl)^2 is added to the objective and, crucially, folded into the inner core solve as a ridge term. It shrinks the cores – lowering the Hamiltonian one-norm lambda and the measurement variance – and conditions the inner system. rho is an absolute coefficient (its useful scale depends on the integral magnitude; the paper uses ~1e-6 to 1e-3). rho = 0 reproduces plain C-DF.

inner_solver selects how the cores are solved each step: "lstsq" (default) forms an explicit design matrix, while "cg" is the matrix-free conjugate-gradient solve (RC-DF Eqs. 25-30) that avoids the n^4-row design matrix and scales to large orbital counts. cg_tolerance and cg_max_iterations control the CG solve.

For inner_solver="cg" two accelerators cut the per-step CG cost without changing the final accuracy: cg_warm_start (default True) seeds each step’s CG from the previous step’s cores – which move slowly between L-BFGS steps – and cg_optimization_tolerance (default max(cg_tolerance, 1e-6)) solves the in-loop systems only loosely (an inexact inner solve; the gradient need only be approximate by the envelope theorem) while the single final solve is tightened to cg_tolerance.

Returns a DoubleFactorization with NumPy arrays.

Parameters:
  • eri (ArrayLike)

  • num_leaves (int)

  • max_iterations (int)

  • tolerance (float)

  • regularization (float)

  • inner_solver (str)

  • cg_tolerance (float)

  • cg_max_iterations (int | None)

  • cg_warm_start (bool)

  • cg_optimization_tolerance (float | None)

  • initial_generators (List[ndarray] | None)

  • backend (str)

Return type:

DoubleFactorization

cudaq_algorithms.double_factorization.reconstruct_eri(factorization)

Reconstruct the chemist-notation ERI tensor from a factorization.

Parameters:

factorization (DoubleFactorization)

Return type:

ndarray

cudaq_algorithms.double_factorization.factorization_error(eri, factorization)

Frobenius norm of the ERI reconstruction residual.

Parameters:
Return type:

float

cudaq_algorithms.double_factorization.modified_one_body_integrals(one_body, eri)

Return the DF-corrected one-body matrix kappa_pq = h_pq - 1/2 sum_r (pr|qr) (Eq. 3 of arXiv:2104.08957), used when assembling the full double-factorized Hamiltonian from the two-body factorization.

Parameters:
  • one_body (ArrayLike)

  • eri (ArrayLike)

Return type:

ndarray

cudaq_algorithms.double_factorization.double_factorization_one_norm(factorization, one_body_eigenvalues, convention='lcu')

One-norm lambda of the double-factorized Hamiltonian (RC-DF, arXiv:2212.07957), used to assess factorization quality.

convention="lcu" (Eq. 13) – the LCU / Pauli-rotation norm sum_k |F_k| + sum_t (sum_{k<l} |Z^t_kl| + 1/4 sum_k |Z^t_kk|).

convention="burg" – the qubitization norm in the standard von Burg/Lee form: with each core eigendecomposed as Z^t = sum_i lambda^t_i v^t_i (v^t_i)^T, sum_k |F_k| + 1/4 sum_t sum_i |lambda^t_i| (sum_k |v^t_ki|)^2. (A factorization Z = W W^T leaves W free up to a right orthogonal gauge, and the column-norm formula is not gauge invariant; the eigenfactor is the standard, gauge-fixed choice and reduces to RC-DF Eq. 15 / von Burg’s (1/4)(sum_k |gamma_k|)^2 for rank-one cores.)

one_body_eigenvalues are the diagonal one-body (Fock-like) eigenvalues.

Parameters:
Return type:

float

cudaq_algorithms.double_factorization.cupy_gpu_available()

Return True when CuPy is importable and at least one GPU is visible.

Return type:

bool

cudaq_algorithms.double_factorization.resolve_backend(backend='auto', problem_size=None, gpu_min_size=0)

Return (array_module, name) for the requested backend.

"auto" selects CuPy when a GPU is available and the problem is large enough to amortize GPU launch/sync overhead – i.e. problem_size (the orbital count n) is at least gpu_min_size – otherwise NumPy. With no problem_size hint it keeps the legacy behavior: CuPy whenever a GPU is present. "cupy" / "numpy" force the backend regardless of size.

Parameters:
  • backend (str)

  • problem_size (int | None)

  • gpu_min_size (int)

Return type:

tuple[Any, str]

State preparation

State-preparation kernels and operator pools (pure Python).

Same API as the former compiled bindings: the uccsd, uccgsd, upccgsd, and ceo device kernels are @cudaq.kernel functions composable from user kernels, and the excitation/pool helpers run on the host with cudaq.spin algebra. hartree_fock / hartree_fock_occupation prepare the reference determinant (closed shell, or open shell via make_hartree_fock_occupation), and fixed_parameter_ucc / hartree_fock_ucc_kernel apply an arbitrary operator pool at fixed, non-variational amplitudes on top of it. The Givens-rotation Slater-determinant kernels and schedule helpers (_givens) follow the same split: composable device kernels plus host-side planning.

Error-type convention: the two error cases the compiled bindings defined keep their historical RuntimeError (odd qubit count and odd-electrons-at-spin-0 in get_uccsd_excitations); every guard added in the pure implementation raises ValueError. Note also that the CEO helpers take num_orbitals in spatial orbitals (the pool acts on 2 * num_orbitals qubits), matching the compiled API.

cudaq_algorithms.stateprep.get_uccsd_excitations(num_qubits, num_electrons, spin=0)

Enumerate UCCSD excitations for the interleaved spin-orbital layout.

Returns (singles_alpha, singles_beta, doubles_mixed, doubles_alpha, doubles_beta) as lists of index lists, in the C++ enumeration order (which fixes the parameter order of the uccsd kernel).

cudaq_algorithms.stateprep.get_num_uccsd_parameters(num_qubits, num_electrons, spin=0)

Number of UCCSD ansatz parameters (one per excitation).

cudaq_algorithms.stateprep.get_uccgsd_pauli_lists(num_qubits, only_singles=False, only_doubles=False)

UCCGSD pool as (pauli word groups, coefficient groups).

cudaq_algorithms.stateprep.get_upccgsd_pauli_lists(num_qubits, only_doubles=False)

UpCCGSD pool as (pauli word groups, coefficient groups).

cudaq_algorithms.stateprep.get_ceo_pauli_lists(num_orbitals)

CEO pool as (pauli word groups, coefficient groups).

cudaq_algorithms.stateprep.get_fixed_parameter_ucc_pauli_lists(operator_pool, num_qubits, coefficient_tolerance=1e-12)

Any operator pool as (Pauli word groups, coefficient groups).

Like the pool-specific get_*_pauli_lists helpers, but for an arbitrary pool (e.g. make_uccsd_operator_pool): one group per pool operator, in pool order, ready for the fixed_parameter_ucc kernel. Terms with |coefficient| <= coefficient_tolerance are dropped (they would waste identity rotations); coefficients with an imaginary part above the tolerance are rejected — exp_pauli angles are real.

cudaq_algorithms.stateprep.make_uccsd_operator_pool(num_qubits, num_electrons, spin=0)

One spin operator per UCCSD excitation, in excitation order.

cudaq_algorithms.stateprep.make_uccgsd_operator_pool(num_qubits, only_singles=False, only_doubles=False)

Generalized singles and doubles over all qubit pairs/quadruples.

cudaq_algorithms.stateprep.make_upccgsd_operator_pool(num_qubits, only_doubles=False)

Spin-preserving singles plus paired (same-spatial-orbital) doubles.

cudaq_algorithms.stateprep.make_ceo_operator_pool(num_orbitals)

Coupled-exchange-operator pool (arXiv:2407.08696 conventions).

cudaq_algorithms.stateprep.make_hartree_fock_occupation(num_qubits, num_electrons, spin=0)

Occupied spin-orbital indices of the Hartree-Fock reference.

spin == 0 (closed shell): the contiguous set {0, ..., num_electrons - 1}. spin > 0 (open shell): alpha electrons on even spin orbitals and beta on odd, matching get_uccsd_excitations so the determinant lines up with a fixed-parameter UCCSD pool built at the same spin (e.g. 4 electrons at spin 2 occupy {0, 1, 2, 4}, not {0, 1, 2, 3}).

cudaq_algorithms.stateprep.validate_hartree_fock_occupation(num_qubits, occupied_orbitals)

Reject out-of-range, duplicate, or non-integral orbital indices.

cudaq_algorithms.stateprep.validate_fixed_parameter_ucc(num_qubits, parameters, pauli_words, coefficients)

Validate grouped fixed-parameter UCC data against num_qubits.

Pauli words given as strings are checked for length and alphabet; cudaq.pauli_word objects expose no accessor and are trusted (the get_*_pauli_lists helpers build them at the right width).

cudaq_algorithms.stateprep.estimate_hartree_fock_resources(num_qubits, num_electrons, spin=0)

Resource estimate for the canonical Hartree-Fock reference.

Return type:

HartreeFockResourceEstimate

cudaq_algorithms.stateprep.estimate_hartree_fock_occupation_resources(num_qubits, occupied_orbitals)

Resource estimate for an explicit-occupation reference.

Return type:

HartreeFockResourceEstimate

cudaq_algorithms.stateprep.estimate_fixed_parameter_ucc_resources(num_qubits, pauli_words)

Resource estimate for a fixed-parameter UCC product.

Return type:

FixedParameterUccResourceEstimate

cudaq_algorithms.stateprep.hartree_fock_ucc_kernel(num_qubits, parameters, pauli_words, coefficients, *, num_electrons=None, spin=0, occupied_orbitals=None)

A (qubits: qview) kernel: Hartree-Fock reference + UCC product.

Provide exactly one of num_electrons (with optional spin for an open-shell reference) or explicit occupied_orbitals. The returned kernel expects a num_qubits-wide register in |0...0> and is directly injectable as a state_prep kernel (e.g. into PauliLCU.encode_kernel). The grouped data is flattened into per-rotation angles before capture — nested lists cannot be captured by Python kernels.

class cudaq_algorithms.stateprep.HartreeFockResourceEstimate(num_qubits, num_electrons, num_x_gates)

Bases: object

Circuit cost of a Hartree-Fock reference preparation.

Parameters:
  • num_qubits (int)

  • num_electrons (int)

  • num_x_gates (int)

class cudaq_algorithms.stateprep.FixedParameterUccResourceEstimate(num_qubits, num_excitations, num_pauli_rotations, max_pauli_rotations_per_excitation)

Bases: object

Circuit cost of a fixed-parameter UCC product (Pauli rotations).

Parameters:
  • num_qubits (int)

  • num_excitations (int)

  • num_pauli_rotations (int)

  • max_pauli_rotations_per_excitation (int)

class cudaq_algorithms.stateprep.GivensRotation(first_orbital, second_orbital, theta, phase=0.0)

Bases: object

One adjacent Givens rotation between two orbitals.

phase is the relative phase applied after the rotation (exp(i * phase * n_second)); it is 0 for real schedules.

Parameters:
class cudaq_algorithms.stateprep.GivensRotationSchedule(num_spin_orbitals, num_electrons, is_complex=False, rotations=<factory>, final_phases=<factory>)

Bases: object

A Givens rotation sequence preparing a Slater determinant.

rotations are in application order (the reverse of the elimination order). final_phases holds one phase per electron, applied to the occupied qubits before the rotations; it is all-zero for real schedules.

Parameters:
class cudaq_algorithms.stateprep.GivensResourceEstimate(num_spin_orbitals, num_electrons, num_givens_rotations, num_exp_pauli_calls, num_phase_rotations, two_qubit_gate_count_proxy, depth_proxy)

Bases: object

Lightweight circuit-cost summary for a Givens schedule.

num_spin_orbitals and num_electrons echo the schedule. num_exp_pauli_calls counts the two-qubit exp_pauli rotations (two per Givens rotation); num_phase_rotations counts the single-qubit rz gates of a complex preparation (one per rotation plus one per electron). The proxies are decomposition-independent upper bounds, not transpiled gate counts.

Parameters:
  • num_spin_orbitals (int)

  • num_electrons (int)

  • num_givens_rotations (int)

  • num_exp_pauli_calls (int)

  • num_phase_rotations (int)

  • two_qubit_gate_count_proxy (int)

  • depth_proxy (int)

cudaq_algorithms.stateprep.slater_determinant_kernel(schedule)

A (qubits: qview) kernel preparing the schedule’s determinant.

The returned kernel expects a schedule.num_spin_orbitals-wide register in |0...0> and is directly injectable as a state_prep kernel (e.g. into PauliLCU.encode_kernel). It dispatches on schedule.is_complex to the slater_determinant / complex_slater_determinant kernel path. The schedule is flattened into plain index/angle/phase arrays before capture — nested structures marshal as kernel arguments but cannot be closure-captured by Python kernels.

Parameters:

schedule (GivensRotationSchedule)

cudaq_algorithms.stateprep.make_givens_rotation_schedule(orbital_coefficients, tolerance=1e-12)

Build the Givens rotation schedule preparing a Slater determinant.

orbital_coefficients is a (num_spin_orbitals x num_electrons) matrix (numpy array or nested lists) whose orthonormal columns are the occupied orbitals. Real and complex inputs dispatch automatically (a complex dtype routes complex even when all values are real). For interleaved-spin systems the matrix rows must follow the package’s alpha (even) / beta (odd) spin-orbital ordering, so the prepared determinant composes with hartree_fock_occupation references and the UCCSD excitation conventions built at the same spin.

Return type:

GivensRotationSchedule

cudaq_algorithms.stateprep.validate_givens_rotation_schedule(schedule)

Validate a schedule against the state-preparation kernel contract.

make_givens_rotation_schedule output always passes; this guards hand-built schedules (the kernels themselves cannot raise).

Parameters:

schedule (GivensRotationSchedule)

cudaq_algorithms.stateprep.get_givens_rotation_indices(schedule)

Flattened (first, second) orbital pairs, two entries per rotation.

Parameters:

schedule (GivensRotationSchedule)

Return type:

list[int]

cudaq_algorithms.stateprep.get_givens_rotation_angles(schedule)

Rotation angles in application order.

Parameters:

schedule (GivensRotationSchedule)

Return type:

list[float]

cudaq_algorithms.stateprep.get_givens_rotation_phases(schedule)

Relative phases in application order (all zero for real schedules).

Parameters:

schedule (GivensRotationSchedule)

Return type:

list[float]

cudaq_algorithms.stateprep.estimate_givens_resources(schedule)

Resource estimate for preparing a schedule’s Slater determinant.

Parameters:

schedule (GivensRotationSchedule)

Return type:

GivensResourceEstimate

Simulation utilities

Simulation-only helpers.

Everything here depends on statevector access (cudaq.get_state / postselection slicing), which only exists on simulators. The module ships with the package as a clearly-labeled companion, but it is not part of the hardware-shaped API: the library classes (encodings, kernel factories, observables, Walk.moment via cudaq.observe) never execute get_state.

cudaq_algorithms.sim_utils.state_from(ket)

Build a cudaq.State from array data at the current target’s precision.

fp32 simulators (e.g. the default nvidia target) reject complex128 input (“[sim-state] invalid data precision”); cudaq.complex() reports the dtype the active target expects.

Return type:

State

cudaq_algorithms.sim_utils.good_subspace(encoding, state)

Postselect the all-zero-ancilla block of a simulated statevector.

The kernel factories allocate the system register first, so with CUDA-Q’s little-endian statevector order (q[0] = least-significant bit) the good subspace is the first contiguous block of 2**num_system amplitudes.

Parameters:
Return type:

NDArray[np.complex128]

cudaq_algorithms.sim_utils.action(encoding, ket)

Return (H/alpha)|ket> by simulating the encoding and postselecting.

Multiply by encoding.alpha to recover H|ket>.

Parameters:
Return type:

NDArray[np.complex128]

cudaq_algorithms.sim_utils.transform(transformer, ket, sequence, convention=None)

Return the good-subspace state after a QSVT sequence.

For an eigenstate of H with eigenvalue lambda the result is p(lambda / alpha) times the input, where p is the polynomial the phase sequence implements.

Parameters:
Return type:

NDArray[np.complex128]

cudaq_algorithms.sim_utils.evolve(evolution, ket, time, steps=1, order=2, include_identity_phase=True)

Simulate a Trotter evolution on ket; return the evolved statevector.

Unlike the circuit primitive, this can reintroduce the identity phase exp(-i * identity_coefficient * time) (on by default), so the result approximates the full exp(-i H t)|ket>.

Delegates to Trotter.state_kernel — the same validation (finite time, positive integral steps, order in {1, 2, 4}) and marshaling as Trotter.kernel, raising ValueError for invalid parameters instead of silently returning an unevolved state.

Parameters:
Return type:

NDArray[np.complex128]

cudaq_algorithms.common_kernels.state_from(ket)

Build a cudaq.State from array data at the current target’s precision.

fp32 simulators (e.g. the default nvidia target) reject complex128 input (“[sim-state] invalid data precision”); cudaq.complex() reports the dtype the active target expects.

Return type:

State