Skip to content

qten.symbolics.state_space

Module reference for qten.symbolics.state_space.

state_space

Indexed symbolic state-space containers.

This module defines ordered finite state spaces used as tensor dimensions in QTen. StateSpace stores arbitrary spatial or symbolic elements with stable integer indices, while specialized spaces such as MomentumSpace and BzPath describe reciprocal-space grids and paths.

Repository usage

Use state spaces as labelled tensor dimensions and as the finite index sets that connect symbolic geometry to numeric tensor data. Hilbert-space basis objects live in qten.symbolics.hilbert_space.

StateSpaceType module-attribute

StateSpaceType = TypeVar(
    "StateSpaceType", bound="StateSpace[Any]"
)

StateSpace dataclass

StateSpace(structure: OrderedDict[T, int])

Bases: Spatial, Convertible, Generic[T], Span[T]

StateSpace is a collection of indices with additional information attached to the elements, for the case of TNS there are only two types of state spaces: MomentumSpace and HilbertSpace. MomentumSpace is needed because some tensors are better represented in momentum space, e.g. Hamiltonians with translational symmetry, while HilbertSpace is needed to represent local degrees of freedom, e.g. spin or fermionic modes.

Attributes:

Name Type Description
structure OrderedDict[Spatial, int]

An ordered dictionary mapping each spatial component (e.g., Offset, Momentum) to its single flattened index.

dim int

The total dimension of the state space, calculated as the count of elements regardless of their lengths.

structure instance-attribute

structure: OrderedDict[T, int]

An ordered dictionary mapping each spatial component (e.g., Offset, Momentum) to its single flattened index.

dim property

dim: int

The total size of the vector space.

elements

elements() -> tuple[T, ...]

Return the spatial elements as a tuple.

Source code in src/qten/symbolics/state_space.py
83
84
85
86
@override
def elements(self) -> Tuple[T, ...]:
    """Return the spatial elements as a tuple."""
    return tuple(self.structure.keys())

__len__

__len__() -> int

Return the number of spatial elements.

Source code in src/qten/symbolics/state_space.py
88
89
90
def __len__(self) -> int:
    """Return the number of spatial elements."""
    return len(self.structure)

__iter__

__iter__() -> Iterator[T]

Iterate over spatial elements.

Source code in src/qten/symbolics/state_space.py
92
93
94
def __iter__(self) -> Iterator[T]:
    """Iterate over spatial elements."""
    return iter(self.structure.keys())

__hash__

__hash__()

Return a hash derived from the ordered state-space structure.

The hash is computed from tuple(self.structure.items()), so it depends on both the spatial elements and their stored integer indices in insertion order. Two state spaces with the same elements but a different order, or with the same elements mapped to different integer positions, intentionally produce different hashes.

This custom implementation is required because structure is an OrderedDict, which is mutable and unhashable by itself. The state-space dataclasses are frozen, so the tuple snapshot is stable as long as the contained spatial elements are themselves hashable and immutable.

Returns:

Type Description
int

Hash value for the ordered (element, index) mapping.

Source code in src/qten/symbolics/state_space.py
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
def __hash__(self) -> int:
    """
    Return a hash derived from the ordered state-space structure.

    The hash is computed from `tuple(self.structure.items())`, so it
    depends on both the spatial elements and their stored integer indices in
    insertion order. Two state spaces with the same elements but a different
    order, or with the same elements mapped to different integer positions,
    intentionally produce different hashes.

    This custom implementation is required because `structure` is an
    `OrderedDict`, which is mutable and unhashable by itself. The state-space
    dataclasses are frozen, so the tuple snapshot is stable as long as the
    contained spatial elements are themselves hashable and immutable.

    Returns
    -------
    int
        Hash value for the ordered `(element, index)` mapping.
    """
    return hash(tuple(self.structure.items()))

__getitem__

__getitem__(v: int) -> T
__getitem__(v: slice | range) -> Self
__getitem__(v: Sequence[int]) -> Self

Index into the state-space by element position.

Supported forms

space[i] returns a single spatial element by position, including negative indices. space[start:stop:step] returns a new space with the selected elements in slice order. space[range(...)] returns a new space with the range-selected elements. space[[i, j, ...]] returns a new space with elements in explicit index order.

Parameters:

Name Type Description Default
key Union[int, slice, range, Sequence[int]]

Index selector. Sequences must contain unique integers; negative integers are normalized relative to len(self).

required

Returns:

Type Description
Spatial or StateSpace

A spatial element for int indexing, otherwise a new instance of the same class containing the selected elements. Any extra dataclass fields on subclasses are preserved in the returned instance.

Raises:

Type Description
IndexError

If an integer index is out of bounds.

TypeError

If key is not an int, slice, range, or sequence of integers.

ValueError

If a sequence selector contains duplicate indices.

Source code in src/qten/symbolics/state_space.py
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
def __getitem__(
    self, key: Union[int, slice, range, Sequence[int]]
) -> Union[T, "StateSpace[T]"]:
    """
    Index into the state-space by element position.

    Supported forms
    ---------------
    `space[i]` returns a single spatial element by position, including
    negative indices. `space[start:stop:step]` returns a new space with the
    selected elements in slice order. `space[range(...)]` returns a new
    space with the range-selected elements. `space[[i, j, ...]]` returns a
    new space with elements in explicit index order.

    Parameters
    ----------
    key : Union[int, slice, range, Sequence[int]]
        Index selector. Sequences must contain unique integers; negative
        integers are normalized relative to `len(self)`.

    Returns
    -------
    Spatial or StateSpace
        A spatial element for `int` indexing, otherwise a new instance of the
        same class containing the selected elements. Any extra dataclass fields
        on subclasses are preserved in the returned instance.

    Raises
    ------
    IndexError
        If an integer index is out of bounds.
    TypeError
        If `key` is not an `int`, `slice`, `range`, or sequence of integers.
    ValueError
        If a sequence selector contains duplicate indices.
    """
    if isinstance(key, int):
        if key < 0:
            key += len(self.structure)
        if key < 0 or key >= len(self.structure):
            raise IndexError("StateSpace index out of range")
        return next(islice(self.structure.keys(), key, None))
    if isinstance(key, slice):
        keys = tuple(self.structure.keys())[key]
        new_structure = OrderedDict((k, self.structure[k]) for k in keys)
        return replace(self, structure=restructure(new_structure))
    if isinstance(key, range):
        keys = tuple(self.structure.keys())
        new_structure = OrderedDict((keys[i], self.structure[keys[i]]) for i in key)
        return replace(self, structure=restructure(new_structure))
    if isinstance(key, Sequence) and not isinstance(key, (str, bytes)):
        keys = tuple(self.structure.keys())
        indices: list[int] = []
        seen = set()
        for idx in key:
            if isinstance(idx, bool) or not isinstance(idx, int):
                raise TypeError(
                    "StateSpace sequence indices must contain only integers"
                )
            normalized = idx
            if normalized < 0:
                normalized += len(keys)
            if normalized < 0 or normalized >= len(keys):
                raise IndexError("StateSpace index out of range")
            if normalized in seen:
                raise ValueError("StateSpace sequence indices must be unique")
            seen.add(normalized)
            indices.append(normalized)
        new_structure = OrderedDict(
            (keys[i], self.structure[keys[i]]) for i in indices
        )
        return replace(self, structure=restructure(new_structure))
    raise TypeError(
        "StateSpace indices must be int, slice, range, or a sequence of ints, "
        f"not {type(key)}"
    )

same_rays

same_rays(other: StateSpace) -> bool

Check if this state space has the same rays as another, i.e., they have the same set of spatial keys regardless of order.

Parameters:

Name Type Description Default
other StateSpace

The other state space to compare against.

required

Returns:

Type Description
bool

True if both state spaces have the same rays, False otherwise.

Source code in src/qten/symbolics/state_space.py
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
def same_rays(self, other: "StateSpace") -> bool:
    """
    Check if this state space has the same rays as another, i.e., they have the same set of spatial keys regardless of order.

    Parameters
    ----------
    other : StateSpace
        The other state space to compare against.

    Returns
    -------
    bool
        True if both state spaces have the same rays, `False` otherwise.
    """
    return same_rays(self, other)

map

map(func: Callable[[T], T]) -> Self

Map the spatial elements of this state space using a provided function.

Parameters:

Name Type Description Default
func Callable[[T], T]

A function that takes a spatial element and returns a transformed spatial element.

required

Returns:

Type Description
Self

A new state space with the transformed spatial elements.

Source code in src/qten/symbolics/state_space.py
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
def map(self, func: Callable[[T], T]) -> "Self":
    """
    Map the spatial elements of this state space using a provided function.

    Parameters
    ----------
    func : Callable[[T], T]
        A function that takes a spatial element and returns a transformed spatial element.

    Returns
    -------
    Self
        A new state space with the transformed spatial elements.
    """
    new_structure = OrderedDict()
    for k, s in self.structure.items():
        new_k = func(k)
        new_structure[new_k] = s
    return replace(self, structure=restructure(new_structure))

filter

filter(pred: Callable[[T], bool]) -> Self

Return the subspace containing elements where pred(element) is True.

Parameters:

Name Type Description Default
pred Callable[[T], bool]

Predicate applied to each element in basis order.

required

Returns:

Type Description
Self

A new state space of the same concrete type containing only the selected elements, with indices repacked contiguously.

Source code in src/qten/symbolics/state_space.py
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
def filter(self, pred: Callable[[T], bool]) -> "Self":
    """
    Return the subspace containing elements where `pred(element)` is `True`.

    Parameters
    ----------
    pred : Callable[[T], bool]
        Predicate applied to each element in basis order.

    Returns
    -------
    Self
        A new state space of the same concrete type containing only the
        selected elements, with indices repacked contiguously.
    """
    new_structure = OrderedDict(
        (k, s) for k, s in self.structure.items() if pred(k)
    )
    return replace(self, structure=restructure(new_structure))

tensor_product

tensor_product(other: Self) -> Self

Return the tensor-product state space of this space and another space.

This method defines the protocol used by the @ operator on StateSpace instances. The base class cannot construct a generic product because it does not know how to combine two elements of type T. Concrete subclasses must implement the element-level product and rebuild a contiguous structure for the resulting basis.

Implementations should preserve deterministic product ordering. The convention used by concrete tensor-product spaces in QTen is the Cartesian product order of self.elements() and other.elements(), where elements from self vary slowest and elements from other vary fastest. The returned space should be the same concrete state-space family when the operation is closed over that family.

Parameters:

Name Type Description Default
other StateSpace

Right-hand tensor factor. Implementations may require other to be the same concrete state-space type as self.

required

Returns:

Type Description
StateSpace

New state space representing self ⊗ other, with contiguous integer indices in the implementation-defined product order.

Raises:

Type Description
NotImplementedError

Always raised by the base class. Subclasses that support tensor products must override this method.

