Skip to content

Inputs and input types

Build the matrix, operator and state arguments of a Problem, and look up the types that Problem and record fields accept. The Supply inputs guide says which Method accepts which representation, and Choose a problem and output lists the Problems.

from nwqlib.operators import operator_input, ingest_pauli, PeriodicStencil
from nwqlib.problems import state_input

A Problem field accepts a NumPy array, a SciPy sparse matrix, a Qiskit SparsePauliOp, a PeriodicStencil or a state vector directly. The functions on this page make the same conversion explicit and return a handle that keeps an immutable copy of the data in its original representation. Passing one handle to several Problems reuses that copy:

import numpy as np
from qiskit.quantum_info import SparsePauliOp
from nwqlib import LinearSystem
from nwqlib.operators import operator_input
from nwqlib.problems import state_input

H = operator_input(SparsePauliOp(["ZI", "XX"], coeffs=[1.0, 0.5]))
print(H.manifest.reference.representation, H.structure, H.basis.dimension)

A = operator_input(np.array([[2.0, 1.0], [1.0, 2.0]]))
b = state_input([3, 4j])
print(A.matvec(np.array([1.0, 1.0])))
print(b.preparation.physical_scale.as_float())

problem = LinearSystem(A=A, b=b)
print(problem.A is A)
pauli hermitian 4
[3. 3.]
5.0
True

The Pauli operator stays a sum of two terms on 2 qubits, the dense matrix maps [1, 1] to [3, 3], and the state keeps its norm 5 beside the normalized direction [0.6, 0.8j] that a circuit prepares.

You have Call You get
A dense matrix: NumPy array, nested lists operator_input(A) or ingest_dense(A) OperatorInput, dense
A SciPy CSR or CSC matrix operator_input(A) or ingest_sparse(A) OperatorInput, kept sparse
A Qiskit SparsePauliOp operator_input(op) OperatorInput, Pauli terms
Pauli labels and coefficients ingest_pauli(terms, num_qubits=q) OperatorInput, Pauli terms
Packed Pauli masks ingest_pauli_masks(x, z, coefficients, num_qubits=q) OperatorInput, Pauli terms
A periodic grid operator with mass, diffusion and potential PeriodicStencil(q, mass, diffusion, potential) Parameters, accepted as a Problem's matrix
Fermionic ladder-operator strings ingest_fermion(terms, num_modes=q), then .fermion_terms().to_pauli(mapping="jw") OperatorInput, fermionic, then Pauli
A double-factorized electronic Hamiltonian ingest_df(T, factors, ...), then .to_pauli() FactorizedHamiltonian, then DFConversion
An XACC Hamiltonian file read_xacc or parse_xacc Qiskit SparsePauliOp
A product of operators FactorizedOperatorProduct((A, B)) The factors, kept separate
A state vector or Qiskit Statevector state_input(v) or ingest_vector(v) StateInput, unnormalized
A state-preparation circuit state_input(circuit) or bind_preparation_circuit(...) StateInput
One pair of amplitudes per qubit ingest_product(rows) StateInput, product state
A computational basis state ingest_occupation(bits, num_qubits=q) StateInput, at most q X gates
Norm and spectral bounds of an operator refine_operator_facts(A, unit=..., scope=..., refinements=(...)) OperatorFactReport

Every function checks the bytes it will keep against max_bytes, default 10 GB (decimal, 10_000_000_000), before it copies data. Input cost controls gives each size formula. Coordinates follow Qiskit, with qubit 0 the rightmost tensor factor and the rightmost character of a Pauli label.

Operators

operator_input

operator_input(value, *, max_bytes=DEFAULT_INPUT_BYTES) -> OperatorInput

Return an OperatorInput for a matrix or operator, keeping its representation.

The call dispatches on the type of value:

Qiskit stores each Pauli word as (-i)**phase times its label, so the coefficient of the canonical I/X/Y/Z label is coeff * (-i)**phase. Qiskit is imported only for a SparsePauliOp argument. Sparse and Pauli input is never converted to a dense matrix.

Parameters:

  • value (object) –

    The matrix or operator.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Byte limit of the dispatched function. Default 10 GB (decimal, 10_000_000_000).

Returns:

Raises:

  • TypeError –

    If value has none of the types above, or a dispatched function rejects its contents.

  • ValueError –

    If the dispatched function rejects value.

Examples:

A NumPy matrix stays dense, and a SparsePauliOp stays a Pauli sum:

>>> import numpy as np
>>> from qiskit.quantum_info import SparsePauliOp
>>> from nwqlib.operators import operator_input
>>> A = operator_input(np.array([[2.0, 1.0], [1.0, 2.0]]))
>>> A.manifest.reference.representation, A.structure
('dense', 'hermitian')
>>> A.matvec(np.array([1.0, 1.0]))
array([3., 3.])
>>> H = operator_input(SparsePauliOp(["ZI", "XX"], coeffs=[1.0, 0.5]))
>>> H.manifest.reference.representation, H.basis.dimension
('pauli', 4)
>>> H.pauli_terms().labels()
(('ZI', (1+0j)), ('XX', (0.5+0j)))

ingest_dense

ingest_dense(matrix, *, max_bytes=DEFAULT_INPUT_BYTES) -> OperatorInput

Return an OperatorInput holding an immutable copy of a square dense matrix.

Integer and real data become float64 and complex data complex128. The matrix is neither padded nor symmetrized. The call scans the O(D**2) entries once, checking that they are finite and whether the stored matrix equals its conjugate transpose exactly. Those checks use O(D**2) temporary storage and no eigensolver.

Parameters:

  • matrix (ndarray | list | tuple) –

    A nonempty square NumPy array, or nested lists or tuples of real or complex numbers.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Limit on the bytes of the stored copy. Default 10 GB (decimal, 10_000_000_000).

Returns:

  • operator ( OperatorInput ) –

    Structure "hermitian" or "general".

Raises:

  • TypeError –

    If matrix is another type or holds booleans, objects or strings.

  • ValueError –

    If matrix is empty, not square, ragged or not finite, or its copy exceeds max_bytes.

ingest_sparse

ingest_sparse(matrix, *, max_bytes=DEFAULT_INPUT_BYTES) -> OperatorInput

Return an OperatorInput holding an immutable copy of a SciPy CSR or CSC matrix, kept sparse.

The matrix must be a csr_matrix, csc_matrix, csr_array or csc_array in canonical form, with sorted indices and no duplicate entries. Canonicalize other storage before the call. The copy keeps the CSR or CSC orientation and index dtype. Checking finiteness and exact equality with the conjugate transpose costs O(nnz + D) work and O(nnz + D) temporary sparse storage. The matrix never becomes dense.

Parameters:

  • matrix (csr_matrix | csc_matrix) –

    A nonempty square canonical CSR or CSC matrix or array of real or complex numbers.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Limit on the stored values, indices and index pointers. Default 10 GB (decimal, 10_000_000_000).

Returns:

  • operator ( OperatorInput ) –

    Structure "hermitian" or "general".

Raises:

  • TypeError –

    If matrix is another type or holds booleans or objects.

  • ValueError –

    If matrix is empty, not square, not canonical or not finite, or its copy exceeds max_bytes.

ingest_pauli

ingest_pauli(terms, *, num_qubits: int, max_bytes=DEFAULT_INPUT_BYTES) -> OperatorInput

Return an OperatorInput for the Pauli sum sum_k c_k P_k given as (label, coefficient) pairs.

Terms with identical labels are summed with stable summation, and only a sum that is exactly zero is removed. No nonzero coefficient is pruned. Because distinct Pauli words are Hermitian and linearly independent, the operator is Hermitian exactly when every summed coefficient is real, and its structure records that test without a tolerance. Labels follow Qiskit order, in which the rightmost character acts on qubit 0. The byte check is that of pauli_table.

Parameters:

  • terms (Iterable[tuple[str, complex]]) –

    Pairs of a label of exactly num_qubits characters from IXYZ and a finite real or complex coefficient.

  • num_qubits (int) –

    Positive number of qubits q.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Byte limit. Default 10 GB (decimal, 10_000_000_000).

Returns:

Raises:

  • ValueError –

    If a label has another length or character, a coefficient is not finite, or the terms exceed max_bytes.

  • TypeError –

    If a coefficient is not a number.

Examples:

Two ZI terms add up to one, with coefficient 1.25:

