Source code for qdk_chemistry.data.symmetry

"""Single-particle symmetry types and symmetry-blocked storage primitives.

This module exposes the single-particle symmetry types used to block
quantum-chemistry tensors (orbital coefficients, energies, integrals, reduced
density matrices) by conserved single-particle quantum numbers, together with
the symmetry-blocked tensor storage primitives (the rank/scalar variants listed
below) and their index-set companion :class:`SymmetryBlockedIndexSet`.

In this release only the spin axis (:math:`S_z`) is populated, supporting
restricted (RHF/ROHF) and unrestricted (UHF) references.

Exposed symmetry types are:

- :class:`AxisName`: Enumeration of single-particle symmetry axes.
- :func:`axis_name_to_string`: Human-readable name for an :class:`AxisName`.
- :class:`SymmetryAxisValue`: Abstract value carried by a single symmetry axis.
- :class:`SpinValue`: Concrete spin-1/2 axis value (stored as :math:`2 M_s`).
- :class:`SymmetryAxis`: One named symmetry partition with its admissible labels.
- :class:`SymmetryProduct`: An ordered set of axes a basis is blocked under.
- :class:`SymmetryLabel`: A composite addressing key, one value per axis.

Exposed storage types are:

- :class:`SymmetryBlockedScalarCount`: One scalar count per symmetry sector.
- :class:`SymmetryBlockedTensorRank1` / :class:`SymmetryBlockedTensorRank1Complex`
- :class:`SymmetryBlockedTensorRank2` / :class:`SymmetryBlockedTensorRank2Complex`
- :class:`SymmetryBlockedTensorRank3` / :class:`SymmetryBlockedTensorRank3Complex`
- :class:`SymmetryBlockedTensorRank4` / :class:`SymmetryBlockedTensorRank4Complex`
- :class:`SymmetryBlockedSparseMapRank4`
- :class:`SymmetryBlockedIndexSet`

Errors are surfaced as standard Python exceptions mapped from the underlying
C++ standard-library exceptions.
"""

# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See LICENSE.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

from qdk_chemistry._core.data.symmetry import (
    AxisName,
    SpinValue,
    SymmetryAxis,
    SymmetryAxisValue,
    SymmetryBlockedIndexSet,
    SymmetryBlockedScalarCount,
    SymmetryBlockedSparseMapRank4,
    SymmetryBlockedTensorRank1,
    SymmetryBlockedTensorRank1Complex,
    SymmetryBlockedTensorRank2,
    SymmetryBlockedTensorRank2Complex,
    SymmetryBlockedTensorRank3,
    SymmetryBlockedTensorRank3Complex,
    SymmetryBlockedTensorRank4,
    SymmetryBlockedTensorRank4Complex,
    SymmetryLabel,
    SymmetryProduct,
    axes,
    axis_name_to_string,
)

__all__ = [
    "AxisName",
    "SpinValue",
    "SymmetryAxis",
    "SymmetryAxisValue",
    "SymmetryBlockedIndexSet",
    "SymmetryBlockedScalarCount",
    "SymmetryBlockedSparseMapRank4",
    "SymmetryBlockedTensorRank1",
    "SymmetryBlockedTensorRank1Complex",
    "SymmetryBlockedTensorRank2",
    "SymmetryBlockedTensorRank2Complex",
    "SymmetryBlockedTensorRank3",
    "SymmetryBlockedTensorRank3Complex",
    "SymmetryBlockedTensorRank4",
    "SymmetryBlockedTensorRank4Complex",
    "SymmetryLabel",
    "SymmetryProduct",
    "axes",
    "axis_name_to_string",
    "spin_index_set",
]


from collections.abc import Sequence


[docs] def spin_index_set( num_modes: int, alpha: Sequence[int], beta: Sequence[int], *, equivalent: bool = True, ) -> SymmetryBlockedIndexSet: """Build a spin-resolved SymmetryBlockedIndexSet from alpha/beta index lists. Args: num_modes: Universe size (total number of orbitals per spin channel). alpha: Sorted active/inactive indices for the alpha channel. beta: Sorted active/inactive indices for the beta channel. equivalent: Whether the spin axis labels share storage (restricted). Returns: A SymmetryBlockedIndexSet carrying the spin symmetry and per-channel indices. """ sym = SymmetryProduct([axes.spin(1, equivalent)]) alpha_label = SymmetryLabel([axes.alpha()]) beta_label = SymmetryLabel([axes.beta()]) extents = {alpha_label: num_modes, beta_label: num_modes} indices = { alpha_label: list(alpha), beta_label: list(beta), } return SymmetryBlockedIndexSet(sym, extents, indices)