Source code in src/qten/symbolics/state_space.py
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
def tensor_product(self, other: Self) -> Self:
    """
    Return the tensor-product state space of this space and another space.

    This method defines the protocol used by the `@` operator on
    [`StateSpace`][qten.symbolics.state_space.StateSpace] instances. The
    base class cannot construct a generic product because it does not know
    how to combine two elements of type `T`. Concrete subclasses must
    implement the element-level product and rebuild a contiguous
    `structure` for the resulting basis.

    Implementations should preserve deterministic product ordering. The
    convention used by concrete tensor-product spaces in QTen is the
    Cartesian product order of `self.elements()` and `other.elements()`,
    where elements from `self` vary slowest and elements from `other` vary
    fastest. The returned space should be the same concrete state-space
    family when the operation is closed over that family.

    Parameters
    ----------
    other : StateSpace
        Right-hand tensor factor. Implementations may require `other` to be
        the same concrete state-space type as `self`.

    Returns
    -------
    StateSpace
        New state space representing `self ⊗ other`, with contiguous
        integer indices in the implementation-defined product order.

    Raises
    ------
    NotImplementedError
        Always raised by the base class. Subclasses that support tensor
        products must override this method.
    """
    raise NotImplementedError(f"Tensor product not implemented for {type(self)}!")

extract

extract(info_type: type[Any]) -> Any

Extract an object implied by the elements of this state space.

Subclasses may register specialized implementations for supported target types.

Parameters:

Name Type Description Default
info_type type[Any]

Type of metadata or object to extract from this state space.

required

Returns:

Type Description
Any

Extracted object produced by a registered specialization.

Raises:

Type Description
NotImplementedError

If no extraction rule is registered for info_type.

Source code in src/qten/symbolics/state_space.py
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
@multimethod
def extract(self, info_type: type[Any]) -> Any:
    """
    Extract an object implied by the elements of this state space.

    Subclasses may register specialized implementations for supported
    target types.

    Parameters
    ----------
    info_type : type[Any]
        Type of metadata or object to extract from this state space.

    Returns
    -------
    Any
        Extracted object produced by a registered specialization.

    Raises
    ------
    NotImplementedError
        If no extraction rule is registered for `info_type`.
    """
    raise NotImplementedError(
        f"Extraction of {info_type} from {type(self)} is not supported!"
    )

register_plot_method classmethod

register_plot_method(name: str, backend: str = 'plotly')

Register a backend plotting function for this plottable class.

The returned decorator stores the function in the global plotting registry. Registered functions receive the object being plotted as their first argument, followed by any extra positional and keyword arguments supplied to plot().

Parameters:

Name Type Description Default
name str

User-facing plot method name, such as scatter, structure, or heatmap.

required
backend str

Backend name that selects the implementation. The qten-plots extension currently uses plotly and matplotlib.

'plotly'

Returns:

Type Description
Callable

Decorator that registers the provided plotting function and returns it unchanged.

Source code in src/qten/plottings/_plottings.py
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
@classmethod
def register_plot_method(cls, name: str, backend: str = "plotly"):
    """
    Register a backend plotting function for this plottable class.

    The returned decorator stores the function in the global plotting
    registry. Registered functions receive the object being plotted as their
    first argument, followed by any extra positional and keyword arguments
    supplied to [`plot()`][qten.plottings.Plottable.plot].

    Parameters
    ----------
    name : str
        User-facing plot method name, such as `scatter`, `structure`, or
        `heatmap`.
    backend : str
        Backend name that selects the implementation. The `qten-plots`
        extension currently uses `plotly` and `matplotlib`.

    Returns
    -------
    Callable
        Decorator that registers the provided plotting function and returns
        it unchanged.
    """

    def decorator(func: Callable):
        # We register against 'cls' - the class this method was called on.
        Plottable._registry[(cls, name, backend)] = func
        return func

    return decorator

plot

plot(method: str, backend: str = 'plotly', *args, **kwargs)

Dispatch a named plot method to a registered backend implementation.

The dispatcher first loads plotting entry points, then searches the instance type and its base classes for a matching (type, method, backend) registration. Additional arguments are forwarded unchanged to the selected backend function.

Parameters:

Name Type Description Default
method str

Plot method name registered for this object's type.

required
backend str

Backend implementation to use. The qten-plots extension currently registers plotly and matplotlib.

'plotly'
args

Positional arguments forwarded to the registered plotting function.

()
kwargs

Keyword arguments forwarded to the registered plotting function.

{}

Returns:

Type Description
object

Backend-specific figure object returned by the registered plotting function, such as a Plotly or Matplotlib figure.

Raises:

Type Description
ValueError

If no plotting function is registered for the requested method and backend on this object.

See Also

qten_plots.plottables.PointCloud Public plottable helper object provided by the plotting extension.

Source code in src/qten/plottings/_plottings.py
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
def plot(self, method: str, backend: str = "plotly", *args, **kwargs):
    """
    Dispatch a named plot method to a registered backend implementation.

    The dispatcher first loads plotting entry points, then searches the
    instance type and its base classes for a matching `(type, method,
    backend)` registration. Additional arguments are forwarded unchanged to
    the selected backend function.

    Parameters
    ----------
    method : str
        Plot method name registered for this object's type.
    backend : str
        Backend implementation to use. The `qten-plots` extension currently
        registers `plotly` and `matplotlib`.
    args
        Positional arguments forwarded to the registered plotting function.
    kwargs
        Keyword arguments forwarded to the registered plotting function.

    Returns
    -------
    object
        Backend-specific figure object returned by the registered plotting
        function, such as a Plotly or Matplotlib figure.

    Raises
    ------
    ValueError
        If no plotting function is registered for the requested method and
        backend on this object.

    See Also
    --------
    qten_plots.plottables.PointCloud
        Public plottable helper object provided by the plotting extension.
    """
    Plottable._ensure_backends_loaded()

    # Iterate over the MRO (Method Resolution Order) of the instance
    for class_in_hierarchy in type(self).__mro__:
        key = (class_in_hierarchy, method, backend)

        # Check the central registry
        if key in Plottable._registry:
            plot_func = Plottable._registry[key]
            return plot_func(self, *args, **kwargs)

    # If we reach here, no method was found. Provide a helpful error.
    self._raise_method_not_found(method, backend)

add_conversion classmethod

add_conversion(
    T: type[B],
) -> Callable[[Callable[[A], B]], Callable[[A], B]]

Register a conversion from cls to T.

The decorated function is stored under (cls, T). When an instance of cls later calls convert(T), that function is used to produce the converted object.

Parameters:

Name Type Description Default
T Type[B]

Destination type produced by the registered conversion function.

required

Returns:

Type Description
Callable[[Callable[[A], B]], Callable[[A], B]]

Decorator that stores the conversion function and returns it unchanged.

Examples:

@MyType.add_conversion(TargetType)
def to_target(x: MyType) -> TargetType:
    ...
Source code in src/qten/abstracts.py
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
@classmethod
def add_conversion(
    cls: Type[A], T: Type[B]
) -> Callable[[Callable[[A], B]], Callable[[A], B]]:
    """
    Register a conversion from `cls` to `T`.

    The decorated function is stored under `(cls, T)`. When an instance of
    `cls` later calls [`convert(T)`][qten.abstracts.Convertible.convert],
    that function is used to produce the converted object.

    Parameters
    ----------
    T : Type[B]
        Destination type produced by the registered conversion function.

    Returns
    -------
    Callable[[Callable[[A], B]], Callable[[A], B]]
        Decorator that stores the conversion function and returns it
        unchanged.

    Examples
    --------
    ```python
    @MyType.add_conversion(TargetType)
    def to_target(x: MyType) -> TargetType:
        ...
    ```
    """

    def decorator(func: Callable[[A], B]) -> Callable[[A], B]:
        _type_conversion_table[(cls, T)] = cast(Callable[[Any], Any], func)
        return func

    return decorator

convert

convert(T: type[B]) -> B

Convert this instance to the requested target type.

Parameters:

Name Type Description Default
T Type[B]

Destination type to convert into.

required

Returns:

Type Description
B

Converted object produced by the registered conversion function.

Raises:

Type Description
NotImplementedError

If no conversion function has been registered for (type(self), T) or any source supertype via add_conversion().

Source code in src/qten/abstracts.py
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
@final
def convert(self, T: Type[B]) -> B:
    """
    Convert this instance to the requested target type.

    Parameters
    ----------
    T : Type[B]
        Destination type to convert into.

    Returns
    -------
    B
        Converted object produced by the registered conversion function.

    Raises
    ------
    NotImplementedError
        If no conversion function has been registered for
        `(type(self), T)` or any source supertype via
        [`add_conversion()`][qten.abstracts.Convertible.add_conversion].
    """
    source_type = type(self)
    table_get = _type_conversion_table.get

    convertor = table_get((source_type, T))
    if convertor is None:
        for super_type in source_type.__mro__[1:]:
            convertor = table_get((super_type, T))
            if convertor is not None:
                # Cache resolved parent conversion under the concrete source type.
                _type_conversion_table[(source_type, T)] = convertor
                break

    if convertor is None:
        raise NotImplementedError(
            f"No conversion from {source_type.__name__} to {T.__name__}!"
        )
    return cast(Callable[["Convertible"], B], convertor)(self)

MomentumSpace dataclass

MomentumSpace(structure: OrderedDict[T, int])

Bases: StateSpace[Momentum]

Ordered state space of momentum points over one reciprocal lattice.

MomentumSpace is the reciprocal-space specialization of StateSpace. Its structure keys are Momentum objects and its values are the corresponding integer basis indices.

Notes

The class inherits the custom hashing behavior from StateSpace so instances remain hashable despite storing an OrderedDict.

dim property

dim: int

The total size of the vector space.

structure instance-attribute

structure: OrderedDict[T, int]

An ordered dictionary mapping each spatial component (e.g., Offset, Momentum) to its single flattened index.

__hash__

__hash__() -> int

Return a hash derived from the ordered momentum structure.

MomentumSpace uses the same structure-based hash as StateSpace. The hash includes every Momentum key and its stored integer basis index in insertion order. This means two momentum spaces with the same momentum set but different basis order hash differently.

Returns:

Type Description
int

Hash value for the ordered (Momentum, index) mapping.

Source code in src/qten/symbolics/state_space.py
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
def __hash__(self) -> int:
    """
    Return a hash derived from the ordered momentum structure.

    [`MomentumSpace`][qten.symbolics.state_space.MomentumSpace] uses the
    same structure-based hash as
    [`StateSpace`][qten.symbolics.state_space.StateSpace]. The hash includes
    every [`Momentum`][qten.geometries.spatials.Momentum] key and its stored
    integer basis index in insertion order. This means two momentum spaces
    with the same momentum set but different basis order hash differently.

    Returns
    -------
    int
        Hash value for the ordered `(Momentum, index)` mapping.
    """
    return StateSpace.__hash__(self)

__str__

__str__()

Return a compact momentum-space summary.

Returns:

Type Description
str

Summary containing the momentum-space dimension.

Source code in src/qten/symbolics/state_space.py
535
536
537
538
539
540
541
542
543
544
def __str__(self):
    """
    Return a compact momentum-space summary.

    Returns
    -------
    str
        Summary containing the momentum-space dimension.
    """
    return f"MomentumSpace({self.dim})"

__repr__

__repr__()

Return a multiline representation with indexed momentum elements.

Returns:

Type Description
str

Header plus one line per momentum element in basis order.

Source code in src/qten/symbolics/state_space.py
546
547
548
549
550
551
552
553
554
555
556
557
558
559
def __repr__(self):
    """
    Return a multiline representation with indexed momentum elements.

    Returns
    -------
    str
        Header plus one line per momentum element in basis order.
    """
    header = f"{str(self)}:\n"
    body = "\t" + "\n\t".join(
        [f"{n}: {k}" for n, k in enumerate(self.structure.keys())]
    )
    return header + body