>>> from nwqlib.operators import ingest_pauli
>>> H = ingest_pauli([("ZI", 1.0), ("XX", 0.5), ("ZI", 0.25)],
...                  num_qubits=2)
>>> H.pauli_terms().labels()
(('ZI', (1.25+0j)), ('XX', (0.5+0j)))
>>> H.structure
'hermitian'

pauli_table

pauli_table(terms, *, num_qubits: int, max_bytes=DEFAULT_INPUT_BYTES) -> PauliTerms

Return the raw Pauli table of (label, coefficient) pairs, keeping duplicates and zeros.

The terms keep their order, repeated labels and zero coefficients. Use ingest_pauli for an operator with identical labels summed. Labels follow Qiskit order, in which the rightmost character acts on qubit 0. The number of terms is checked against max_bytes before they are read, and an iterator of terms is read at most one term past the number that fits (row "Pauli labels" of Input cost controls).

Parameters:

  • terms (Iterable[tuple[str, complex]]) –

    Pairs of a label of exactly num_qubits characters from IXYZ and a finite real or complex coefficient.

  • num_qubits (int) –

    Positive number of qubits q.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Byte limit. Default 10 GB (decimal, 10_000_000_000).

Returns:

  • table ( PauliTerms ) –

    Immutable uint64 x and z masks and complex128 coefficients, one row per term.

Raises:

  • ValueError –

    If a label has another length or character, a coefficient is not finite, or the terms exceed max_bytes.

  • TypeError –

    If a coefficient is not a number.

ingest_pauli_masks

ingest_pauli_masks(x, z, coefficients, *, num_qubits: int, max_bytes=DEFAULT_INPUT_BYTES) -> OperatorInput

Return an OperatorInput from packed Pauli masks and coefficients.

Row k with masks (x, z) denotes the word i**popcount(x & z) X**x Z**z, so a qubit with both bits set carries Y, and its coefficient multiplies that canonical I/X/Y/Z word. Bit b of word w refers to qubit 64*w + b. Identical words are summed as in ingest_pauli, and the result has the same content hash as label input of the same ordered terms. The byte check is the row "Pauli masks" of Input cost controls.

Parameters:

  • x (ndarray) –

    uint64 X masks of shape (R, W), with W = ceil(q/64).

  • z (ndarray) –

    uint64 Z masks of the same shape.

  • coefficients (ndarray) –

    complex128 coefficients of shape (R,), all finite.

  • num_qubits (int) –

    Positive number of qubits q.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Byte limit. Default 10 GB (decimal, 10_000_000_000).

Returns:

Raises:

  • TypeError –

    If an argument is not a NumPy array of the stated dtype.

  • ValueError –

    If the shapes disagree, a bit above qubit q-1 is set, a coefficient is not finite, or the arrays exceed max_bytes.

PeriodicStencil

PeriodicStencil(num_qubits: int, mass: float, diffusion: float, potential: float = 0.0)

Parameters of the periodic operator mass*I + diffusion*(2I - S - S†) + i*potential*Z_0.

S is the cyclic shift S|j> = |j+1 mod 2**q> on a grid of 2**q points, and Z_0 is Pauli Z on qubit 0. For q = 1 both wrap-around edges are kept. With potential = 0 the operator is Hermitian, with spectral endpoints mass and mass + 4*diffusion.

Build it with PeriodicStencil(num_qubits, mass, diffusion, potential) and pass it as a Problem's matrix, for example LinearDynamics(A=...), or to operator_input. Only the four parameters are stored, never a matrix or a Pauli expansion.

Parameters:

  • num_qubits (int) –

    Positive integer q. The grid has 2**q points.

  • mass (float) –

    Nonnegative finite coefficient of the identity.

  • diffusion (float) –

    Nonnegative finite coefficient of 2I - S - S†.

  • potential (float, default: 0.0 ) –

    Finite real coefficient of i*Z_0. Zero gives a Hermitian operator.

Raises:

  • ValueError –

    If num_qubits is not a positive integer, if mass or diffusion is negative, or if a coefficient is not finite.

ingest_periodic_stencil

ingest_periodic_stencil(num_qubits: int, mass, diffusion, potential=0.0, *, max_bytes=DEFAULT_INPUT_BYTES) -> OperatorInput

Return an OperatorInput for mass*I + diffusion*(2I - S - S†) + i*potential*Z_0.

This is the operator of PeriodicStencil on a periodic grid of 2**q points, with the cyclic shift S|j> = |j+1 mod 2**q>. For q = 1 both wrap-around edges are kept. Only the four parameters are stored, so the handle has no matrix, Pauli expansion or matrix-vector access. With potential = 0 the operator is Hermitian, with spectral endpoints mass and mass + 4*diffusion.

Parameters:

  • num_qubits (int) –

    Positive integer q.

  • mass (float) –

    Nonnegative finite coefficient of the identity.

  • diffusion (float) –

    Nonnegative finite coefficient of 2I - S - S†.

  • potential (float, default: 0.0 ) –

    Finite real coefficient of i*Z_0.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Limit on the bytes checked before the parameters are stored. Default 10 GB (decimal, 10_000_000_000).

Returns:

  • operator ( OperatorInput ) –

    Structure "hermitian" when potential is zero, "general" otherwise.

Raises:

  • ValueError –

    If num_qubits is not a positive integer, if mass or diffusion is negative, or if a coefficient is not finite.

OperatorInput

OperatorInput(*args, **kwargs)

An operator ready to use in a Problem: an immutable copy of its data and its metadata.

operator_input and the ingest_* functions return it. Constructing it directly raises TypeError, and its fields cannot be replaced. It keeps the data in the representation it was given (dense, CSR, CSC, Pauli terms, ordered fermionic terms or periodic-stencil parameters) and never converts it to a dense matrix implicitly. Pass it wherever a matrix or operator is accepted, for example Eigenproblem(A=handle). Reusing one handle reuses its stored copy and its content hash.

The methods below read the stored data or apply it classically. Each raises ValueError when the representation does not provide that access, or when the handle was rebuilt by from_record and holds metadata only. The fields below are read-only.

Attributes:

  • manifest (InputManifest) –

    The InputManifest: content hash, representation, basis, stored size, available classical operations and the checks made when the input was accepted.

  • structure (str) –

    "hermitian" or "general", from an exact check with no tolerance. The check is equality of a stored matrix with its conjugate transpose, real coefficients of a Pauli sum, or zero potential of a periodic stencil. Fermionic terms are always "general". A handle rebuilt by from_record may also declare "unitary".

basis

basis

The computational Basis: dimension and coordinate order, qubit 0 rightmost.

reference

reference

The input's reference: content hash, representation and source.

to_record

to_record()

Return a JSON-ready description of this handle without its numerical data.

Returns:

  • record ( dict ) –

    The keys format, manifest and structure. Building it copies and hashes no numerical data.

from_record

from_record(record)

Rebuild a metadata-only handle from a to_record() description.

The handle reports the saved metadata, but every data method raises ValueError, even for operations its manifest lists. Saved Results and Runs restore their numerical inputs separately.

Parameters:

  • record (dict) –

    A description returned by to_record().

Returns:

Raises:

  • ValueError –

    If record is not such a description.

pauli_terms

pauli_terms()

Return the stored Pauli table without expanding it.

The table holds uint64 x and z masks and complex128 coefficients, one row per Pauli word. Its labels() method returns (label, coefficient) pairs in Qiskit order, with the rightmost character acting on qubit 0.

Returns:

  • table ( PauliTerms ) –

    The immutable stored table.

Raises:

  • ValueError –

    If the operator is not a Pauli sum.

dense_array

dense_array()

Return the stored dense matrix as a read-only array, without copying it.

Returns:

  • matrix ( ndarray ) –

    The stored float64 or complex128 matrix.

Raises:

  • ValueError –

    If the operator was not given as a dense matrix. No other representation is converted to dense.

fermion_terms

fermion_terms()

Return the stored ordered fermionic table, without mapping it to qubits.

Returns:

  • table ( FermionTerms ) –

    The immutable stored FermionTerms. Its to_pauli(mapping=...) maps it to a Pauli operator.

Raises:

  • ValueError –

    If the operator is not a fermionic operator.

periodic_stencil

periodic_stencil()

Return the stored PeriodicStencil parameters.

A periodic-stencil operator has no classical matrix-vector action on its handle.

Returns:

Raises:

  • ValueError –

    If the operator is not a periodic stencil.

entry

entry(row: int, column: int)

Return one matrix entry, without converting a sparse matrix to dense.

Parameters:

  • row (int) –

    Row index, 0 <= row < D.

  • column (int) –

    Column index, 0 <= column < D.

