General QHAM

English · 简体中文

Category C6 · Module oracq.applications.qham · Stage V1

Overview

QHAM turns finite-polynomial evolution PDEs into quantum-solvable linear systems. The input is an autonomous first-order time-evolution system

\[ u' = f + Lu + \sum_r B_r(u,\dots,u), \qquad u(0)=u_{in}, \]

allowing arbitrary finite components, finite spatial dimension, finite polynomials of the unknown fields and their spatial derivatives, known coefficients/forcing and their derivatives, and outer derivatives over complete monomials. The generator recurses out the \(U_i\) of each order per the HAM (homotopy analysis) truncation order m, then applies quantum-adapted linearization (QCL) to the truncated HAM system, obtaining \(Y'=GY\) on the lifted space and handing it to any QODE solver; the output selects the physical block \(u_{sum}=\sum_i U_i\). The construction follows the QHAM paper (arXiv:2411.06759); the mathematical rules are in the derivation reference.

The finite closure of the tensor words \(Y_{(a_0,\dots,a_{k-1})}\) takes \(\mathrm{grade}\cdot\sum a_j + \mathrm{rank} \le \mathrm{grade}\cdot m + 1\) (grade = max(1, D−1), where D is the highest polynomial degree of the PDE); nonlinear substitutions strictly decrease the HAM order sum; the closure represents the truncated HAM system exactly, with no further Carleman-style higher-order truncation.

Interface and input model

The entry points come in four parts (from oracq.applications.qham import ...):

PolynomialPDE.from_equations(equations, *, axes=("x",), label="polynomial_pde")   # Field/Known expressions
QHAMPlan(pde, order)                                    # lazy closure: blocks / row_terms / offset / locate
Discretization(pde, Grid(axes, shape, spacing), known)  # spatial discretization and classical reference
qham_input_model(plan, bindings, *, eta=-1.0, max_blocks=256, max_terms=4096)

API entry points: QHAMPlan, Discretization, qham_input_model

  • PDEs are constructed with the Field/Known expression algebra (addition/subtraction/multiplication, non-negative integer powers, d(axis, order) derivatives; an unknown field in a denominator and non-integer powers raise ValidationError), and dumps/loads round-trip through the JSON Schema.

  • bindings is built by gate_bindings(discretization, initial) (small-scale materialized ports for comparison, single-port target ≤ 5 bits) or structured_fd_bindings(discretization, initial) (shifts + component selection + same-point contraction, without materializing the \(N^r\times N^r\) port matrix); open ports can also be declared with QHAMBindings.declare(plan, state_width, port_specs, *, initial_norm, ...).

  • The input model is ODE (generator + initial state + physical output window): the generator is carried by a BE, the initial value by an SP, and open slots are late-bound via bind.

qham_input_model returns a QHAMInputModel:

Member

Meaning

generator / initial

the BE of the lifted generator and the lifted initial-state preparation

state_width / eta

physical state bit width / homotopy parameter

log_initial_norm

logarithm of the initial norm (generation-time uses rescaled weights to avoid summing large powers directly)

solve(qode, time)

invokes the QODE protocol and selects the physical block, returning StateOracle

dissipative_shift(shift=None)

explicit global shift G − μI (μ ≥ α_G), adapting to LCHS/CBMD, accumulating growth_shift

There is also open_qham_input(plan, bindings, *, generator_alpha, generator_signal, eta=-1.0, name="QhamGenerator"): the whole generator stays an unresolved abstract BE (no fake empty body is fabricated for it), while the initial state is still generated structurally; taylor_qode(generator, initial, time, *, degree=2) provides a finite-Taylor candidate that requires no Hermitian/dissipative premises, used to wire up gate-level execution and comparison. The generator module attributes include algorithm="qham_generated_qcl", ham_order, pde_degree, tensor_rank_limit, raw_dimension, explicit_couplings, qham_plan, and correctness="linearization_witnessed; solver pending".

Implementation notes

The generation chain is PDE → HAM recurrence (correction-term weight \(-\eta(1+\eta)^{p}\), physical-term weight \(1-(1+\eta)^{p}\)) → ordered tensor-word closure → rectangular port placement and embedding → LCU composition into G. Each port is interpreted as a multilinear map (L: V→V, B_τ: r-fold tensor product of V → V, F: constants → V; the port coefficients already carry the PDE’s signs and constants): place_port places a port at the designated tensor position and permutes the remaining coordinates, and embed_rectangular constrains both the input and output windows, preventing rectangular zero padding from contaminating neighboring blocks. QHAMPlan is a lazy object — for quadratic without forcing at m = 20 it can describe \(2^{21}\) function blocks without materializing them, and row_terms/offset/locate can be queried individually; explicit generation beyond the max_blocks/max_terms budget raises, while the plan itself remains valid.

The lifted initial state preserves the relative norms \(r, r, r^2, \dots, r^K\) of the tensor words (r = ‖u_in‖; a one branch is added when forcing is present): branch labels are prepared from rescaled weights, a repeatable initial-value oracle is invoked multiple times on the corresponding target ranges (this is not cloning an unknown quantum state), and the labels are back-computed from the address ranges through a Boolean network; every preparation from a known zero input cleans its work, and the same work register is reused sequentially. When u_in = 0 with forcing, the initial state is just the one component; a zero initial value without forcing corresponds to the zero solution and should be returned directly on the classical side.

Applicability boundary: the target packing of a single BE is subject to the 64-bit limit (plan.max_rank * n > 64 raises; lazy plans and row-by-row algorithms are not subject to it); correctness="linearization_witnessed; solver pending" indicates that what has been witnessed is the linearization algebra, while HAM/PDE convergence certification and QODE solution accuracy belong to the solver side; automatic selection of convergent h/m, time-dependent bindings, and the IQHAM outer restart are not implemented (see section 9 of the user guide for the full boundary).

Validation approach

Category C6 (composition skeleton; acceptance criteria in ../../development/validation-plan.md §2: component contracts satisfied + end-to-end small-instance semantic correctness + bind invariance). Three layers of evidence in tests/core/test_qham_general.py:QhamGeneralTests:

  • Structure: construction and attribute assertions of the class; test_rules_roundtrip_and_unsupported_nonlinearity (PDE JSON round-trip equality, 1/u and u**0.5 rejected).

  • Numerical: test_lazy_closure_and_rank_unrank — closure self-consistency for degrees 2–4 × orders 0–3 (nonlinear substitutions strictly decrease the order sum; offset/locate mutually inverse); the serialization of the \(2^{21}\)-block plan is < 3000 characters; exceeding the block budget on explicit generation raises. test_quadratic_dimension_and_nontrivial_eta_weight — for u′ = u², block_count = 2^(m+1) and raw_dimension(4) = 5^(m+1)+3; for η = −0.4 the homotopy weights are 0.24 / 0.4 / 0.4. test_multidimensional_coupled_identity — on a two-dimensional coupled PDE, the residual of G·lift against an independent chain-rule evaluation is < 1e-10. test_m1_reduces_to_previous_special_case — the m = 1 no-forcing generator is cross-checked column by column against the BE of the earlier special case qham_lift_m1 (16×16 amplitudes times α, places = 10). There are additionally test_chain_rule_identity_general_cases (5 PDE families × η ∈ {−1, −0.4, 0.2}, same residual bound), test_lazy_stencil_rows_match_explicit_linearization (lazy row rules versus the explicit matrix, places = 11), test_structured_initial_preserves_relative_tensor_norms, test_rectangular_forcing_and_contraction_do_not_spill, test_dissipative_adaptation_is_explicit, and test_zero_initial_forcing_and_reused_work, adding details on initial values, rectangular embedding, shifts, and workspace reuse.

  • Binding: test_open_qode_inputs_keep_operator_and_initial_oracles — the open ports declared by QHAMBindings.declare (Qham_L, Qham_B_*, Qham_initial) remain unresolved after model.solve; after bind swaps in gate implementations there are no unresolved slots and the IR serialization round-trip is unchanged; the slots kept by open_qham_input are exactly {QhamGenerator, Qham_initial}.

Known gaps and planned stages

Consistent with the application-layer qfvm.py/qham/ row of validation-coverage.md: no registered gaps, stage V1. Solution accuracy and convergence certification are marked pending per the correctness attribute; they are implementation boundaries on the QODE-solver side and are not listed as gaps of this module.

Numerical validation

Paper-grade numerical validation executed on 2026-09-16 by tests/verification/verify_qham_qfvm.py (real backends: the PySparQ native RIR interpreter, the oracq built-in reference executor, the PySparQ event adapter, and the UniQC full-amplitude state vector; no mocks, no skips).

Experiment design

  • Full generator-matrix cross-check: an aux-register superposition (Σ|c⟩|c⟩) extracts the complete signal-0 matrix block of the BE in a single run, checked element-wise against the independent classical matrix in applications/qham/reference.py, and the support set is verified to be exact with no leakage into the padding subspace. Instances u′=−0.2u+0.1u² (order 2, grid 2, raw dimension 28, η=−0.4), once with structured shift ports and once with spectrally embedded Pauli ports; another instance u′=0.5·ν(x)·uₓ−0.2u (order 1, grid 4) compares the three input models stencil / spectral / QRAM angle table.

  • Homotopy step and contraction mapping: the homotopy weights are checked against the explicit formulas; the generation row rules (linear_action) are checked against an independent HAM recurrence + tensor chain rule (chain_rule, including forced Burgers); the HAM partial sums are run against the analytic solution of the Riccati equation (Bernoulli closed form) for m=1..6, with the measured contraction factors compared against the theoretical value |1+η|.

  • Initial state and solve chain: the lifted initial-state preparation is checked amplitude by amplitude against a direct construction from the tensor-word weights (71 qubits exceeds the UniQC budget of 24, so only the pysparq path); the taylor_qode end-to-end chain is checked against the classical (I+tG)Y_in, with the two input models cross-checked against each other; the explicit dissipative shift G−μI is validated as a full matrix on the complete 2ʷ space (including the −μ diagonal on the padding subspace); make_qpde / qpde_solver from algorithms/pde.py get a numerical passthrough on the four-cycle Laplacian.

Key metrics

Case

Scale

Backend path

Value

generator full matrix (stencil ports)

28×28, α=2.968

rir-pysparq

max_error 1.46e-17, support exact

generator full matrix (spectral ports)

28×28, α=3.336

rir-pysparq

max_error 7.96e-18

generator four-path cross-check

14 qubits

reference / rir / adapter / originir-ext

pairwise deviation 8.67e-18

input-model consistency

28×28

rir-pysparq(+QRAM)

stencil 1.40e-17, spectral 6.97e-18, QRAM 5.99e-05 (angle-quantization bound 9.20e-03)

QRAM coefficient angle encoding pointwise

4 addresses, α=0.75

rir-pysparq + originir-ext

amplitude error 2.15e-03 (bound 6.14e-03), cross-path 0.0

lifted initial state

raw 28, 71 qubits

rir-pysparq

max_error 1.11e-16, log norm −1.2525710053499335 agrees, work cleaned

Taylor QODE end-to-end

t=0.01, degree 1

rir-pysparq

per-model errors 1.11e-16 each, mutual cross-check 8.87e-25

dissipative-shift full matrix

32×32, μ=2.968

rir-pysparq

max_error 5.70e-17

homotopy weights/row rules

2 PDEs × η∈{−1,−0.4,0.2}

classical independent

weights exact, row rules vs chain rule 1.39e-17

HAM contraction convergence

t=0.5, m=1..6

classical independent (RK4 vs analytic solution)

η=−0.4 mean contraction factor 0.604 (theory 0.6); η=−0.8 gives 0.208 (theory 0.2)

pde.py wrapper passthrough

four-cycle, t=0.05

rir-pysparq

max_error 2.11e-18

Reproduce

PYTHONPATH=src /path/to/backend/python tests/verification/verify_qham_qfvm.py

Artifact: out/verification/qham_qfvm.json (full metrics and criteria of the 15 cases).