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 matrixG_t, Dalzell Eqs. (8)-(11)) and"shortcut_dilation"(an even polynomial on the Hermitian dilation ofG_t) give only a unitStateVectormodulo global phase, aNormalizedExpectationorSamples, and needencoded_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 domain1/polynomial_kappa <= |x| <= 1. When every eigenvalue of a HermitianA/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 issqrt(2)times the kernel-reflection parametereta. 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. Suppliedalphaandkappado 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 of1e-12is rejected. -
kappa(Real | Literal['auto']) –Default
"auto", which useskappa_be = alpha/sigma_min(A)from the original singular endpoints, at least 1. A number at least 1 is the caller's bound onkappa_be, the encoded inverse-gap parameter, which is not the condition numbersigma_max/sigma_min. Pauli A, and a non-dense A with a suppliedencoding, need a number at leastalpha/sigma_min(A), because QLS computes no singular values for them. The polynomial domain parameterpolynomial_kappais at leastkappa_beand 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. ASelectedBlockblock 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 with1 <= 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 (completingA/alphato 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_000bytes). 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 sampledPrograms, whose planning work grows with the number of their distinct measured registers. Upper limit on the planning work of checking the quantumProgram(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_estimateis set with"qsvt_inverse". -
TypeError–If
encodingis not aSelectedBlock.
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,QuadraticFormorNormalizedExpectationoutput, physical or unit-normalized as that output defines it, orNone. -
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.
Nonewhen 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
Samplesoutput, the distinct original-coordinate indices (samples.indices) and their counts (samples.counts), not all returned shots.Nonefor 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.
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.
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 thepopulations[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 vof 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
numeratorfrom 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
ObservationChunkthat 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) orphysical_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
ObservationChunkthat 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 namedname + "." + comparison. -
comparisons(tuple[Literal['spectral_domain', 'inverse_relative_error', 'inverse_success', 'shortcut_direction', 'eq17'], ...]) –Required. Distinct comparisons, at least one.
"spectral_domain"checks thatalphaandkappa_becover 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.Nonereports 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.Noneuses5*epsilon_inv. -
probability_tolerance(Nonnegative | None) –Default
None. Nonnegative absolute threshold on the mass comparisons.Nonereports 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 automatickappa. 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_000bytes). Upper limit on the known reference arrays, checked before any solve.
Raises:
-
ValueError–If
comparisonsis empty or repeats a name.
Limits¶
epsilon_invis 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.