Returns:

  • value ( complex ) –

    The stored entry, zero where a sparse matrix stores none.

Raises:

  • ValueError –

    If the operator is not a dense or sparse matrix, or an index is outside the dimension.

sparse_entries

sparse_entries(*, max_bytes=DEFAULT_INPUT_BYTES)

Return the stored (data, indices, indptr) arrays of a CSR or CSC matrix.

The arrays are the stored read-only arrays, in their original CSR or CSC orientation and index dtype. Their stored bytes are checked against max_bytes first. Nothing is converted, traversed or copied.

Parameters:

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Limit on the stored bytes. Default 10 GB (decimal, 10_000_000_000).

Returns:

  • arrays ( tuple[ndarray, ndarray, ndarray] ) –

    The values, indices and index pointers.

Raises:

  • ValueError –

    If the operator is not a CSR or CSC matrix, or its stored bytes exceed max_bytes.

matvec

matvec(vector: ndarray, *, max_bytes=DEFAULT_INPUT_BYTES, max_products=1000000000, limit_name='max_products') -> ndarray

Apply the operator to a vector classically and return A @ vector.

Before it reads the vector, the call checks the bytes of the vector, output and work arrays against max_bytes, and the number of scalar products against max_products. The product count is D**2 for a dense matrix, nnz + D for a sparse one, and for M Pauli terms the grouped-action count on Input cost controls, which includes a possible ordered retry. It is derived from the representation, not measured time. Beyond the stored operator the action keeps O(D) numerical storage, and a Pauli action also bounded coordinate tiles and O(M) grouping metadata.

Parameters:

  • vector (ndarray) –

    One-dimensional float64 or complex128 array of length D with finite entries.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Limit on the checked bytes. Default 10 GB (decimal, 10_000_000_000).

  • max_products (int, default: 1000000000 ) –

    Limit on the scalar products. Default 1_000_000_000 (engineering constants).

  • limit_name (str, default: 'max_products' ) –

    Name of the caller's option that supplies max_products, used in the error message.

Returns:

  • result ( ndarray ) –

    The product A @ vector.

Raises:

  • ValueError –

    If the handle has no classical action (a periodic stencil, fermionic terms or a metadata-only handle), if a Pauli operator acts on more than 64 qubits, if vector has another shape, dtype or a nonfinite entry, or if a limit is exceeded.

Fermionic and factorized operators

ingest_fermion

ingest_fermion(terms, *, num_modes, max_bytes=DEFAULT_INPUT_BYTES)

Return an OperatorInput for a fermionic operator given as ordered ladder strings.

Rows are read as in fermion_table. Only strings with the same complete ordered (mode, action) sequence are summed, and only an exactly zero sum is removed. No anticommutation or normal ordering is applied, so two orderings of one operator stay separate rows, and the structure of the result is "general". Map it to qubits with operator.fermion_terms().to_pauli(mapping="jw").

Parameters:

  • terms (Iterable[tuple[complex, Iterable[tuple[int, int]]]]) –

    Rows of a finite coefficient and its ordered (mode, action) pairs.

  • num_modes (int) –

    Number of modes q.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Byte limit. Default 10 GB (decimal, 10_000_000_000).

Returns:

  • operator ( OperatorInput ) –

    The summed fermionic operator.

Raises:

  • ValueError –

    As for fermion_table.

  • TypeError –

    If a coefficient is not a number.

fermion_table

fermion_table(terms, *, num_modes, max_bytes=DEFAULT_INPUT_BYTES)

Return the raw table of ordered fermionic strings, keeping duplicates, order and zeros.

Each row is (coefficient, ops), where ops lists (mode, action) pairs with the left factor first. Action 0 annihilates and 1 creates, and the rightmost operator acts first. No normal ordering is applied. Use ingest_fermion for an operator with identical strings summed. The table size is checked against max_bytes before data is stored (see Input cost controls). An iterator is read at most one item past the limit, and an over-limit item is rejected before it is stored.

Parameters:

  • terms (Iterable[tuple[complex, Iterable[tuple[int, int]]]]) –

    Rows of a finite coefficient and its ordered (mode, action) pairs.

  • num_modes (int) –

    Number of modes q, a nonnegative int64 value.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Byte limit. Default 10 GB (decimal, 10_000_000_000).

Returns:

Raises:

  • ValueError –

    If a mode is outside 0 <= mode < num_modes, an action is not 0 or 1, a coefficient is not finite, or the table exceeds max_bytes.

  • TypeError –

    If a coefficient is not a number.

FermionTerms

FermionTerms(*args, **kwargs)

Table of M ordered ladder-operator strings with complex coefficients.

Each string is a product of creation and annihilation operators, written with the left factor first. The rightmost operator acts first. No normal ordering is applied. fermion_table and OperatorInput.fermion_terms() return it, and constructing it directly raises TypeError. len(table) is M. The fields below are read-only.

Attributes:

  • num_modes (int) –

    Number of fermionic modes, nonnegative.

  • offsets (ndarray) –

    int64 array of length M+1. String k uses entries offsets[k] to offsets[k+1] - 1 of modes and actions.

  • modes (ndarray) –

    int64 array of length P, the mode of each ladder operator.

  • actions (ndarray) –

    uint8 array of length P. 0 annihilates and 1 creates.

  • coefficients (ndarray) –

    complex128 array of length M.

product

product(other, *, max_bytes=DEFAULT_INPUT_BYTES)

Return the ordered product table, every string of this table times every string of other.

String (i, j) is string i of this table followed by string j of other, with coefficient c_i * d_j. With M and K strings and P_left and P_right ladder entries, the product has M*K strings and K*P_left + M*P_right entries. No term is combined or dropped.

Parameters:

  • other (FermionTerms) –

    Table with the same num_modes.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Byte limit, checked before the product is formed. Default 10 GB (decimal, 10_000_000_000).

Returns:

Raises:

  • ValueError –

    If the mode counts differ, a product coefficient is not finite, or the product exceeds max_bytes.

to_pauli

to_pauli(*, mapping, max_bytes=DEFAULT_INPUT_BYTES)

Map the strings to qubits and return the Pauli operator as an OperatorInput.

Mode j goes to qubit j, with |1> meaning occupied. With mapping="jw" (Jordan–Wigner, with the parity of the lower modes), a_j† = (prod_{k<j} Z_k) (X_j - i Y_j)/2 and a_j = (prod_{k<j} Z_k) (X_j + i Y_j)/2. With mapping="z_free" the parity string is omitted, which gives qubit ladder operators. Every product term is kept until the final sum, which adds identical Pauli words and removes only exact zeros. No coefficient is pruned, and no state is formed. The mapping cost is checked against max_bytes before the first product (see Input cost controls).

Parameters:

  • mapping (str) –

    "jw" or "z_free".

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Byte limit. Default 10 GB (decimal, 10_000_000_000).

Returns:

  • operator ( OperatorInput ) –

    The Pauli operator on num_modes qubits.

Raises:

  • ValueError –

    If mapping is another value, the table has no modes, or the mapping exceeds max_bytes.

ingest_df

ingest_df(shifted_one_body, factors, *, constant_energy, orbital_basis: Basis, energy_unit: Unit, source: InputRef, max_bytes=DEFAULT_INPUT_BYTES) -> FactorizedHamiltonian

Return a FactorizedHamiltonian for E0 I + dΓ(T) + (1/2) sum_l dΓ(V_l diag(w_l) V_l^T)**2.

Here dΓ(A) = sum_{p,q,σ} A[p,q] a†(p,σ) a(q,σ), and T is the one-body coefficient of this polynomial. For an electronic Hamiltonian with one-body integrals h and chemists'-notation two-body integrals g[p,q,r,s] = sum_l B_l[p,q] B_l[r,s], rewriting the two-body term as sum_l dΓ(B_l)**2/2 shifts the one-body coefficient to T[p,s] = h[p,s] - (1/2) sum_q g[p,q,q,s]. Pass that shifted T. No integrals are read, and no molecule is reconstructed.

T must be exactly symmetric. The columns of V need not be orthogonal, and negative or zero weights are allowed. An empty factor tuple gives E0 I + dΓ(T). The arrays are copied after their size, including the copies, checks and hashes, is checked against max_bytes. Call to_pauli on the result for a Pauli operator.