register_plot_method classmethod

register_plot_method(name: str, backend: str = 'plotly')

Register a backend plotting function for this plottable class.

The returned decorator stores the function in the global plotting registry. Registered functions receive the object being plotted as their first argument, followed by any extra positional and keyword arguments supplied to plot().

Parameters:

Name Type Description Default
name str

User-facing plot method name, such as scatter, structure, or heatmap.

required
backend str

Backend name that selects the implementation. The qten-plots extension currently uses plotly and matplotlib.

'plotly'

Returns:

Type Description
Callable

Decorator that registers the provided plotting function and returns it unchanged.

Source code in src/qten/plottings/_plottings.py
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
@classmethod
def register_plot_method(cls, name: str, backend: str = "plotly"):
    """
    Register a backend plotting function for this plottable class.

    The returned decorator stores the function in the global plotting
    registry. Registered functions receive the object being plotted as their
    first argument, followed by any extra positional and keyword arguments
    supplied to [`plot()`][qten.plottings.Plottable.plot].

    Parameters
    ----------
    name : str
        User-facing plot method name, such as `scatter`, `structure`, or
        `heatmap`.
    backend : str
        Backend name that selects the implementation. The `qten-plots`
        extension currently uses `plotly` and `matplotlib`.

    Returns
    -------
    Callable
        Decorator that registers the provided plotting function and returns
        it unchanged.
    """

    def decorator(func: Callable):
        # We register against 'cls' - the class this method was called on.
        Plottable._registry[(cls, name, backend)] = func
        return func

    return decorator

plot

plot(method: str, backend: str = 'plotly', *args, **kwargs)

Dispatch a named plot method to a registered backend implementation.

The dispatcher first loads plotting entry points, then searches the instance type and its base classes for a matching (type, method, backend) registration. Additional arguments are forwarded unchanged to the selected backend function.

Parameters:

Name Type Description Default
method str

Plot method name registered for this object's type.

required
backend str

Backend implementation to use. The qten-plots extension currently registers plotly and matplotlib.

'plotly'
args

Positional arguments forwarded to the registered plotting function.

()
kwargs

Keyword arguments forwarded to the registered plotting function.

{}

Returns:

Type Description
object

Backend-specific figure object returned by the registered plotting function, such as a Plotly or Matplotlib figure.

Raises:

Type Description
ValueError

If no plotting function is registered for the requested method and backend on this object.

See Also

qten_plots.plottables.PointCloud Public plottable helper object provided by the plotting extension.

Source code in src/qten/plottings/_plottings.py
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
def plot(self, method: str, backend: str = "plotly", *args, **kwargs):
    """
    Dispatch a named plot method to a registered backend implementation.

    The dispatcher first loads plotting entry points, then searches the
    instance type and its base classes for a matching `(type, method,
    backend)` registration. Additional arguments are forwarded unchanged to
    the selected backend function.

    Parameters
    ----------
    method : str
        Plot method name registered for this object's type.
    backend : str
        Backend implementation to use. The `qten-plots` extension currently
        registers `plotly` and `matplotlib`.
    args
        Positional arguments forwarded to the registered plotting function.
    kwargs
        Keyword arguments forwarded to the registered plotting function.

    Returns
    -------
    object
        Backend-specific figure object returned by the registered plotting
        function, such as a Plotly or Matplotlib figure.

    Raises
    ------
    ValueError
        If no plotting function is registered for the requested method and
        backend on this object.

    See Also
    --------
    qten_plots.plottables.PointCloud
        Public plottable helper object provided by the plotting extension.
    """
    Plottable._ensure_backends_loaded()

    # Iterate over the MRO (Method Resolution Order) of the instance
    for class_in_hierarchy in type(self).__mro__:
        key = (class_in_hierarchy, method, backend)

        # Check the central registry
        if key in Plottable._registry:
            plot_func = Plottable._registry[key]
            return plot_func(self, *args, **kwargs)

    # If we reach here, no method was found. Provide a helpful error.
    self._raise_method_not_found(method, backend)

elements

elements() -> tuple[T, ...]

Return the spatial elements as a tuple.

Source code in src/qten/symbolics/state_space.py
83
84
85
86
@override
def elements(self) -> Tuple[T, ...]:
    """Return the spatial elements as a tuple."""
    return tuple(self.structure.keys())

add_conversion classmethod

add_conversion(
    T: type[B],
) -> Callable[[Callable[[A], B]], Callable[[A], B]]

Register a conversion from cls to T.

The decorated function is stored under (cls, T). When an instance of cls later calls convert(T), that function is used to produce the converted object.

Parameters:

Name Type Description Default
T Type[B]

Destination type produced by the registered conversion function.

required

Returns:

Type Description
Callable[[Callable[[A], B]], Callable[[A], B]]

Decorator that stores the conversion function and returns it unchanged.

Examples:

@MyType.add_conversion(TargetType)
def to_target(x: MyType) -> TargetType:
    ...
Source code in src/qten/abstracts.py
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
@classmethod
def add_conversion(
    cls: Type[A], T: Type[B]
) -> Callable[[Callable[[A], B]], Callable[[A], B]]:
    """
    Register a conversion from `cls` to `T`.

    The decorated function is stored under `(cls, T)`. When an instance of
    `cls` later calls [`convert(T)`][qten.abstracts.Convertible.convert],
    that function is used to produce the converted object.

    Parameters
    ----------
    T : Type[B]
        Destination type produced by the registered conversion function.

    Returns
    -------
    Callable[[Callable[[A], B]], Callable[[A], B]]
        Decorator that stores the conversion function and returns it
        unchanged.

    Examples
    --------
    ```python
    @MyType.add_conversion(TargetType)
    def to_target(x: MyType) -> TargetType:
        ...
    ```
    """

    def decorator(func: Callable[[A], B]) -> Callable[[A], B]:
        _type_conversion_table[(cls, T)] = cast(Callable[[Any], Any], func)
        return func

    return decorator

convert

convert(T: type[B]) -> B

Convert this instance to the requested target type.

Parameters:

Name Type Description Default
T Type[B]

Destination type to convert into.

required

Returns:

Type Description
B

Converted object produced by the registered conversion function.

Raises:

Type Description
NotImplementedError

If no conversion function has been registered for (type(self), T) or any source supertype via add_conversion().

Source code in src/qten/abstracts.py
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
@final
def convert(self, T: Type[B]) -> B:
    """
    Convert this instance to the requested target type.

    Parameters
    ----------
    T : Type[B]
        Destination type to convert into.

    Returns
    -------
    B
        Converted object produced by the registered conversion function.

    Raises
    ------
    NotImplementedError
        If no conversion function has been registered for
        `(type(self), T)` or any source supertype via
        [`add_conversion()`][qten.abstracts.Convertible.add_conversion].
    """
    source_type = type(self)
    table_get = _type_conversion_table.get

    convertor = table_get((source_type, T))
    if convertor is None:
        for super_type in source_type.__mro__[1:]:
            convertor = table_get((super_type, T))
            if convertor is not None:
                # Cache resolved parent conversion under the concrete source type.
                _type_conversion_table[(source_type, T)] = convertor
                break

    if convertor is None:
        raise NotImplementedError(
            f"No conversion from {source_type.__name__} to {T.__name__}!"
        )
    return cast(Callable[["Convertible"], B], convertor)(self)

__len__

__len__() -> int

Return the number of spatial elements.

Source code in src/qten/symbolics/state_space.py
88
89
90
def __len__(self) -> int:
    """Return the number of spatial elements."""
    return len(self.structure)

__iter__

__iter__() -> Iterator[T]

Iterate over spatial elements.

Source code in src/qten/symbolics/state_space.py
92
93
94
def __iter__(self) -> Iterator[T]:
    """Iterate over spatial elements."""
    return iter(self.structure.keys())

__getitem__

__getitem__(v: int) -> T
__getitem__(v: slice | range) -> Self
__getitem__(v: Sequence[int]) -> Self

Index into the state-space by element position.

Supported forms

space[i] returns a single spatial element by position, including negative indices. space[start:stop:step] returns a new space with the selected elements in slice order. space[range(...)] returns a new space with the range-selected elements. space[[i, j, ...]] returns a new space with elements in explicit index order.

Parameters:

Name Type Description Default
key Union[int, slice, range, Sequence[int]]

Index selector. Sequences must contain unique integers; negative integers are normalized relative to len(self).

required

Returns:

Type Description
Spatial or StateSpace

A spatial element for int indexing, otherwise a new instance of the same class containing the selected elements. Any extra dataclass fields on subclasses are preserved in the returned instance.

Raises:

Type Description
IndexError

If an integer index is out of bounds.

TypeError

If key is not an int, slice, range, or sequence of integers.

ValueError

If a sequence selector contains duplicate indices.

Source code in src/qten/symbolics/state_space.py
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
def __getitem__(
    self, key: Union[int, slice, range, Sequence[int]]
) -> Union[T, "StateSpace[T]"]:
    """
    Index into the state-space by element position.

    Supported forms
    ---------------
    `space[i]` returns a single spatial element by position, including
    negative indices. `space[start:stop:step]` returns a new space with the
    selected elements in slice order. `space[range(...)]` returns a new
    space with the range-selected elements. `space[[i, j, ...]]` returns a
    new space with elements in explicit index order.

    Parameters
    ----------
    key : Union[int, slice, range, Sequence[int]]
        Index selector. Sequences must contain unique integers; negative
        integers are normalized relative to `len(self)`.

    Returns
    -------
    Spatial or StateSpace
        A spatial element for `int` indexing, otherwise a new instance of the
        same class containing the selected elements. Any extra dataclass fields
        on subclasses are preserved in the returned instance.

    Raises
    ------
    IndexError
        If an integer index is out of bounds.
    TypeError
        If `key` is not an `int`, `slice`, `range`, or sequence of integers.
    ValueError
        If a sequence selector contains duplicate indices.
    """
    if isinstance(key, int):
        if key < 0:
            key += len(self.structure)
        if key < 0 or key >= len(self.structure):
            raise IndexError("StateSpace index out of range")
        return next(islice(self.structure.keys(), key, None))
    if isinstance(key, slice):
        keys = tuple(self.structure.keys())[key]
        new_structure = OrderedDict((k, self.structure[k]) for k in keys)
        return replace(self, structure=restructure(new_structure))
    if isinstance(key, range):
        keys = tuple(self.structure.keys())
        new_structure = OrderedDict((keys[i], self.structure[keys[i]]) for i in key)
        return replace(self, structure=restructure(new_structure))
    if isinstance(key, Sequence) and not isinstance(key, (str, bytes)):
        keys = tuple(self.structure.keys())
        indices: list[int] = []
        seen = set()
        for idx in key:
            if isinstance(idx, bool) or not isinstance(idx, int):
                raise TypeError(
                    "StateSpace sequence indices must contain only integers"
                )
            normalized = idx
            if normalized < 0:
                normalized += len(keys)
            if normalized < 0 or normalized >= len(keys):
                raise IndexError("StateSpace index out of range")
            if normalized in seen:
                raise ValueError("StateSpace sequence indices must be unique")
            seen.add(normalized)
            indices.append(normalized)
        new_structure = OrderedDict(
            (keys[i], self.structure[keys[i]]) for i in indices
        )
        return replace(self, structure=restructure(new_structure))
    raise TypeError(
        "StateSpace indices must be int, slice, range, or a sequence of ints, "
        f"not {type(key)}"
    )

