Skip to content

Python native API

The objects below are thin, typed request builders. Numerical work begins only when an operation such as eigsh enters the shared Rust library.

qmbed

Native Python request types for the shared QMBED Rust core.

The classes exported here are immutable descriptions of bases, local operator products, couplings, and eigensolver options. Numerical work is executed by the same Rust implementation used by native QMBED applications.

QmbedError

Bases: RuntimeError

Error reported by the QMBED native library or language boundary.

Source code in bindings/python/src/qmbed/_ffi.py
class QmbedError(RuntimeError):
    """Error reported by the QMBED native library or language boundary."""

    pass

LocalOperator

Bases: str, Enum

Built-in local actions understood by the universal Rust assembler.

Members describe one-site identity, number, Cartesian spin, and raising/lowering actions. A string may be used in :class:OpProduct for a custom action supported by a callback-defined basis.

Source code in bindings/python/src/qmbed/model.py
class LocalOperator(str, Enum):
    """Built-in local actions understood by the universal Rust assembler.

    Members describe one-site identity, number, Cartesian spin, and
    raising/lowering actions. A string may be used in :class:`OpProduct` for a
    custom action supported by a callback-defined basis.
    """

    IDENTITY = "identity"
    NUMBER = "number"
    Z = "z"
    RAISING = "raising"
    LOWERING = "lowering"
    X = "x"
    Y = "y"

OpProduct dataclass

Ordered product of local actions.

Parameters:

Name Type Description Default
local tuple[LocalOperator | str, ...]

Local actions in the same order as the coupling's site tuple.

required
split int | None

Boundary between the up and down species of a two-species product.

None
splits tuple[int, ...]

Boundaries for products with more than two species.

()

split and splits are mutually exclusive. Site indices themselves live in :class:Coupling so one product can be reused over many bonds.

Source code in bindings/python/src/qmbed/model.py
@dataclass(frozen=True)
class OpProduct:
    """Ordered product of local actions.

    Args:
        local: Local actions in the same order as the coupling's site tuple.
        split: Boundary between the up and down species of a two-species
            product.
        splits: Boundaries for products with more than two species.

    ``split`` and ``splits`` are mutually exclusive. Site indices themselves
    live in :class:`Coupling` so one product can be reused over many bonds.
    """

    local: tuple[LocalOperator | str, ...]
    split: int | None = None
    splits: tuple[int, ...] = ()

    @classmethod
    def spinful(
        cls,
        up: Iterable[LocalOperator | str],
        down: Iterable[LocalOperator | str],
    ) -> "OpProduct":
        """Construct a two-species product from up- and down-sector actions.

        Args:
            up: Ordered local actions for the up species.
            down: Ordered local actions for the down species.

        Returns:
            A product whose species boundary is placed after ``up``.
        """

        up = tuple(up)
        return cls(up + tuple(down), split=len(up))

    def request(self) -> dict:
        """Serialize the product into the language-neutral C-ABI schema."""

        local = [
            operator.value if isinstance(operator, LocalOperator) else operator
            for operator in self.local
        ]
        result = {"local": local}
        if self.splits:
            if self.split is not None:
                raise ValueError("OpProduct cannot define both split and splits")
            result["splits"] = list(self.splits)
        elif self.split is not None:
            result["split"] = self.split
        return result

spinful classmethod

spinful(up, down)

Construct a two-species product from up- and down-sector actions.

Parameters:

Name Type Description Default
up Iterable[LocalOperator | str]

Ordered local actions for the up species.

required
down Iterable[LocalOperator | str]

Ordered local actions for the down species.

required

Returns:

Type Description
'OpProduct'

A product whose species boundary is placed after up.