Parameters:

  • shifted_one_body (ndarray) –

    Real n-by-n array T, exactly symmetric.

  • factors (tuple) –

    Tuple of (vectors, weights) pairs of NumPy arrays, vectors of shape (n, r) and weights of shape (r,) with r >= 1.

  • constant_energy (float) –

    E0 in energy_unit, finite.

  • orbital_basis (Basis) –

    Basis of the n spatial orbitals.

  • energy_unit (Unit) –

    A unit with dimension "energy".

  • source (InputRef) –

    Declaration of where the factors came from.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Byte limit. Default 10 GB (decimal, 10_000_000_000).

Returns:

Raises:

  • TypeError –

    If orbital_basis, source or factors has another type, or an array is not real numerical data.

  • ValueError –

    If energy_unit is not an energy unit, a shape disagrees with n, T is not exactly symmetric, a value is not finite, or the arrays exceed max_bytes.

FactorizedHamiltonian

FactorizedHamiltonian(*args, **kwargs)

Hamiltonian E0 I + dΓ(T) + (1/2) sum_l dΓ(B_l)**2, B_l = V_l diag(w_l) V_l^T, kept in factorized form.

dΓ(A) = sum_{p,q,σ} A[p,q] a†(p,σ) a(q,σ). ingest_df returns it, and constructing it directly raises TypeError. It stores immutable copies of T, V and w and builds no Pauli operator until to_pauli is called. The fields below are read-only.

Attributes:

to_pauli

to_pauli(*, max_bytes=DEFAULT_INPUT_BYTES, max_products=1000000000) -> DFConversion

Convert to a Pauli operator by normal ordering and the Jordan–Wigner mapping.

Each square is normal-ordered with the anticommutator, dΓ(B)**2/2 = dΓ(B@B)/2 + (1/2) sum B[p,q] B[r,s] a†(p,σ) a†(r,τ) a(s,τ) a(q,σ). The first term is added to T, and the second is summed over factors as the pair Gram matrix gram[pq, rs] = sum_l B_l[p,q] B_l[r,s] over unordered spatial pairs. Spin orbital (p, σ) is mode 2p + σ (alpha and beta interleaved), mapped to qubits by Jordan–Wigner. The output has n**4 growth in its terms (1 + 8n**2 + 64n**4 rows before summing), and the complete conversion is checked first: its bytes against max_bytes and the n**2*k + r*n**3 + r*(n(n+1)/2)**2 scalar products of the contractions (r factors, k columns in total) against max_products. No decomposition or reference computation runs. The numerical error of the conversion is reported as unknown.

Parameters:

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Byte limit. Default 10 GB (decimal, 10_000_000_000).

  • max_products (int, default: 1000000000 ) –

    Limit on the scalar products of the contractions. Default 1_000_000_000.

Returns:

  • conversion ( DFConversion ) –

    The Pauli operator with its record and work.

Raises:

  • ValueError –

    If a limit is exceeded or the contraction produces a nonfinite coefficient.

  • ArithmeticError –

    If the imaginary parts of the mapped coefficients do not cancel exactly.

DFConversion

DFConversion(operator: OperatorInput, receipt: DFConversionReceipt, work_fact: Fact)

What FactorizedHamiltonian.to_pauli returns: the Pauli operator, its conversion record and its work.

The three fields name one conversion. The fields below are read-only.

Attributes:

  • operator (OperatorInput) –

    The Hermitian Pauli operator, an OperatorInput to pass as a Problem's operator. Reusing it repeats no conversion.

  • receipt (DFConversionReceipt) –

    The DFConversionReceipt with the input and output metadata and the counts.

  • work_fact (Fact) –

    A Fact with quantity planning_work, equal to receipt.work, in work units, the abstract operation count that NWQLib's work limits use. Pass it in the prior_work of a Candidate to count the conversion.

Raises:

  • ValueError –

    If the operator, conversion record and work fact describe different conversions.

DFConversionReceipt

Bases: Record

Record of one FactorizedHamiltonian.to_pauli conversion: its input, output and counts.

DFConversion.receipt holds it. It stores the metadata of both sides, not the factors or the Pauli terms. With n spatial orbitals and at least one factor, the conversion forms 1 + 2n**2 + 4n**4 fermionic strings and 1 + 8n**2 + 64n**4 Pauli rows before identical words are summed. The fields below are read-only.

Attributes:

  • input (DFManifest) –

    The DFManifest of the factorized Hamiltonian.

  • output (InputManifest) –

    The InputManifest of the Hermitian Pauli operator on 2n qubits.

  • construction (Literal[CONSTRUCTION]) –

    Fixed description of the arithmetic, symmetry and mapping: binary64, upper-triangle B and B**2, unordered-pair Gram matrix, shared Hermitian coefficients, Jordan–Wigner.

  • conversion_error (FramedFact) –

    Always unknown, because no independently justified bound of the binary64 contraction error exists. It is stated for the spectral norm of the factorized operator minus the Pauli operator, over the full operator, so it concerns the operator, not the error of an energy computed from it.

  • raw_fermion_rows (Count) –

    Fermionic strings before summing.

  • raw_jw_candidates (Count) –

    Pauli rows before summing.

  • pauli_terms (Count) –

    Pauli terms of the output after summing.

  • items (Count) –

    Cumulative items counted before the output was returned.

  • payload_bytes (Count) –

    Cumulative logical bytes counted before the output was returned, including a per-row share for the JSON of the Plan records that will hold the terms. Not allocator bytes or the output size. Other text, JSON and Python object overhead is not counted.

  • work (Count) –

    Cumulative work units counted before the output was returned, not wall time.

Raises:

  • ValueError –

    When a record is loaded whose output is not the Hermitian Pauli operator on 2n qubits, whose row counts differ from the formulas above, whose counters are below the size of the raw tables, or whose conversion_error is not unknown for that norm.

DFManifest

Bases: Record

Metadata of a FactorizedHamiltonian: data hash, source, orbitals, energy unit and constant.

FactorizedHamiltonian.manifest holds it. The weights w have units of the square root of energy, and the vectors V are dimensionless. The fields below are read-only.

Attributes:

  • payload_digest (ContentID) –

    SHA-256 hash of the stored T, the ordered V and w arrays and their shapes.

  • source (InputRef) –

    The caller's declaration of where the factors came from.

  • orbital_basis (Basis) –

    Basis of the n spatial orbitals.

  • energy_unit (Unit) –

    Energy unit of T, E0 and the Hamiltonian.

  • constant_energy (Float64) –

    E0, which already includes any core or nuclear constant the caller supplied.

  • columns (tuple[Count, ...]) –

    Number of columns of each factor, in order, counting columns with negative or zero weight.

  • dtype (Literal['float64']) –

    Always "float64", for T, V and w.

  • byte_order (Literal['little', 'big']) –

    Byte order of the stored arrays.

  • payload_bytes (Count) –

    Bytes of T, V and w, 8*(n*n + (n+1)*sum(columns)).

  • convention (Literal['E0+dGamma(T)+sum(dGamma(V diag(w) V.T)^2)/2']) –

    The fixed formula E0 + dΓ(T) + sum_l dΓ(V_l diag(w_l) V_l^T)**2 / 2.

Raises:

  • ValueError –

    If energy_unit is not an energy unit, a factor has no columns, or payload_bytes disagrees with the shapes.

reference

reference

The input reference of this Hamiltonian, whose identifier is this record's content hash.

It identifies the stored data and its metadata together, so the declared source cannot stand in for the data. The factor arrays are not read.

FactorizedOperatorProduct

FactorizedOperatorProduct(factors, *, max_bytes=DEFAULT_INPUT_BYTES)

Ordered product A_1 A_2 ... A_k of operator handles, kept as separate factors.

Build it with a nonempty tuple of OperatorInput handles that share one basis, for example FactorizedOperatorProduct((A, B)). The factors are referenced, not copied or read. matvec applies the product to a vector factor by factor, and expand multiplies it out into one operator when the factors share a representation. The fields below are read-only.

Attributes:

Reference the factor handles in order, without reading their data.

Parameters:

  • factors (tuple[OperatorInput, ...]) –

    Nonempty tuple of handles with one shared basis and dimension.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Limit on the bytes of the factor references and dimension metadata. Default 10 GB (decimal, 10_000_000_000).

Raises:

  • ValueError –

    If factors is not a nonempty tuple, the bases differ, or the references exceed max_bytes.

  • TypeError –

    If a factor is not an OperatorInput.

action_requirements

action_requirements()

Return the size of one matvec call as (D, bytes, products), from metadata only.