same_rays

same_rays(other: StateSpace) -> bool

Check if this state space has the same rays as another, i.e., they have the same set of spatial keys regardless of order.

Parameters:

Name Type Description Default
other StateSpace

The other state space to compare against.

required

Returns:

Type Description
bool

True if both state spaces have the same rays, False otherwise.

Source code in src/qten/symbolics/state_space.py
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
def same_rays(self, other: "StateSpace") -> bool:
    """
    Check if this state space has the same rays as another, i.e., they have the same set of spatial keys regardless of order.

    Parameters
    ----------
    other : StateSpace
        The other state space to compare against.

    Returns
    -------
    bool
        True if both state spaces have the same rays, `False` otherwise.
    """
    return same_rays(self, other)

map

map(func: Callable[[T], T]) -> Self

Map the spatial elements of this state space using a provided function.

Parameters:

Name Type Description Default
func Callable[[T], T]

A function that takes a spatial element and returns a transformed spatial element.

required

Returns:

Type Description
Self

A new state space with the transformed spatial elements.

Source code in src/qten/symbolics/state_space.py
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
def map(self, func: Callable[[T], T]) -> "Self":
    """
    Map the spatial elements of this state space using a provided function.

    Parameters
    ----------
    func : Callable[[T], T]
        A function that takes a spatial element and returns a transformed spatial element.

    Returns
    -------
    Self
        A new state space with the transformed spatial elements.
    """
    new_structure = OrderedDict()
    for k, s in self.structure.items():
        new_k = func(k)
        new_structure[new_k] = s
    return replace(self, structure=restructure(new_structure))

filter

filter(pred: Callable[[T], bool]) -> Self

Return the subspace containing elements where pred(element) is True.

Parameters:

Name Type Description Default
pred Callable[[T], bool]

Predicate applied to each element in basis order.

required

Returns:

Type Description
Self

A new state space of the same concrete type containing only the selected elements, with indices repacked contiguously.

Source code in src/qten/symbolics/state_space.py
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
def filter(self, pred: Callable[[T], bool]) -> "Self":
    """
    Return the subspace containing elements where `pred(element)` is `True`.

    Parameters
    ----------
    pred : Callable[[T], bool]
        Predicate applied to each element in basis order.

    Returns
    -------
    Self
        A new state space of the same concrete type containing only the
        selected elements, with indices repacked contiguously.
    """
    new_structure = OrderedDict(
        (k, s) for k, s in self.structure.items() if pred(k)
    )
    return replace(self, structure=restructure(new_structure))

tensor_product

tensor_product(other: Self) -> Self

Return the tensor-product state space of this space and another space.

This method defines the protocol used by the @ operator on StateSpace instances. The base class cannot construct a generic product because it does not know how to combine two elements of type T. Concrete subclasses must implement the element-level product and rebuild a contiguous structure for the resulting basis.

Implementations should preserve deterministic product ordering. The convention used by concrete tensor-product spaces in QTen is the Cartesian product order of self.elements() and other.elements(), where elements from self vary slowest and elements from other vary fastest. The returned space should be the same concrete state-space family when the operation is closed over that family.

Parameters:

Name Type Description Default
other StateSpace

Right-hand tensor factor. Implementations may require other to be the same concrete state-space type as self.

required

Returns:

Type Description
StateSpace

New state space representing self ⊗ other, with contiguous integer indices in the implementation-defined product order.

Raises:

Type Description
NotImplementedError

Always raised by the base class. Subclasses that support tensor products must override this method.

Source code in src/qten/symbolics/state_space.py
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
def tensor_product(self, other: Self) -> Self:
    """
    Return the tensor-product state space of this space and another space.

    This method defines the protocol used by the `@` operator on
    [`StateSpace`][qten.symbolics.state_space.StateSpace] instances. The
    base class cannot construct a generic product because it does not know
    how to combine two elements of type `T`. Concrete subclasses must
    implement the element-level product and rebuild a contiguous
    `structure` for the resulting basis.

    Implementations should preserve deterministic product ordering. The
    convention used by concrete tensor-product spaces in QTen is the
    Cartesian product order of `self.elements()` and `other.elements()`,
    where elements from `self` vary slowest and elements from `other` vary
    fastest. The returned space should be the same concrete state-space
    family when the operation is closed over that family.

    Parameters
    ----------
    other : StateSpace
        Right-hand tensor factor. Implementations may require `other` to be
        the same concrete state-space type as `self`.

    Returns
    -------
    StateSpace
        New state space representing `self ⊗ other`, with contiguous
        integer indices in the implementation-defined product order.

    Raises
    ------
    NotImplementedError
        Always raised by the base class. Subclasses that support tensor
        products must override this method.
    """
    raise NotImplementedError(f"Tensor product not implemented for {type(self)}!")

extract

extract(info_type: type[Any]) -> Any

Extract an object implied by the elements of this state space.

Subclasses may register specialized implementations for supported target types.

Parameters:

Name Type Description Default
info_type type[Any]

Type of metadata or object to extract from this state space.

required

Returns:

Type Description
Any

Extracted object produced by a registered specialization.

Raises:

Type Description
NotImplementedError

If no extraction rule is registered for info_type.

Source code in src/qten/symbolics/state_space.py
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
@multimethod
def extract(self, info_type: type[Any]) -> Any:
    """
    Extract an object implied by the elements of this state space.

    Subclasses may register specialized implementations for supported
    target types.

    Parameters
    ----------
    info_type : type[Any]
        Type of metadata or object to extract from this state space.

    Returns
    -------
    Any
        Extracted object produced by a registered specialization.

    Raises
    ------
    NotImplementedError
        If no extraction rule is registered for `info_type`.
    """
    raise NotImplementedError(
        f"Extraction of {info_type} from {type(self)} is not supported!"
    )

BzPath dataclass

BzPath(
    k_space: MomentumSpace,
    labels: tuple,
    waypoint_indices: tuple,
    path_order: tuple,
    path_positions: tuple,
)

A Brillouin-zone path through high-symmetry waypoints.

Attributes:

Name Type Description
k_space MomentumSpace

Unique momentum points sampled along the path.

labels tuple

Labels for the waypoints in path order.

waypoint_indices tuple

Indices into the dense path where each waypoint occurs.

path_order tuple

For each dense path sample, index of the corresponding unique momentum in k_space.

path_positions tuple

Cumulative Cartesian arc-length coordinate for each dense path sample.

k_space instance-attribute

k_space: MomentumSpace

Unique momentum points sampled along the path, with duplicates across segments removed while preserving the path's effective traversal order.

labels instance-attribute

labels: tuple

Labels for the waypoints in path order, typically high-symmetry point names used for plotting.

waypoint_indices instance-attribute

waypoint_indices: tuple

Indices into the dense path where each waypoint occurs, suitable for axis ticks or segment markers in band-structure plots.

path_order instance-attribute

path_order: tuple

For each dense path sample, index of the corresponding unique momentum in k_space. This maps the full piecewise-linear path back onto the unique momentum list.

path_positions instance-attribute

path_positions: tuple

Cumulative Cartesian arc-length coordinate for each dense path sample, used as the continuous x-axis parameter along the path.

BroadcastSpace dataclass

BroadcastSpace(structure: OrderedDict[T, int])

Bases: StateSpace[_BAxis]

Metadata marker for singleton/broadcast tensor axes.

Design intent

BroadcastSpace represents an axis that behaves like a size-1 axis under tensor broadcasting. It is used to model dimensions introduced by unsqueeze, None indexing, or other operations where data may be expanded without introducing a concrete physical basis.

Structure semantics

BroadcastSpace stores a private singleton marker in structure: OrderedDict({_BAxis(): 0}). This keeps the axis dimension at 1 while still providing a stable coordinate for structure-based index mapping helpers.

Implication for index mapping

For BroadcastSpace -> BroadcastSpace, embedding_order(...) resolves to (0,). This is intentional and allows consumers that build runtime index coordinates from structure mappings to treat broadcast axes as a singleton axis at position 0.

The _BAxis marker is internal implementation detail. It is not a physical basis element and should not be relied on outside broadcast-axis plumbing.

Compatibility rules

Multimethod rules in this module treat BroadcastSpace as compatible with any StateSpace in same_rays(...), and as neutral in __add__(...). The neutral-addition behavior is BroadcastSpace + X -> X, X + BroadcastSpace -> X, and BroadcastSpace + BroadcastSpace -> BroadcastSpace.

This makes it suitable as a placeholder axis that can be promoted to a concrete state space during alignment/broadcast operations.

Attributes:

Name Type Description
structure OrderedDict

Private singleton mapping OrderedDict({_BAxis(): 0}) used to encode a size-1 broadcast axis.

structure class-attribute instance-attribute

structure: OrderedDict[_BAxis, int] = field(
    default_factory=lambda: OrderedDict({_BAxis(): 0}),
    init=False,
)

Private singleton mapping OrderedDict({_BAxis(): 0}) used to encode a size-1 broadcast axis. The stored marker is internal and exists only so structure-based helpers can consistently refer to the unique broadcast slot.

__str__ class-attribute instance-attribute

__str__ = __repr__

dim property

dim: int

The total size of the vector space.

__hash__

__hash__() -> int

Return a hash for the singleton broadcast-axis structure.

BroadcastSpace hashes the same ordered structure snapshot as StateSpace. Because the structure always contains one private _BAxis marker at index 0, the hash represents this singleton broadcast dimension rather than a physical basis element.

Returns:

Type Description
int

Hash value for the ordered singleton (_BAxis(), 0) mapping.

Source code in src/qten/symbolics/state_space.py
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
def __hash__(self) -> int:
    """
    Return a hash for the singleton broadcast-axis structure.

    [`BroadcastSpace`][qten.symbolics.state_space.BroadcastSpace] hashes the
    same ordered structure snapshot as
    [`StateSpace`][qten.symbolics.state_space.StateSpace]. Because the
    structure always contains one private `_BAxis` marker at index `0`, the
    hash represents this singleton broadcast dimension rather than a
    physical basis element.

    Returns
    -------
    int
        Hash value for the ordered singleton `(_BAxis(), 0)` mapping.
    """
    return StateSpace.__hash__(self)

__repr__

__repr__()

Return the broadcast-axis marker representation.

Returns:

Type Description
str

The literal string "BroadcastSpace".

Source code in src/qten/symbolics/state_space.py
771
772
773
774
775
776
777
778
779
780
def __repr__(self):
    """
    Return the broadcast-axis marker representation.

    Returns
    -------
    str
        The literal string `"BroadcastSpace"`.
    """
    return "BroadcastSpace"

register_plot_method classmethod

register_plot_method(name: str, backend: str = 'plotly')

Register a backend plotting function for this plottable class.

The returned decorator stores the function in the global plotting registry. Registered functions receive the object being plotted as their first argument, followed by any extra positional and keyword arguments supplied to plot().

Parameters:

Name Type Description Default
name str

User-facing plot method name, such as scatter, structure, or heatmap.

required
backend str

Backend name that selects the implementation. The qten-plots extension currently uses plotly and matplotlib.

'plotly'

Returns:

Type Description
Callable

Decorator that registers the provided plotting function and returns it unchanged.

