Skip to content

QLS

Use LinearSystem(A=..., b=...) with QLS. Its solver chooses the inverse polynomial or an explicitly configured shortcut model. The QLS guide explains physical outputs, normalization, spectral assumptions and shortcut restrictions.

from nwqlib.algorithms.qls import QLS, QLSVerification

QLSAnalysis also imports from nwqlib.algorithms.qls. The result records QLSSamples, QLSProjectedMoments and QLSGroupMoments are defined in nwqlib.algorithms.qls.primary_records.

solve(problem, method=QLS()) defaults to quantum execution of qsvt_inverse with epsilon_inv=0.01, an automatically chosen encoding normalization alpha and encoded inverse-gap parameter kappa_be, and the physical solution as output. This default runs no reference solve. The residual tolerance epsilon_inv sets the inverse polynomial and does not bound the total error of the output.

Solve a linear system

QLS

Bases: Method

Quantum linear-system (QLS) method for A x = b given by LinearSystem.

Build it with keyword arguments and pass it as method=, for example solve(LinearSystem(A=A, b=b), method=QLS()). Every argument is optional. The result is a QLSAnalysis whose x, for the default Solution output, is the physical solution in the original coordinates, including scale and phase, in the problem's unit.

The default solver="qsvt_inverse" applies an odd Chebyshev polynomial P to A/alpha, through a Hermitian dilation when A is not Hermitian, by quantum singular value transformation (QSVT, Gilyén et al., arXiv:1806.01838v1, Theorem 17, in the conventions of Martyn et al., arXiv:2105.02859v5). Here alpha is the normalization of the block encoding of A, and the polynomial domain parameter polynomial_kappa is at least 1.01 and at least the encoded inverse-gap parameter kappa_be, which is max(1, alpha/sigma_min(A)) or the supplied kappa. All three are recorded in plan.reconstruction. P approximates 1/(polynomial_kappa x) with |polynomial_kappa x P(x) - 1| <= epsilon_inv for 1/polynomial_kappa <= |x| <= 1. NWQLib fits P and evaluates this bound in binary64 on an affine Chebyshev grid (Ehlich and Zeller, doi:10.1007/BF01111276, Satz 2). Its degree search stops at an engineering limit motivated by the degree scaling O(kappa log(kappa/epsilon)) of Childs, Kothari and Somma (arXiv:1511.02306v2, Lemmas 17-19), or at max_degree if that is smaller. This scaling does not guarantee a passing fit below the limit. Physical recovery multiplies the success branch of the circuit, or of the classical model, by ||b|| polynomial_kappa s / alpha, with s the polynomial's rescale. The two shortcut solvers implement Dalzell's kernel-reflection method (arXiv:2406.12086v2, Algorithm 1) and return only the unit direction of x, modulo global phase.

epsilon_inv sets the accuracy of the polynomial approximation. It does not bound the total error of x, which also depends on the spectral assumptions, the phase fit, the circuit execution and sampling. Vector outputs (Solution, StateVector) need exact readout, in which the amplitudes are computed without shot sampling, subject to numerical rounding, so they take no shots, and Samples needs positive shots with quantum execution. execution="classical" evaluates the chosen polynomial model classically, without circuits. It needs a dense A, a vector, product or occupation b and, for an observable output, a dense observable, and it takes no shots. result.analyze() takes no settings, so another polynomial needs a new Plan. result.verify(checks=...) takes a QLSVerification. The QLS guide explains physical outputs, normalization, spectral assumptions and the shortcut restrictions, and its source map gives every equation and its code.

Examples:

The exact solution of this system is (25/28, 5/28), about (0.8929, 0.1786). epsilon_inv=0.01 sets the inverse polynomial, not a bound on the difference.

>>> import numpy as np
>>> from nwqlib import LinearSystem, solve
>>> from nwqlib.algorithms.qls import QLS
>>> problem = LinearSystem(A=[[1.1, .1], [.1, .9]], b=[1., .25])
>>> result = solve(problem, method=QLS(), seed=7)
>>> print(np.round(result.x, 4))
[0.8966+0.j 0.1813+0.j]