The bytes are 32*D for the two intermediate vectors alive across a step (the original input may stay referenced) plus each factor's own matvec byte count, which for Pauli factors includes their conversion and tile space. The products are the sum of the factors' scalar-product counts.

Raises:

  • ValueError –

    If a factor has no classical action, or a Pauli factor acts on more than 64 qubits.

matvec

matvec(vector, *, max_bytes=DEFAULT_INPUT_BYTES, max_products=1000000000, limit_name='max_products')

Apply the product to a vector classically, rightmost factor first.

The total bytes and scalar products of all factors, from action_requirements, are checked before the vector is read.

Parameters:

  • vector (ndarray) –

    float64 or complex128 vector of length D.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Byte limit. Default 10 GB (decimal, 10_000_000_000).

  • max_products (int, default: 1000000000 ) –

    Limit on the total scalar products. Default 1_000_000_000.

  • limit_name (str, default: 'max_products' ) –

    Name of the caller's option that supplies max_products, used in the error message.

Returns:

  • result ( ndarray ) –

    A_1 @ (A_2 @ (... @ (A_k @ vector))).

Raises:

  • ValueError –

    If a factor has no classical action, the vector is invalid, or a limit is exceeded.

expansion_requirements

expansion_requirements(*, max_bytes=DEFAULT_INPUT_BYTES, max_products=1000000000)

Check and return the size of expand as (items, bytes, work), before any multiplication.

For sparse factors, the first product A*B has C = sum over stored A[i, k] of row_nnz(B, k) candidate scalar products, with C >= structural nnz >= final nnz of A*B. Each later factor multiplies the previous nnz bound by its largest row nnz. No sparsity-pattern pass is made. A Pauli step multiplies the running M-row product by the next K-row factor and counts the bytes that the Pauli table product checks. The products are checked against max_products and the bytes against max_bytes.

Parameters:

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Byte limit. Default 10 GB (decimal, 10_000_000_000).

  • max_products (int, default: 1000000000 ) –

    Limit on the sparse candidate products. Default 1_000_000_000.

Returns:

  • sizes ( tuple[int, int, int] ) –

    Items, bytes and work of the expansion.

Raises:

  • ValueError –

    If a factor has a declared identifier rather than computed from its data, a factor holds metadata only, the factors do not all share one of the Pauli, fermionic or sparse representations, or a limit is exceeded.

expand

expand(*, max_bytes=DEFAULT_INPUT_BYTES, max_products=1000000000)

Multiply the factors out into one operator of their shared representation.

Pauli, ordered fermionic, and CSR or CSC factors can be expanded. The sizes from expansion_requirements are checked first. Terms are combined only in the final step: identical Pauli words or fermionic strings are summed and exact zeros removed, and a sparse product is returned in canonical form with duplicate entries summed and zeros removed.

Parameters:

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Byte limit. Default 10 GB (decimal, 10_000_000_000).

  • max_products (int, default: 1000000000 ) –

    Limit on the sparse candidate products. Default 1_000_000_000.

Returns:

Raises:

  • ValueError –

    As for expansion_requirements.

ProductManifest

Bases: Record

Metadata of a FactorizedOperatorProduct: its ordered factors, basis and sizes.

Reading it never reads the factors' numerical data. The fields below are read-only.

Attributes:

  • factors (tuple[InputRef, ...]) –

    References of the factors, in product order.

  • basis (Basis) –

    The basis that every factor shares.

  • structure (Literal['general']) –

    Always "general".

  • payload_bytes (Count) –

    Bytes of the factor-reference tuple only.

  • referenced_payload_bytes (Count | None) –

    Sum of the factors' stored bytes, counted once per occurrence, so a repeated factor counts each time. This is not a measurement of deduplicated memory. None when the size of any factor is unknown.

States

state_input

state_input(value, *, max_bytes=DEFAULT_INPUT_BYTES) -> StateInput

Return a StateInput for a state vector, a Qiskit Statevector or a preparation circuit.

The call dispatches on the type of value:

  • a NumPy array, or a list or tuple of numbers, and a Qiskit Statevector: ingest_vector
  • a Qiskit QuantumCircuit: its unitary action on the all-zero state, as in bind_preparation_circuit
  • a StateInput: returned unchanged, with its identifier

A circuit's data is copied without simulation or synthesis and gets a new random identifier on every call. NWQLib computes no content hash of circuit data, so it never asserts that two circuits prepare the same input. If you know they do, pass one reference to bind_preparation_circuit, or reuse one StateInput.

Parameters:

  • value (object) –

    The state or circuit.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Byte limit of the dispatched function. Default 10 GB (decimal, 10_000_000_000).

Returns:

Raises:

  • TypeError –

    If value has none of the types above, or a dispatched function rejects its contents.

  • ValueError –

    If the dispatched function rejects value.

Examples:

The vector [3, 4j] has norm 5 and is prepared from the direction [0.6, 0.8j]. The stored amplitudes stay unnormalized:

>>> from nwqlib.problems import state_input
>>> b = state_input([3, 4j])
>>> b.preparation.physical_scale.as_float()
5.0
>>> b.physical_vector()
array([3.+0.j, 0.+4.j])
>>> b.preparation.implementation
'qiskit.direct'

ingest_vector

ingest_vector(vector, *, max_bytes=DEFAULT_INPUT_BYTES) -> StateInput

Return a StateInput for a physical state vector, kept unnormalized.

Integer and real data become float64 and complex data complex128. A nonzero vector is normalized once, by a numerically stable BLAS norm, and both the physical amplitudes and the normalized direction are kept (O(D) storage). The norm is preparation.physical_scale. A zero vector is accepted but has no quantum preparation. A quantum preparation needs a power-of-two dimension of at least 2. A vector of another length keeps its length, and a Method that supports it handles any padding. Saving the metadata and preparing a circuit normalize nothing again.

Parameters:

  • vector (ndarray | list | tuple) –

    One-dimensional real or complex numbers, finite and nonempty.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Limit on the bytes of the stored amplitudes and direction. Default 10 GB (decimal, 10_000_000_000).

Returns:

  • state ( StateInput ) –

    Its preparation is "qiskit.direct", or none with a blocker for a zero vector or an unsupported dimension.

Raises:

  • TypeError –

    If vector is another type or holds booleans, objects or strings.

  • ValueError –

    If vector is empty, not one-dimensional or not finite, or exceeds max_bytes.

ingest_product

ingest_product(amplitudes, *, max_bytes=DEFAULT_INPUT_BYTES) -> StateInput

Return a StateInput for a product state given as one pair of amplitudes per qubit.

Row j of the (q, 2) array belongs to qubit j, so the state is row_{q-1} ⊗ ... ⊗ row_0. Factors need not have unit norm, and their complex and global phases are kept. Each row is normalized separately, and the norm is the product of the row norms. No 2**q vector is formed. A row of zeros gives a zero state, which has no quantum preparation.

Parameters:

  • amplitudes (ndarray | list | tuple) –

    Real or complex array of shape (q, 2) with q >= 1.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Byte limit. Default 10 GB (decimal, 10_000_000_000).

Returns:

  • state ( StateInput ) –

    Its preparation is "qiskit.product", one single-qubit preparation per qubit.

Raises:

  • TypeError –

    If amplitudes is another type or holds non-numbers.

  • ValueError –

    If the shape is not (q, 2), a value is not finite, or the data exceed max_bytes.

ingest_occupation

ingest_occupation(occupations, *, num_qubits: int, max_bytes=DEFAULT_INPUT_BYTES) -> StateInput

Return a StateInput for a computational basis state given as one bit per qubit, qubit 0 first.

The string "10" means qubit 0 is 1 and qubit 1 is 0: computational index 1, printed as the ket |01>. The width and the exact 0 or 1 values are checked before any circuit is built. No electron number, spin or symmetry sector is inferred from the bits.

Parameters:

  • occupations (str | list | tuple) –

    Exactly num_qubits bits, 0 or 1.

  • num_qubits (int) –

    Positive number of qubits q.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Byte limit. Default 10 GB (decimal, 10_000_000_000).

Returns:

  • state ( StateInput ) –

    Its preparation is "qiskit.occupation", at most q X gates.

Raises:

  • ValueError –

    If num_qubits is not a positive integer, the length differs, a value is not 0 or 1, or the bits exceed max_bytes.

bind_preparation_circuit

bind_preparation_circuit(circuit, *, reference: InputRef, basis: Basis, max_bytes=DEFAULT_INPUT_BYTES) -> StateInput

Return a StateInput for the state U|0...0> of a Qiskit circuit, under an identifier you choose.

