QSP and QSVT¶
Compute symmetric quantum signal processing (QSP) phase factors for a real Chebyshev target, and build QSVT circuits that apply the polynomial to a block-encoded matrix: a real Chebyshev transform, the Hamiltonian evolution exp(-i t A), the 1/x polynomial of QLS and Dalzell's kernel reflection. The conventions define the normalization and phase signs used here. Import the functions from nwqlib.subroutines.qsp, or from the submodule (phases, evolution, inverse, shortcut) named in each entry's path.
import numpy as np
from qiskit.quantum_info import Operator
from nwqlib.subroutines.block_encoding import build_block_encoding
from nwqlib.subroutines.qsp import (
build_real_chebyshev_encoding,
solve_symmetric_qsp_phases,
)
solution = solve_symmetric_qsp_phases([0.0, 0.0, 0.0, 0.5]) # f = T_3 / 2
encoding = build_block_encoding(np.diag([0.6, -0.2])) # alpha = 0.6
circuit = build_real_chebyshev_encoding(encoding, solution.phases)
stride = 2 ** (circuit.num_qubits - encoding.system_qubits)
block = Operator(circuit).data[::stride, ::stride]
print(np.round(block.real, 6))
[[0.5 0. ]
[0. 0.425926]]
A / alpha is diag(1, -1/3), and T_3(x)/2 is 0.5 at 1 and 23/54 = 0.425926... at -1/3. The ancilla qubits come first, so the block is read at the stride of their dimension.
Phase fitting¶
solve_symmetric_qsp_phases accepts finite, real, definite-parity Chebyshev targets with max |f| <= 1. The module text below states the Wx convention, the solver and their sources (Martyn, Rossi, Tan and Chuang, arXiv:2105.02859v5, Dong, Meng, Whaley and Lin, arXiv:2002.11649v2, and Dong, Lin, Ni and Wang, arXiv:2307.12468v1).
Wx-convention quantum signal processing: evaluation and phase factors.
[MRTC] is Martyn, Rossi, Tan, and Chuang, arXiv:2105.02859v5, [DMWL] is Dong, Meng, Whaley, and Lin, arXiv:2002.11649v2, and [DLNW] is Dong, Lin, Ni, and Wang, arXiv:2307.12468v1. Equation and section numbers refer to these arXiv versions, those of [DLNW] to the PDF of that version.
Convention (project standard, [MRTC] arXiv:2105.02859v5, Sec. II.A,
Eqs. (1)-(3) and Theorem 1; App. A.1, Eq. (A2)): the signal operator is
W(x) = [[x, i sqrt(1-x^2)], [i sqrt(1-x^2), x]], phases apply as
e^{i phi Z}, and a phase vector (phi_0, ..., phi_d) realizes
P(x) = <0| e^{i phi_0 Z} prod_{j=1..d} [ W(x) e^{i phi_j Z} ] |0>.
Conversion identities implemented here (each guarded by a unit test):
- Reflection convention: with
R(x) = [[x, sqrt(1-x^2)], [sqrt(1-x^2), -x]]([MRTC] arXiv:2105.02859v5, Eq. (A4)) andW(x) = i e^{-i pi/4 Z} R(x) e^{-i pi/4 Z}(the inverse of [MRTC] arXiv:2105.02859v5, Eq. (14)), the Wx product equalsi^dtimes the reflection product with phasesphi'_0 = phi_0 - pi/4,phi'_d = phi_d - pi/4, and interiorphi'_j = phi_j - pi/2.wx_phases_to_reflectionreturns those shifted phases plus the compensating global phased * pi/2. [MRTC] arXiv:2105.02859v5, App. A.2, Eq. (A5), uses the same interior and final shifts but setsphi'_0 = phi_0 + (2d-1) pi/4, folding thei^dfactor into the first phase. That form reproduces the<0|.|0>entry. Keeping the factor as a global phase makes the identity hold for the whole 2 x 2 product. - Qiskit sign:
RZGate(theta) = exp(-i theta Z / 2)exactly, so applyinge^{i phi Z}isRZGate(-2 phi)with no residual global phase. The QSVT circuit builders apply projector phasese^{i phi (2 Pi - 1)}asRZGate(+2 phi)on a signal qubit that is flipped onto the projector subspace, which is the same identity.
Phase factors follow the symmetric-QSP optimization of [DMWL]
arXiv:2002.11649v2: symmetric phase vectors phi_j = phi_{d-j}
(Sec. III.1, Theorem 2, and Eq. (24)),
the mean-square residual of Re P(x) against the target polynomial on
positive Chebyshev nodes (Sec. III.2, Eq. (23)), the initialization
(pi/4, 0, ..., 0, pi/4) of Eq. (27), which realizes Re P = 0
and whose free phases (pi/4, 0, ..., 0) are Eq. (28) (Sec. III.4),
and L-BFGS descent (Sec. III.5, Algorithm 1). This module
departs from the paper in four places. The objective uses four times as
many nodes as free phases (QSP_SOLVER_GRID_MULTIPLIER). A damped
Gauss-Newton polish supplies the terminal digits after L-BFGS. If L-BFGS
from the Eq. (27) point leaves an objective-node residual at or above the
tolerance, the same damped iteration runs from that point, which is the
Newton method of [DLNW] arXiv:2307.12468v1, Sec. 3, Eq. (3.1) and
Algorithm 3.1. Their zero reduced phases are the [DMWL] start written in
an imaginary-part convention ([DLNW] Sec. 2.2 and Eq. (2.3)). Acceptance is decided on a
separate dense verification grid with the Chebyshev norming bound rather
than on the objective.
The Newton start exists for targets whose sup norm lies near 1. The
larger parity target of the Hamiltonian evolution of
build_qsp_evolution_encoding has a sup norm near 1/(1 + margin)
with a margin of 1e-3, and every QLS phase target has the norming
bound 1/(1 + QLS_TARGET_MARGIN), with the same margin. [DMWL]
arXiv:2002.11649v2, Sec. IV.1, divides the Jacobi-Anger series by 2, so
their Hamiltonian-simulation tests of the fixed start stay at
max|f| <= 1/2, and Sec. IV.5 reports a Hessian condition number that
grows as max|f| approaches 1. [DLNW] arXiv:2307.12468v1, Sec. 2.2,
states that optimization methods such as L-BFGS lose their
convergence guarantee near max|f| = 1, and Sec. 4.3 (Fig. 8) reports
Newton's method from the same start converging for 1 - max|f| down to
1e-9. The engineering constants record the NWQLib sweeps behind this
order, for the
evolution targets
and for the
QLS targets
in the QLS_TARGET_MARGIN row. In both families L-BFGS missed the
tolerance on some sampled targets, and the Newton start converged on each
of them.
L-BFGS runs in scipy.optimize and each Newton step is one
numpy.linalg.lstsq solve. Phase-factor computation
is classical preprocessing of poly(d) cost, independent of any
Hilbert-space dimension
(classical_preprocessing_scope: "qsp_phase_factor_optimization").
SymmetricQSPPhases ¶
SymmetricQSPPhases(*, phases: tuple[float, ...], degree: int, parity: int, target_chebyshev_coefficients: tuple[float, ...], max_residual: float, residual_sup_bound: float, evaluations: int)
Solved symmetric QSP phase factors with their residual and its sup-norm bound.
solve_symmetric_qsp_phases
returns it. The answer is phases. The fields below are read-only.
Attributes:
-
phases(tuple[float, ...]) –Full symmetric Wx phase vector
(phi_0, ..., phi_d). -
degree(int) –Polynomial degree
d. -
parity(int) –Target parity (
0even,1odd). -
target_chebyshev_coefficients(tuple[float, ...]) –The solved-for coefficient vector.
-
max_residual(float) –Largest
|Re P - f|on the dense verification grid. -
residual_sup_bound(float) –Chebyshev-grid norming bound on
sup_{x in [-1,1]} |Re P(x) - f(x)|. -
evaluations(int) –Number of objective and Jacobian evaluations and final verification calls made, across both starts, polish steps and line searches.
chebyshev_grid ¶
chebyshev_grid(num_points: int) -> ndarray
Return the Chebyshev grid x_j = cos(pi (j + 1/2) / M).
chebyshev_norming_sup_bound ¶
chebyshev_norming_sup_bound(grid_max: float, *, degree: int, num_points: int) -> float
Bound a degree-degree polynomial's sup norm from a Chebyshev grid.
Returns grid_max / cos(pi d / (2 N)), an upper bound on
sup_{x in [-1, 1]} |p(x)| when grid_max is the largest |p|
on the N nodes of chebyshev_grid(N). This is the Chebyshev-node
norming bound of Ehlich and Zeller (1964), doi:10.1007/BF01111276,
Satz 2, Eqs. (12)-(14), pp. 42-43, which use exactly these
Chebyshev-zero nodes.
The extension to complex coefficients follows by rotating a maximum
value to the real axis and applying the real-polynomial inequality.
Sunderhauf et al., arXiv:2507.15537v1 Eq. (25), state this factor for
equidistant x points, where it is not valid. Equispaced angles give
the required nodes x_j=cos(theta_j), not an equispaced x grid.
Ehlich--Zeller, doi:10.1007/BF01111276, Satz 1, treats equidistant x
nodes separately. The QLS
guide gives an exact-rational counterexample to the Eq. (25) extension.
num_points is the number N of nodes on the whole interval
[-1, 1], as opposed to the positive-half grid of the phase solver.
The inequality requires strictly more nodes than the polynomial degree.
The result is an exact-arithmetic bound evaluated in binary64, not an
interval-arithmetic enclosure.
chebyshev_polynomial_sup_bound ¶
chebyshev_polynomial_sup_bound(chebyshev_coefficients: Any, *, max_degree: int = 256, max_bytes: int = DEFAULT_INPUT_BYTES) -> float
Return an upper bound on sup_{x in [-1, 1]} |f(x)| for f = sum_k c_k T_k.
The series is sampled on N = 64 (d + 1) Chebyshev zeros, and the
sampled maximum is divided by cos(pi d / (2N)) as in
chebyshev_norming_sup_bound. The QLS rescale, the evolution target
scale and the input check of solve_symmetric_qsp_phases all use this
bound. max_degree (default 256) and max_bytes (default 10 GB) are
checked before the grid is formed.
evaluate_qsp_polynomial ¶
evaluate_qsp_polynomial(phases: Any, x_values: Any) -> ndarray
Evaluate the Wx-convention QSP polynomial P(x) on a grid.
Parameters:
-
phases(Any) –Phase vector
(phi_0, ..., phi_d). -
x_values(Any) –Signal values in
[-1, 1].
Returns:
-
ndarray–Complex
P(x)values, one per grid point.
wx_phases_to_reflection ¶
wx_phases_to_reflection(phases: Any) -> tuple[ndarray, float]
Convert Wx phases to reflection-convention phases ([MRTC] arXiv:2105.02859v5, Eq. (14)).
The shifts are those of [MRTC] arXiv:2105.02859v5, App. A.2, Eq. (A5),
except that the
i^d factor is returned as a global phase (see the module docstring).
Returns:
-
ndarray–(reflection_phases, global_phase)such that the reflection-form -
float–product times
e^{i global_phase}equals the Wx-form product; -
tuple[ndarray, float]–global_phase = d * pi / 2compensates thei^dfactor.
solve_symmetric_qsp_phases ¶
solve_symmetric_qsp_phases(chebyshev_coefficients: Any, *, residual_tolerance: float = QSP_SOLVER_RESIDUAL_TOLERANCE, max_degree: int = 256, max_evaluations: int = 20000, max_bytes: int = DEFAULT_INPUT_BYTES, limit_name: str = 'max_evaluations') -> SymmetricQSPPhases
Solve symmetric Wx phase factors whose Re P(x) matches a real definite-parity Chebyshev target.
Implements the [DMWL] optimization (arXiv:2002.11649v2, Sec. III):
symmetric phases, positive Chebyshev node objective,
(pi/4, 0, ..., 0, pi/4) initialization and L-BFGS, followed by a
damped Gauss-Newton polish. If the objective-node residual from that
start is at or above residual_tolerance or nonfinite, the damped
Newton iteration of [DLNW] arXiv:2307.12468v1 (Sec. 3, Eq. (3.1) and
Algorithm 3.1) runs from the same initialization, and the better of the
two results is verified. Near max|f| = 1, where the evolution and QLS
targets lie, L-BFGS from that point has no convergence guarantee
([DLNW] Sec. 2.2). The returned phases satisfy Re P(x) ~= f(x) in
the Wx convention. residual_sup_bound bounds sup |Re P - f| over
[-1, 1] by the Chebyshev norming inequality. The degree and the known
simultaneous numerical arrays are checked before optimization.
Parameters:
-
chebyshev_coefficients(array_like) –Finite real Chebyshev coefficients
(c_0, ..., c_d)of the targetf. Entries of the wrong parity must be zero, andmax |f|must not exceed 1. -
residual_tolerance(float, default:QSP_SOLVER_RESIDUAL_TOLERANCE) –Default
1e-12. Largest acceptable|Re P - f|on the dense verification grid. -
max_degree(int, default:256) –Default
256. Largest accepted target degree. -
max_evaluations(int, default:20000) –Default
20000. Limit on the combined objective and Jacobian evaluations and final verification calls across both starts, polish steps and line searches. -
max_bytes(int, default:DEFAULT_INPUT_BYTES) –Default 10 GB (decimal,
10_000_000_000bytes). Bound on known simultaneous numerical arrays. It does not measure process memory, vendor workspaces or elapsed time. -
limit_name(str, default:'max_evaluations') –Default
"max_evaluations". Name of the caller's option that setsmax_evaluations, used in the error messages.
Returns:
-
solution(SymmetricQSPPhases) –The full phase vector in
solution.phases, with the residual and its sup-norm bound.
Raises:
-
ValueError–For empty, mixed-parity or out-of-range targets, or when the solver cannot reach
residual_tolerance(with diagnostics).
Examples:
For f(x) = x / 2, a degree-one target, both symmetric phases are
-pi/6 = -0.5235987756..., and Re P(0.3) = 0.15:
>>> import numpy as np
>>> from nwqlib.subroutines.qsp import (
... evaluate_qsp_polynomial, solve_symmetric_qsp_phases)
>>> solution = solve_symmetric_qsp_phases([0.0, 0.5])
>>> print([round(phase, 10) for phase in solution.phases])
[-0.5235987756, -0.5235987756]
>>> values = evaluate_qsp_polynomial(solution.phases, [0.3, -0.8])
>>> print(np.round(values.real, 10))
[ 0.15 -0.4 ]
Hamiltonian evolution and circuit construction¶
build_qsvt_circuit and build_real_chebyshev_encoding apply given Wx phases to a block encoding. build_qsp_evolution_encoding builds a block encoding of exp(-i t A) from one of a Hermitian A. Without Qiskit, jacobi_anger_expansion computes its polynomial, with the degree and the Bessel search bounded and the analytic infinite-tail term kept, and prepare_qsp_evolution solves its phases within one evaluation limit. qsp_evolution_error_terms gives its error terms without a circuit. The assumptions and limits below apply to the evolution builders.
QSVT circuits and Jacobi-Anger Hamiltonian-evolution synthesis.
[GSLW] is Gilyen, Su, Low, and Wiebe, arXiv:1806.01838v1, and [MRTC] is Martyn, Rossi, Tan, and Chuang, arXiv:2105.02859v5. Equation, lemma and theorem numbers refer to these arXiv versions.
Implements Jacobi-Anger evolution using the shared block-encoding records and the block-encoding and QSP conventions:
build_qsvt_circuit: projector-controlled phase QSVT ([MRTC] arXiv:2105.02859v5, Sec. II.C-II.D, Eq. (27), Fig. 3, Theorems 3-4; [GSLW] arXiv:1806.01838v1, Theorem 17 and Lemma 19): alternateU_BE/U_BE^daggerwithe^{i phi (2 Pi - 1)}phases, wherePiprojects onto the all-zero block-encoding ancillas. The phase operator is realized by the X-conjugation trick: flip a signal qubit onto thePisubspace (Xcontrolled on the ancillas being all zero), rotateRZGate(+2 phi)(= e^{-i phi Z}, the Qiskit signRZGate(theta) = exp(-i theta Z / 2)), and flip back. Wx phases, in the convention dictionary of [MRTC] arXiv:2105.02859v5, App. A, are converted withwx_phases_to_reflectionand thei^dfactor becomes circuit global phase, so the encoded block is exactly the Wx polynomialP(A / alpha).build_real_chebyshev_encoding: block-encodesRe P(A / alpha)by averaging the+Phiand-Phipasses over one pair ancilla ([GSLW] arXiv:1806.01838v1, Corollary 18, Eq. (33)). Both branches share the sameU_BEladder: a CNOT from the pair qubit onto the signal qubit conjugates everyRZ, negating the reflection phases on the pair-one branch (X RZ(theta) X = RZ(-theta)); aZon the pair qubit for odd degree fixes the(-1)^dofi^d <0|U_R(-Phi')|0> = (-1)^d conj(P). The shared ladder is NWQLib's circuit for Corollary 18's controlledU_Phi/U_-Phipair.build_qsp_evolution_encoding: Jacobi-Anger split ([GSLW] arXiv:1806.01838v1, Lemma 57, with the Bessel tails of Eqs. (53)-(56))cos(tau x) = J_0(tau) + 2 sum (-1)^k J_2k(tau) T_2k(x)(even) andsin(tau x) = 2 sum (-1)^k J_2k+1(tau) T_2k+1(x)(odd), truncation degree from the Bessel tail bound2 sum_{k>d} |J_k(tau)| <= epswith the recorded slack, one parity ancilla combining the passes with coefficients(1/2, -i/2)(the construction in the proof of [GSLW] arXiv:1806.01838v1, Theorem 58), and 3-step oblivious amplitude amplificationA R A^dagger R A([GSLW] arXiv:1806.01838v1, Theorem 28 withn = 3), which realizes-(3B - 4BB^dagB). The circuit adds a compensatingpiglobal phase. At block amplitudea = 1/(2s)the OAA output(3a - 4a^3)is quadratically insensitive to the recorded target rescales, so the margin costs only the recorded amplitude deficit.build_control_diagonal_generator_encoding: block encoding of the LCHS effective Hamiltonian, adapted from Pocrnic, Johnson, Katabarwa, and Wiebe, arXiv:2506.20760v2, Lemma 7 (p. 15).
The qubitized walk of Low and Chuang, arXiv:1610.06546v3, is an alternative route to Hamiltonian evolution that this module does not implement.
JacobiAngerExpansion ¶
JacobiAngerExpansion(*, tau: float, epsilon: float, degree: int, cos_degree: int, sin_degree: int, cos_coefficients: tuple[float, ...], sin_coefficients: tuple[float, ...], tail_bound: float | None, tail_slack: float | None, cos_tail_bound: float | None, sin_tail_bound: float | None, analysis_terminal: int, analytic_infinite_tail_bound: float | None)
Truncated Jacobi-Anger expansion of exp(-i tau x) with its Bessel tail bounds.
jacobi_anger_expansion
returns it. The polynomial is in cos_coefficients and
sin_coefficients, and its truncation error bound is tail_bound. The
fields below are read-only.
Attributes:
-
tau(float) –Effective evolution time
alpha * t. -
epsilon(float) –Requested truncation tolerance for the combined expansion.
-
degree(int) –Smallest feasible degree at the first certified tail terminal. This is not a global minimum over all possible terminals.
-
cos_degree(int) –Even-part polynomial degree.
-
sin_degree(int) –Odd-part polynomial degree.
-
cos_coefficients(tuple[float, ...]) –Chebyshev coefficients of the truncated cosine.
-
sin_coefficients(tuple[float, ...]) –Chebyshev coefficients of the truncated sine.
-
tail_bound(float | None) –Upper bound on the combined Bessel tail
2 sum_{k>degree} |J_k|, computed as the finite sum throughanalysis_terminalplusanalytic_infinite_tail_bound. -
tail_slack(float | None) –epsilon / tail_bound, the margin to the truncation boundary. A degree selected with slack near one can change under a different Bessel-function implementation, so integer degree anchors are meaningful only together with this slack. -
cos_tail_bound(float | None) –Complete even-part finite-plus-infinite tail bound.
-
sin_tail_bound(float | None) –Complete odd-part finite-plus-infinite tail bound.
-
analysis_terminal(int) –Last Bessel order evaluated directly.
-
analytic_infinite_tail_bound(float | None) –Combined analytic infinite-tail term added across both parity bounds, or
Nonewhen that mathematically nonzero term is not representable in binary64. On that path, all tail bounds and tail_slack are also None.
QSPPreparedEvolution ¶
QSPPreparedEvolution(*, expansion: JacobiAngerExpansion, cos_solution: SymmetricQSPPhases, sin_solution: SymmetricQSPPhases, scale: float, target_norming_bounds: tuple[float, float], margin: float, attempted_margins: tuple[float, ...])
The solved phases of both parity parts of a QSP evolution, with the common target scale.
prepare_qsp_evolution
returns it, and
qsp_evolution_error_terms
reads it. It holds numbers only, no circuit. The coefficient and phase
tuples are immutable. The fields below are read-only.
Attributes:
-
expansion(JacobiAngerExpansion) –The Jacobi-Anger truncation whose parity targets were solved.
-
cos_solution(SymmetricQSPPhases) –Phases realizing
Re P = cos-series / scale. -
sin_solution(SymmetricQSPPhases) –Phases realizing
Re P = sin-series / scale. -
scale(float) –Common target divisor
s = max(1, cos bound, sin bound) * (1 + margin) >= 1. -
target_norming_bounds(tuple[float, float]) –Norming bounds on the cos and sin series before division by
scale. -
margin(float) –The registered target margin that succeeded.
-
attempted_margins(tuple[float, ...]) –Every margin tried, in order, including failures.
recovery_scale ¶
recovery_scale
Return 1 / (3a - 4a^3) with a = 1/(2 scale).
Multiplying recovered postselected amplitudes by this value removes the known OAA amplitude deficit.
jacobi_anger_expansion ¶
jacobi_anger_expansion(tau: float, epsilon: float, *, min_degree: int = 1, max_degree: int = 256, max_bytes: int = DEFAULT_INPUT_BYTES) -> JacobiAngerExpansion
Truncate the Jacobi-Anger expansion by the Bessel tail bound.
exp(-i tau x) = cos(tau x) - i sin(tau x) with
cos(tau x) = J_0 + 2 sum_{k>=1} (-1)^k J_2k T_2k and
sin(tau x) = 2 sum_{k>=0} (-1)^k J_2k+1 T_2k+1 ([GSLW] Lemma 57,
arXiv:1806.01838v1, pp. 49-50). Truncating both parities at k <= d
leaves error
at most 2 sum_{k>d} |J_k(tau)| because |T_k| <= 1 on [-1, 1]
(Eqs. (53)-(54)). The bound adds the Bessel magnitudes through the
first admissible terminal T directly and bounds the rest by an
analytic remainder (NWQLib's power-series bound, for which [GSLW]
Eq. (55) is the sharper real-argument form). Each parity tail carries the whole
analytic suffix, so the combined tail_bound counts it twice, which
is conservative. The scaling of [GSLW] arXiv:1806.01838v1, Cor. 60,
d = Theta(tau + log(1/eps)/log(e + log(1/eps)/tau)), is the
documented reference form for the resulting degree. min_degree floors the selected
degree; the phase solver needs min_degree=2 so the even (cos) part
is never a constant.
max_degree bounds the returned polynomial and the finite search:
at most max_degree + 200 Bessel orders are explored. max_bytes
bounds known numerical arrays, not special-function workspaces or
process memory.
Parameters:
-
tau(float) –Effective evolution time
alpha * t. -
epsilon(float) –Truncation tolerance for the combined expansion.
-
min_degree(int, default:1) –Default
1. Smallest returned degree. -
max_degree(int, default:256) –Default
256. Largest returned degree. -
max_bytes(int, default:DEFAULT_INPUT_BYTES) –Default 10 GB (decimal,
10_000_000_000bytes). Limit on the known numerical arrays.
Returns:
-
expansion(JacobiAngerExpansion) –Cosine and sine Chebyshev coefficients with their tail bounds and
tail_slack.
build_qsvt_circuit ¶
build_qsvt_circuit(encoding: BlockEncoding, wx_phases: Any) -> QuantumCircuit
Build the projector-controlled-phase QSVT circuit for Wx phases.
The all-zero block (signal + block-encoding ancillas) equals the Wx
polynomial P(A / alpha) exactly (for Hermitian encoded blocks and
definite-parity-compatible phases), as in [MRTC] arXiv:2105.02859v5,
Theorem 3. Trivial
(all-zero) Wx phases realize the Chebyshev polynomial T_d(A / alpha)
([MRTC] arXiv:2105.02859v5, Sec. II.A, p. 3). That known answer checks
the phase, sign and
ordering conventions of this module at circuit level.
Parameters:
-
encoding(BlockEncoding) –Block encoding of the operator to transform, including its normalization and ancilla layout.
-
wx_phases(Any) –Wx-convention phase vector
(phi_0, ..., phi_d).
Returns:
-
QuantumCircuit–Circuit on
1 + num_ancillas + system_qubitsqubits with the -
QuantumCircuit–signal qubit first (register order: signal, block ancillas, system).
build_real_chebyshev_encoding ¶
build_real_chebyshev_encoding(encoding: BlockEncoding, wx_phases: Any) -> QuantumCircuit
Block-encode Re P(A / alpha) via the shared-ladder +-Phi pair.
This is [GSLW] arXiv:1806.01838v1, Corollary 18, Eq. (33):
Re P = (P + P^*)/2, and the
phases -Phi realize P^*.
One pair ancilla in H .. H averages the +Phi and -Phi QSVT
passes; both branches share the U_BE ladder because a CNOT from the
pair qubit negates every reflection phase on the pair-one branch, and a
Z on the pair qubit for odd degree absorbs the (-1)^d of the
conjugated pass. Register order: pair, signal, block ancillas, system.
build_control_diagonal_generator_encoding ¶
build_control_diagonal_generator_encoding(encoding_l: BlockEncoding, encoding_h: BlockEncoding | None, *, l_diagonal: Any, h_diagonal: Any | None = None, max_work: int = 1000000000, max_bytes: int = DEFAULT_INPUT_BYTES, dense_control_route: str = 'auto') -> BlockEncoding
Block-encode the joint generator D_L (x) L + D_H (x) H.
Following the effective-Hamiltonian SELECT route of Pocrnic et al.,
arXiv:2506.20760v2, Lemma 7 (p. 15), adapted to the library's separate BE(L)/BE(H)
children, the LCHS node coefficients (k, 1) become real diagonals D_L,
D_H on a control register that joins the encoded operator's system
space. Length-one diagonals give the scalar generator k L + H. Each
child branch is a one-ancilla multiplexed-RY encoding of its rescaled
diagonal tensored with the child encoding, and one LCU combine qubit sums
the branches, so
alpha = max|D_L| * alpha_L + max|D_H| * alpha_H.
A child with fewer ancillas uses a prefix of the shared ancilla register,
and the idle ancillas keep its all-zero block. Encoded system order: control
register first (low-order), then the child system, so the encoded matrix
is kron(L, D_L) + kron(H, D_H) in numpy index convention. Zero
diagonal entries make their control state evolve trivially under
downstream Hamiltonian simulation (identity padding).
Parameters:
-
encoding_l(BlockEncoding) –Block encoding of the Hermitian part
L. -
encoding_h(BlockEncoding | None) –Block encoding of
H, orNonewhenH = 0. -
l_diagonal(Any) –Real diagonal for the
Lbranch, power-of-two length2**control_qubitsindexed by the control-register basis. -
h_diagonal(Any | None, default:None) –Real diagonal for the
Hbranch (same length); required exactly whenencoding_his supplied. -
max_work(int, default:1000000000) –Default
1_000_000_000. Limit on the work of the exact dense syntheses that controlling the two branches makes, and of Qiskit's control of the synthesized gates, in the work units of Exact dense synthesis. Adense_dilationchild is synthesized and controlled once. A single active branch is not controlled here. -
max_bytes(int, default:DEFAULT_INPUT_BYTES) –Default 10 GB (decimal,
10_000_000_000bytes). Limit on the working and kept bytes of those syntheses and control steps. -
dense_control_route(str, default:'auto') –Default
"auto"."gatewise","whole_matrix"or"auto", the route by which the combine qubit controls adense_dilationchild (dense control route)."auto"takes the whole-matrix route for this one control. The child's dilation is then synthesized with the control, and the branch's diagonal rotation is controlled gate-wise. A child whose circuit is not one dense unitary is controlled gate-wise on either route.
Returns:
-
BlockEncoding–BlockEncoding of the joint generator (implementation
-
BlockEncoding–"control_diagonal_generator_lcu"; an all-zero diagonal on one -
BlockEncoding–branch degenerates to the other branch alone).
prepare_qsp_evolution ¶
prepare_qsp_evolution(*, tau, epsilon, expansion=None, max_degree=256, max_evaluations=20000, max_bytes=DEFAULT_INPUT_BYTES, limit_name='max_evaluations')
Solve the QSP phases of both parity parts of a Jacobi-Anger expansion within one evaluation limit.
Both parity targets are divided by one common scale
s = max(1, cos bound, sin bound) * (1 + margin), so the parity
passes keep the relative weights of the Jacobi-Anger expansion. Margins
are tried in the registered order and the first one for which both
phase solves converge is kept. Only a phase-convergence failure moves to
the next margin. The allowance covers both parities and every attempted
target margin, including failed solves and both starts of each solve.
Sup-norm and Bessel preprocessing are bounded by degree and known
numerical-array bytes. A supplied expansion is used directly, without
another Bessel selection. This function and jacobi_anger_expansion do
not import Qiskit.
Parameters:
-
tau(float) –Positive effective evolution time
alpha * t. -
epsilon(float) –Truncation tolerance, strictly between 0 and 1.
-
expansion(JacobiAngerExpansion | None, default:None) –Default
None, which computesjacobi_anger_expansion(tau, epsilon, min_degree=2). A supplied expansion must have the sametauandepsilon. -
max_degree(int, default:256) –Default
256. Largest accepted degree. -
max_evaluations(int, default:20000) –Default
20000. Limit on the phase-solver evaluations summed over both parities, both starts of each solve and every attempted margin. -
max_bytes(int, default:DEFAULT_INPUT_BYTES) –Default 10 GB (decimal,
10_000_000_000bytes). Limit on known numerical arrays. -
limit_name(str, default:'max_evaluations') –Default
"max_evaluations". Name of the caller's option that setsmax_evaluations, used in the error messages.
Returns:
-
prepared(QSPPreparedEvolution) –Both phase solutions, the scale and the margins tried.
Raises:
-
ValueError–If
tau <= 0,epsilonis not in(0, 1), the degree exceedsmax_degree, the evaluations are exhausted, or the phases do not converge at any registered margin.
qsp_evolution_error_terms ¶
qsp_evolution_error_terms(prepared, *, evolution_time, child_error_bound)
Return the error terms of a selected QSP evolution without building a circuit.
NWQLib's derivation. Before amplification the combined half block is
B = a (V + E) with a = 1/(2s) and V = exp(-i t A), the
target at effective time tau = alpha t. The polynomial part obeys
||E|| <= tail_c + tail_s + s (resid_c + resid_s), where tail_c
and tail_s are the parity Bessel tail bounds and resid_c and
resid_s the phase-solver residual bounds. The child
encoding represents A only within child_error_bound.
For Hermitian A and A', [GSLW] arXiv:1806.01838v1, Lemma 61, gives
||exp(-i t A) - exp(-i t A')|| <= abs(t) ||A - A'||.
That physical-time term is added to e_B = a ||E|| without the factor
a, which is conservative because a <= 1/2. OAA maps B to
3B - 4 B B^dagger B. Expanding around aV gives
||block - (3a - 4a^3) V|| <= 3 e_B (1 + 4a^2) + 12 a e_B^2 + 4 e_B^3,
which is at most 6 e_B + 6 e_B^2 + 4 e_B^3 for a <= 1/2.
error_bound is the raw BlockEncoding bound against
exp(-i t A): the amplitude deficit 1 - (3a - 4a^3) plus that
residual. Code that divides recovered amplitudes by the known
factor 3a - 4a^3 uses compensated_recovery_error_bound, the
residual bound times recovery_scale, instead.
A missing child bound or an unrepresentable Bessel tail makes the
dependent terms None.
Parameters:
-
prepared(QSPPreparedEvolution) –Output of
prepare_qsp_evolution. -
evolution_time(float) –Physical evolution time
t. -
child_error_bound(float | None) –Operator-norm error bound of the child encoding of
A, orNonewhen unknown.
Returns:
-
terms(dict) –amplitude(a),oaa_amplitude_factor(3a - 4a^3),deficit,polynomial_part_error,child_error,oaa_residual_error_bound,recovery_scale,compensated_recovery_error_boundanderror_bound.
build_qsp_evolution_encoding ¶
build_qsp_evolution_encoding(encoding: BlockEncoding, *, evolution_time: float, epsilon: float, require_hermitian_evidence: bool = False, max_work: int = 1000000000, max_bytes: int = DEFAULT_INPUT_BYTES, _prepared: QSPPreparedEvolution | None = None) -> BlockEncoding
Synthesize a block encoding of exp(-i t A) from BE(A).
Follows the proof of [GSLW] arXiv:1806.01838v1, Theorem 58: Jacobi-Anger
parity split
(Lemma 57) at effective time tau = alpha * t, one real-Chebyshev
pass per parity (each a shared ladder over the +-Phi pair), a parity
ancilla combining them with coefficients (1/2, -i/2), and 3-step
OAA (Theorem 28, n = 3) raising the amplitude from a = 1/(2s) to
3a - 4a^3, close to one because s is close to one. The error
terms are derived in qsp_evolution_error_terms.
Parameters:
-
encoding(BlockEncoding) –Block encoding of a Hermitian operator
A(the QSVT eigenvalue calculus assumes Hermitian encoded blocks). -
evolution_time(float) –Evolution time
t > 0. -
epsilon(float) –Jacobi-Anger truncation tolerance for
exp(-i tau x). -
require_hermitian_evidence(bool, default:False) –Require construction metadata declaring both
Aand the encoded block Hermitian. By default, missing evidence is a caller premise, recorded in the output with a warning. Explicitly non-Hermitian inputs are rejected in either mode. This option reads metadata only and never materializes a circuit matrix or applies an operator to a state. -
max_work(int, default:1000000000) –Default
1_000_000_000, the defaultmax_workof the block-encoding builders. Limit on the work of the exact dense syntheses that controlling the two passes makes, and of Qiskit's control of the synthesized gates, in the work units of Exact dense synthesis. A child that holds a denseUnitaryGate, such as adense_dilationencoding, has that unitary synthesized once for each pass, and its adjoint once for each pass of degree two or more, and the parity control unrolls the synthesized gates at every query of the pass. The parity control takes the gate-wise route on every route of the joint generator, because its controlled object is the whole pass. A gate that an earlier control already synthesized, such as a branch of a two-child joint generator, is controlled again outside this count, and LCHS planning counts it. -
max_bytes(int, default:DEFAULT_INPUT_BYTES) –Default 10 GB (decimal,
10_000_000_000bytes). Limit on the working and kept bytes of those syntheses and control steps.
GSLW, arXiv:1806.01838v1, Lemma 61 (p. 53), bounds the change in
evolution by abs(t) * ||A - A_encoded|| when both generators are
Hermitian. The QSVT polynomial calculus also needs a Hermitian encoded
block. For an externally constructed encoding, the caller can record
these separately as target_operator_is_hermitian and
encoded_operator_is_hermitian after establishing them. A dense
numerical check belongs to the source representation and its resource
budget, since a circuit matrix requires space exponential in its width.
Dense Hermitian evidence uses exact entry equality, so even an assembly
roundoff asymmetry is rejected. If the intended target is Hermitian, the
caller can explicitly choose (A + A.conj().T)/2 before encoding.
That changes the supplied target and belongs to the caller's input model.
The check never performs this projection implicitly.
Returns:
-
BlockEncoding–BlockEncoding of
exp(-i t A)with subnormalization 1, ancillas -
BlockEncoding–num_ancillas + 3(parity, pair, signal + block ancillas), the -
BlockEncoding–documented
error_bound, and full synthesis metadata (degrees, -
BlockEncoding–recorded tail slack, rescale, solver residuals, amplitude deficit,
-
BlockEncoding–raw OAA residual bound, compensated-recovery scale and bound, and
-
BlockEncoding–query counts).
Inverse polynomials¶
Certified 1/x polynomial construction for QSVT matrix inversion.
QLS polynomial selection builds an
odd polynomial P approximating 1/(kappa x) on the domain
D(a) = {x : a <= |x| <= 1} with a = 1/kappa: odd-Chebyshev least
squares on domain-restricted Chebyshev nodes, degree found by
double-then-bisect against an affine Chebyshev-grid norming bound on
max_D |kappa * x * P(x) - 1| <= epsilon_inv. The fit procedure is
NWQLib's own construction.
The domain parameter kappa must exceed 1. QLS passes its
polynomial_kappa, the encoding's kappa_be raised to at least
QLS_POLYNOMIAL_KAPPA_FLOOR = 1.01 so that a perfectly conditioned A
still gives a domain with a < 1. kappa_be is
max(1, alpha / sigma_min(A)) for kappa="auto" and otherwise the
supplied kappa, which must cover that value. With kappa="auto", the
analytic periodic encoding passes alpha / min(sigma_min, encoded gap),
rounded outward (QLS periodic encoding). Every kappa below is
that domain parameter.
Two choices make the polynomial usable by QSVT and by physical recovery.
The target 1/(kappa x) has magnitude at most one on D, so P
needs only a small rescale into the QSP amplitude domain. The criterion is
a relative residual. For each eigenvalue (Hermitian A) or singular value
(general A, through its odd singular-value transform) s of
A/alpha in D, |P(s) - 1/(kappa s)| <= epsilon_inv / (kappa |s|).
Summing over components, the transformed vector y of b satisfies
||y - (kappa A/alpha)^{-1} b|| <= epsilon_inv ||(kappa A/alpha)^{-1} b||.
Childs, Kothari, and Somma [CKS], arXiv:1511.02306v2, and Sunderhauf,
Nemeth, Walayat, Patterson, and Berntson [SNWPB], arXiv:2507.15537v1,
instead bound the absolute error |p(x) - 1/x|. Equation, lemma and
section numbers refer to these arXiv versions.
InverseChebyshevFit ¶
InverseChebyshevFit(*, coefficients: tuple[float, ...], degree: int, kappa: float, epsilon_inv: float, certificate: float, certificate_grid_points: int, lsq_node_count: int)
Certified odd-Chebyshev fit of 1/(kappa * x) on D(1/kappa).
QLS polynomial selection produces it, and its coefficients define the
polynomial P. The fields below are read-only.
Attributes:
-
coefficients(tuple[float, ...]) –Full Chebyshev coefficient vector
(c_0..c_d)of the fittedP; even entries are exactly zero. -
degree(int) –Selected odd degree
dfrom the bounded search. -
kappa(float) –Domain parameter, greater than 1, defining the domain
D = {1/kappa <= |x| <= 1}. QLS passes itspolynomial_kappa. -
epsilon_inv(float) –Requested certificate tolerance.
-
certificate(float) –Chebyshev-grid norming upper bound on
max_D |kappa * x * P(x) - 1|, evaluated in binary64, not interval arithmetic. -
certificate_grid_points(int) –Affine Chebyshev-grid size behind the bound.
-
lsq_node_count(int) –Least-squares node count of the accepted fit.
Dalzell kernel reflection¶
Kernel-reflection polynomial of Dalzell's shortcut quantum linear solver.
Dalzell, "A shortcut to an optimal quantum linear system solver",
arXiv:2406.12086v2. Equation and page numbers refer to that version. Algorithm 1
(p. 5) applies kernel reflection (KR) to |e_n> through QSVT on the
augmented matrix G_t of Eq. (11). KR uses the even degree-2 ell
polynomial K of App. B.3, Eq. (62), built from the filter F of
App. B.2, Eq. (52), with Delta = 1/kappa and ell from Eq. (6).
Lemma 3 gives K(0) = 1 and |K| <= 1 on [-1, 1], and p. 4
states -1 <= K(x) <= -1 + 4 eta/(1 + eta) for 1/kappa <= x <= 1.
Lemma 3, item 2, prints this upper bound for |K(x)|, which cannot hold
for eta < 1/3 because the bound is then negative. The proof, through
Eq. (63), bounds K(x) itself. That signed bound is the statement of
p. 4 and the one behind Eqs. (5) and (17). The circuit and host-model
users are the QLS Method's circuit and its numerical model.
KernelReflectionPolynomial ¶
KernelReflectionPolynomial(*, coefficients: tuple[float, ...], kr_ell: int, kappa_be: float, kr_eta: float)
Kernel-reflection polynomial K of Dalzell arXiv:2406.12086v2, App. B.3, Eq. (62).
plan_kernel_reflection
returns a coefficient-free plan, and QLS fills in the coefficients. The
domain gap is Delta = 1/kappa_be. The fields below are read-only.
Attributes:
-
coefficients(tuple[float, ...]) –Chebyshev coefficients of the even kernel-reflection polynomial; empty for a coefficient-free sizing plan.
-
kr_ell(int) –Integer half-degree from Dalzell arXiv:2406.12086v2, Eq. 6.
-
kappa_be(float) –Reciprocal of the gap
Delta = 1/kappa_be, a lower bound on the nonzero singular values of the normalized input. It is not a matrix condition number. QLS passes its polynomial domain parameter, which is at least its encoded gap parameter,alpha/sigma_min(A)or the caller's bound on it (thekappasetting ofQLS). That parameter can exceedsigma_max(A)/sigma_min(A)(QLS guide). -
kr_eta(float) –Kernel-reflection approximation parameter in
(0, 1].
dalzell_eta_from_precision ¶
dalzell_eta_from_precision(epsilon_inv: float) -> float
Return the known-norm shortcut choice eta = eps / sqrt(2).
Dalzell (arXiv:2406.12086v2, pp. 5-6, before Eq. (22)) chooses this
kernel-reflection
parameter for the norm estimate equal to the solution norm,
t = ||x||. Eq. (20) bounds the output trace distance by
eta / cos(theta_t), and cos(theta_t) = 1/sqrt(2) at that t,
so the bound equals eps. The shortcut solvers use this eta for
every numeric t. For t != ||x|| the same bound is
eta / cos(theta_t) with theta_t = arctan(||x||/t) (Eq. (7)).
plan_kernel_reflection ¶
plan_kernel_reflection(kappa_be: float, eta: float) -> KernelReflectionPolynomial
Return the coefficient-free sizing plan with the half-degree of Dalzell arXiv:2406.12086v2, Eq. 6.
kr_ell = ceil(kappa_be * ln(2 / eta) / 2). This is the upper bound
in Dalzell arXiv:2406.12086v2, Eq. (51), with Delta = 1/kappa_be, so
it satisfies the
degree condition under which Lemma 3 holds with the filter value
F(Delta) <= eta.
Parameters:
-
kappa_be(float) –Reciprocal of the gap
Delta, greater than 1. -
eta(float) –Kernel-reflection approximation parameter, in
(0, 1].
Returns:
-
plan(KernelReflectionPolynomial) –Empty
coefficients, the half-degreekr_ellabove, and the arguments askappa_beandkr_eta. The polynomial degree is2*kr_ell.
Raises:
-
ValueError–If
kappa_be <= 1, or ifetais not in(0, 1].
Assumptions and limits of the evolution builders¶
Hermitian assumption of build_qsp_evolution_encoding:
- It requires Hermitian target and encoded generators. These two assumptions support the QSVT polynomial calculus and the perturbation bound of GSLW, arXiv:1806.01838v1, Lemma 61, p. 53.
- The check reads existing construction metadata. Real Pauli coefficients and conjugate-paired periodic shifts establish the assumption from their stored terms.
- For an external encoding with missing evidence, the default assumes that the caller has checked both operators, issues a warning and records
hermitian_premise="caller_assumption". The numerical error bound is then conditional on that assumption.require_hermitian_evidence=Trueinstead requires both metadata entries. An explicit non-Hermitian entry is rejected in either mode. - The check does not expand a circuit or apply an operator. A dense complex128 matrix needs
16 * 4**nbytes, which is 16 TiB at 20 system qubits and 16 PiB at 25, before ancillas or temporary arrays, so an optional numerical check of an external operator belongs to the caller's representation and resource budget. A declaration for the target alone does not establish that an approximate encoded block is Hermitian.
Synthesis limits of the controlled passes and branches:
- Controlling a parity pass of
build_qsp_evolution_encoding, or a branch ofbuild_control_diagonal_generator_encoding, synthesizes each denseUnitaryGatethat it holds exactly, such as the unitary of adense_dilationchild. On the gate-wise route, which the parity control of a pass always takes, Qiskit then controls the synthesized gates at every occurrence. - Both builders take
max_work(default 1,000,000,000) andmax_bytes(default 10,000,000,000), and they check the work and bytes of those syntheses and of Qiskit's control of them before the first synthesis (checks of the exact synthesis). build_control_diagonal_generator_encodingtakesdense_control_route, whose default"auto"synthesizes adense_dilationchild together with the combine qubit's control and controls the branch's diagonal rotation gate-wise (dense control route). The parity control of a pass is gate-wise on every route.- A gate that an earlier control already synthesized or unrolled, such as a branch of a two-child joint generator, is controlled again by each pass outside this count, and LCHS planning counts that control.
Missing error bounds:
- When a mathematically nonzero analytic tail is unrepresentable in binary64, the expansion's tail bounds and slack are
None. Circuit construction remains available. ItsBlockEncoding.error_boundand dependent OAA error claims areNone, while the known normalization, recovery scale and query counts remain available. - A missing child error bound propagates only to claims that depend on that child.
- NaN, infinity and negative physical error inputs are invalid, not missing bounds.
Source map¶
The evolution steps follow Gilyén, Su, Low and Wiebe, arXiv:1806.01838v1. The QLS source map collects the phase-convention, phase-solving, inverse-polynomial and kernel-reflection rows. The Newton step of the phase solver is derived in the docstring of phases._damped_newton, and the engineering constants record the solver sweeps of the evolution targets and the QLS targets.
| Step | Location in arXiv:1806.01838v1 | Code |
|---|---|---|
Jacobi-Anger expansion of cos(tau x) and sin(tau x), parity tails |
Lemma 57, Eqs. (53)-(54) | jacobi_anger_expansion |
| Bessel remainder beyond the analysis terminal | NWQLib power-series bound. Eq. (55) is the sharper real-argument form. | jacobi_anger_expansion |
Parity combination with coefficients (1/2, -i/2) and 3-step OAA |
Proof of Theorem 58, and Theorem 28 with n = 3 |
build_qsp_evolution_encoding |
| Child encoding error in physical time | Lemma 61 | qsp_evolution_error_terms |
| OAA residual and amplitude-deficit bound | NWQLib derivation in the docstring | qsp_evolution_error_terms |
| Reference query scaling | Corollary 60 | jacobi_anger_expansion |