Source code in src/qten/plottings/_plottings.py
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
@classmethod
def register_plot_method(cls, name: str, backend: str = "plotly"):
    """
    Register a backend plotting function for this plottable class.

    The returned decorator stores the function in the global plotting
    registry. Registered functions receive the object being plotted as their
    first argument, followed by any extra positional and keyword arguments
    supplied to [`plot()`][qten.plottings.Plottable.plot].

    Parameters
    ----------
    name : str
        User-facing plot method name, such as `scatter`, `structure`, or
        `heatmap`.
    backend : str
        Backend name that selects the implementation. The `qten-plots`
        extension currently uses `plotly` and `matplotlib`.

    Returns
    -------
    Callable
        Decorator that registers the provided plotting function and returns
        it unchanged.
    """

    def decorator(func: Callable):
        # We register against 'cls' - the class this method was called on.
        Plottable._registry[(cls, name, backend)] = func
        return func

    return decorator

plot

plot(method: str, backend: str = 'plotly', *args, **kwargs)

Dispatch a named plot method to a registered backend implementation.

The dispatcher first loads plotting entry points, then searches the instance type and its base classes for a matching (type, method, backend) registration. Additional arguments are forwarded unchanged to the selected backend function.

Parameters:

Name Type Description Default
method str

Plot method name registered for this object's type.

required
backend str

Backend implementation to use. The qten-plots extension currently registers plotly and matplotlib.

'plotly'
args

Positional arguments forwarded to the registered plotting function.

()
kwargs

Keyword arguments forwarded to the registered plotting function.

{}

Returns:

Type Description
object

Backend-specific figure object returned by the registered plotting function, such as a Plotly or Matplotlib figure.

Raises:

Type Description
ValueError

If no plotting function is registered for the requested method and backend on this object.

See Also

qten_plots.plottables.PointCloud Public plottable helper object provided by the plotting extension.

Source code in src/qten/plottings/_plottings.py
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
def plot(self, method: str, backend: str = "plotly", *args, **kwargs):
    """
    Dispatch a named plot method to a registered backend implementation.

    The dispatcher first loads plotting entry points, then searches the
    instance type and its base classes for a matching `(type, method,
    backend)` registration. Additional arguments are forwarded unchanged to
    the selected backend function.

    Parameters
    ----------
    method : str
        Plot method name registered for this object's type.
    backend : str
        Backend implementation to use. The `qten-plots` extension currently
        registers `plotly` and `matplotlib`.
    args
        Positional arguments forwarded to the registered plotting function.
    kwargs
        Keyword arguments forwarded to the registered plotting function.

    Returns
    -------
    object
        Backend-specific figure object returned by the registered plotting
        function, such as a Plotly or Matplotlib figure.

    Raises
    ------
    ValueError
        If no plotting function is registered for the requested method and
        backend on this object.

    See Also
    --------
    qten_plots.plottables.PointCloud
        Public plottable helper object provided by the plotting extension.
    """
    Plottable._ensure_backends_loaded()

    # Iterate over the MRO (Method Resolution Order) of the instance
    for class_in_hierarchy in type(self).__mro__:
        key = (class_in_hierarchy, method, backend)

        # Check the central registry
        if key in Plottable._registry:
            plot_func = Plottable._registry[key]
            return plot_func(self, *args, **kwargs)

    # If we reach here, no method was found. Provide a helpful error.
    self._raise_method_not_found(method, backend)

elements

elements() -> tuple[T, ...]

Return the spatial elements as a tuple.

Source code in src/qten/symbolics/state_space.py
83
84
85
86
@override
def elements(self) -> Tuple[T, ...]:
    """Return the spatial elements as a tuple."""
    return tuple(self.structure.keys())

add_conversion classmethod

add_conversion(
    T: type[B],
) -> Callable[[Callable[[A], B]], Callable[[A], B]]

Register a conversion from cls to T.

The decorated function is stored under (cls, T). When an instance of cls later calls convert(T), that function is used to produce the converted object.

Parameters:

Name Type Description Default
T Type[B]

Destination type produced by the registered conversion function.

required

Returns:

Type Description
Callable[[Callable[[A], B]], Callable[[A], B]]

Decorator that stores the conversion function and returns it unchanged.

Examples:

@MyType.add_conversion(TargetType)
def to_target(x: MyType) -> TargetType:
    ...
Source code in src/qten/abstracts.py
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
@classmethod
def add_conversion(
    cls: Type[A], T: Type[B]
) -> Callable[[Callable[[A], B]], Callable[[A], B]]:
    """
    Register a conversion from `cls` to `T`.

    The decorated function is stored under `(cls, T)`. When an instance of
    `cls` later calls [`convert(T)`][qten.abstracts.Convertible.convert],
    that function is used to produce the converted object.

    Parameters
    ----------
    T : Type[B]
        Destination type produced by the registered conversion function.

    Returns
    -------
    Callable[[Callable[[A], B]], Callable[[A], B]]
        Decorator that stores the conversion function and returns it
        unchanged.

    Examples
    --------
    ```python
    @MyType.add_conversion(TargetType)
    def to_target(x: MyType) -> TargetType:
        ...
    ```
    """

    def decorator(func: Callable[[A], B]) -> Callable[[A], B]:
        _type_conversion_table[(cls, T)] = cast(Callable[[Any], Any], func)
        return func

    return decorator

convert

convert(T: type[B]) -> B

Convert this instance to the requested target type.

Parameters:

Name Type Description Default
T Type[B]

Destination type to convert into.

required

Returns:

Type Description
B

Converted object produced by the registered conversion function.

Raises:

Type Description
NotImplementedError

If no conversion function has been registered for (type(self), T) or any source supertype via add_conversion().

Source code in src/qten/abstracts.py
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
@final
def convert(self, T: Type[B]) -> B:
    """
    Convert this instance to the requested target type.

    Parameters
    ----------
    T : Type[B]
        Destination type to convert into.

    Returns
    -------
    B
        Converted object produced by the registered conversion function.

    Raises
    ------
    NotImplementedError
        If no conversion function has been registered for
        `(type(self), T)` or any source supertype via
        [`add_conversion()`][qten.abstracts.Convertible.add_conversion].
    """
    source_type = type(self)
    table_get = _type_conversion_table.get

    convertor = table_get((source_type, T))
    if convertor is None:
        for super_type in source_type.__mro__[1:]:
            convertor = table_get((super_type, T))
            if convertor is not None:
                # Cache resolved parent conversion under the concrete source type.
                _type_conversion_table[(source_type, T)] = convertor
                break

    if convertor is None:
        raise NotImplementedError(
            f"No conversion from {source_type.__name__} to {T.__name__}!"
        )
    return cast(Callable[["Convertible"], B], convertor)(self)

__len__

__len__() -> int

Return the number of spatial elements.

Source code in src/qten/symbolics/state_space.py
88
89
90
def __len__(self) -> int:
    """Return the number of spatial elements."""
    return len(self.structure)

__iter__

__iter__() -> Iterator[T]

Iterate over spatial elements.

Source code in src/qten/symbolics/state_space.py
92
93
94
def __iter__(self) -> Iterator[T]:
    """Iterate over spatial elements."""
    return iter(self.structure.keys())

__getitem__

__getitem__(v: int) -> T
__getitem__(v: slice | range) -> Self
__getitem__(v: Sequence[int]) -> Self

Index into the state-space by element position.

Supported forms

space[i] returns a single spatial element by position, including negative indices. space[start:stop:step] returns a new space with the selected elements in slice order. space[range(...)] returns a new space with the range-selected elements. space[[i, j, ...]] returns a new space with elements in explicit index order.

Parameters:

Name Type Description Default
key Union[int, slice, range, Sequence[int]]

Index selector. Sequences must contain unique integers; negative integers are normalized relative to len(self).

required

Returns:

Type Description
Spatial or StateSpace

A spatial element for int indexing, otherwise a new instance of the same class containing the selected elements. Any extra dataclass fields on subclasses are preserved in the returned instance.

Raises:

Type Description
IndexError

If an integer index is out of bounds.

TypeError

If key is not an int, slice, range, or sequence of integers.

ValueError

If a sequence selector contains duplicate indices.

Source code in src/qten/symbolics/state_space.py
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
def __getitem__(
    self, key: Union[int, slice, range, Sequence[int]]
) -> Union[T, "StateSpace[T]"]:
    """
    Index into the state-space by element position.

    Supported forms
    ---------------
    `space[i]` returns a single spatial element by position, including
    negative indices. `space[start:stop:step]` returns a new space with the
    selected elements in slice order. `space[range(...)]` returns a new
    space with the range-selected elements. `space[[i, j, ...]]` returns a
    new space with elements in explicit index order.

    Parameters
    ----------
    key : Union[int, slice, range, Sequence[int]]
        Index selector. Sequences must contain unique integers; negative
        integers are normalized relative to `len(self)`.

    Returns
    -------
    Spatial or StateSpace
        A spatial element for `int` indexing, otherwise a new instance of the
        same class containing the selected elements. Any extra dataclass fields
        on subclasses are preserved in the returned instance.

    Raises
    ------
    IndexError
        If an integer index is out of bounds.
    TypeError
        If `key` is not an `int`, `slice`, `range`, or sequence of integers.
    ValueError
        If a sequence selector contains duplicate indices.
    """
    if isinstance(key, int):
        if key < 0:
            key += len(self.structure)
        if key < 0 or key >= len(self.structure):
            raise IndexError("StateSpace index out of range")
        return next(islice(self.structure.keys(), key, None))
    if isinstance(key, slice):
        keys = tuple(self.structure.keys())[key]
        new_structure = OrderedDict((k, self.structure[k]) for k in keys)
        return replace(self, structure=restructure(new_structure))
    if isinstance(key, range):
        keys = tuple(self.structure.keys())
        new_structure = OrderedDict((keys[i], self.structure[keys[i]]) for i in key)
        return replace(self, structure=restructure(new_structure))
    if isinstance(key, Sequence) and not isinstance(key, (str, bytes)):
        keys = tuple(self.structure.keys())
        indices: list[int] = []
        seen = set()
        for idx in key:
            if isinstance(idx, bool) or not isinstance(idx, int):
                raise TypeError(
                    "StateSpace sequence indices must contain only integers"
                )
            normalized = idx
            if normalized < 0:
                normalized += len(keys)
            if normalized < 0 or normalized >= len(keys):
                raise IndexError("StateSpace index out of range")
            if normalized in seen:
                raise ValueError("StateSpace sequence indices must be unique")
            seen.add(normalized)
            indices.append(normalized)
        new_structure = OrderedDict(
            (keys[i], self.structure[keys[i]]) for i in indices
        )
        return replace(self, structure=restructure(new_structure))
    raise TypeError(
        "StateSpace indices must be int, slice, range, or a sequence of ints, "
        f"not {type(key)}"
    )

same_rays

same_rays(other: StateSpace) -> bool

Check if this state space has the same rays as another, i.e., they have the same set of spatial keys regardless of order.

Parameters:

Name Type Description Default
other StateSpace

The other state space to compare against.

required

Returns:

Type Description
bool

True if both state spaces have the same rays, False otherwise.

Source code in src/qten/symbolics/state_space.py
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
def same_rays(self, other: "StateSpace") -> bool:
    """
    Check if this state space has the same rays as another, i.e., they have the same set of spatial keys regardless of order.

    Parameters
    ----------
    other : StateSpace
        The other state space to compare against.

    Returns
    -------
    bool
        True if both state spaces have the same rays, `False` otherwise.
    """
    return same_rays(self, other)