Source code in bindings/python/src/qmbed/model.py
@classmethod
def spinful(
    cls,
    up: Iterable[LocalOperator | str],
    down: Iterable[LocalOperator | str],
) -> "OpProduct":
    """Construct a two-species product from up- and down-sector actions.

    Args:
        up: Ordered local actions for the up species.
        down: Ordered local actions for the down species.

    Returns:
        A product whose species boundary is placed after ``up``.
    """

    up = tuple(up)
    return cls(up + tuple(down), split=len(up))

request

request()

Serialize the product into the language-neutral C-ABI schema.

Source code in bindings/python/src/qmbed/model.py
def request(self) -> dict:
    """Serialize the product into the language-neutral C-ABI schema."""

    local = [
        operator.value if isinstance(operator, LocalOperator) else operator
        for operator in self.local
    ]
    result = {"local": local}
    if self.splits:
        if self.split is not None:
            raise ValueError("OpProduct cannot define both split and splits")
        result["splits"] = list(self.splits)
    elif self.split is not None:
        result["split"] = self.split
    return result

Coupling dataclass

One complex coefficient and the zero-based sites on which it acts.

Parameters:

Name Type Description Default
coefficient complex

Scalar multiplying the local operator product.

required
sites tuple[int, ...]

Site indices in the same order as the product's local actions.

required
Source code in bindings/python/src/qmbed/model.py
@dataclass(frozen=True)
class Coupling:
    """One complex coefficient and the zero-based sites on which it acts.

    Args:
        coefficient: Scalar multiplying the local operator product.
        sites: Site indices in the same order as the product's local actions.
    """

    coefficient: complex
    sites: tuple[int, ...]

    def request(self) -> dict:
        """Serialize the coupling into the language-neutral C-ABI schema."""

        return {
            "coefficient": [self.coefficient.real, self.coefficient.imag],
            "sites": list(self.sites),
        }

request

request()

Serialize the coupling into the language-neutral C-ABI schema.

Source code in bindings/python/src/qmbed/model.py
def request(self) -> dict:
    """Serialize the coupling into the language-neutral C-ABI schema."""

    return {
        "coefficient": [self.coefficient.real, self.coefficient.imag],
        "sites": list(self.sites),
    }

OperatorSpec dataclass

A reusable local product together with all of its couplings.

The Rust core validates the product arity against every coupling and assembles the resulting term in the requested storage format.

Source code in bindings/python/src/qmbed/model.py
@dataclass(frozen=True)
class OperatorSpec:
    """A reusable local product together with all of its couplings.

    The Rust core validates the product arity against every coupling and
    assembles the resulting term in the requested storage format.
    """

    product: OpProduct
    couplings: tuple[Coupling, ...]

    def request(self) -> dict:
        """Serialize this term into the language-neutral C-ABI schema."""

        return {
            "product": self.product.request(),
            "couplings": [coupling.request() for coupling in self.couplings],
        }

request

request()

Serialize this term into the language-neutral C-ABI schema.

Source code in bindings/python/src/qmbed/model.py
def request(self) -> dict:
    """Serialize this term into the language-neutral C-ABI schema."""

    return {
        "product": self.product.request(),
        "couplings": [coupling.request() for coupling in self.couplings],
    }

BasisSpec

Abstract base for immutable basis requests.

Source code in bindings/python/src/qmbed/model.py
class BasisSpec:
    """Abstract base for immutable basis requests."""

    def request(self) -> dict:
        """Serialize this basis request for the Rust core."""

        raise NotImplementedError

request

request()

Serialize this basis request for the Rust core.

Source code in bindings/python/src/qmbed/model.py
def request(self) -> dict:
    """Serialize this basis request for the Rust core."""

    raise NotImplementedError

SpinBasis dataclass

Bases: BasisSpec

One-dimensional spin basis with optional conserved and symmetry sectors.

Parameters:

Name Type Description Default
sites int

Number of lattice sites.

required
spin_twice int

Twice the on-site spin quantum number; 1 means spin one half.

1
up int | None

Fixed total raising-quantum count, or None for the full space.

None
momentum int | None

Translation momentum sector, or None.

None
parity int | None

