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

solve(problem, method=QLS()) defaults to quantum execution of qsvt_inverse with epsilon_inv=0.01, auto-selected encoding scale and condition estimate, and physical solution output. This default performs no reference solve. The inverse target controls the selected approximation and does not establish a total-output error guarantee.

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 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), and checks its degree against the degree bound of Childs, Kothari and Somma (arXiv:1511.02306v2, Lemmas 17-19). 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 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 amplitude readout, so they take no shots, and Samples needs positive shots with quantum execution. execution="classical" evaluates the chosen polynomial model on the host. 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. Polynomial construction target. 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 refused.

  • 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 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 supplied block encoding of the original A, with its declared operator. Its projected equation and error are the caller's assumptions, not checked by a dense test.

  • 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" refuses any value.

  • max_degree (PositiveInt) –

    Default 256. Upper limit on the polynomial degree, checked before coefficient and phase work.

  • 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, dense completion, 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 undocumented vendor workspace. Each exact scalar readout must fit it before the circuits run.

  • max_admission_steps (PositiveInt) –

    Default 1_000_000, ten times the shared default, because the planning work of a sampled Program grows with the number of its distinct measured registers. Upper limit on the planning work of checking the quantum Program (NWQLib's description of a circuit as named steps), counting its stored fields and the work of validation, preparation and circuit building. A refusal with a complete count names a value that passes. Summing the Program's resource counts may use up to 24 times this value. Raising it 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 selected block encoding.

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 stored 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 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 stored solution array. Printing the result does not load it.

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

    Classical model applications and their recorded work.

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

    "classical", the polynomial model evaluated on the host, 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 stored 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 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.

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), with one nonnegative dimensionless fact 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 a construction target for the polynomial, not a bound on the total error of x. Rounding in circuit execution and the complete 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 simulator's solution vector is an explicit simulator output, not a hardware readout.

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.