map

map(func: Callable[[T], T]) -> Self

Map the spatial elements of this state space using a provided function.

Parameters:

Name Type Description Default
func Callable[[T], T]

A function that takes a spatial element and returns a transformed spatial element.

required

Returns:

Type Description
Self

A new state space with the transformed spatial elements.

Source code in src/qten/symbolics/state_space.py
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
def map(self, func: Callable[[T], T]) -> "Self":
    """
    Map the spatial elements of this state space using a provided function.

    Parameters
    ----------
    func : Callable[[T], T]
        A function that takes a spatial element and returns a transformed spatial element.

    Returns
    -------
    Self
        A new state space with the transformed spatial elements.
    """
    new_structure = OrderedDict()
    for k, s in self.structure.items():
        new_k = func(k)
        new_structure[new_k] = s
    return replace(self, structure=restructure(new_structure))

filter

filter(pred: Callable[[T], bool]) -> Self

Return the subspace containing elements where pred(element) is True.

Parameters:

Name Type Description Default
pred Callable[[T], bool]

Predicate applied to each element in basis order.

required

Returns:

Type Description
Self

A new state space of the same concrete type containing only the selected elements, with indices repacked contiguously.

Source code in src/qten/symbolics/state_space.py
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
def filter(self, pred: Callable[[T], bool]) -> "Self":
    """
    Return the subspace containing elements where `pred(element)` is `True`.

    Parameters
    ----------
    pred : Callable[[T], bool]
        Predicate applied to each element in basis order.

    Returns
    -------
    Self
        A new state space of the same concrete type containing only the
        selected elements, with indices repacked contiguously.
    """
    new_structure = OrderedDict(
        (k, s) for k, s in self.structure.items() if pred(k)
    )
    return replace(self, structure=restructure(new_structure))

tensor_product

tensor_product(other: Self) -> Self

Return the tensor-product state space of this space and another space.

This method defines the protocol used by the @ operator on StateSpace instances. The base class cannot construct a generic product because it does not know how to combine two elements of type T. Concrete subclasses must implement the element-level product and rebuild a contiguous structure for the resulting basis.

Implementations should preserve deterministic product ordering. The convention used by concrete tensor-product spaces in QTen is the Cartesian product order of self.elements() and other.elements(), where elements from self vary slowest and elements from other vary fastest. The returned space should be the same concrete state-space family when the operation is closed over that family.

Parameters:

Name Type Description Default
other StateSpace

Right-hand tensor factor. Implementations may require other to be the same concrete state-space type as self.

required

Returns:

Type Description
StateSpace

New state space representing self ⊗ other, with contiguous integer indices in the implementation-defined product order.

Raises:

Type Description
NotImplementedError

Always raised by the base class. Subclasses that support tensor products must override this method.

Source code in src/qten/symbolics/state_space.py
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
def tensor_product(self, other: Self) -> Self:
    """
    Return the tensor-product state space of this space and another space.

    This method defines the protocol used by the `@` operator on
    [`StateSpace`][qten.symbolics.state_space.StateSpace] instances. The
    base class cannot construct a generic product because it does not know
    how to combine two elements of type `T`. Concrete subclasses must
    implement the element-level product and rebuild a contiguous
    `structure` for the resulting basis.

    Implementations should preserve deterministic product ordering. The
    convention used by concrete tensor-product spaces in QTen is the
    Cartesian product order of `self.elements()` and `other.elements()`,
    where elements from `self` vary slowest and elements from `other` vary
    fastest. The returned space should be the same concrete state-space
    family when the operation is closed over that family.

    Parameters
    ----------
    other : StateSpace
        Right-hand tensor factor. Implementations may require `other` to be
        the same concrete state-space type as `self`.

    Returns
    -------
    StateSpace
        New state space representing `self ⊗ other`, with contiguous
        integer indices in the implementation-defined product order.

    Raises
    ------
    NotImplementedError
        Always raised by the base class. Subclasses that support tensor
        products must override this method.
    """
    raise NotImplementedError(f"Tensor product not implemented for {type(self)}!")

extract

extract(info_type: type[Any]) -> Any

Extract an object implied by the elements of this state space.

Subclasses may register specialized implementations for supported target types.

Parameters:

Name Type Description Default
info_type type[Any]

Type of metadata or object to extract from this state space.

required

Returns:

Type Description
Any

Extracted object produced by a registered specialization.

Raises:

Type Description
NotImplementedError

If no extraction rule is registered for info_type.

Source code in src/qten/symbolics/state_space.py
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
@multimethod
def extract(self, info_type: type[Any]) -> Any:
    """
    Extract an object implied by the elements of this state space.

    Subclasses may register specialized implementations for supported
    target types.

    Parameters
    ----------
    info_type : type[Any]
        Type of metadata or object to extract from this state space.

    Returns
    -------
    Any
        Extracted object produced by a registered specialization.

    Raises
    ------
    NotImplementedError
        If no extraction rule is registered for `info_type`.
    """
    raise NotImplementedError(
        f"Extraction of {info_type} from {type(self)} is not supported!"
    )

IndexSpace dataclass

IndexSpace(structure: OrderedDict[T, int])

Bases: StateSpace[int]

A simple state space where the spatial elements are just integer indices. This can be useful for representing generic tensor dimensions that don't have a specific physical interpretation, such as the virtual bond dimension in a TNS.

dim property

dim: int

The total size of the vector space.

structure instance-attribute

structure: OrderedDict[T, int]

An ordered dictionary mapping each spatial component (e.g., Offset, Momentum) to its single flattened index.

__hash__

__hash__() -> int

Return a hash derived from the ordered integer-index structure.

IndexSpace uses the same structure-based hash as StateSpace. The hash includes each integer element and its stored basis index in order. For spaces produced by linear(size), this is the hash of the canonical mapping 0 -> 0, 1 -> 1, and so on.

Returns:

Type Description
int

Hash value for the ordered (int, index) mapping.

Source code in src/qten/symbolics/state_space.py
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
def __hash__(self) -> int:
    """
    Return a hash derived from the ordered integer-index structure.

    [`IndexSpace`][qten.symbolics.state_space.IndexSpace] uses the same
    structure-based hash as
    [`StateSpace`][qten.symbolics.state_space.StateSpace]. The hash includes
    each integer element and its stored basis index in order. For spaces
    produced by [`linear(size)`][qten.symbolics.state_space.IndexSpace.linear],
    this is the hash of the canonical mapping `0 -> 0`, `1 -> 1`, and so on.

    Returns
    -------
    int
        Hash value for the ordered `(int, index)` mapping.
    """
    return StateSpace.__hash__(self)

linear staticmethod

linear(size: int) -> IndexSpace

Build a contiguous index space of length size.

The resulting space contains integer keys 0..size-1, each mapped to the same integer index.

Parameters:

Name Type Description Default
size int

Number of indices in the space.

required

Returns:

Type Description
IndexSpace

A contiguous IndexSpace with canonical linear ordering.

Raises:

Type Description
ValueError

If size is negative.

Source code in src/qten/symbolics/state_space.py
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
@staticmethod
def linear(size: int) -> "IndexSpace":
    """
    Build a contiguous index space of length [`size`][qten.geometries.spatials.ReciprocalLattice.size].

    The resulting space contains integer keys `0..size-1`, each mapped to
    the same integer index.

    Parameters
    ----------
    size : int
        Number of indices in the space.

    Returns
    -------
    IndexSpace
        A contiguous [`IndexSpace`][qten.symbolics.state_space.IndexSpace] with canonical linear ordering.

    Raises
    ------
    ValueError
        If [`size`][qten.geometries.spatials.ReciprocalLattice.size] is negative.
    """
    if size < 0:
        raise ValueError("IndexSpace size must be non-negative.")
    return IndexSpace(OrderedDict((i, i) for i in range(size)))

__str__

__str__()

Return a compact index-space summary.

Returns:

Type Description
str

Summary containing the index-space size.

Source code in src/qten/symbolics/state_space.py
870
871
872
873
874
875
876
877
878
879
def __str__(self):
    """
    Return a compact index-space summary.

    Returns
    -------
    str
        Summary containing the index-space size.
    """
    return f"IndexSpace(size={self.dim})"

__repr__

__repr__()

Return the developer representation of this index space.

Returns:

Type Description
str

Same value as str(self).

Source code in src/qten/symbolics/state_space.py
881
882
883
884
885
886
887
888
889
890
def __repr__(self):
    """
    Return the developer representation of this index space.

    Returns
    -------
    str
        Same value as `str(self)`.
    """
    return str(self)

register_plot_method classmethod

register_plot_method(name: str, backend: str = 'plotly')

Register a backend plotting function for this plottable class.

The returned decorator stores the function in the global plotting registry. Registered functions receive the object being plotted as their first argument, followed by any extra positional and keyword arguments supplied to plot().

Parameters:

Name Type Description Default
name str

User-facing plot method name, such as scatter, structure, or heatmap.

required
backend str

Backend name that selects the implementation. The qten-plots extension currently uses plotly and matplotlib.

'plotly'

Returns:

Type Description
Callable

Decorator that registers the provided plotting function and returns it unchanged.

Source code in src/qten/plottings/_plottings.py
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
@classmethod
def register_plot_method(cls, name: str, backend: str = "plotly"):
    """
    Register a backend plotting function for this plottable class.

    The returned decorator stores the function in the global plotting
    registry. Registered functions receive the object being plotted as their
    first argument, followed by any extra positional and keyword arguments
    supplied to [`plot()`][qten.plottings.Plottable.plot].

    Parameters
    ----------
    name : str
        User-facing plot method name, such as `scatter`, `structure`, or
        `heatmap`.
    backend : str
        Backend name that selects the implementation. The `qten-plots`
        extension currently uses `plotly` and `matplotlib`.

    Returns
    -------
    Callable
        Decorator that registers the provided plotting function and returns
        it unchanged.
    """

    def decorator(func: Callable):
        # We register against 'cls' - the class this method was called on.
        Plottable._registry[(cls, name, backend)] = func
        return func

    return decorator

plot

plot(method: str, backend: str = 'plotly', *args, **kwargs)

Dispatch a named plot method to a registered backend implementation.

The dispatcher first loads plotting entry points, then searches the instance type and its base classes for a matching (type, method, backend) registration. Additional arguments are forwarded unchanged to the selected backend function.

Parameters:

Name Type Description Default
method str

Plot method name registered for this object's type.

required
backend str

Backend implementation to use. The qten-plots extension currently registers plotly and matplotlib.

'plotly'
args

Positional arguments forwarded to the registered plotting function.

()
kwargs

Keyword arguments forwarded to the registered plotting function.

{}

Returns:

Type Description
object

Backend-specific figure object returned by the registered plotting function, such as a Plotly or Matplotlib figure.

Raises:

Type Description
ValueError

If no plotting function is registered for the requested method and backend on this object.

See Also

qten_plots.plottables.PointCloud Public plottable helper object provided by the plotting extension.