Reflection eigenvalue, normally -1 or 1.

None
pauli bool

Use Pauli rather than angular-momentum normalization.

False
Source code in bindings/python/src/qmbed/model.py
@dataclass(frozen=True)
class SpinBasis(BasisSpec):
    """One-dimensional spin basis with optional conserved and symmetry sectors.

    Args:
        sites: Number of lattice sites.
        spin_twice: Twice the on-site spin quantum number; ``1`` means
            spin one half.
        up: Fixed total raising-quantum count, or ``None`` for the full space.
        momentum: Translation momentum sector, or ``None``.
        parity: Reflection eigenvalue, normally ``-1`` or ``1``.
        pauli: Use Pauli rather than angular-momentum normalization.
    """

    sites: int
    spin_twice: int = 1
    up: int | None = None
    momentum: int | None = None
    parity: int | None = None
    pauli: bool = False

    def request(self) -> dict:
        """Serialize this spin basis request."""

        return {
            "kind": "spin",
            "sites": self.sites,
            "spin_twice": self.spin_twice,
            "up": self.up,
            "momentum": self.momentum,
            "parity": self.parity,
            "pauli": self.pauli,
        }

request

request()

Serialize this spin basis request.

Source code in bindings/python/src/qmbed/model.py
def request(self) -> dict:
    """Serialize this spin basis request."""

    return {
        "kind": "spin",
        "sites": self.sites,
        "spin_twice": self.spin_twice,
        "up": self.up,
        "momentum": self.momentum,
        "parity": self.parity,
        "pauli": self.pauli,
    }

BosonBasis dataclass

Bases: BasisSpec

Bosonic lattice basis with a finite local cutoff.

Parameters:

Name Type Description Default
sites int

Number of lattice sites.

required
states_per_site int

Allowed local occupations 0 through states_per_site - 1.

required
particles int | None

Fixed total boson number, or None for the full product space.

None
Source code in bindings/python/src/qmbed/model.py
@dataclass(frozen=True)
class BosonBasis(BasisSpec):
    """Bosonic lattice basis with a finite local cutoff.

    Args:
        sites: Number of lattice sites.
        states_per_site: Allowed local occupations ``0`` through
            ``states_per_site - 1``.
        particles: Fixed total boson number, or ``None`` for the full product
            space.
    """

    sites: int
    states_per_site: int
    particles: int | None = None

    def request(self) -> dict:
        """Serialize this boson basis request."""

        return {
            "kind": "boson",
            "sites": self.sites,
            "states_per_site": self.states_per_site,
            "particles": self.particles,
        }

request

request()

Serialize this boson basis request.

Source code in bindings/python/src/qmbed/model.py
def request(self) -> dict:
    """Serialize this boson basis request."""

    return {
        "kind": "boson",
        "sites": self.sites,
        "states_per_site": self.states_per_site,
        "particles": self.particles,
    }

SpinlessFermionBasis dataclass

Bases: BasisSpec

Spinless-fermion Fock basis.

Parameters:

Name Type Description Default
sites int

Number of fermionic orbitals.

required
particles int | None

Fixed particle number, or None.

None
momentum int | None

Translation momentum sector, or None.

None
Source code in bindings/python/src/qmbed/model.py
@dataclass(frozen=True)
class SpinlessFermionBasis(BasisSpec):
    """Spinless-fermion Fock basis.

    Args:
        sites: Number of fermionic orbitals.
        particles: Fixed particle number, or ``None``.
        momentum: Translation momentum sector, or ``None``.
    """

    sites: int
    particles: int | None = None
    momentum: int | None = None

    def request(self) -> dict:
        """Serialize this spinless-fermion basis request."""

        return {
            "kind": "spinless_fermion",
            "sites": self.sites,
            "particles": self.particles,
            "momentum": self.momentum,
        }

request

request()

Serialize this spinless-fermion basis request.