Attributes:

  • solver (Literal['qsvt_inverse', 'shortcut_native_svp', 'shortcut_dilation']) –

    Default "qsvt_inverse", which recovers the physical solution. "shortcut_native_svp" (Dalzell's kernel reflection on the right singular vectors of the augmented matrix G_t, Dalzell Eqs. (8)-(11)) and "shortcut_dilation" (an even polynomial on the Hermitian dilation of G_t) give only a unit StateVector modulo global phase, a NormalizedExpectation or Samples, and need encoded_solution_norm_estimate.

  • epsilon_inv (Real) –

    Default 0.01, strictly between 0 and 1. Accuracy target of the polynomial. For "qsvt_inverse" it bounds |polynomial_kappa x P(x) - 1| on the polynomial domain 1/polynomial_kappa <= |x| <= 1. When every eigenvalue of a Hermitian A/alpha, or every singular value through the dilation, lies in that domain, the vector y after the polynomial step satisfies ||y - (polynomial_kappa A/alpha)^-1 b|| <= epsilon_inv ||(polynomial_kappa A/alpha)^-1 b||. For the shortcuts it is sqrt(2) times the kernel-reflection parameter eta. It does not bound the total error of the physical output.

  • alpha (Real | Literal['auto']) –

    Default "auto", which takes the normalization of the chosen block encoding, for Pauli input the coefficient 1-norm. A positive number is the caller's assumption. Supplied alpha and kappa do not force an extra spectral computation. When planning computes the original singular endpoints anyway, an assumption that misses them by more than a relative window of 1e-12 is rejected.

  • kappa (Real | Literal['auto']) –

    Default "auto", which uses kappa_be = alpha/sigma_min(A) from the original singular endpoints, at least 1. A number at least 1 is the caller's bound on kappa_be, the encoded inverse-gap parameter, which is not the condition number sigma_max/sigma_min. Pauli A, and a non-dense A with a supplied encoding, need a number at least alpha/sigma_min(A), because QLS computes no singular values for them. The polynomial domain parameter polynomial_kappa is at least kappa_be and at least 1.01.

  • block_encoding_implementation (Literal['auto', 'pauli_lcu', 'multiplexed_pauli', 'banded', 'dense_dilation']) –

    Default "auto", which chooses among the banded, Pauli and dense encodings that apply to the input. "pauli_lcu", "multiplexed_pauli", "banded" and "dense_dilation" request one family, which the input must support.

  • encoding (Any) –

    Default None. A SelectedBlock block encoding of the original A, with its declared operator, for example one composed as Compose blocks shows. For its projected block B, the relation ||A - alpha B|| <= epsilon, with epsilon the encoding's error bound in the units of A, is the caller's assumption, which QLS does not test against a dense matrix.

  • dense_control_route (Literal['gatewise', 'whole_matrix', 'auto']) –

    Default "auto". How a controlled query controls a dense-dilation encoding. "gatewise" synthesizes the dilation and lets Qiskit control each synthesized gate, "whole_matrix" synthesizes the controlled dilation, and "auto" takes the whole-matrix route for one control and the gate-wise route for more. With the default limits, "auto" accepts a controlled dense dilation of at most 64 padded coordinates. A supplied encoding and a supplied RHS circuit are controlled gate-wise on every route.

  • encoded_solution_norm_estimate (Real | Literal['grid', 'noisy_binary_search', 'linear_kappa_sequence'] | None) –

    Default None. Dalzell's norm parameter t of a shortcut, a number with 1 <= t <= polynomial_kappa, which quantum shortcuts require. Classical shortcuts also accept "grid", "noisy_binary_search" or "linear_kappa_sequence" (Dalzell Secs. 5.1-5.3), which evaluate the classical probability model of that search. t is not the recovered physical norm. "qsvt_inverse" rejects any value.

  • max_degree (PositiveInt) –

    Default 256. Upper limit on the polynomial degree, checked before the coefficients and phases are computed.

  • max_qsp_evaluations (PositiveInt) –

    Default 20_000. Upper limit on the residual evaluations of the QSP phase solver.

  • max_work (PositiveInt) –

    Default 1e9 (1_000_000_000). Upper limit on the counted classical work, applied separately to each planning phase, for example spectral selection (computing the extreme singular values of A), dense completion (completing A/alpha to the unitary of the dense dilation), encoding construction, the polynomial fit and the grouping of sampled Pauli terms. It includes the exact synthesis of a dense dilation, or of the dense unitaries in a supplied encoding or RHS circuit, that a controlled query needs, and Qiskit's control of the synthesized gates. The exact scalar readouts of one Run count together against it. Work units are operation counts, not timings.

  • max_bytes (PositiveInt) –

    Default 10 GB (decimal, 10_000_000_000 bytes). Upper limit on the known bytes of numerical arrays, including those syntheses. It excludes the undocumented internal workspace of external libraries. Each exact scalar readout must fit it before the circuits run.

  • max_admission_steps (PositiveInt) –

    Default 1_000_000, sized for sampled Programs, whose planning work grows with the number of their distinct measured registers. Upper limit on the planning work of checking the quantum Program (NWQLib's description of a circuit as named steps), counting the fields of that description and the work of each check during validation, preparation and circuit building. Each stage applies the limit before doing that work. Summing the Program's resource counts may use up to 24 times this value. A larger Program is rejected with a ValueError that names this field, the stage at which it was rejected and the work count of that stage. Raising the limit changes neither the polynomial nor any quantum operation. See the planning work limit.

Raises:

  • ValueError –

    If encoded_solution_norm_estimate is set with "qsvt_inverse".

  • TypeError –

    If encoding is not a SelectedBlock.

Read the result

QLSAnalysis

Bases: Result

Solution or requested output of A x = b from a QLS run.

solve returns it for a QLS method, and load_result reopens a saved one. For the default Solution output the answer is x, the physical solution in the original coordinates with its scale and phase, in the problem's unit. value gives the requested output of any kind, the saved array, the Samples arrays or the scalar scalar_value. The shortcut solvers give a unit direction without the physical magnitude, so x is unavailable for them. When a requested quantity cannot be recovered, unavailable gives the reason. epsilon_inv does not bound the error of these values. Check a result with result.verify(checks=QLSVerification(...)). result.analyze() takes no settings, so another polynomial needs a new Plan. The fields below are read-only. The fields of Result are present too.

An exact scalar output (shots=None) saves the statistics of its one readout in reduction: the complete mass (the squared norm) of the saved state, the success-only mass p_alg, the physical-slice mass p and the projected moment q. A NormalizedExpectation reports q/p, a QuadraticForm Gamma**2 q and a NormSquared Gamma**2 p, each with norm_squared equal to Gamma**2 p, where Gamma is the physical recovery scale. A NormSquared reduction saves q as zero. All these values share the readout's mass_contribution_id.

Attributes:

  • scalar_value (Real | None) –

    Requested scalar of a NormSquared, QuadraticForm or NormalizedExpectation output, physical or unit-normalized as that output defines it, or None.

  • unavailable (Text | None) –

    Reason a requested scalar or array is unavailable, or None.

  • norm_squared (Nonnegative | None) –

    Recovered physical norm squared ||x||**2, when available. The shortcut solvers never set it.

  • physical_scale (PhysicalScale | None) –

    Physical scale of the obtained vector, from the amplitudes or the classical model, not inferred from counts.

  • physical_scale_unavailable (Text | None) –

    Why the physical magnitude cannot be recovered, for example for a shortcut's unit direction.

  • numerator (Real | None) –

    Observable numerator before division by the mass.

  • numerator_frame (Literal['physical', 'unit'] | None) –

    Normalization of numerator, "unit" for a normalized expectation or "physical" for a quadratic form.

  • algorithm_success_mass (Real | None) –

    Success-only mass p_alg, a probability, empirical for counts.

  • physical_slice_mass (Real | None) –

    Mass p of the success-and-physical slice, a fraction of the whole state, or of all returned shots for counts. None when no measurement tests the original-coordinate prefix, a padded sampled quadratic form whose group bases all contain X or Y. For an unpadded output without condition bits, the two masses describe the same outcomes, and the exact and sampled readouts report equal values.

  • mass_contribution_id (ContentID | None) –

    Content hash of the measurement that supplies those masses.

  • artifact (ArtifactManifest | None) –

    Description of the saved solution array. Printing the result does not load it.

  • applications (tuple[KernelApplication, ...]) –

    Evaluations of the classical model and their recorded work.

  • execution (Literal['classical', 'quantum']) –

    "classical", the polynomial model evaluated classically, or "quantum", the circuits run on a backend.

  • submitted_shots (Count | None) –

    Shots requested for the mass measurement, when sampled.

  • returned_shots (Count | None) –

    Shots returned by that measurement, before either selection.

  • algorithm_selected_shots (Count | None) –

    Counts that satisfy algorithmic success.

  • physical_selected_shots (Count | None) –

    Counts that also satisfy the conditions and lie in original coordinates.

  • samples (QLSSamples | None) –

    For a Samples output, the distinct original-coordinate indices (samples.indices) and their counts (samples.counts), not all returned shots. None for other outputs.

  • reduction (QLSProjectedMoments | None) –

    Saved statistics of the exact scalar readout.

  • groups (tuple[QLSGroupMoments, ...]) –

    Weighted moments of each sampled measurement setting, with its Pauli labels, basis and returned and selected shots.

value

value

The requested output, the saved array, the Samples arrays or the scalar.

x

x

The physical solution x in the original coordinates, a complex array.

Available for Solution and physical StateVector outputs, and None when the array is unavailable, with the reason in unavailable. A unit StateVector, the only vector output of the shortcut solvers, carries no physical magnitude.

Raises:

  • ValueError –

    For any other output.

alpha

alpha

The encoding normalization alpha chosen at planning.

kappa

kappa

The encoded inverse-gap parameter kappa_be, not the original condition number.

With kappa="auto" it is max(1, alpha / sigma_min) from the computed singular endpoint. A supplied numeric kappa is kept as given, after a check that it covers that value when sigma_min is known.

QLSSamples

Bases: Record

Sampled output of a QLS run: the observed original coordinates and their counts, as two int64 arrays.

QLSAnalysis.samples holds it for a Samples output. Analysis uses the new C-contiguous int64 arrays that the sample reduction returns, without copying them. For m indices, the two arrays occupy 16m data bytes, and validating them needs at most 17m data bytes while one Boolean comparison mask exists. These byte counts exclude input data held by the caller, workspace of earlier reductions and Python object overhead. Building the record does not check these bytes against a memory limit.

Attributes:

  • indices (FrozenArray) –

    Distinct original-coordinate indices below the original dimension, increasing. Padding coordinates are excluded.

  • counts (FrozenArray) –

    Positive returned counts of those indices, each at most MAX_COUNT.

QLSProjectedMoments

Bases: Record

Saved statistics of the exact scalar readout of a QLS run (shots=None): the three masses and the projected moment.

QLSAnalysis.reduction holds it. Each scalar is a canonical (mantissa, exponent) pair, in which zero is (0.0, 0) and a nonzero mantissa has absolute value in [1/2, 1).

Attributes:

  • kernel (Text) –

    Versioned name of the computation of the masses and the moment, such as "pow2-mass-pauli-moment/1".

  • complete_mass (tuple[Real, int]) –

    Computed sum of squared amplitude magnitudes over the full saved state, including all populations[0] amplitudes.

  • success_mass (tuple[Real, int]) –

    Success-only mass p_alg, computed as the sum of squared magnitudes of the populations[1] amplitudes whose success selectors match. This selection can include branches that fail the additional conditions and coordinates added by padding.

  • physical_mass (tuple[Real, int]) –

    Physical-slice mass p over the populations[2] coordinates whose success and condition selectors match and whose original-coordinate index is below the original dimension.

  • numerator (tuple[Real, int]) –

    Projected moment q = v^dagger O v of the Pauli form of the observable on the physical slice v, not a moment over the whole success block. Zero for a NormSquared output.

  • numerator_radius (tuple[Real, int]) –

    Upper bound, rounded upward, on the absolute rounding error in numerator from its classical evaluation using the Pauli form of the observable and the computed physical slice. It assumes binary64 round-to-nearest arithmetic with gradual underflow and finite intermediate results. Errors in the prepared state and in converting the original observable to its Pauli form are separate.

  • lost_state_components (Count) –

    Number of initially nonzero real or imaginary parts of physical-slice amplitudes that round to zero when rescaled by a power of two for the moment calculation. Real and imaginary parts are counted separately. Default 0.

  • lost_coefficients (Count) –

    Number of initially nonzero coefficients of non-identity Pauli terms that round to zero when rescaled by a power of two for the moment calculation. Default 0.

  • populations (tuple[Count, Count, Count]) –

    Numbers of amplitudes in the full saved state, the success-only selection and the physical slice, in that order. The last is the original dimension. These counts include zero amplitudes.

  • contribution_id (ContentID) –

    Content hash of the ObservationChunk that holds the saved reduction.

QLSGroupMoments

Bases: Record

Shot counts and weighted moments of one sampled measurement setting of a QLS run.

QLSAnalysis.groups holds one per setting.

Attributes:

  • name (Text) –

    Setting name.

  • labels (tuple[Text, ...]) –

    Member Pauli labels of a group, in first-fit order. Empty for a mass setting.

  • basis (Text) –

    Accumulated measurement basis, qubit zero rightmost.

  • population (Literal['success_conditional', 'unconditional', 'physical_prefix']) –

    success_conditional (weighted values over the shots whose success and condition selectors match), unconditional (that selector indicator times the weighted values over all returned shots, the identity term assigned to the first group) or physical_prefix (the computational-basis mass setting).

  • returned_shots (Count) –

    Shots returned for the setting.

  • selected_shots (Count) –

    Returned shots whose success and condition selectors match (and, for the mass setting, whose original-coordinate index is below the original dimension).

  • mean (Real | None) –

    Weighted outcome mean, or the selected fraction of the mass setting. None when the setting has no shots to average.

  • second_moment (Real | None) –

    Weighted second moment, for a group.

  • variance (Real | None) –

    Unbiased variance of the mean, for a group of at least two shots.

  • contribution_id (ContentID) –

    Content hash of the ObservationChunk that holds the setting's counts.

Check a result

QLSVerification

Bases: Record

Reference comparisons for a QLS Result, with bounded reference work.

Build it with keyword arguments and pass it to result.verify(checks=...), for example result.verify(checks=QLSVerification(comparisons=("spectral_domain",))). comparisons is the only required argument. The call returns (receipt, facts): a VerificationReceipt that records the check, its raw values and the numerical calls it made, and a tuple with one nonnegative dimensionless FramedFact per comparison, in the given order, ready for Certificate.with_verification with the same options. The receipt also keeps the companion values, such as raw discrepancies and error budgets. The QLS guide shows a complete check.

All comparisons share one solve of the original A/alpha with the normalized b, and a spectral-only request solves nothing. Singular endpoints that the Plan already computed are reused. A comparison that needs only the norm of the solution, such as "eq17", reuses the encoded reference norm that a grid or noisy-search norm model recorded from its own solve, which is that model's intermediate value, not independent evidence. A new spectral or solution reference needs a dense A, and compact Pauli or sparse input is never converted to a dense matrix. Without relative_tolerance, "inverse_relative_error" reports the raw relative error divided by the error budget epsilon_inv + polynomial_kappa s delta / ||y_ref||, with delta the phase-fit residual bound (zero for classical execution), s the polynomial rescale and y_ref = (A/alpha)^-1 b/||b||. A value of 0.386 then means 0.386 of that budget, not 38.6% physical inverse error. A missing phase bound leaves that budget unknown. The automatic mass windows and the default 5*epsilon_inv direction window are heuristics. These checks do not prove a bound on the total physical error or establish confidence coverage.

Attributes:

  • name (Text) –

    Default "reference". Prefix of every reported fact. Each check is named name + "." + comparison.

  • comparisons (tuple[Literal['spectral_domain', 'inverse_relative_error', 'inverse_success', 'shortcut_direction', 'eq17'], ...]) –

    Required. Distinct comparisons, at least one. "spectral_domain" checks that alpha and kappa_be cover the original singular endpoints. "inverse_relative_error" and "inverse_success" compare the "qsvt_inverse" output and its success mass with the shared reference solve. "shortcut_direction" compares a shortcut's unit direction modulo global phase. "eq17" compares a shortcut's success mass with Dalzell's Eq. (17) window (arXiv:2406.12086v2). The inverse comparisons need an inverse Plan, and the shortcut comparisons a shortcut Plan.

  • relative_tolerance (Nonnegative | None) –

    Default None. Nonnegative threshold on the relative L2 inverse error. None reports the error divided by the method's error budget, checked against 1.

  • direction_tolerance (Nonnegative | None) –

    Default None. Nonnegative threshold on the phase-aligned L2 direction error. None uses 5*epsilon_inv.

  • probability_tolerance (Nonnegative | None) –

    Default None. Nonnegative absolute threshold on the mass comparisons. None reports the discrepancy divided by a heuristic window, checked against 1.

  • spectral_tolerance (Nonnegative) –

    Default 1e-9, nonnegative. Window on the dimensionless spectral-domain deficit, wide enough for ordinary rounding of an automatic kappa. It is a numerical window, not a spectral theorem.

  • max_work (PositiveInt) –

    Default 1e9 (1_000_000_000). Upper limit on the known reference work, checked before any solve.

  • max_bytes (PositiveInt) –

    Default 10 GB (decimal, 10_000_000_000 bytes). Upper limit on the known reference arrays, checked before any solve.

Raises:

  • ValueError –

    If comparisons is empty or repeats a name.

Limits

  • epsilon_inv is the residual tolerance of the inverse polynomial, not a bound on the total error of x. The rounding in circuit execution and the total propagated physical error remain unknown.
  • The shortcut solvers give a unit direction modulo global phase. Their classical norm models do not supply the physical magnitude of x.
  • Pauli A, and a non-dense A with a supplied encoding, need kappa, because QLS computes no singular values for them.
  • Classical execution needs a dense A. QLS has no CSR or CSC route.
  • The solution vector is a simulator output, not a hardware measurement.

Limitations and open work lists the open items. The QLS source map gives the paper, equation and implementing function of each step. To add a method of your own, see Extending NWQLib.