Source code in src/qten/plottings/_plottings.py
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
def plot(self, method: str, backend: str = "plotly", *args, **kwargs):
    """
    Dispatch a named plot method to a registered backend implementation.

    The dispatcher first loads plotting entry points, then searches the
    instance type and its base classes for a matching `(type, method,
    backend)` registration. Additional arguments are forwarded unchanged to
    the selected backend function.

    Parameters
    ----------
    method : str
        Plot method name registered for this object's type.
    backend : str
        Backend implementation to use. The `qten-plots` extension currently
        registers `plotly` and `matplotlib`.
    args
        Positional arguments forwarded to the registered plotting function.
    kwargs
        Keyword arguments forwarded to the registered plotting function.

    Returns
    -------
    object
        Backend-specific figure object returned by the registered plotting
        function, such as a Plotly or Matplotlib figure.

    Raises
    ------
    ValueError
        If no plotting function is registered for the requested method and
        backend on this object.

    See Also
    --------
    qten_plots.plottables.PointCloud
        Public plottable helper object provided by the plotting extension.
    """
    Plottable._ensure_backends_loaded()

    # Iterate over the MRO (Method Resolution Order) of the instance
    for class_in_hierarchy in type(self).__mro__:
        key = (class_in_hierarchy, method, backend)

        # Check the central registry
        if key in Plottable._registry:
            plot_func = Plottable._registry[key]
            return plot_func(self, *args, **kwargs)

    # If we reach here, no method was found. Provide a helpful error.
    self._raise_method_not_found(method, backend)

elements

elements() -> tuple[T, ...]

Return the spatial elements as a tuple.

Source code in src/qten/symbolics/state_space.py
83
84
85
86
@override
def elements(self) -> Tuple[T, ...]:
    """Return the spatial elements as a tuple."""
    return tuple(self.structure.keys())

add_conversion classmethod

add_conversion(
    T: type[B],
) -> Callable[[Callable[[A], B]], Callable[[A], B]]

Register a conversion from cls to T.

The decorated function is stored under (cls, T). When an instance of cls later calls convert(T), that function is used to produce the converted object.

Parameters:

Name Type Description Default
T Type[B]

Destination type produced by the registered conversion function.

required

Returns:

Type Description
Callable[[Callable[[A], B]], Callable[[A], B]]

Decorator that stores the conversion function and returns it unchanged.

Examples:

@MyType.add_conversion(TargetType)
def to_target(x: MyType) -> TargetType:
    ...
Source code in src/qten/abstracts.py
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
@classmethod
def add_conversion(
    cls: Type[A], T: Type[B]
) -> Callable[[Callable[[A], B]], Callable[[A], B]]:
    """
    Register a conversion from `cls` to `T`.

    The decorated function is stored under `(cls, T)`. When an instance of
    `cls` later calls [`convert(T)`][qten.abstracts.Convertible.convert],
    that function is used to produce the converted object.

    Parameters
    ----------
    T : Type[B]
        Destination type produced by the registered conversion function.

    Returns
    -------
    Callable[[Callable[[A], B]], Callable[[A], B]]
        Decorator that stores the conversion function and returns it
        unchanged.

    Examples
    --------
    ```python
    @MyType.add_conversion(TargetType)
    def to_target(x: MyType) -> TargetType:
        ...
    ```
    """

    def decorator(func: Callable[[A], B]) -> Callable[[A], B]:
        _type_conversion_table[(cls, T)] = cast(Callable[[Any], Any], func)
        return func

    return decorator

convert

convert(T: type[B]) -> B

Convert this instance to the requested target type.

Parameters:

Name Type Description Default
T Type[B]

Destination type to convert into.

required

Returns:

Type Description
B

Converted object produced by the registered conversion function.

Raises:

Type Description
NotImplementedError

If no conversion function has been registered for (type(self), T) or any source supertype via add_conversion().

Source code in src/qten/abstracts.py
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
@final
def convert(self, T: Type[B]) -> B:
    """
    Convert this instance to the requested target type.

    Parameters
    ----------
    T : Type[B]
        Destination type to convert into.

    Returns
    -------
    B
        Converted object produced by the registered conversion function.

    Raises
    ------
    NotImplementedError
        If no conversion function has been registered for
        `(type(self), T)` or any source supertype via
        [`add_conversion()`][qten.abstracts.Convertible.add_conversion].
    """
    source_type = type(self)
    table_get = _type_conversion_table.get

    convertor = table_get((source_type, T))
    if convertor is None:
        for super_type in source_type.__mro__[1:]:
            convertor = table_get((super_type, T))
            if convertor is not None:
                # Cache resolved parent conversion under the concrete source type.
                _type_conversion_table[(source_type, T)] = convertor
                break

    if convertor is None:
        raise NotImplementedError(
            f"No conversion from {source_type.__name__} to {T.__name__}!"
        )
    return cast(Callable[["Convertible"], B], convertor)(self)

__len__

__len__() -> int

Return the number of spatial elements.

Source code in src/qten/symbolics/state_space.py
88
89
90
def __len__(self) -> int:
    """Return the number of spatial elements."""
    return len(self.structure)

__iter__

__iter__() -> Iterator[T]

Iterate over spatial elements.

Source code in src/qten/symbolics/state_space.py
92
93
94
def __iter__(self) -> Iterator[T]:
    """Iterate over spatial elements."""
    return iter(self.structure.keys())

__getitem__

__getitem__(v: int) -> T
__getitem__(v: slice | range) -> Self
__getitem__(v: Sequence[int]) -> Self

Index into the state-space by element position.

Supported forms

space[i] returns a single spatial element by position, including negative indices. space[start:stop:step] returns a new space with the selected elements in slice order. space[range(...)] returns a new space with the range-selected elements. space[[i, j, ...]] returns a new space with elements in explicit index order.

Parameters:

Name Type Description Default
key Union[int, slice, range, Sequence[int]]

Index selector. Sequences must contain unique integers; negative integers are normalized relative to len(self).

required

Returns:

Type Description
Spatial or StateSpace

A spatial element for int indexing, otherwise a new instance of the same class containing the selected elements. Any extra dataclass fields on subclasses are preserved in the returned instance.

Raises:

Type Description
IndexError

If an integer index is out of bounds.

TypeError

If key is not an int, slice, range, or sequence of integers.

ValueError

If a sequence selector contains duplicate indices.

Source code in src/qten/symbolics/state_space.py
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
def __getitem__(
    self, key: Union[int, slice, range, Sequence[int]]
) -> Union[T, "StateSpace[T]"]:
    """
    Index into the state-space by element position.

    Supported forms
    ---------------
    `space[i]` returns a single spatial element by position, including
    negative indices. `space[start:stop:step]` returns a new space with the
    selected elements in slice order. `space[range(...)]` returns a new
    space with the range-selected elements. `space[[i, j, ...]]` returns a
    new space with elements in explicit index order.

    Parameters
    ----------
    key : Union[int, slice, range, Sequence[int]]
        Index selector. Sequences must contain unique integers; negative
        integers are normalized relative to `len(self)`.

    Returns
    -------
    Spatial or StateSpace
        A spatial element for `int` indexing, otherwise a new instance of the
        same class containing the selected elements. Any extra dataclass fields
        on subclasses are preserved in the returned instance.

    Raises
    ------
    IndexError
        If an integer index is out of bounds.
    TypeError
        If `key` is not an `int`, `slice`, `range`, or sequence of integers.
    ValueError
        If a sequence selector contains duplicate indices.
    """
    if isinstance(key, int):
        if key < 0:
            key += len(self.structure)
        if key < 0 or key >= len(self.structure):
            raise IndexError("StateSpace index out of range")
        return next(islice(self.structure.keys(), key, None))
    if isinstance(key, slice):
        keys = tuple(self.structure.keys())[key]
        new_structure = OrderedDict((k, self.structure[k]) for k in keys)
        return replace(self, structure=restructure(new_structure))
    if isinstance(key, range):
        keys = tuple(self.structure.keys())
        new_structure = OrderedDict((keys[i], self.structure[keys[i]]) for i in key)
        return replace(self, structure=restructure(new_structure))
    if isinstance(key, Sequence) and not isinstance(key, (str, bytes)):
        keys = tuple(self.structure.keys())
        indices: list[int] = []
        seen = set()
        for idx in key:
            if isinstance(idx, bool) or not isinstance(idx, int):
                raise TypeError(
                    "StateSpace sequence indices must contain only integers"
                )
            normalized = idx
            if normalized < 0:
                normalized += len(keys)
            if normalized < 0 or normalized >= len(keys):
                raise IndexError("StateSpace index out of range")
            if normalized in seen:
                raise ValueError("StateSpace sequence indices must be unique")
            seen.add(normalized)
            indices.append(normalized)
        new_structure = OrderedDict(
            (keys[i], self.structure[keys[i]]) for i in indices
        )
        return replace(self, structure=restructure(new_structure))
    raise TypeError(
        "StateSpace indices must be int, slice, range, or a sequence of ints, "
        f"not {type(key)}"
    )

same_rays

same_rays(other: StateSpace) -> bool

Check if this state space has the same rays as another, i.e., they have the same set of spatial keys regardless of order.

Parameters:

Name Type Description Default
other StateSpace

The other state space to compare against.

required

Returns:

Type Description
bool

True if both state spaces have the same rays, False otherwise.

Source code in src/qten/symbolics/state_space.py
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
def same_rays(self, other: "StateSpace") -> bool:
    """
    Check if this state space has the same rays as another, i.e., they have the same set of spatial keys regardless of order.

    Parameters
    ----------
    other : StateSpace
        The other state space to compare against.

    Returns
    -------
    bool
        True if both state spaces have the same rays, `False` otherwise.
    """
    return same_rays(self, other)

map

map(func: Callable[[T], T]) -> Self

Map the spatial elements of this state space using a provided function.

Parameters:

Name Type Description Default
func Callable[[T], T]

A function that takes a spatial element and returns a transformed spatial element.

required

Returns:

Type Description
Self

A new state space with the transformed spatial elements.

Source code in src/qten/symbolics/state_space.py
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
def map(self, func: Callable[[T], T]) -> "Self":
    """
    Map the spatial elements of this state space using a provided function.

    Parameters
    ----------
    func : Callable[[T], T]
        A function that takes a spatial element and returns a transformed spatial element.

    Returns
    -------
    Self
        A new state space with the transformed spatial elements.
    """
    new_structure = OrderedDict()
    for k, s in self.structure.items():
        new_k = func(k)
        new_structure[new_k] = s
    return replace(self, structure=restructure(new_structure))

filter

filter(pred: Callable[[T], bool]) -> Self

Return the subspace containing elements where pred(element) is True.

Parameters:

Name Type Description Default
pred Callable[[T], bool]

Predicate applied to each element in basis order.

required

Returns:

Type Description
Self

A new state space of the same concrete type containing only the selected elements, with indices repacked contiguously.

Source code in src/qten/symbolics/state_space.py
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
def filter(self, pred: Callable[[T], bool]) -> "Self":
    """
    Return the subspace containing elements where `pred(element)` is `True`.

    Parameters
    ----------
    pred : Callable[[T], bool]
        Predicate applied to each element in basis order.

    Returns
    -------
    Self
        A new state space of the same concrete type containing only the
        selected elements, with indices repacked contiguously.
    """
    new_structure = OrderedDict(
        (k, s) for k, s in self.structure.items() if pred(k)
    )
    return replace(self, structure=restructure(new_structure))

tensor_product

tensor_product(other: Self) -> Self

Return the tensor-product state space of this space and another space.

This method defines the protocol used by the @ operator on StateSpace instances. The base class cannot construct a generic product because it does not know how to combine two elements of type T. Concrete subclasses must implement the element-level product and rebuild a contiguous structure for the resulting basis.