Source code in bindings/python/src/qmbed/model.py
def request(self) -> dict:
    """Serialize this spinless-fermion basis request."""

    return {
        "kind": "spinless_fermion",
        "sites": self.sites,
        "particles": self.particles,
        "momentum": self.momentum,
    }

SpinfulFermionBasis dataclass

Bases: BasisSpec

Two-species fermion basis with independent number sectors.

Parameters:

Name Type Description Default
sites int

Number of spatial sites for each species.

required
particles_up int | None

Fixed up-species particle number, or None.

None
particles_down int | None

Fixed down-species particle number, or None.

None
Source code in bindings/python/src/qmbed/model.py
@dataclass(frozen=True)
class SpinfulFermionBasis(BasisSpec):
    """Two-species fermion basis with independent number sectors.

    Args:
        sites: Number of spatial sites for each species.
        particles_up: Fixed up-species particle number, or ``None``.
        particles_down: Fixed down-species particle number, or ``None``.
    """

    sites: int
    particles_up: int | None = None
    particles_down: int | None = None

    def request(self) -> dict:
        """Serialize this spinful-fermion basis request."""

        return {
            "kind": "spinful_fermion",
            "sites": self.sites,
            "particles_up": self.particles_up,
            "particles_down": self.particles_down,
        }

request

request()

Serialize this spinful-fermion basis request.

Source code in bindings/python/src/qmbed/model.py
def request(self) -> dict:
    """Serialize this spinful-fermion basis request."""

    return {
        "kind": "spinful_fermion",
        "sites": self.sites,
        "particles_up": self.particles_up,
        "particles_down": self.particles_down,
    }

EigshOptions dataclass

Controls a selected Hermitian eigensolve.

Parameters:

Name Type Description Default
eigenpairs int

Number of requested eigenpairs.

required
target str

Spectral target such as "smallest_algebraic" or "shift".

'smallest_algebraic'
shift float | None

Interior target used when target="shift".

None
krylov_dimension int | None

Maximum search-space dimension. None selects the core default.

None
tolerance float

Residual convergence tolerance.

1e-10
max_iterations int

Maximum restart or iteration budget.

1000
seed int

Deterministic initial-vector seed.

0
eigenvectors bool

Return eigenvectors in addition to values and residuals.

False
Source code in bindings/python/src/qmbed/model.py
@dataclass(frozen=True)
class EigshOptions:
    """Controls a selected Hermitian eigensolve.

    Args:
        eigenpairs: Number of requested eigenpairs.
        target: Spectral target such as ``"smallest_algebraic"`` or
            ``"shift"``.
        shift: Interior target used when ``target="shift"``.
        krylov_dimension: Maximum search-space dimension. ``None`` selects the
            core default.
        tolerance: Residual convergence tolerance.
        max_iterations: Maximum restart or iteration budget.
        seed: Deterministic initial-vector seed.
        eigenvectors: Return eigenvectors in addition to values and residuals.
    """

    eigenpairs: int
    target: str = "smallest_algebraic"
    shift: float | None = None
    krylov_dimension: int | None = None
    tolerance: float = 1.0e-10
    max_iterations: int = 1_000
    seed: int = 0
    eigenvectors: bool = False

    def request(self) -> dict:
        """Serialize and normalize the eigensolver options."""

        target = (
            {"kind": "shift", "value": self.shift}
            if self.target == "shift"
            else {"kind": self.target}
        )
        return {
            "eigenpairs": self.eigenpairs,
            "target": target,
            "krylov_dimension": self.krylov_dimension,
            "tolerance": self.tolerance,
            "max_iterations": self.max_iterations,
            "seed": self.seed,
            "eigenvectors": self.eigenvectors,
        }

request

request()

Serialize and normalize the eigensolver options.

