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

Install with:

pip install qsvt-pennylane

Package overview

The package is organised into the following modules:

  • qsvt.polynomials

  • qsvt.approximation

  • qsvt.matrices

  • qsvt.spectral

  • qsvt.design

  • qsvt.templates

  • qsvt.reports

  • qsvt.qsvt

  • qsvt.__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.polynomials

Utilities for working with Chebyshev polynomials and standard coefficient-form polynomials.

chebyshev_t(n, x)

Evaluate the Chebyshev polynomial of the first kind:

\[ T_n(x) = \cos(n \arccos x). \]

Parameters

  • n (int): polynomial degree

  • x (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:

\[ T_3(x) = 4x^3 - 3x. \]

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:

\[ P(x) = c_0 + c_1 x + c_2 x^2 + \dots \]

Parameters

  • coeffs: iterable of coefficients

  • x: 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:

\[ |P(x)| \le \text{bound} \]

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.


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

mode

CLI wrapper label for the selected report command

kind

The chosen report kind, such as sign or inverse

builder

Underlying builder function name

fit_domain

Interval used for fit-error sampling

bounded_domain

Interval used for boundedness sampling

max_error

Maximum sampled absolute error on the fit domain

rms_error

Root-mean-square sampled error on the fit domain

bounded_margin

bound - max_abs_value on the boundedness domain

is_bounded

Whether the sampled values stayed within the bound

xs, target_values, polynomial_values, errors

Fit-domain sample arrays

bounded_xs, bounded_polynomial_values

Bounded-domain sample arrays

coeffs

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:

\[ R(\theta) = \begin{pmatrix} \cos\theta & -\sin\theta \ \sin\theta & \cos\theta \end{pmatrix}. \]

Example

from qsvt.matrices import rotation

R = rotation(0.6)

rotated_diagonal(eigenvalues, theta)

Construct a symmetric matrix with known eigenvalues:

\[ A = R(\theta),\mathrm{diag}(\lambda),R(\theta)^T. \]

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:

\[ A^2 = I. \]

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:

\[ A = V \operatorname{diag}(\lambda) V^\dagger \quad\Rightarrow\quad f(A) = V \operatorname{diag}(f(\lambda)) V^\dagger. \]

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:

\[ \Pi_+ = \frac{I + \mathrm{sgn}(A)}{2}. \]

negative_projector_from_sign(matrix, zero_tol=1e-12)

Construct the negative projector using:

\[ \Pi_- = \frac{I - \mathrm{sgn}(A)}{2}. \]

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.


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, and synthesis_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_succeeded plus synthesis error details when requested by callers

  • encoding 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_succeeded plus synthesis error details when requested by callers

  • encoding 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.