NWQLib computes no content hash of circuit data, so reference is a declared identifier. Pass one reference for circuits you know prepare the same input. The call copies the circuit's stored data, keeps its global phase and checks that it has a supported unitary structure. It does not simulate or synthesize the circuit, measure a norm or expose amplitudes. The unit norm is the circuit's unitarity, an assumption rather than a measurement. The byte check counts the copied data with fixed per-object allowances, not the Qiskit synthesis or allocator overhead.

Parameters:

  • circuit (QuantumCircuit) –

    Unitary circuit without classical bits or free parameters.

  • reference (InputRef) –

    An InputRef with representation="circuit".

  • basis (Basis) –

    Basis of dimension 2**circuit.num_qubits.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Byte limit of the copy. Default 10 GB (decimal, 10_000_000_000).

Returns:

  • state ( StateInput ) –

    Its preparation is "qiskit.supplied".

Raises:

  • TypeError –

    If circuit is not a QuantumCircuit.

  • ValueError –

    If reference or basis does not fit the circuit, the circuit has classical bits, free parameters or an unsupported operation, or the copy exceeds max_bytes.

StateInput

StateInput(*args, **kwargs)

A state ready to use in a Problem: its physical data, norm and preparation.

state_input and the ingest_* functions of nwqlib.problems return it. Constructing it directly raises TypeError, and its fields cannot be replaced. It keeps the physical amplitudes, unnormalized, or a compact form (product factors, occupation bits or a supplied circuit), together with the normalized direction that a preparation uses. Pass it wherever a state is accepted, for example LinearSystem(b=state).

The data methods raise ValueError for a handle rebuilt by from_record, which holds metadata only. The fields below are read-only.

Attributes:

basis

basis

The computational Basis: dimension and coordinate order, qubit 0 rightmost.

reference

reference

The input's reference: content hash or declared identifier, representation and source.

to_record

to_record()

Return a JSON-ready description of this handle without its numerical data.

Returns:

  • record ( dict ) –

    The keys format, manifest and preparation. Building it copies and normalizes no numerical data.

from_record

from_record(record)

Rebuild a metadata-only handle from a to_record() description.

Its data methods raise ValueError, and no circuit can be prepared from it. Saved Results and Runs restore their numerical inputs separately.

Parameters:

  • record (dict) –

    A description returned by to_record().

Returns:

  • handle ( StateInput ) –

    A handle without numerical data.

Raises:

  • ValueError –

    If record is not such a description, or its preparation names another input or basis.

entry

entry(index: int)

Return one physical amplitude of a vector input.

Parameters:

  • index (int) –

    Coordinate index, 0 <= index < D.

Returns:

  • amplitude ( complex ) –

    The stored, unnormalized amplitude.

Raises:

  • ValueError –

    If the input is not a vector, for example a product or occupation state, which is never expanded, or the index is outside the dimension.

physical_vector

physical_vector()

Return the stored physical amplitudes of a vector input, unnormalized and read-only.

Returns:

  • vector ( ndarray ) –

    The float64 or complex128 amplitudes.

Raises:

  • ValueError –

    If the input is not a vector. A product or occupation state is never expanded.

StatePreparationSpec

Bases: Record

How a state can be prepared on qubits, recorded without building a circuit.

StateInput.preparation holds it, and prepare_qiskit builds the circuit it describes. The circuit prepares the input divided by its positive norm, so a negative or complex global phase is kept. Inverse and control availability refer to that unitary construction. The fields below are read-only.

Attributes:

  • input (InputRef) –

    Reference of the state input.

  • basis (Basis) –

    Its computational basis and coordinate order.

  • physical_scale (PhysicalScale | None) –

    Norm of the input as a PhysicalScale, or None when unknown.

  • normalization (Literal['physical input; prepare input divided by positive norm']) –

    The fixed convention that the circuit prepares the input divided by its positive norm.

  • required_ancillas (Count | None) –

    Extra qubits the construction needs, 0 for every built-in construction, None (the default) when unknown.

  • inverse_available (bool) –

    Whether the circuit may be inverted.

  • control_available (bool) –

    Whether the circuit may be controlled.

  • implementation (Literal['qiskit.direct', 'qiskit.product', 'qiskit.occupation', 'qiskit.supplied', 'qiskit.mps_circuit'] | None) –

    The construction, or None when no quantum preparation exists: "qiskit.direct" (magnitude and phase synthesis of a vector), "qiskit.product" (one single-qubit preparation per qubit), "qiskit.occupation" (X gates), "qiskit.supplied" (a supplied circuit) or "qiskit.mps_circuit" (a layered matrix-product-state circuit).

  • approximation (Text | None) –

    Statement of the algorithmic approximation, or None (the default) when unknown. The preparations of vector, product and occupation inputs make none and do not bound their floating-point synthesis error. A "qiskit.mps_circuit" preparation is an approximation whose circuit fidelity is not evaluated.

  • work_law (Text) –

    Text form of the construction's cost.

  • items (Count | None) –

    Stored items the construction reads: amplitudes, qubit factors, occupation bits or circuit instructions.

  • payload_bytes (Count | None) –

    Logical bytes of the construction: the item bytes of the input, which prepare_qiskit checks, or the layered construction bound for "qiskit.mps_circuit".

  • work (Count | None) –

    Construction size: q*2**q for a direct vector, q for product or occupation input, the instruction count of a supplied circuit, or the layered construction bound for "qiskit.mps_circuit".

  • blocker (Text | None) –

    Why no preparation exists, or None.

Raises:

  • ValueError –

    If a specification without implementation lacks a blocker or claims inverse or control, or a specification with one has a blocker, a zero or missing norm, ancillas other than 0, or unknown size fields.

prepare_qiskit

prepare_qiskit(state: StateInput, *, max_bytes=DEFAULT_INPUT_BYTES, max_direct_amplitudes=DEFAULT_MAX_DIRECT_AMPLITUDES) -> QiskitPreparation

Build the Qiskit circuit that prepares a StateInput, without running it.

The circuit prepares the normalized direction stored with the input, so its global phase is kept. It may be composed, inverted or made into a controlled gate. Nothing is submitted, transpiled or simulated. Direct synthesis of a vector takes O(q*2**q) arithmetic even when the data fit in memory, so its amplitude count is limited by max_direct_amplitudes. That limit does not apply to product, occupation or supplied-circuit preparations. For a supplied circuit the call returns a new copy of the stored circuit on every call, so extending the returned circuit in place leaves the stored one unchanged. Inside a Run, preparation uses ExecutionLimits.max_direct_amplitudes instead, checked for the whole Plan before the first preparation.

Parameters:

  • state (StateInput) –

    A state with an available preparation.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Limit on the bytes of the preparation data. Default 10 GB (decimal, 10_000_000_000).

  • max_direct_amplitudes (int, default: DEFAULT_MAX_DIRECT_AMPLITUDES ) –

    Largest vector dimension for direct synthesis. Default 65_536 = 2**16, that is 16 qubits (engineering constants).

Returns:

Raises:

  • ValueError –

    If the state has no preparation (the error gives the blocker, for example a zero vector), holds metadata only, or exceeds max_direct_amplitudes or max_bytes.

QiskitPreparation

QiskitPreparation(spec: StatePreparationSpec, circuit: object)

What prepare_qiskit returns: the preparation circuit and its specification.

The circuit has not been run. The fields below are read-only.

Attributes:

  • spec (StatePreparationSpec) –

    The StatePreparationSpec the circuit was built from.

  • circuit (object) –

    The Qiskit QuantumCircuit, a unitary that may be inverted or controlled. It is a new copy, which the caller may extend.

PhysicalScale

Bases: Record

A nonnegative norm stored as mantissa * 2**exponent, so that it can lie outside the float64 range.

It holds the norm itself, not its square. Input states keep their norm in StateInput.preparation.physical_scale, and Method records keep scale factors in it. A product of factors stays representable even when its float64 value would overflow or underflow. Each scale has one representation. A nonzero scale has 0.5 <= mantissa < 1, as math.frexp returns, zero is (0, 0), and the unit norm is (0.5, 1). The values are floating-point results, not certified exact arithmetic. The fields below are read-only.

Attributes:

  • mantissa (Real) –

    Binary mantissa, 0 or in [0.5, 1).

  • exponent (StrictInt) –

    Power of two, 0 for a zero scale.

  • evidence (Literal['floating_point_norm', 'composed_floating_point_recovery', 'supplied_unitary_contract']) –

    Default "floating_point_norm", a computed norm. "composed_floating_point_recovery" is a product of a Method's factors, and "supplied_unitary_contract" is the unit norm that a supplied preparation circuit promises, which is an assumption, not a measured norm.