Source code in bindings/python/src/qmbed/model.py
def request(self) -> dict:
    """Serialize and normalize the eigensolver options."""

    target = (
        {"kind": "shift", "value": self.shift}
        if self.target == "shift"
        else {"kind": self.target}
    )
    return {
        "eigenpairs": self.eigenpairs,
        "target": target,
        "krylov_dimension": self.krylov_dimension,
        "tolerance": self.tolerance,
        "max_iterations": self.max_iterations,
        "seed": self.seed,
        "eigenvectors": self.eigenvectors,
    }

Eigensystem dataclass

Result of a QMBED Hermitian eigensolve.

Attributes:

Name Type Description
dimension int

Hilbert-space dimension.

eigenvalues tuple[float, ...]

Ordered real Ritz or exact eigenvalues.

residuals tuple[float, ...]

Norm of H v - λ v for each returned pair.

iterations int

Solver iteration count.

converged bool

Whether every requested residual met the tolerance.

eigenvectors tuple[tuple[complex, ...], ...] | None

Eigenvectors when requested, otherwise None.

Source code in bindings/python/src/qmbed/model.py
@dataclass(frozen=True)
class Eigensystem:
    """Result of a QMBED Hermitian eigensolve.

    Attributes:
        dimension: Hilbert-space dimension.
        eigenvalues: Ordered real Ritz or exact eigenvalues.
        residuals: Norm of ``H v - λ v`` for each returned pair.
        iterations: Solver iteration count.
        converged: Whether every requested residual met the tolerance.
        eigenvectors: Eigenvectors when requested, otherwise ``None``.
    """

    dimension: int
    eigenvalues: tuple[float, ...]
    residuals: tuple[float, ...]
    iterations: int
    converged: bool
    eigenvectors: tuple[tuple[complex, ...], ...] | None = None

eigsh

eigsh(basis, terms, options, *, format='csc')

Solve selected eigenpairs of a Hamiltonian assembled from local terms.

Parameters:

Name Type Description Default
basis BasisSpec

Typed Hilbert-space request.

required
terms Sequence[OperatorSpec]

Local operator specifications to sum into the Hamiltonian.

required
options EigshOptions

Spectral target and convergence controls.

required
format str

Materialization format, normally "csc". Other core formats include "dense", "csr", "dia", and "matrix_free" when supported by the selected solver.

'csc'

Returns:

Type Description
Eigensystem

Eigenvalues, residuals, convergence evidence, and optional

Eigensystem

eigenvectors from the Rust solver.

Raises:

Type Description
QmbedError

If the basis, terms, storage route, or solver options are invalid, or if the native operation fails.

Source code in bindings/python/src/qmbed/model.py
def eigsh(
    basis: BasisSpec,
    terms: Sequence[OperatorSpec],
    options: EigshOptions,
    *,
    format: str = "csc",
) -> Eigensystem:
    """Solve selected eigenpairs of a Hamiltonian assembled from local terms.

    Args:
        basis: Typed Hilbert-space request.
        terms: Local operator specifications to sum into the Hamiltonian.
        options: Spectral target and convergence controls.
        format: Materialization format, normally ``"csc"``. Other core
            formats include ``"dense"``, ``"csr"``, ``"dia"``, and
            ``"matrix_free"`` when supported by the selected solver.

    Returns:
        Eigenvalues, residuals, convergence evidence, and optional
        eigenvectors from the Rust solver.

    Raises:
        QmbedError: If the basis, terms, storage route, or solver options are
            invalid, or if the native operation fails.
    """

    result = run(
        {
            "basis": basis.request(),
            "terms": [term.request() for term in terms],
            "format": format,
            "solver": options.request(),
        }
    )
    vectors = result.get("eigenvectors")
    return Eigensystem(
        dimension=result["dimension"],
        eigenvalues=tuple(result["eigenvalues"]),
        residuals=tuple(result["residuals"]),
        iterations=result["iterations"],
        converged=result["converged"],
        eigenvectors=None
        if vectors is None
        else tuple(
            tuple(complex(real, imag) for real, imag in vector)
            for vector in vectors
        ),
    )