Implementations should preserve deterministic product ordering. The convention used by concrete tensor-product spaces in QTen is the Cartesian product order of self.elements() and other.elements(), where elements from self vary slowest and elements from other vary fastest. The returned space should be the same concrete state-space family when the operation is closed over that family.

Parameters:

Name Type Description Default
other StateSpace

Right-hand tensor factor. Implementations may require other to be the same concrete state-space type as self.

required

Returns:

Type Description
StateSpace

New state space representing self ⊗ other, with contiguous integer indices in the implementation-defined product order.

Raises:

Type Description
NotImplementedError

Always raised by the base class. Subclasses that support tensor products must override this method.

Source code in src/qten/symbolics/state_space.py
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
def tensor_product(self, other: Self) -> Self:
    """
    Return the tensor-product state space of this space and another space.

    This method defines the protocol used by the `@` operator on
    [`StateSpace`][qten.symbolics.state_space.StateSpace] instances. The
    base class cannot construct a generic product because it does not know
    how to combine two elements of type `T`. Concrete subclasses must
    implement the element-level product and rebuild a contiguous
    `structure` for the resulting basis.

    Implementations should preserve deterministic product ordering. The
    convention used by concrete tensor-product spaces in QTen is the
    Cartesian product order of `self.elements()` and `other.elements()`,
    where elements from `self` vary slowest and elements from `other` vary
    fastest. The returned space should be the same concrete state-space
    family when the operation is closed over that family.

    Parameters
    ----------
    other : StateSpace
        Right-hand tensor factor. Implementations may require `other` to be
        the same concrete state-space type as `self`.

    Returns
    -------
    StateSpace
        New state space representing `self ⊗ other`, with contiguous
        integer indices in the implementation-defined product order.

    Raises
    ------
    NotImplementedError
        Always raised by the base class. Subclasses that support tensor
        products must override this method.
    """
    raise NotImplementedError(f"Tensor product not implemented for {type(self)}!")

extract

extract(info_type: type[Any]) -> Any

Extract an object implied by the elements of this state space.

Subclasses may register specialized implementations for supported target types.

Parameters:

Name Type Description Default
info_type type[Any]

Type of metadata or object to extract from this state space.

required

Returns:

Type Description
Any

Extracted object produced by a registered specialization.

Raises:

Type Description
NotImplementedError

If no extraction rule is registered for info_type.

Source code in src/qten/symbolics/state_space.py
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
@multimethod
def extract(self, info_type: type[Any]) -> Any:
    """
    Extract an object implied by the elements of this state space.

    Subclasses may register specialized implementations for supported
    target types.

    Parameters
    ----------
    info_type : type[Any]
        Type of metadata or object to extract from this state space.

    Returns
    -------
    Any
        Extracted object produced by a registered specialization.

    Raises
    ------
    NotImplementedError
        If no extraction rule is registered for `info_type`.
    """
    raise NotImplementedError(
        f"Extraction of {info_type} from {type(self)} is not supported!"
    )

StateSpaceFactorization

Bases: NamedTuple

Ruleset for factorizing one StateSpace-like tensor dimension.

Attributes:

Name Type Description
factorized Tuple[StateSpace, ...]

Target factor spaces in torch.Tensor.reshape ordering.

align_dim StateSpace

A permutation of the original dimension whose flattened order is compatible with reshaping into factorized.

factorized instance-attribute

factorized: tuple[StateSpace, ...]

align_dim instance-attribute

align_dim: StateSpace

restructure

restructure(
    structure: OrderedDict[T, int],
) -> OrderedDict[T, int]

Return a new OrderedDict with contiguous, ordered integer indices.

Parameters:

Name Type Description Default
structure OrderedDict[Spatial, int]

The original structure with possibly non-contiguous indices.

required

Returns:

Type Description
OrderedDict[Spatial, int]

The restructured OrderedDict with contiguous, ordered indices.

Source code in src/qten/symbolics/state_space.py
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
def restructure(
    structure: OrderedDict[T, int],
) -> OrderedDict[T, int]:
    """
    Return a new `OrderedDict` with contiguous, ordered integer indices.

    Parameters
    ----------
    structure : OrderedDict[Spatial, int]
        The original structure with possibly non-contiguous indices.

    Returns
    -------
    OrderedDict[Spatial, int]
        The restructured `OrderedDict` with contiguous, ordered indices.
    """
    return OrderedDict((k, i) for i, k in enumerate(structure.keys()))

permutation_order cached

permutation_order(
    src: StateSpace, dest: StateSpace
) -> tuple[int, ...]

Return the permutation of src sectors needed to match dest sector order.

This returns a per-sector permutation: each entry corresponds to a key in dest.structure and gives the index of the same key in src.structure. The mapping is directly index-based on the current StateSpace structure and can be used to reorder sector-aligned data.

Parameters:

Name Type Description Default
src StateSpace

The source state space defining the original ordering.

required
dest StateSpace

The destination state space defining the target ordering.

required

Returns:

Type Description
Tuple[int, ...]

Sector indices mapping each key in dest to its position in src.

Raises:

Type Description
ValueError

If a destination sector key is missing from the source state space.

Source code in src/qten/symbolics/state_space.py
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
@lru_cache
def permutation_order(src: "StateSpace", dest: "StateSpace") -> Tuple[int, ...]:
    """
    Return the permutation of `src` sectors needed to match `dest` sector order.

    This returns a per-sector permutation: each entry corresponds to a key in
    `dest.structure` and gives the index of the same key in `src.structure`.
    The mapping is directly index-based on the current [`StateSpace`][qten.symbolics.state_space.StateSpace] structure
    and can be used to reorder sector-aligned data.

    Parameters
    ----------
    src : StateSpace
        The source state space defining the original ordering.
    dest : StateSpace
        The destination state space defining the target ordering.

    Returns
    -------
    Tuple[int, ...]
        Sector indices mapping each key in `dest` to its position in `src`.

    Raises
    ------
    ValueError
        If a destination sector key is missing from the source state space.
    """
    src_indices = src.structure
    dest_keys = dest.structure.keys()
    try:
        return tuple(src_indices[k] for k in dest_keys)
    except KeyError:
        missing = [k for k in dest_keys if k not in src_indices]
        raise ValueError(
            "Cannot build permutation order: destination contains keys not present "
            f"in source: {missing}"
        ) from None

embedding_order cached

embedding_order(
    sub: StateSpace, sup: StateSpace
) -> tuple[int, ...]

Return the positions of sub elements inside sup.

The returned tuple has one integer for each element of sub, in sub.elements() order. Each integer is the stored basis index of that same element in sup.structure. This is useful when a tensor axis represents a smaller state space and its data must be scattered into, gathered from, or aligned against a larger state space.

For example, if sup contains elements (a, b, c) with indices (0, 1, 2) and sub contains (c, a), then this function returns (2, 0). The result follows the order of sub, not the order of sup.

Parameters:

Name Type Description Default
sub StateSpace

State space whose elements should be located in sup.

required
sup StateSpace

State space providing the reference element-to-index mapping.

required

Returns:

Type Description
Tuple[int, ...]

Indices in sup corresponding to each element of sub, ordered like sub.elements().

Raises:

Type Description
ValueError

If any element of sub is not present as a key in sup.structure.

Source code in src/qten/symbolics/state_space.py
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
@lru_cache
def embedding_order(sub: StateSpace, sup: StateSpace) -> Tuple[int, ...]:
    """
    Return the positions of `sub` elements inside `sup`.

    The returned tuple has one integer for each element of `sub`, in
    `sub.elements()` order. Each integer is the stored basis index of that same
    element in `sup.structure`. This is useful when a tensor axis represents a
    smaller state space and its data must be scattered into, gathered from, or
    aligned against a larger state space.

    For example, if `sup` contains elements `(a, b, c)` with indices
    `(0, 1, 2)` and `sub` contains `(c, a)`, then this function returns
    `(2, 0)`. The result follows the order of `sub`, not the order of `sup`.

    Parameters
    ----------
    sub : StateSpace
        State space whose elements should be located in `sup`.
    sup : StateSpace
        State space providing the reference element-to-index mapping.

    Returns
    -------
    Tuple[int, ...]
        Indices in `sup` corresponding to each element of `sub`, ordered like
        `sub.elements()`.

    Raises
    ------
    ValueError
        If any element of `sub` is not present as a key in `sup.structure`.
    """
    indices: list[int] = []
    sup_indices = sup.structure
    for key, _ in sub.structure.items():
        if key not in sup_indices:
            raise ValueError(f"Key {key} not found in superspace")
        indices.append(sup_indices[key])
    return tuple(indices)

same_rays

same_rays(a: HilbertSpace, b: HilbertSpace) -> bool

Check whether two state spaces span the same ray representatives.

Parameters:

Name Type Description Default
a StateSpace

First state space.

required
b StateSpace

Second state space.

required

Returns:

Type Description
bool

True when the two state spaces contain the same set of basis keys, ignoring ordering and stored integer indices.

Source code in src/qten/symbolics/state_space.py
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
@multimethod
def same_rays(a: StateSpace, b: StateSpace) -> bool:
    """
    Check whether two state spaces span the same ray representatives.

    Parameters
    ----------
    a : StateSpace
        First state space.
    b : StateSpace
        Second state space.

    Returns
    -------
    bool
        `True` when the two state spaces contain the same set of basis keys,
        ignoring ordering and stored integer indices.
    """
    return set(a.structure.keys()) == set(b.structure.keys())

momentum_to_momentumspace

momentum_to_momentumspace(k: Momentum) -> MomentumSpace

Convert one momentum point to a one-element momentum space.

Parameters:

Name Type Description Default
k Momentum

Momentum point to wrap.

required

Returns:

Type Description
MomentumSpace

One-element momentum space containing k.

Source code in src/qten/symbolics/state_space.py
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
@Momentum.add_conversion(StateSpace)
def momentum_to_momentumspace(k: Momentum) -> StateSpace:
    """
    Convert one momentum point to a one-element momentum space.

    Parameters
    ----------
    k : Momentum
        Momentum point to wrap.

    Returns
    -------
    MomentumSpace
        One-element momentum space containing `k`.
    """
    structure = OrderedDict({k: 0})
    return MomentumSpace(structure=structure)

brillouin_zone cached

brillouin_zone(lattice: ReciprocalLattice) -> MomentumSpace

Enumerate the discrete Brillouin-zone momenta of a reciprocal lattice.

Parameters:

Name Type Description Default
lattice ReciprocalLattice

Reciprocal lattice whose Cartesian momentum samples should be collected.

required

Returns:

Type Description
MomentumSpace

Momentum space whose ordering follows ReciprocalLattice.cartes().

Source code in src/qten/symbolics/state_space.py
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
@lru_cache
def brillouin_zone(lattice: ReciprocalLattice) -> MomentumSpace:
    """
    Enumerate the discrete Brillouin-zone momenta of a reciprocal lattice.

    Parameters
    ----------
    lattice : ReciprocalLattice
        Reciprocal lattice whose Cartesian momentum samples should be
        collected.

    Returns
    -------
    MomentumSpace
        Momentum space whose ordering follows
        [`ReciprocalLattice.cartes()`][qten.geometries.spatials.ReciprocalLattice.cartes].
    """
    elements = lattice.cartes()
    structure = OrderedDict((el, n) for n, el in enumerate(elements))
    return MomentumSpace(structure=structure)