Raises:

  • ValueError –

    If the mantissa and exponent are not in the form above, or "supplied_unitary_contract" has a scale other than (0.5, 1).

as_float

as_float() -> float | None

Return the norm as a float, or None when it overflows or a nonzero norm underflows to zero.

squared_as_float

squared_as_float() -> float | None

Return the squared norm as a float, or None when it overflows or a nonzero value underflows to zero.

Operator bounds

refine_operator_facts

refine_operator_facts(operator, *, unit: Unit, scope: Scope, max_bytes=DEFAULT_INPUT_BYTES, refinements: tuple[Refinement, ...] = (), previous: OperatorFactReport | None = None) -> OperatorFactReport

Compute exact bounds on an operator's norm and spectrum, and return them in a report.

Only the computations named in refinements run:

  • "certify_pauli_l1", for a Hermitian Pauli operator H = c_I I + sum_{P != I} c_P P. Every Pauli word has spectral norm one, so the triangle inequality gives ||H|| <= sum_P |c_P| and puts the spectrum in [c_I - sum_{P != I} |c_P|, c_I + sum_{P != I} |c_P|]. It also reads c_I and bounds ||H - c_I I|| by sum_{P != I} |c_P|.
  • "certify_sparse_rows", for a Hermitian CSR or CSC matrix A. By the Gershgorin circle theorem every eigenvalue lies in some interval [a_ii - R_i, a_ii + R_i] with R_i = sum_{j != i} |a_ij|. For a Hermitian matrix the spectral norm equals the spectral radius, which is at most the largest absolute row sum. The diagonal of an exactly Hermitian matrix is real, and |Re a| + |Im a| >= |a| keeps the radius rational.

The sums use exact fractions of the stored binary64 values, so the bounds hold for the stored operator without rounding error. They bound the operator, not the total error of a computed result. No matrix-vector product, eigensolver, backend or dense conversion runs. With empty refinements the report is built from metadata only. Passing previous keeps its bounds and records, and a computation run again gets a new record.

Parameters:

  • operator (OperatorInput) –

    The operator.

  • unit (Unit) –

    Unit of the operator's values.

  • scope (Scope) –

    Scope of the bounds.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Limit on the bytes read and the exact integers kept alive, checked before each computation. Default 10 GB (decimal, 10_000_000_000).

  • refinements (tuple[str, ...], default: () ) –

    Distinct computations to run, each available for this operator. Default ().

  • previous (OperatorFactReport | None, default: None ) –

    A report from an earlier call with the same operator, unit and scope.

Returns:

  • report ( OperatorFactReport ) –

    The bounds and the records of every computation behind them.

Raises:

  • TypeError –

    If operator is not an OperatorInput or previous is not an OperatorFactReport.

  • ValueError –

    If a computation is unavailable for this operator or repeated in refinements, previous belongs to another operator, unit or scope, or max_bytes is exceeded.

OperatorFactReport

Bases: Record

Exact norm and spectral bounds of an operator, with the computations that produced them.

refine_operator_facts returns it. Building or loading a report reads no numerical data. Each entry of facts is a FramedFact for one of these quantities of the full operator H, in its unit:

  • operator_norm_upper_bound: an upper bound on the spectral norm of H
  • identity_coefficient: the coefficient c_I of the identity, read exactly
  • centered_norm_upper_bound: an upper bound on the spectral norm of H - c_I I
  • eigenvalue_lower_bound and eigenvalue_upper_bound: an interval containing every eigenvalue of H

A quantity is unknown until a computation produces it. A computed identity coefficient is an exact read of the stored data (evidence kind proved_relation), and the other quantities are certified bounds (certified_bound). The fields below are read-only.

Attributes:

  • manifest (InputManifest) –

    Manifest of the operator the bounds describe.

  • unit (Unit) –

    Unit of the operator's values.

  • scope (Scope) –

    Scope of the bounds.

  • facts (tuple[FramedFact, ...]) –

    One FramedFact per quantity above.

  • options (tuple[RefinementOption, ...]) –

    Computations available for this operator, empty when none applies.

  • receipts (tuple[RefinementReceipt, ...]) –

    Records of every computation behind this report, in run order. A later computation's values replace an earlier one's for the same quantities.

  • reason (Text | None) –

    Why no computation is available, set exactly when options is empty.

Raises:

  • ValueError –

    If a fact or record belongs to another operator, unit or scope, a norm bound is negative, or the lower eigenvalue bound exceeds the upper one.

RefinementOption

Bases: Record

One bound computation available for an operator, with its cost.

OperatorFactReport.options lists them. The fields below are read-only.

Attributes:

  • operation (Refinement) –

    "certify_pauli_l1" for a Hermitian Pauli operator or "certify_sparse_rows" for a Hermitian CSR or CSC matrix.

  • access (Text) –

    The stored data the computation reads.

  • work_law (Text) –

    Text form of its scalar-operation count.

  • payload_law (Text) –

    Text form of its byte count.

RefinementReceipt

Bases: Record

Record of one bound computation: what it read and how much exact arithmetic it did.

OperatorFactReport.receipts holds one per computation. The byte counts are logical sizes, not process memory, and scalar_operations is a count derived from the data, not measured CPU time. The fields below are read-only.

Attributes:

  • acquisition_id (Text) –

    Random identifier of this computation. Repeating a computation gives a new identifier, so it is never mistaken for the earlier one.

  • manifest (InputManifest) –

    Manifest of the operator that was read.

  • unit (Unit) –

    Unit of the operator's values.

  • scope (Scope) –

    Scope of the resulting bounds.

  • operation (Refinement) –

    The computation that ran.

  • input_entries (Count) –

    Pauli terms or stored entries read.

  • input_bytes (Count) –

    Bytes of the Pauli labels or compressed arrays read.

  • scalar_operations (Count) –

    Exact scalar operations performed.

  • output_bytes (Count) –

    Bytes of the exact numerators and denominators produced.

Input metadata

InputManifest

Bases: Record

Metadata of an accepted operator or state: content hash, representation, basis, size and checks.

OperatorInput.manifest and StateInput.manifest hold it. Reading or saving it never reads the numerical data. access lists the classical operations of the handle only. How a state can be prepared on qubits is recorded separately, in StatePreparationSpec. The fields below are read-only.

Attributes:

  • reference (InputRef) –

    Reference of the input: identifier, representation (for example "dense", "csr", "pauli" or "vector") and source.

  • basis (Basis) –

    Computational basis, dimension and coordinate order.

  • identity_status (Literal['ingested', 'declared']) –

    "ingested" when the identifier is a SHA-256 hash of the stored data with its representation, dtype, shape and order, "declared" when the caller supplied it, as for a preparation circuit.

  • dtype (Text | None) –

    Stored numerical dtype, or None when the input has none.

  • shape (tuple[Count, ...] | None) –

    Stored array or table shape, or None.

  • byte_order (Literal['little', 'big', 'not_applicable'] | None) –

    "little" or "big" for stored numbers, "not_applicable" for one-byte data, or None.

  • payload_bytes (Count | None) –

    Bytes of the stored data, or None when unknown.

  • access (tuple[Literal['matvec', 'entries', 'pauli_terms', 'fermion_terms'], ...]) –

    Classical operations of the handle, among "matvec", "entries", "pauli_terms" and "fermion_terms".

  • checked (tuple[Text, ...]) –

    Properties checked when the input was accepted, such as finite entries or exact equality with the conjugate transpose.

  • work_law (Text) –

    Text form of the cost of accepting and applying this representation.

Input types

Problem and record fields use these types. A field typed OperatorData or StateData accepts the raw forms in the table and stores the handle that operator_input or state_input returns.

Type Accepts
OperatorData A square NumPy array or nested lists, a canonical SciPy CSR or CSC matrix, a Qiskit SparsePauliOp, a PeriodicStencil or an OperatorInput
StateData A vector of numbers, a Qiskit Statevector or QuantumCircuit, or a StateInput
Real A finite float. An int is converted, and -0.0 becomes 0.0
Nonnegative A Real that is 0 or larger
PositiveInt An int larger than 0
Count An int that is 0 or larger
Text A string that is not empty after surrounding whitespace is removed
ContentID A content hash, "sha256:" followed by 64 lowercase hexadecimal digits
Unit, Scope, Source, Basis Records that label a value's unit, its scope, its source and a coordinate basis
Float64, Complex128, Rational Scalar records: a finite binary64 value, a complex pair of them, an exact integer ratio in lowest terms
Symbol, Limit A named mathematical symbol, and a limit on one resource in one workflow stage

