API Reference¶
This page documents the public Python API for the qsvt-pennylane package.
The package provides lightweight utilities for:
polynomial and Chebyshev helpers
bounded polynomial approximation
small Hermitian matrix construction
classical spectral matrix-function calculations
explicit PennyLane QSVT wrappers
QNode-based QSVT execution for finite instances
Install with:
pip install qsvt-pennylane
Package overview¶
The package is organised into the following modules:
qsvt.polynomialsqsvt.approximationqsvt.algorithmsqsvt.block_encodingqsvt.matricesqsvt.hamiltoniansqsvt.pdeqsvt.rescalingqsvt.matrix_functionsqsvt.diagnosticsqsvt.spectralqsvt.designqsvt.templatesqsvt.workflowqsvt.reportsqsvt.resourcesqsvt.benchmarksqsvt.operatorsqsvt.executionqsvt.diagonalqsvt.matrixqsvt.compatibilityqsvt.qsvtcompatibility re-exportsqsvt.__main__
You can either import from submodules directly:
from qsvt.qsvt import qsvt_scalar_output
from qsvt.polynomials import chebyshev_t
or import selected names from the package root:
from qsvt import qsvt_scalar_output, chebyshev_t
For the higher-level polynomial builders and ready-made templates, see:
qsvt.workflow¶
Use design_workflow when you want coefficients, approximation diagnostics,
and a QSVT compatibility report from one call:
from qsvt.workflow import design_workflow
result = design_workflow("sign", gamma=0.25, degree=13)
coeffs = result.coeffs
payload = result.as_report()
resource_payload = result.resource_report(matrix_dimension=4)
The same combined workflow report is available from the CLI:
qsvt design-workflow --kind sign --gamma 0.25 --degree 13 \
--output sign-workflow.json
qsvt.algorithms¶
Use linear_system_workflow for small positive-definite linear-system
experiments that combine inverse-polynomial design, rescaling, solution
estimates, residual diagnostics, and QSVT compatibility metadata:
import numpy as np
from qsvt.algorithms import linear_system_workflow
result = linear_system_workflow(
np.diag([1.0, 2.0]),
np.array([1.0, 1.0]),
degree=20,
attempt_synthesis=False,
)
print(result.polynomial_solution)
print(result.polynomial_residual_norm)
Use linear_system_comparison_workflow when you want the same finite instance
reported as rows for dense solve, conjugate gradients, QSVT-style polynomial
inverse, and the optional PennyLane QSVT matrix check:
from qsvt.algorithms import linear_system_comparison_workflow
comparison = linear_system_comparison_workflow(
np.diag([1.0, 2.0]),
np.array([1.0, 1.0]),
degree=20,
attempt_synthesis=False,
apply_qsvt=False,
)
for row in comparison.as_report()["rows"]:
print(row["solver"], row["residual_norm"])
Compact comparison rows can be written as CSV:
from qsvt.algorithms import write_linear_system_comparison_csv
write_linear_system_comparison_csv(
comparison,
"results/tables/linear_system_comparison_summary.csv",
)
The module also includes simulator-scale physics workflows that wrap existing matrix-function polynomial builders with exact spectral references:
block_encoded_qsvt_workflowground_state_filtering_workflowhamiltonian_simulation_workflowresolvent_workflowspectral_density_workflowspectral_thresholding_workflowthermal_gibbs_workflow
Each returns a frozen dataclass with numerical outputs, diagnostics, and an
as_report() helper.
Use spectral_thresholding_workflow when you want a smooth QSVT-style
interval projector and an exact hard-projector reference:
import numpy as np
from qsvt.algorithms import spectral_thresholding_workflow
matrix = np.diag([-0.8, -0.15, 0.2, 0.75])
state = np.array([0.1, 0.8, 0.5, 0.2])
result = spectral_thresholding_workflow(
matrix,
lower=-0.3,
upper=0.3,
degree=32,
sharpness=18.0,
state=state,
)
print(result.exact_rank)
print(result.polynomial_rank_proxy)
print(result.leakage_outside_interval)
The same workflow is available from the CLI:
qsvt threshold-workflow \
--matrix="-0.8,0,0,0;0,-0.15,0,0;0,0,0.2,0;0,0,0,0.75" \
--lower -0.3 \
--upper 0.3 \
--degree 32 \
--state "0.1,0.8,0.5,0.2"
For workflow-level targets, rescaling conventions, diagnostics, and limitations, see Algorithm notes.
qsvt.block_encoding¶
Use block_encode_matrix when you need an explicit dense finite block encoding
whose top-left block is A / alpha:
import numpy as np
from qsvt.block_encoding import block_encode_matrix, verify_block_encoding
encoding = block_encode_matrix(np.array([[2.0, 0.5], [0.5, 1.0]]))
verification = verify_block_encoding(encoding)
print(verification["block_encoding_verified"])
print(verification["unitary_verified"])
The higher-level block_encoded_qsvt_workflow combines this encoding check
with a small PennyLane QSVT transform for positive Hermitian signal operators.
qsvt.resources¶
Use qsvt_resource_report to compare small QSVT-style workflows by polynomial
degree, coefficient count, QSP phase-count proxy, signal-call proxy, optional
matrix-register width, and compatibility metadata:
from qsvt.resources import qsvt_resource_report
report = qsvt_resource_report(
[0.0, 0.0, 1.0],
matrix_dimension=4,
attempt_synthesis=False,
)
The same report is available from the CLI:
qsvt resource-report --poly "0,0,1" --matrix-dimension 4 --no-synthesis
These are proxy reports for simulator-scale comparison. They do not include block-encoding construction, state preparation, error correction, compilation, or hardware runtime costs.
For interpretation limits and omitted costs, see QSVT resource model.
qsvt.benchmarks¶
Use qsvt.benchmarks to build classical baseline reports that can be compared
with QSVT resource proxies:
import numpy as np
from qsvt.benchmarks import (
conjugate_gradient_benchmark,
dense_linear_solve_benchmark,
)
matrix = np.array([[4.0, 1.0], [1.0, 3.0]])
rhs = np.array([1.0, 2.0])
coeffs = [0.0, 1.0]
dense = dense_linear_solve_benchmark(matrix, rhs, qsvt_coeffs=coeffs)
cg = conjugate_gradient_benchmark(matrix, rhs, qsvt_coeffs=coeffs)
Available baseline helpers include:
dense_eigendecomposition_benchmarkdense_linear_solve_benchmarkconjugate_gradient_benchmarkpolynomial_matrix_function_benchmarkspectral_matrix_function_benchmarkbenchmark_summary_tablewrite_benchmark_summary_csvplot_benchmark_timingsplot_qsvt_proxy_resourceslinear_system_comparison_summary_tablewrite_linear_system_comparison_csv
The same baseline reports are available from the CLI:
qsvt benchmark cg-solve \
--matrix "4,1;1,3" \
--rhs "1,2" \
--qsvt-poly "0,1"
The linear-system comparison workflow is also available from the CLI:
qsvt linear-system-compare \
--matrix "2,0.25;0.25,1.25" \
--rhs "1,-0.5" \
--degree 8 \
--no-synthesis \
--no-qsvt \
--output results/algorithms/linear_system_comparison.json \
--rows-output results/tables/linear_system_comparison_summary.csv
Benchmark reports are classical references and QSVT cost proxies. They are intended to support advantage-oriented comparisons, not to claim end-to-end quantum speedups.
For per-baseline assumptions and cost-model context, see Classical baseline details.
qsvt.polynomials¶
Utilities for working with Chebyshev polynomials and standard coefficient-form polynomials.
chebyshev_t(n, x)¶
Evaluate the Chebyshev polynomial of the first kind:
Parameters
n(int): polynomial degreex(float | np.ndarray): evaluation point(s)
Returns
scalar or NumPy array with the same shape as
x
Example
from qsvt.polynomials import chebyshev_t
value = chebyshev_t(3, 0.5)
print(value) # -1.0
chebyshev_t3(x)¶
Evaluate the cubic Chebyshev polynomial:
Example
from qsvt.polynomials import chebyshev_t3
print(chebyshev_t3(0.5)) # -1.0
print(chebyshev_t3(-0.5)) # 1.0
eval_polynomial(coeffs, x)¶
Evaluate a polynomial with coefficients in ascending order:
Parameters
coeffs: iterable of coefficientsx: scalar or array of inputs
Example
from qsvt.polynomials import eval_polynomial
print(eval_polynomial([0, 0, 1], 0.5)) # 0.25
polynomial_degree(coeffs)¶
Return the effective polynomial degree, ignoring trailing zeros.
polynomial_parity(coeffs)¶
Classify a polynomial as:
"even""odd""mixed""zero"
Example
from qsvt.polynomials import polynomial_parity
print(polynomial_parity([0, 0, 1])) # even
print(polynomial_parity([0, 1])) # odd
is_bounded_on_interval(coeffs, lower=-1.0, upper=1.0, bound=1.0, ...)¶
Numerically check whether:
on a sampled grid over an interval.
This is useful for quick QSVT-style boundedness checks.
normalize_coefficients(coeffs)¶
Clean a coefficient list by zeroing tiny values and removing trailing zeros.
chebyshev_to_monomial(coeffs, domain=(-1.0, 1.0))¶
Convert Chebyshev-basis coefficients to ascending monomial coefficients.
monomial_to_chebyshev(coeffs, domain=(-1.0, 1.0))¶
Convert ascending monomial coefficients to Chebyshev-basis coefficients.
qsvt.approximation¶
Helpers for constructing and evaluating Chebyshev approximations on bounded intervals.
scale_to_chebyshev_domain(x, domain)¶
Map a physical interval [a, b] to [-1, 1].
scale_from_chebyshev_domain(t, domain)¶
Map from [-1, 1] back to [a, b].
chebyshev_fit_function(func, degree, domain=(-1.0, 1.0), num_points=500)¶
Fit a function with a Chebyshev polynomial over a bounded interval.
Returns
Chebyshev-basis coefficients
Example
import numpy as np
from qsvt.approximation import chebyshev_fit_function
coeffs = chebyshev_fit_function(np.sqrt, degree=6, domain=(0.2, 1.0))
chebyshev_eval(coeffs, x, domain=(-1.0, 1.0))¶
Evaluate a Chebyshev approximation on its physical interval.
chebyshev_approximant(coeffs, domain=(-1.0, 1.0))¶
Construct a callable approximation function from Chebyshev coefficients.
Example
import numpy as np
from qsvt.approximation import chebyshev_fit_function, chebyshev_approximant
coeffs = chebyshev_fit_function(np.sqrt, degree=6, domain=(0.2, 1.0))
P = chebyshev_approximant(coeffs, domain=(0.2, 1.0))
print(P(0.5))
max_error(func, approx, domain=(-1.0, 1.0), num_points=1000)¶
Compute the maximum sampled absolute error on a grid.
rms_error(func, approx, domain=(-1.0, 1.0), num_points=1000)¶
Compute the RMS approximation error on a grid.
fit_and_build_approximant(func, degree, domain=(-1.0, 1.0), num_points=500)¶
Convenience function returning both:
approximation coefficients
callable approximation
sample_approximation(func, approx, domain=(-1.0, 1.0), num_points=400)¶
Sample the true function and approximation on a shared grid.
Useful for plotting.
approximation_quality_report(func, approx, domain=(-1.0, 1.0), num_points=1000, bound=1.0, ...)¶
Build a compact sampled report with:
fit error metrics
boundedness margin
target vs polynomial sample arrays
This is the shared reporting helper used by the qsvt.design and
qsvt.templates diagnostics functions.
For JSON serialization, saving, loading, and plotting, see qsvt.reports.
Report fields¶
field |
meaning |
|---|---|
|
CLI wrapper label for the selected report command |
|
The chosen report kind, such as |
|
Underlying builder function name |
|
Interval used for fit-error sampling |
|
Interval used for boundedness sampling |
|
Maximum sampled absolute error on the fit domain |
|
Root-mean-square sampled error on the fit domain |
|
|
|
Whether the sampled values stayed within the bound |
|
Fit-domain sample arrays |
|
Bounded-domain sample arrays |
|
Generated coefficient array |
qsvt.reports¶
Helpers for converting diagnostics reports into reusable artifacts.
report_to_jsonable(report)¶
Convert a diagnostics report containing NumPy arrays/scalars into plain Python
containers that can be passed to json.dumps.
save_report(report, path, indent=2)¶
Write a diagnostics report to JSON.
load_report(path)¶
Load a JSON diagnostics report from disk.
plot_approximation_report(report, ax=None)¶
Plot the sampled target values, polynomial values, and error curve from a diagnostics report.
Returns a Matplotlib (fig, axes) pair.
save_report_plot(report, path, dpi=150)¶
Save a target-vs-polynomial diagnostics plot to an image file.
qsvt.matrices¶
Small matrix constructors for explicit QSVT and spectral demos.
diagonal_matrix(values)¶
Construct a diagonal matrix from a list of entries.
identity(n)¶
Construct the n x n identity matrix.
pauli_x()¶
Return the Pauli-\(X\) matrix.
pauli_z()¶
Return the Pauli-\(Z\) matrix.
rotation(theta)¶
Construct the real 2D rotation matrix:
Here \(\theta\) is the rotation angle in radians.
Example
from qsvt.matrices import rotation
R = rotation(0.6)
rotated_diagonal(eigenvalues, theta)¶
Construct a symmetric matrix with known eigenvalues:
This is useful for generating small Hermitian matrices with non-trivial eigenvectors.
hermitian_from_eigendecomposition(eigenvalues, eigenvectors)¶
Reconstruct a Hermitian matrix from its spectral data.
involutory_diagonal(sign_pattern)¶
Construct a diagonal involutory matrix with entries ±1.
These satisfy:
normalized_vector(values)¶
Return a unit-norm version of a vector.
embed_vector(vec, dimension)¶
Embed a vector into a larger Hilbert space by padding with zeros.
qsvt.spectral¶
Classical matrix-function helpers based on eigendecomposition.
eigh_hermitian(matrix)¶
Compute the eigendecomposition of a Hermitian matrix.
Returns:
eigenvalues
eigenvectors
matrix_from_eigendecomposition(eigenvalues, eigenvectors)¶
Reconstruct a Hermitian matrix from its eigendecomposition.
apply_function_to_hermitian(matrix, func)¶
Apply a scalar function spectrally:
Example
import numpy as np
from qsvt.spectral import apply_function_to_hermitian
A = np.diag([0.2, 0.8])
A2 = apply_function_to_hermitian(A, lambda x: x**2)
apply_polynomial_to_hermitian(matrix, coeffs)¶
Apply a standard coefficient-form polynomial to a Hermitian matrix.
matrix_power_spectral(matrix, power)¶
Compute an integer power spectrally.
matrix_fractional_power(matrix, power, require_nonnegative_spectrum=True)¶
Compute a fractional matrix power via the eigenspectrum.
matrix_square_root(matrix)¶
Compute the principal square root of a positive semidefinite Hermitian matrix.
matrix_sign(matrix, zero_tol=1e-12)¶
Compute the matrix sign function.
spectral_projector_positive(matrix, zero_tol=1e-12)¶
Construct the projector onto the positive-eigenvalue subspace.
spectral_projector_negative(matrix, zero_tol=1e-12)¶
Construct the projector onto the negative-eigenvalue subspace.
positive_projector_from_sign(matrix, zero_tol=1e-12)¶
Construct the positive projector using:
negative_projector_from_sign(matrix, zero_tol=1e-12)¶
Construct the negative projector using:
transformed_eigenvalues(matrix, func)¶
Apply a scalar function directly to the eigenvalues of a Hermitian matrix.
qsvt.qsvt¶
Thin PennyLane-facing wrappers for explicit QSVT calculations.
qsvt_operator(operator, poly, encoding_wires=None, block_encoding="embedding")¶
Construct the PennyLane qml.qsvt(...) operator.
qsvt_unitary(operator, poly, encoding_wires=None, wire_order=None, block_encoding="embedding")¶
Extract the explicit matrix representation of a QSVT transform using qml.matrix(...).
Example
from qsvt.qsvt import qsvt_unitary
U = qsvt_unitary(0.5, [0, 0, 1], encoding_wires=[0])
print(U)
qsvt_top_left_block(operator, poly, ...)¶
For a matrix input, extract the logical top-left block of the full QSVT unitary.
This is the key helper for explicit small-scale examples.
qsvt_scalar_output(x, poly, ...)¶
Apply QSVT to a scalar and return the top-left matrix element.
This is the scalar-QSP-style helper used throughout the introductory notebooks.
Example
from qsvt.qsvt import qsvt_scalar_output
out = qsvt_scalar_output(0.5, [0, 0, 1], encoding_wires=[0])
print(out) # ~0.25
qsvt_scalar_scan(xs, poly, ...)¶
Evaluate scalar QSVT outputs over many scalar inputs.
Useful for plotting QSVT curves against classical polynomial curves.
qsvt_diagonal_transform(diagonal, poly, ...)¶
Apply QSVT to a diagonal matrix and return the transformed diagonal entries.
Example
from qsvt.qsvt import qsvt_diagonal_transform
vals = qsvt_diagonal_transform(
[1.0, 0.7, 0.3, 0.1],
[0, 0, 1],
encoding_wires=[0, 1, 2],
)
print(vals)
qsvt_matrix_transform(operator, poly, ...)¶
Apply QSVT to a small Hermitian matrix and return the logical matrix block.
When real_output=True, this returns the real part of the extracted block.
This is the quantity compared against the classical reference in the standard
real-symmetric report path.
Example
from qsvt.matrices import rotated_diagonal
from qsvt.qsvt import qsvt_matrix_transform
A = rotated_diagonal([0.2, 0.8], theta=0.45)
block = qsvt_matrix_transform(A, [0, 0, 1])
print(block)
apply_qsvt_to_embedded_vector(operator, vector, poly, ...)¶
Embed a logical vector into the enlarged Hilbert space, apply the full QSVT unitary, and extract the logical output.
This is useful for explicit linear-solver-style demonstrations.
execute_qsvt_circuit(operator, poly, state, ...)¶
Execute a finite QSVT circuit through a PennyLane QNode.
This path prepares the supplied logical state in the first amplitudes of the
QNode register, queues qml.qsvt, and measures either:
a statevector plus exact probabilities when
shots=None,sampled probabilities when
shotsis finite.
The result includes execution_kind, resource_summary,
logical_success_probability, and a dense classical polynomial output used
only as a validation reference. The helper does not call qml.matrix
internally.
Example:
import numpy as np
from qsvt.qsvt import execute_qsvt_circuit
A = np.diag([0.2, 0.8])
result = execute_qsvt_circuit(
A,
[0, 0, 1],
[1.0, 0.0],
encoding_wires=[0, 1],
)
print(result.execution_kind)
print(result.logical_success_probability)
print(result.resource_summary["gate_types"])
Use result.as_report() when you need a machine-readable truth contract for
the circuit execution layer.
classical_diagonal_polynomial_transform(diagonal, poly)¶
Apply a polynomial classically to a list of diagonal entries.
compare_qsvt_vs_classical_diagonal(diagonal, poly, ...)¶
Return a comparison dictionary containing:
input values
QSVT outputs
classical outputs
absolute error
This is useful for smoke tests and validation.
compare_qsvt_vs_classical_matrix(operator, poly, ...)¶
Return a comparison dictionary for a Hermitian matrix containing:
input matrix
QSVT real block
QSVT imaginary block
classical spectral polynomial matrix
absolute error
This is useful for validating non-diagonal block-encoded examples.
qsvt_compatibility_report(poly, ...)¶
Check whether polynomial coefficients are structurally suitable for PennyLane QSVT synthesis.
The report includes:
coefficient finiteness
parity classification
sampled boundedness on
[-1, 1]optional PennyLane synthesis status
structured failure reasons such as
mixed_parity,out_of_bounds, andsynthesis_failed
Example:
from qsvt.qsvt import qsvt_compatibility_report
report = qsvt_compatibility_report([0, 0, 1])
print(report["compatible"], report["reasons"])
qsvt_transform_report(diagonal, poly, ...)¶
Build a QSVT-vs-classical report for a diagonal transform.
The report includes:
input values and polynomial coefficients
QSVT output and direct classical output
absolute error, max error, and RMS error
qsvt_succeededplus synthesis error details when requested by callersencoding wires, wire order, block-encoding mode, and dimension metadata
Example:
from qsvt.qsvt import qsvt_transform_report
report = qsvt_transform_report(
[1.0, 0.7, 0.3, 0.1],
[0, 0, 1],
encoding_wires=[0, 1, 2],
)
print(report["max_error"])
qsvt_matrix_transform_report(operator, poly, ...)¶
Build a QSVT-vs-classical report for a non-diagonal Hermitian matrix.
The report includes:
input matrix, eigenvalues, and polynomial coefficients
real and imaginary parts of the extracted QSVT logical block
classical spectral polynomial matrix
P(A)absolute error, max error, RMS error, and Frobenius error
maximum absolute imaginary block entry
qsvt_succeededplus synthesis error details when requested by callersencoding wires, wire order, block-encoding mode, and dimension metadata
Example:
from qsvt.matrices import rotated_diagonal
from qsvt.qsvt import qsvt_matrix_transform_report
A = rotated_diagonal([0.2, 0.8], theta=0.45)
report = qsvt_matrix_transform_report(A, [0, 0, 1])
print(report["max_error"], report["max_imag_abs"])
Minimal example¶
import numpy as np
from qsvt.qsvt import qsvt_scalar_output, qsvt_diagonal_transform
from qsvt.polynomials import chebyshev_t
print(qsvt_scalar_output(0.5, [0, 0, 1], encoding_wires=[0]))
vals = qsvt_diagonal_transform(
[1.0, 0.7, 0.3, 0.1],
[0, 0, 1],
encoding_wires=[0, 1, 2],
)
print(vals)
print(chebyshev_t(3, 0.5))
Notes¶
The package is designed for educational and small-scale explicit use.
Most QSVT examples use
block_encoding="embedding".The API is intentionally lightweight and close to the corresponding notebook logic.
For conceptual background, see the notebooks and THEORY.md.