Conventions¶
These conventions fix the sign of time evolution, phase units, qubit and bit order, units, normalization and error metrics in every NWQLib method. Rows named after a method give a convention specific to that method. Paper notation often differs. The docstring of the implementing function states each departure, and each algorithm guide's source map links its steps to paper equations. The Code column names the module whose docstring states the convention.
Frequent lookups: count keys and Pauli labels, occupation strings, sign of time evolution, Eigenphase in turns, units are labels, norms of each error and block encodings and QSP phases.
Time evolution, phases and Hadamard tests¶
| Convention | Statement | Code |
|---|---|---|
| Evolution sign | A Hermitian generator H evolves as exp(-i t H). This covers Pauli-evolution blocks and product formulas, QSP evolution of a block encoding of A (exp(-i t A) at effective time alpha * t), the controlled powers U = exp(-i tau H) of QPE, each LCHS branch exp(-i t (k L + H)) with A = L + i H, and each QHD step. |
subroutines/hamiltonian_evolution/pauli_evolution.py, subroutines/qsp/evolution.py, algorithms/qpe/method.py, algorithms/lchs/time_independent_terms.py, algorithms/qhd/compiler.py |
| QHD schedule | QHD.schedule is a record whose kind names the formula of the weights in H(t) = a(t) K + b(t) V, with K the kinetic operator and V the objective. "quadratic" has a = 1/(1 + gamma t²) and b = 1 + gamma t², "cubic" has a = 2/(s + t³) and b = 2t³, and "shifted_cubic" has a = (2/(s + t))³ and b = 2t³. The record holds only its own parameter, which belongs to the model and stays fixed when num_steps changes, and its kind enters the Method identity. Step k covers [k dt, (k+1) dt]. The "midpoint" coefficient rule takes a and b at the step midpoint, and "integrated" takes the step averages of their interval integrals. |
algorithms/qhd/schedules.py step_weights |
| Linear dynamics | LinearDynamics is du/dt = -A u + source, so the homogeneous solution is expm(-A (time - initial_time)) initial_state. |
problems/records.py LinearDynamics |
| ADAPT generators | Pool members are anti-Hermitian generators A_j. Basis states apply exp(theta A_j) to the reference, and the screening gradient is <[H, A_j]>. At a fixed angle, replacing A_j by -A_j changes the basis. |
subroutines/fermionic_pool.py, algorithms/gcim/adapt_acquisition.py |
| Eigenphase | Eigenphase is phi in turns, in [0, 1), with U v = exp(2 pi i phi) v. For a Hamiltonian, U = exp(-i tau H) and phi = -tau E / (2 pi) modulo 1, so the phase order need not follow the energy order. result.eigenvalue is the estimator's energy itself, and phase is computed from it. Converting phase back fixes E only modulo 2 pi / tau. For a unitary, estimator_value is a principal angle in radians. |
problems/records.py Eigenphase, algorithms/qpe/records.py energy_phase_turns |
| Estimator target | An Eigenproblem asks for the smallest eigenvalue in its full space or explicit sector, while a QPE estimator returns one eigencomponent of the prepared state. QCELS, RFE and RWPE are verified against the cluster of largest prepared weight. SPE locates the lowest component on its coordinate. For a Hamiltonian that is the lowest energy. For a unitary it is the lowest principal eigenphase, which for U = exp(-i tau H) is the highest energy when tau times the spectral radius keeps every prepared phase inside (-pi/2, pi/2), the interval that the scan covers. Supplying H, or U† = exp(i tau H), targets the lowest energy. SPE verification compares the lowest cluster of the dense spectrum and checks its prepared weight against overlap_lower_bound, unless QPEVerification.minimum_overlap is set. |
problems/records.py Eigenproblem, algorithms/qpe/method.py SPE, algorithms/qpe/numerical.py spe, algorithms/qpe/verification.py |
| Hadamard test | The ancilla starts in |+>, controls the operation and is measured in Z after a final Hadamard. With ancilla phase s before the final Hadamard, the mean P(0) - P(1) is Re(exp(i s) z), so s = 0 gives Re z and s = -pi/2 (S†) gives +Im z. QPE measures z_p = <psi|U^p|psi>, and its exact static route reads the same two quadratures as the ancilla X and Y expectations at each power position of one controlled trajectory, with no phase or final Hadamard. ADAPT's sampled queries measure z = <phi_i|P|phi_j> for the Pauli words P of the Eigenproblem operator A, so the stored pencil entries are H_ij = <phi_i|A|phi_j> and S_ij = <phi_i|phi_j>. Sampled FixedGCIM obtains the same entries from grouped joint-state counts, one system group at a time, and exact FixedGCIM and ADAPT from each pair's saved state. |
algorithms/qpe/method.py _quantum_program, algorithms/gcim/adapt_acquisition.py, algorithms/gcim/pencil.py |
| Parity readout | Outcome 0 of a measured Pauli parity is the eigenvalue +1, so a mean is (n0 - n1)/n. |
evidence/binary.py, algorithms/expectation.py |
| Controlled phases | Under control, a global phase becomes a relative phase, so no identity term is dropped. QPE applies the identity coefficient c_I of a Pauli Hamiltonian on the control through phase increments P(-c_I (p_k - p_(k-1)) tau) between adjacent static power positions, and as P(-p tau c_I) at an RWPE time. Each LCHS product-formula branch applies exp(-i t c_I(k)), where c_I(k) is the identity coefficient of k L + H. Dense powers and branches keep c_I inside their matrices, and their controlled matrices are synthesized exactly because Qiskit's controlled UnitaryGate can err (Dependency issues). |
blocks/selection.py, algorithms/qpe/method.py _split_pauli_terms, algorithms/lchs/time_independent_terms.py _combined_trotter_terms, subroutines/_dense_synthesis.py |
Qubit, bit and mode order¶
"Little-endian" refers to index significance, k = sum_q b_q 2**q. Strings are described by the position of qubit 0 rather than by an endianness adjective, because the index order and the written order of a label run in opposite directions.
Units and frames¶
Normalization¶
| Convention | Statement | Code |
|---|---|---|
| States | A vector input keeps its physical norm and phase. For a nonzero vector, the input check forms the direction v/||v|| once. A zero vector is accepted with zero norm and no direction. PhysicalScale stores a norm as a binary mantissa and exponent. |
problems/inputs.py |
| Outputs | Solution and a physical StateVector carry the physical scale and phase. A unit StateVector has norm one. modulo_global_phase leaves the returned amplitudes unchanged. It changes the comparison metric to phase_aligned_l2 and the declared phase of the output array, and the QLS shortcut solvers accept a StateVector only in this form. NormSquared is u†u, QuadraticForm is u†Ou and NormalizedExpectation is u†Ou/u†u. |
problems/records.py |
| Block encodings | The all-zero ancilla block is A/alpha, and error_bound bounds ||A - alpha * block||_2 in the units of A. For an LCU of unitaries, alpha = sum_j |c_j|, PREP prepares sum_j sqrt(|c_j|/alpha) |j> and SELECT applies the coefficient phases. A combination of block encodings with subnormalizations alpha_j has alpha = sum_j |c_j| alpha_j. |
subroutines/block_encoding/core.py, subroutines/lcu/core.py, subroutines/qsp/evolution.py, Block encodings and QSP |
| QLS recovery | For the default qsvt_inverse solver, x = ||b|| (polynomial_kappa s / alpha) (P/s)(A/alpha) b/||b||, where P is the stored fit polynomial.coefficients and s its rescale. The circuit implements P/s. The shortcut solvers return a unit direction without a physical norm. |
algorithms/qls/method.py _realize |
| LCHS recovery | Without a source the physical solution is alpha times the QSP amplitude factor times ||u0|| times the success-projected amplitudes. With a constant source the branch coefficients already contain the input norms. A PSD shift multiplies each coefficient by exp(shift * t) for its elapsed time t, and when that factor exceeds binary64 a power of two moves from the coefficients into the recovery. coefficient_l1_norm is therefore dimensionless for the kernel table of a classical or source-free Plan, and in the solution's unit for the branch layout of a quantum constant-source Plan. |
algorithms/lchs/quantum.py plan_quantum, algorithms/lchs/source_selection.py, algorithms/lchs/primary_records.py |
| Recovery scale of an observation | ObservationChunk.physical_scale is the norm of the output vector in LCHS and in QLS with the qsvt_inverse solver, which analysis multiplies into the unit solution direction, and the norm of the supplied input state in Expectation, Lanczos and QPE. QHD, FixedGCIM and ADAPT host chunks record None with a reason, because their scalars need no recovery. A QLS shortcut chunk records None because the shortcut recovers no physical norm, and quantum circuit chunks other than amplitude readout carry None. |
execution.py ObservationChunk, blocks/kernels.py KernelOutput |
| Masses and samples | A mass or success probability is an unconditional probability over all returned outcomes. Samples bins are conditional on the method's success event and exclude dummy coordinates. QHD expected_objective is conditional on an outcome that encodes a grid point, which every binary outcome does. |
amplitudes.py, _quantum_readout.py, algorithms/qhd/records.py |
| Reused symbols | alpha is a block-encoding subnormalization or LCU one-norm, except in Lanczos, where it is the half-width of the spectral enclosure, and in binary inference, where alpha = delta/F is the failure probability of one of F settings. s is the QLS rescale, the squared state norm in Expectation, the PSD shift and the Duhamel source time in LCHS, and the ancilla phase in QPE. kappa_be = max(1, alpha/sigma_min) when kappa="auto" and the singular endpoints are known, and the supplied kappa otherwise, polynomial_kappa = max(kappa_be, 1.01), except that the analytic periodic encoding with kappa="auto" uses alpha / min(sigma_min, encoded gap) rounded outward, and condition_number = sigma_max/sigma_min. |
algorithms/qls/host_planning.py, algorithms/expectation.py, evidence/binary.py, algorithms/lchs/solution_error_budget.py, algorithms/lanczos/records.py, algorithms/qpe/method.py |
Block encodings and QSP¶
A unitary U on a + n qubits is an (alpha, a, epsilon) block encoding of A when the all-zero ancilla block approximates A / alpha, equivalently ||A - alpha (<0^a| (x) I) U (|0^a> (x) I)|| <= epsilon. Every BlockEncoding records alpha, ancilla and system widths, its operator-error bound, and the resolved implementation as canonical fields. Polynomial transformations act on A / alpha, so simulating exp(-i A t) uses effective time alpha * t. Products multiply subnormalizations, while an LCU combination has subnormalization sum_j |c_j| alpha_j.
Tensor formulas in these docs and in docstrings write the ancilla, label or control register first, as the papers do, for example (<0^a| (x) I) U (|0^a> (x) I) above and SELECT = sum_j |j><j| (x) sign(c_j) P_j. The circuits place that register on the low-order qubits, starting at qubit 0. A dense matrix of such a circuit in Qiskit's Kronecker order, whose qubit 0 is the least significant index, therefore reads (I (x) <0^a|) U (I (x) |0^a>) and sum_j sign(c_j) P_j (x) |j><j|. The written order is notation, and the stored register order decides the qubit positions. Saved relation strings keep the paper order.
The project uses the Wx QSP convention, W(x) = [[x, i sqrt(1-x^2)], [i sqrt(1-x^2), x]], with phases applied as exp(i phi Z). Since Qiskit uses RZ(theta) = exp(-i theta Z / 2), a direct exp(i phi Z) is RZ(-2 phi). The projector-phase circuit of build_qsvt_circuit applies reflection-convention phases phi' instead, which wx_phases_to_reflection computes from the Wx phases as phi'_0 = phi_0 - pi/4, phi'_d = phi_d - pi/4 and phi'_j = phi_j - pi/2 for 0 < j < d (Martyn et al., arXiv:2105.02859v5, Eq. (14) and App. A.2, Eq. (A5)). Each phase step flips the signal qubit onto the projector subspace Pi, applies RZ(+2 phi'_j) = exp(-i phi'_j Z) and flips back, which realizes exp(i phi'_j (2 Pi - 1)). The circuit's global phase d pi / 2 multiplies the reflection-form product by i^d, which makes the encoded block the Wx polynomial, and this global phase stays correct under control. Phase ordering and convention are part of the contract and may not be silently reversed, conjugated, or renormalized. The all-zero phase vector of length d + 1 realizes T_d(x) and remains the convention known-answer test.
Composition combines only errors with compatible mathematical metrics, domains and premises. A sum of multiplicities times unitary operator-norm bounds needs the applicable telescoping relation and is not a general total-error rule. State-preparation agreement on the all-zero input does not establish full-unitary equivalence under control, adjoint or workspace reuse. Solver residual criteria, physical operator error and model/cost uncertainty remain distinct. Small dense matrix extraction is a test oracle, not the runtime definition of a structured encoding.
Code: subroutines/block_encoding/core.py, subroutines/lcu/core.py, subroutines/qsp/phases.py wx_phases_to_reflection, subroutines/qsp/evolution.py.
Error quantities¶
| Convention | Statement | Code |
|---|---|---|
| Absolute or relative | An output's error metric is absolute (OutputRecord.metric defaults to absolute_error). A relative criterion or a relative_l2 metric divides the error by the magnitude or norm of the reference. Without explicit tolerances, the QLS inverse-error and mass checks report a discrepancy divided by its allowance (relative_error_over_method_allowance, heuristic_mass_window_discrepancy_ratio), while shortcut_direction reports its raw discrepancy. |
problems/records.py OutputRecord.metric, Accuracy, evidence/error_model.py accuracy_threshold, family verification.py modules |
| Norms and metrics | Vector discrepancies use the Euclidean norm in the original coordinates, phase_aligned_l2 for a modulo_global_phase StateVector. Operator bounds for block encodings, product formulas, QSP evolution and the LCHS kernel and quadrature use the spectral norm. The Lanczos Gram noise uses the Frobenius norm. Eigenphase discrepancies use the circular distance in turns, Samples the total variation distance and OptimizationCandidate the objective gap. |
problems/records.py output metrics, subroutines/block_encoding/core.py, subroutines/trotterization/error_budget.py, algorithms/lanczos/numerical.py |
| Bounds and intervals | A component bound is a one-sided upper bound on a nonnegative error. Hoeffding intervals (doi:10.1080/01621459.1963.10500830) are two-sided, and a family failure probability is divided among the predeclared settings or moments by a union bound. The RWPE 95 percent interval comes from its Gaussian model and carries no frequentist coverage guarantee. | evidence/error_model.py ErrorTerm, ErrorModel.assess, evidence/binary.py, algorithms/lanczos/numerical.py, algorithms/qpe/numerical.py |
| Sampling with exact readout | With exact readout, as with shots=None, the sampling error source is zero only for a Method whose estimate averages or emulates no random draw, and Sampling error by method gives the rule for each method. |
evidence/error_model.py exact_readout_sampling, ErrorModel.assess, algorithms/qpe/method.py _analysis |
| LCHS frames | approximation_tolerance sets operator-norm allowances for a unit input to the shifted propagator, and the reconstruction fields kernel_approximation_bound and quadrature_bound are the bounds chosen at planning in that frame. The facts kernel_approximation and k_quadrature in Plan.facts, which a classical Result also carries in Result.facts, are physical L2 bounds. Each sums, over the physical applications, the input norm times the Duhamel weight times exp(shift * t) times the operator bound. |
algorithms/lchs/primary_records.py, algorithms/lchs/solution_error_budget.py |
| Combination | Result.assess adds component bounds by the triangle inequality and their failure probabilities by a union bound. It combines only facts stated in a frame compatible with the output's frame. |
evidence/error_model.py |
| Verification verdicts | result.verify(checks=options) returns (receipt, facts) for every options type. Except for LCHSRefinement, facts answer the options' verification_checks, and Certificate.with_verification with the same options compares each fact with its check's threshold. It gives PASS or FAIL, or INCONCLUSIVE when the check has no threshold, the value is unavailable or a premise is open, as for an LCHSVerification without threshold. |
core/analysis.py Result.verify, evidence/verification.py witness_check_facts, evidence/error_model.py Certificate.with_verification |