None of these types accepts a bool where a number is expected.

OperatorData

OperatorData

Matrix or operator accepted by a Problem or output field, such as Eigenproblem.A.

Pass one of these forms:

  • a square NumPy array, or a nested list or tuple of numbers
  • a SciPy CSR or CSC matrix or array in canonical form
  • a Qiskit SparsePauliOp
  • a PeriodicStencil
  • an OperatorInput from nwqlib.operators.operator_input or an ingest_* function of nwqlib.operators

The field keeps the representation it receives and does not convert sparse or Pauli input to a dense matrix. Accepting the input is limited to 10 GB (decimal) of known bytes. Pass operator_input(value, max_bytes=...) to set another limit. A saved description, a dict with a manifest entry, gives a handle with metadata only, which refuses numerical access. Loading a saved archive restores the data. See Supply operators and states.

StateData

StateData

State or vector accepted by a Problem field, such as Expectation.state or LinearSystem.b.

Pass one of these forms:

  • a NumPy array, or a list or tuple of numbers, with its magnitude and phase
  • a Qiskit Statevector
  • a Qiskit QuantumCircuit without classical bits or free parameters, which means its unitary applied to the all-zero state
  • a StateInput from nwqlib.problems.state_input or an ingest_* function of nwqlib.problems

The field keeps the vector's magnitude and phase. A circuit is copied without simulating or synthesizing it. Accepting the input is limited to 10 GB (decimal) of known bytes. Pass state_input(value, max_bytes=...) to set another limit. A saved description, a dict with a manifest entry, gives a handle with metadata only, which refuses numerical access. Loading a saved archive restores the data. See Supply operators and states.

Real

Real

A finite real number, stored as a binary64 float.

A Python float or int is accepted, and an int becomes a float. Infinity, NaN, bool and strings are rejected. -0.0 becomes 0.0, so equal values give one content hash.

Nonnegative

Nonnegative

A finite real number at least 0, accepted as for Real.

PositiveInt

PositiveInt

A positive Python int.

A float, a bool or a NumPy integer is rejected. Convert it with int(...).

Count

Count

Nonnegative integer field: a Python int that is 0 or larger.

A bool or a float such as 2.0 is rejected, not converted.

Text

Text

A nonempty string.

Surrounding whitespace is removed, and a string that is then empty is rejected. Only a str is accepted, not a number or bytes.

ContentID

ContentID

A content hash: "sha256:" followed by 64 lowercase hexadecimal digits.

Every record has one in its content_id, computed from its type and fields, and a record refers to another, such as a Result to its Plan, by this hash. See Record.

Unit

Bases: Record

A unit label with its dimension. NWQLib converts no units and does no unit algebra.

Build it with keyword arguments, for example Unit(symbol="Hartree", dimension="energy"). Both arguments are required. A Problem's unit also accepts a string, which becomes a Unit of dimension "custom".

Attributes:

  • symbol (Text) –

    Required. The unit's symbol, a nonempty string.

  • dimension (Literal['dimensionless', 'energy', 'time', 'inverse_time', 'angle', 'bytes', 'count', 'currency', 'custom']) –

    Required. "dimensionless", "energy", "time", "inverse_time", "angle", "bytes", "count", "currency" or "custom".

same_unit

same_unit(other: Unit) -> bool

Return whether other has the same symbol and dimension, whatever the revision history of either.

Parameters:

  • other (Unit) –

    The unit to compare with.

Returns:

  • same ( bool ) –

    True when symbol and dimension are equal.

Scope

Bases: Record

The algebraic object, or the declared physical or model domain, that a value refers to.

Build it with keyword arguments, for example Scope(kind="model", domain="1D heat equation on 64 grid points"). domain is required.

Attributes:

  • kind (Literal['algebraic', 'physical', 'model']) –

    Default "algebraic". "algebraic", "physical" or "model".

  • domain (Text) –

    Required. Description of the object or domain.

Source

Bases: Record

The name, version, domain and reference of a piece of code, data or method.

It declares where something came from. It is not evidence that the source was verified. Build it with keyword arguments. All four arguments are required.

Attributes:

  • name (Text) –

    Required. Name of the source.

  • version (Text) –

    Required. Its version.

  • domain (Text) –

    Required. What it applies to.

  • reference (Text) –

    Required. Where to find it, such as a paper identifier, a URL or a function name.

Basis

Bases: Record

The coordinate basis of an input: its name, its dimension and the order of its entries and bits.

A Problem reports the basis of its inputs in basis, and all inputs of one Problem must have the same basis.

Attributes:

  • identity (Text) –

    Required. Name of the basis, such as "computational".

  • dimension (PositiveInt) –

    Required. Number of coordinates, a positive integer.

  • ordering (Text) –

    Required. Order of the entries and bits, for example "coordinate index increasing; qubit 0 is rightmost tensor/bit position".

Float64

Bases: Record

A finite binary64 number, as a record.

Build it with keyword arguments, Float64(value=0.5). Its decimal form is the float's value and does not claim that the number is exact.

Attributes:

  • kind (Literal['float64']) –

    Fixed "float64".

  • value (Real) –

    Required. The number, accepted as for Real.

Complex128

Bases: Record

A complex number with finite binary64 parts, as a record.

A part given as -0.0 is stored as 0.0.

Attributes:

  • kind (Literal['complex128']) –

    Fixed "complex128".

  • real (Real) –

    Required. Real part.

  • imag (Real) –

    Required. Imaginary part.

Rational

Bases: Record

An exact rational number numerator / denominator.

Build it with keyword arguments, for example Rational(numerator=2, denominator=6). Construction reduces it to lowest terms with a positive denominator, here 1/3, so each rational number has one representation and one content hash.

Attributes:

  • kind (Literal['rational']) –

    Fixed "rational".

  • numerator (StrictInt) –

    Required. Integer numerator. After reduction it carries the sign of the number.

  • denominator (StrictInt) –

    Required. Nonzero integer denominator, positive after reduction.

Raises:

  • ValueError –

    If denominator is zero.

Symbol

Bases: Record

A named mathematical symbol and the source that defines it.

It is a name only and is never evaluated as an expression.

Attributes:

  • name (str) –

    Required. A letter followed by letters, digits or underscores.

  • reference (Source) –

    Required. The Source that defines the symbol.

Limit

Bases: Record

A declared limit on one quantity at one stage of the workflow.

Declaring a limit neither approves nor runs any work. kind separates a budget that is used up ("consumption", such as CPU seconds, shots or currency), a capacity that is reused ("capacity_stock", such as memory or stored bytes) and a "deadline", because they combine differently. Use adds up across work, a capacity is compared with a peak, and a deadline bounds the elapsed time. Each metric accepts one unit and one kind, so a limit cannot be read in the wrong sense:

  • cpu_time is a budget and wall_time a deadline, both in Unit(symbol="s", dimension="time").
  • memory and stored are capacities, in Unit(symbol="byte", dimension="bytes").
  • materialization and transfer are budgets, in the same byte unit.
  • evaluations, shots, jobs, host_invocations and host_work are budgets, in Unit(symbol="count", dimension="count").
  • currency is a budget, in any unit of dimension "currency".

Attributes:

  • stage (Stage) –

    Required. Workflow stage the limit applies to: "planning", "preparation", "execution", "analysis" or "verification".

  • metric (Literal['cpu_time', 'wall_time', 'memory', 'materialization', 'stored', 'transfer', 'evaluations', 'shots', 'jobs', 'currency', 'host_invocations', 'host_work']) –

    Required. Limited quantity: "cpu_time", "wall_time", "memory", "materialization", "stored", "transfer", "evaluations", "shots", "jobs", "currency", "host_invocations" or "host_work".

  • unit (Unit) –

    Required. Unit, which must match the metric.

  • kind (Literal['consumption', 'capacity_stock', 'deadline']) –

    Required. "consumption", "capacity_stock" or "deadline", which must match the metric.

  • value (StrictInt | Nonnegative) –

    Required. Nonnegative limit value. Byte and count metrics require an exact integer.

  • scope (Text) –

    Required. What the limit applies to.

Raises:

  • ValueError –

    If the unit or kind does not match the metric, or a byte or count limit is not an integer.