Skip to content

qten.pointgroups.abelian

Module reference for qten.pointgroups.abelian.

abelian

Symbolic abelian point-group representations.

This module defines the core point-group objects used by QTen's symmetry machinery. AbelianGroup stores an abelian generator representation, derives Euclidean polynomial bases, and computes symbolic eigen-basis sectors. AbelianBasis labels those sectors, while AbelianOpr couples a group action with an affine offset for use as a symbolic operator.

Repository usage

Use this module for explicit point-group construction and algebra. Higher-level query-string construction is available through pointgroup(), and tensor/Hilbert space projection helpers live in qten.pointgroups.ops.

AbelianBasis dataclass

AbelianBasis(
    expr: Expr,
    axes: tuple[Symbol, ...],
    order: int,
    rep: ImmutableDenseMatrix,
)

Bases: Spatial

Symbolic abelian eigen-basis expressed in a polynomial basis over given axes.

Ordering

AbelianBasis comparison (<, >) is defined by lexicographic string ordering of expr (str(expr)).

Attributes:

Name Type Description
expr Expr

Symbolic expression in axes representing the affine function.

axes Tuple[Symbol, ...]

Ordered tuple of symbols defining the coordinate axes.

order int

Polynomial order used to build the basis representation.

rep ImmutableDenseMatrix

Coefficient vector in the Euclidean monomial basis (column matrix).

expr instance-attribute

expr: Expr

Symbolic expression in axes representing the basis function in coordinate form.

axes instance-attribute

axes: tuple[Symbol, ...]

Ordered tuple of symbols defining the coordinate axes against which expr and rep are interpreted.

order instance-attribute

order: int

Polynomial order used to build the basis representation, i.e. the total degree of the commuting monomial space.

rep instance-attribute

rep: ImmutableDenseMatrix

Coefficient vector in the Euclidean monomial basis, stored as a column matrix aligned with the order-specific monomial enumeration.

dim property

dim: int

Number of axes (spatial dimension) for this affine function.

from_rep classmethod

from_rep(
    rep: ImmutableDenseMatrix,
    euclidean_basis: ImmutableDenseMatrix,
    axes: tuple[Symbol, ...],
    order: int,
) -> AbelianBasis

Build an AbelianBasis from a Euclidean representation vector.

The input rep is first normalized to a canonical representative by dividing through its first non-zero coefficient. The normalized vector is then converted into the symbolic polynomial expression in euclidean_basis and stored as both expr and canonical rep data of the resulting AbelianBasis.

Parameters:

Name Type Description Default
rep ImmutableDenseMatrix

Euclidean representation vector in the commuting monomial basis. The vector need not already be normalized, but it must be non-zero.

required
euclidean_basis ImmutableDenseMatrix

Row matrix of commuting monomials spanning the Euclidean polynomial basis for the given order.

required
axes Tuple[Symbol, ...]

Ordered coordinate symbols associated with the Euclidean basis.

required
order int

Polynomial order of the Euclidean representation.

required

Returns:

Type Description
AbelianBasis

Canonicalized abelian basis function whose stored rep is the normalized version of the input vector and whose expr is the corresponding symbolic polynomial.

Raises:

Type Description
StopIteration

If rep is the zero vector, so there is no first non-zero coefficient available for normalization.

Source code in src/qten/pointgroups/abelian.py
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
@classmethod
def from_rep(
    cls,
    rep: sy.ImmutableDenseMatrix,
    euclidean_basis: sy.ImmutableDenseMatrix,
    axes: Tuple[sy.Symbol, ...],
    order: int,
) -> "AbelianBasis":
    """
    Build an [`AbelianBasis`][qten.pointgroups.abelian.AbelianBasis] from a Euclidean representation vector.

    The input `rep` is first normalized to a canonical representative by
    dividing through its first non-zero coefficient. The normalized vector
    is then converted into the symbolic polynomial expression in
    [`euclidean_basis`][qten.pointgroups.abelian.AbelianGroup.euclidean_basis] and stored as both `expr` and canonical `rep` data
    of the resulting [`AbelianBasis`][qten.pointgroups.abelian.AbelianBasis].

    Parameters
    ----------
    rep : sy.ImmutableDenseMatrix
        Euclidean representation vector in the commuting monomial basis.
        The vector need not already be normalized, but it must be non-zero.
    euclidean_basis : sy.ImmutableDenseMatrix
        Row matrix of commuting monomials spanning the Euclidean polynomial
        basis for the given `order`.
    axes : Tuple[sy.Symbol, ...]
        Ordered coordinate symbols associated with the Euclidean basis.
    order : int
        Polynomial order of the Euclidean representation.

    Returns
    -------
    AbelianBasis
        Canonicalized abelian basis function whose stored `rep` is the
        normalized version of the input vector and whose `expr` is the
        corresponding symbolic polynomial.

    Raises
    ------
    StopIteration
        If `rep` is the zero vector, so there is no first non-zero
        coefficient available for normalization.
    """
    principle_term = next(x for x in rep if x != 0)
    normalized = sy.ImmutableDenseMatrix(sy.simplify(rep / principle_term))
    expr = sy.simplify(normalized.dot(euclidean_basis))
    return cls(expr=expr, axes=axes, order=order, rep=normalized)

__str__

__str__()

Return the compact symbolic label for this basis function.

Returns:

Type Description
str

"e" for the constant identity basis function, otherwise the string form of expr.

Source code in src/qten/pointgroups/abelian.py
172
173
174
175
176
177
178
179
180
181
182
183
184
def __str__(self):
    """
    Return the compact symbolic label for this basis function.

    Returns
    -------
    str
        `"e"` for the constant identity basis function, otherwise the
        string form of `expr`.
    """
    if sy.simplify(self.expr - 1) == 0:
        return "e"
    return str(self.expr)

__repr__

__repr__()

Return the developer representation of this basis function.

The representation intentionally matches __str__ so basis labels render compactly inside tuples, containers, and logs.

Returns:

Type Description
str

Same value as str(self).

Source code in src/qten/pointgroups/abelian.py
186
187
188
189
190
191
192
193
194
195
196
197
198
199
def __repr__(self):
    """
    Return the developer representation of this basis function.

    The representation intentionally matches
    [`__str__`][qten.pointgroups.abelian.AbelianBasis.__str__] so basis
    labels render compactly inside tuples, containers, and logs.

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

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)

AbelianGroup dataclass

AbelianGroup(
    irrep: ImmutableDenseMatrix, axes: tuple[Symbol, ...]
)

Bases: Opr

Abelian linear operator represented on Cartesian coordinate functions.

AbelianGroup stores the linear part g of a symmetry/operator as an exact matrix irrep acting on the coordinate axes axes. It provides the order-dependent polynomial representations induced by that linear action and the corresponding eigen-basis functions (AbelianBasis).

Mathematical meaning

Let the coordinate vector be \(x = (x_1, \ldots, x_d)^{\mathsf{T}}\). The matrix irrep defines a linear action \(x \mapsto Gx\), where \(G\) is the stored irrep matrix.

From this degree-1 action, the class constructs higher-order polynomial representations on homogeneous monomials of total degree order. For example:

For order = 0, the representation acts on constant functions and is always the trivial 1x1 representation [1]. For order = 1, the representation is the original Euclidean representation irrep. For order = 2, the representation acts on quadratic monomials such as x^2, xy, and y^2.

Because coordinate symbols commute, the raw tensor-product representation is symmetrized onto the commuting monomial basis. The resulting matrix is returned by euclidean_repr(order).

For a homogeneous monomial basis \(\phi_m(x)\), the derived representation acts by rewriting \(\phi_m(Gx)\) back in the commuting monomial basis.

Parameters:

Name Type Description Default
irrep ImmutableDenseMatrix

Exact linear representation matrix of the operator in the coordinate basis defined by axes.

required
axes Tuple[Symbol, ...]

Ordered coordinate symbols on which irrep acts.

required

Attributes:

Name Type Description
irrep ImmutableDenseMatrix

Exact linear representation matrix of the operator in the coordinate basis defined by axes.

axes Tuple[Symbol, ...]

Ordered coordinate symbols on which irrep acts.

Main API

euclidean_repr(order) returns the symmetrized linear action on homogeneous commuting monomials of degree order. basis(order) returns eigen-basis functions of that representation as AbelianBasis objects keyed by eigenvalue. basis_table collects representative eigen-basis functions across increasing polynomial orders until all characters of the finite represented element are found. group_order(max_order=128) returns the smallest positive integer n such that irrep**n = I.

Notes

AbelianGroup is the linear object. To obtain an affine operator of the form \(x \mapsto gx + t\), wrap it in AbelianOpr. In that sense, AbelianOpr is the affine extension of AbelianGroup.

AbelianGroup @ AbelianGroup composes linear maps in the same algebraic order as every other Opr: (a @ b) @ x == a(b(x)). When the two groups use different but compatible ordered axis tuples, composition first embeds both matrices into a common axis basis. The merged basis preserves the full left-axis order and appends only unseen right axes. Missing axes act by the identity, while shared axes are aligned by symbol and reordered as needed.

The group_order() and basis_table utilities assume the represented element has finite order. They are appropriate for finite abelian point symmetries, but may fail or be incomplete for infinite-order linear maps.

irrep instance-attribute

irrep: ImmutableDenseMatrix

Exact linear representation matrix of the operator in the coordinate basis defined by axes. This is the degree-1 action from which higher polynomial representations are constructed.

axes instance-attribute

axes: tuple[Symbol, ...]

Ordered coordinate symbols on which irrep acts. Their order fixes the ambient coordinate basis for all derived polynomial representations.

basis_table cached property

basis_table: FrozenDict[Expr, AbelianBasis]

Build a complete eigen-basis lookup table across polynomial orders.

The table is accumulated by increasing homogeneous order, starting from 0, until enough eigen-basis functions have been found to cover the full finite group order returned by group_order.

Returns:

Type Description
FrozenDict

Mapping from eigenvalue/character to a representative AbelianBasis.

Raises:

Type Description
ValueError

If no complete table is found up to order group_order() - 1.

euclidean_basis cached

euclidean_basis(order: int) -> sy.ImmutableDenseMatrix

Return commuting Euclidean monomials spanning the polynomial basis.

Parameters:

Name Type Description Default
order int

Homogeneous polynomial degree. order=0 returns the constant monomial basis.

required

Returns:

Type Description
ImmutableDenseMatrix

Row matrix whose entries are monomials formed from canonical commuting indices of degree order.

Source code in src/qten/pointgroups/abelian.py
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
@lru_cache
def euclidean_basis(self, order: int) -> sy.ImmutableDenseMatrix:
    """
    Return commuting Euclidean monomials spanning the polynomial basis.

    Parameters
    ----------
    order : int
        Homogeneous polynomial degree. `order=0` returns the constant
        monomial basis.

    Returns
    -------
    sy.ImmutableDenseMatrix
        Row matrix whose entries are monomials formed from canonical
        commuting indices of degree `order`.
    """
    indices = self._commute_indices(order)
    return sy.ImmutableDenseMatrix([sy.prod(idx) for idx in indices]).T

euclidean_repr cached

euclidean_repr(order: int) -> sy.ImmutableDenseMatrix

Symmetrized representation on the commuting polynomial basis.

Parameters:

Name Type Description Default
order int

Homogeneous polynomial degree for the induced representation. order=0 returns the trivial one-dimensional representation.

required

Returns:

Type Description
ImmutableDenseMatrix

Matrix representation after contracting permutation-equivalent tensor-product monomials and selecting canonical representatives.

Source code in src/qten/pointgroups/abelian.py
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
@lru_cache
def euclidean_repr(self, order: int) -> sy.ImmutableDenseMatrix:
    """
    Symmetrized representation on the commuting polynomial basis.

    Parameters
    ----------
    order : int
        Homogeneous polynomial degree for the induced representation.
        `order=0` returns the trivial one-dimensional representation.

    Returns
    -------
    sy.ImmutableDenseMatrix
        Matrix representation after contracting permutation-equivalent
        tensor-product monomials and selecting canonical representatives.
    """
    indices = self._full_indices(order)
    contract_indices, select_indices = self._get_contract_select_rules(indices)

    contract_matrix = sy.zeros(len(indices), len(select_indices))
    for i, j in contract_indices:
        contract_matrix[i, j] = 1

    select_matrix = sy.zeros(len(indices), len(select_indices))
    for i, j in select_indices:
        select_matrix[i, j] = 1

    return select_matrix.T @ self._raw_euclidean_repr(order) @ contract_matrix

group_order cached

group_order(max_order: int = 128) -> int

Return the order of this represented group element.

The order is the smallest positive integer n such that \(G^n = I\), where \(G\) is irrep and \(I\) is the identity matrix of matching size.

Parameters:

Name Type Description Default
max_order int

Maximum positive exponent to test during the exact search.

128

Returns:

Type Description
int

The smallest positive exponent for which the represented matrix returns to the identity.

Raises:

Type Description
ValueError

If no finite order is found within the bounded exact search.

Notes

This computes the order of the matrix image under the representation. For a faithful representation, this equals the abstract group-element order; otherwise it may be smaller.

Source code in src/qten/pointgroups/abelian.py
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
@lru_cache
def group_order(self, max_order: int = 128) -> int:
    r"""
    Return the order of this represented group element.

    The order is the smallest positive integer `n` such that \(G^n = I\),
    where \(G\) is `irrep` and \(I\) is the identity matrix of matching size.

    Parameters
    ----------
    max_order : int, default 128
        Maximum positive exponent to test during the exact search.

    Returns
    -------
    int
        The smallest positive exponent for which the represented matrix
        returns to the identity.

    Raises
    ------
    ValueError
        If no finite order is found within the bounded exact search.

    Notes
    -----
    This computes the order of the matrix image under the representation.
    For a faithful representation, this equals the abstract group-element
    order; otherwise it may be smaller.
    """
    ident = sy.ImmutableDenseMatrix.eye(self.irrep.rows)
    power = ident
    for n in range(1, max_order + 1):
        power = sy.ImmutableDenseMatrix(sy.simplify(power @ self.irrep))
        if power.equals(ident):
            return n
    raise ValueError(
        f"Failed to determine a finite group order within max_order={max_order} "
        f"for irrep={self.irrep!r}."
    )

inv cached

inv() -> AbelianGroup

Return the inverse linear operator in the same ordered axis basis.

The inverse is computed exactly from irrep.inv() and keeps the same axes, so self @ self.inv() and self.inv() @ self both represent the identity map on that coordinate system.

Source code in src/qten/pointgroups/abelian.py
482
483
484
485
486
487
488
489
490
491
492
493
494
@lru_cache
def inv(self) -> "AbelianGroup":
    """
    Return the inverse linear operator in the same ordered axis basis.

    The inverse is computed exactly from `irrep.inv()` and keeps the same
    `axes`, so `self @ self.inv()` and `self.inv() @ self` both represent
    the identity map on that coordinate system.
    """
    return AbelianGroup(
        irrep=sy.ImmutableDenseMatrix(sy.simplify(self.irrep.inv())),
        axes=self.axes,
    )

basis cached

basis(order: int) -> FrozenDict[sy.Expr, AbelianBasis]

Compute abelian eigen-basis functions from euclidean_repr(order) eigenvectors.

Parameters:

Name Type Description Default
order int

Homogeneous polynomial degree used to build the Euclidean representation before diagonalization.

required

Returns:

Type Description
FrozenDict

Mapping from eigenvalue to normalized AbelianBasis eigenfunction. Normalization is fixed by dividing by the first non-zero coefficient in each eigenvector.

Source code in src/qten/pointgroups/abelian.py
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
@lru_cache
def basis(self, order: int) -> FrozenDict:
    """
    Compute abelian eigen-basis functions from [`euclidean_repr(order)`][qten.pointgroups.abelian.AbelianGroup.euclidean_repr] eigenvectors.

    Parameters
    ----------
    order : int
        Homogeneous polynomial degree used to build the Euclidean
        representation before diagonalization.

    Returns
    -------
    FrozenDict
        Mapping from eigenvalue to normalized [`AbelianBasis`][qten.pointgroups.abelian.AbelianBasis] eigenfunction.
        Normalization is fixed by dividing by the first non-zero coefficient
        in each eigenvector.
    """
    transform = self.euclidean_repr(order)
    eig = transform.eigenvects()

    tbl = {}
    for v, _, vec_group in eig:
        vec = vec_group[0]
        tbl[v] = AbelianBasis.from_rep(
            rep=sy.ImmutableDenseMatrix(vec),
            euclidean_basis=self.euclidean_basis(order),
            axes=self.axes,
            order=order,
        )

    return FrozenDict(tbl)

register classmethod

register(obj_type: type)

Register a function defining the action of the Functional on a specific object type.

This method returns a decorator. The decorated function should accept the functional instance as its first argument and an object of obj_type as its second argument. Any keyword arguments passed to invoke() are forwarded to the decorated function.

Dispatch is resolved at call time via MRO, so only the exact (obj_type, cls) key is stored here. Resolution later searches both:

  • the MRO of the runtime object type,
  • the MRO of the runtime functional type.

This means registrations on a functional superclass are inherited by subclass functionals unless a more specific registration overrides them.

Parameters:

Name Type Description Default
obj_type type

The type of object the function applies to.

required

Returns:

Type Description
Callable

A decorator that registers the function for the specified object type.

Examples:

@MyFunctional.register(MyObject)
def _(functional: MyFunctional, obj: MyObject) -> MyObject:
    ...
Source code in src/qten/abstracts.py
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
@classmethod
def register(cls, obj_type: type):
    """
    Register a function defining the action of the [`Functional`][qten.abstracts.Functional] on a specific object type.

    This method returns a decorator. The decorated function should accept
    the functional instance as its first argument and an object of
    `obj_type` as its second argument. Any keyword arguments passed to
    [`invoke()`][qten.abstracts.Functional.invoke] are forwarded to the
    decorated function.

    Dispatch is resolved at call time via MRO, so only the exact
    `(obj_type, cls)` key is stored here. Resolution later searches both:

    - the MRO of the runtime object type,
    - the MRO of the runtime functional type.

    This means registrations on a functional superclass are inherited by
    subclass functionals unless a more specific registration overrides them.

    Parameters
    ----------
    obj_type : type
        The type of object the function applies to.

    Returns
    -------
    Callable
        A decorator that registers the function for the specified object type.

    Examples
    --------
    ```python
    @MyFunctional.register(MyObject)
    def _(functional: MyFunctional, obj: MyObject) -> MyObject:
        ...
    ```
    """

    def decorator(func: Callable):
        cls._registered_methods[(obj_type, cls)] = func
        cls._invalidate_resolved_methods(obj_type)
        return func

    return decorator

get_applicable_types staticmethod

get_applicable_types() -> tuple[type, ...]

Get all object types that can be applied by this Functional.

Parameters:

Name Type Description Default
cls Type[Functional]

Functional class whose direct registrations should be inspected.

required

Returns:

Type Description
Tuple[Type, ...]

A tuple of all registered object types that this Functional can handle.

Source code in src/qten/abstracts.py
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
@staticmethod
def get_applicable_types(cls) -> Tuple[Type, ...]:
    """
    Get all object types that can be applied by this [`Functional`][qten.abstracts.Functional].

    Parameters
    ----------
    cls : Type[Functional]
        Functional class whose direct registrations should be inspected.

    Returns
    -------
    Tuple[Type, ...]
        A tuple of all registered object types that this [`Functional`][qten.abstracts.Functional] can handle.
    """
    types = set()
    for obj_type, functional_type in cls._registered_methods.keys():
        if functional_type is cls:
            types.add(obj_type)
    return tuple(types)

allows

allows(obj: Any) -> bool

Check if this Functional can be applied on the given object.

Parameters:

Name Type Description Default
obj Any

The object to check for applicability.

required

Returns:

Type Description
bool

True if this Functional can be applied on the object, False otherwise.

Notes

Applicability is checked using the same inherited dispatch rules as invoke(): both the object's MRO and the functional-class MRO are searched.

Source code in src/qten/abstracts.py
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
def allows(self, obj: Any) -> bool:
    """
    Check if this [`Functional`][qten.abstracts.Functional] can be applied on the given object.

    Parameters
    ----------
    obj : Any
        The object to check for applicability.

    Returns
    -------
    bool
        True if this [`Functional`][qten.abstracts.Functional] can be applied on the object, False otherwise.

    Notes
    -----
    Applicability is checked using the same inherited dispatch rules as
    [`invoke()`][qten.abstracts.Functional.invoke]: both the object's MRO
    and the functional-class MRO are searched.
    """
    return self._resolve_method(type(obj), type(self)) is not None

invoke

invoke(v: _T, **kwargs: Any) -> _T | Multiple[_T]

Apply the operator while preserving QTen's symbolic output invariants.

Parameters:

Name Type Description Default
v _T

Input object to transform.

required
**kwargs Any

Extra keyword arguments forwarded to the resolved registration.

{}

Returns:

Type Description
_T | Multiple[_T]

Transformed object, or a factored result carrying an explicit scalar coefficient.

Raises:

Type Description
AssertionError

If a registered implementation returns a value outside the expected same-type / Multiple[same-type] contract.

Source code in src/qten/symbolics/hilbert_space.py
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
@override
def invoke(  # type: ignore[override]
    self, v: _T, **kwargs
) -> Union[_T, Multiple[_T]]:
    """
    Apply the operator while preserving QTen's symbolic output invariants.

    Parameters
    ----------
    v : _T
        Input object to transform.
    **kwargs : Any
        Extra keyword arguments forwarded to the resolved registration.

    Returns
    -------
    _T | Multiple[_T]
        Transformed object, or a factored result carrying an explicit
        scalar coefficient.

    Raises
    ------
    AssertionError
        If a registered implementation returns a value outside the expected
        same-type / `Multiple[same-type]` contract.
    """
    if type(v) is Multiple:
        result = super().invoke(v.base, **kwargs)
        if type(result) is Multiple:
            return Multiple((v.coef * result.coef).simplify(), result.base)
        return Multiple(v.coef, result)
    result = super().invoke(v, **kwargs)
    if isinstance(v, (U1Basis, U1Span, HilbertSpace)):
        assert type(result) is not Multiple, (
            f"Operator {type(self)} acting on {type(v).__name__} should not yield a Multiple!"
        )
    assert isinstance(result, type(v)) or (
        type(result) is Multiple and isinstance(result.base, type(v))
    ), (
        f"Operator {type(self)} acting on {type(v).__name__} should yield same typed object"
        f"or Multiple[{type(v).__name__}]"
    )
    return result

__call__

__call__(obj: Any, **kwargs) -> Any

Apply this functional to obj.

This is a thin wrapper around invoke().

Parameters:

Name Type Description Default
obj Any

Runtime object to dispatch on.

required
**kwargs Any

Additional keyword arguments forwarded to the resolved implementation.

{}

Returns:

Type Description
Any

Result produced by the resolved registered method.

Raises:

Type Description
NotImplementedError

If no registration exists for the runtime pair after MRO fallback.

See Also

invoke(obj, **kwargs) Full dispatch method used by this call wrapper.

Source code in src/qten/abstracts.py
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
def __call__(self, obj: Any, **kwargs) -> Any:
    """
    Apply this functional to `obj`.

    This is a thin wrapper around [`invoke()`][qten.abstracts.Functional.invoke].

    Parameters
    ----------
    obj : Any
        Runtime object to dispatch on.
    **kwargs : Any
        Additional keyword arguments forwarded to the resolved
        implementation.

    Returns
    -------
    Any
        Result produced by the resolved registered method.

    Raises
    ------
    NotImplementedError
        If no registration exists for the runtime pair after MRO fallback.

    See Also
    --------
    [`invoke(obj, **kwargs)`][qten.abstracts.Functional.invoke]
        Full dispatch method used by this call wrapper.
    """
    return self.invoke(obj, **kwargs)

AbelianOpr dataclass

AbelianOpr(g: AbelianGroup, offset: Offset | None = None)

Bases: Opr, HasBase[AffineSpace]

Abelian operator acting on polynomial coordinate functions.

This class combines an abelian linear representation with a translation: \(x \mapsto gx + t\), where g is carried by AbelianGroup and \(t\) by offset.

Parameters:

Name Type Description Default
g AbelianGroup

Linear part of the affine transformation.

required
offset Offset

Translation part of the affine transformation, stored in the same affine space on which g acts.

None

Attributes:

Name Type Description
g AbelianGroup

Linear part of the affine transformation.

offset Offset

Translation part of the affine transformation, stored in the same affine space on which g acts.

Notes

The operator is initialized at the canonical origin of the identity affine basis. To center it at a specific point, construct it first and then call fixpoint_at(...).

Source code in src/qten/pointgroups/abelian.py
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
def __init__(
    self,
    g: AbelianGroup,
    offset: Offset | None = None,
):
    if offset is not None:
        raise TypeError(
            "AbelianOpr does not accept offset=... directly. "
            "Construct AbelianOpr(g) and use fixpoint_at(...) to set its center."
        )
    dim = g.irrep.rows
    base = AffineSpace(basis=sy.ImmutableDenseMatrix.eye(dim))
    offset = Offset(rep=sy.ImmutableDenseMatrix([0] * dim), space=base)
    object.__setattr__(self, "g", g)
    object.__setattr__(self, "offset", offset)

g instance-attribute

g: AbelianGroup

Linear part of the affine transformation, represented exactly on the ordered coordinate axes of the operator's ambient affine space.

offset instance-attribute

offset: Offset

Translation part of the affine transformation, stored in the same affine space on which g acts so the full map has the form \(x \mapsto gx + \mathrm{offset}\).

base

base() -> AffineSpace

Get the affine space where this element acts.

Returns:

Type Description
AffineSpace

Acting space, identical to offset.space.

Source code in src/qten/pointgroups/abelian.py
744
745
746
747
748
749
750
751
752
753
def base(self) -> AffineSpace:
    """
    Get the affine space where this element acts.

    Returns
    -------
    AffineSpace
        Acting space, identical to `offset.space`.
    """
    return self.offset.space

rebase cached

rebase(new_base: AffineSpace) -> AbelianOpr

Re-express this transform in a different affine space basis.

Parameters:

Name Type Description Default
new_base AffineSpace

Target affine space for the transformed representation.

required

Returns:

Type Description
AbelianOpr

New element with both linear and translation parts expressed in new_base coordinates.

Source code in src/qten/pointgroups/abelian.py
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
@lru_cache(maxsize=None)
def rebase(self, new_base: AffineSpace) -> "AbelianOpr":
    """
    Re-express this transform in a different affine space basis.

    Parameters
    ----------
    new_base : AffineSpace
        Target affine space for the transformed representation.

    Returns
    -------
    AbelianOpr
        New element with both linear and translation parts expressed in
        new_base coordinates.
    """
    old_base = self.offset.space
    B_old = old_base.basis
    if not isinstance(B_old, sy.ImmutableDenseMatrix):
        B_old = sy.ImmutableDenseMatrix(B_old)
    B_new = new_base.basis
    if not isinstance(B_new, sy.ImmutableDenseMatrix):
        B_new = sy.ImmutableDenseMatrix(B_new)

    irrep = self.g.irrep
    if not isinstance(irrep, sy.ImmutableDenseMatrix):
        irrep = sy.ImmutableDenseMatrix(irrep)

    change = B_new.inv() @ B_old
    new_irrep = change @ irrep @ change.inv()
    return AbelianOpr._from_parts(
        g=AbelianGroup(irrep=sy.ImmutableDenseMatrix(new_irrep), axes=self.g.axes),
        offset=self.offset.rebase(new_base),
    )

fixpoint_at

fixpoint_at(r: Offset, rebase: bool = False) -> AbelianOpr

Return a transform with the same linear part whose invariant fixed point is r.

For the affine action \(x \mapsto R x + t\), requiring \(r\) to be fixed means \(Rr + t = r\), so the translation must be \(t = (I - R)r\).

Parameters:

Name Type Description Default
r Offset

Desired fixed point.

required
rebase bool

Base-handling mode when r.space differs from this transform's base: if False, rebase r to this transform's base and keep the returned transform in its current base; if True, rebase the transform to r.space and return the result there.

`False`

Returns:

Type Description
AbelianOpr

A new affine operator with the same linear part and with r as an invariant point.

Source code in src/qten/pointgroups/abelian.py
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
def fixpoint_at(self, r: Offset, rebase: bool = False) -> "AbelianOpr":
    r"""
    Return a transform with the same linear part whose invariant fixed point is `r`.

    For the affine action \(x \mapsto R x + t\), requiring \(r\) to be
    fixed means \(Rr + t = r\), so the translation must be
    \(t = (I - R)r\).

    Parameters
    ----------
    r : Offset
        Desired fixed point.
    rebase : bool, default `False`
        Base-handling mode when `r.space` differs from this transform's base:
        if `False`, rebase `r` to this transform's base and keep the
        returned transform in its current base; if `True`, rebase the
        transform to `r.space` and return the result there.

    Returns
    -------
    AbelianOpr
        A new affine operator with the same linear part and with `r` as an
        invariant point.
    """
    t = self.rebase(r.space) if rebase and r.space != self.offset.space else self
    r_target = r if t.offset.space == r.space else r.rebase(t.offset.space)

    irrep = t.g.irrep
    if not isinstance(irrep, sy.ImmutableDenseMatrix):
        irrep = sy.ImmutableDenseMatrix(irrep)

    r_rep = r_target.rep
    if not isinstance(r_rep, sy.ImmutableDenseMatrix):
        r_rep = sy.ImmutableDenseMatrix(r_rep)

    ident = sy.eye(irrep.rows)
    if not isinstance(ident, sy.ImmutableDenseMatrix):
        ident = sy.ImmutableDenseMatrix(ident)

    fixed_offset = Offset(
        rep=sy.ImmutableDenseMatrix((ident - irrep) @ r_rep),
        space=t.offset.space,
    )
    return AbelianOpr._from_parts(
        g=AbelianGroup(irrep=irrep, axes=t.g.axes),
        offset=fixed_offset,
    )

register classmethod

register(obj_type: type)

Register a function defining the action of the Functional on a specific object type.

This method returns a decorator. The decorated function should accept the functional instance as its first argument and an object of obj_type as its second argument. Any keyword arguments passed to invoke() are forwarded to the decorated function.

Dispatch is resolved at call time via MRO, so only the exact (obj_type, cls) key is stored here. Resolution later searches both:

  • the MRO of the runtime object type,
  • the MRO of the runtime functional type.

This means registrations on a functional superclass are inherited by subclass functionals unless a more specific registration overrides them.

Parameters:

Name Type Description Default
obj_type type

The type of object the function applies to.

required

Returns:

Type Description
Callable

A decorator that registers the function for the specified object type.

Examples:

@MyFunctional.register(MyObject)
def _(functional: MyFunctional, obj: MyObject) -> MyObject:
    ...
Source code in src/qten/abstracts.py
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
@classmethod
def register(cls, obj_type: type):
    """
    Register a function defining the action of the [`Functional`][qten.abstracts.Functional] on a specific object type.

    This method returns a decorator. The decorated function should accept
    the functional instance as its first argument and an object of
    `obj_type` as its second argument. Any keyword arguments passed to
    [`invoke()`][qten.abstracts.Functional.invoke] are forwarded to the
    decorated function.

    Dispatch is resolved at call time via MRO, so only the exact
    `(obj_type, cls)` key is stored here. Resolution later searches both:

    - the MRO of the runtime object type,
    - the MRO of the runtime functional type.

    This means registrations on a functional superclass are inherited by
    subclass functionals unless a more specific registration overrides them.

    Parameters
    ----------
    obj_type : type
        The type of object the function applies to.

    Returns
    -------
    Callable
        A decorator that registers the function for the specified object type.

    Examples
    --------
    ```python
    @MyFunctional.register(MyObject)
    def _(functional: MyFunctional, obj: MyObject) -> MyObject:
        ...
    ```
    """

    def decorator(func: Callable):
        cls._registered_methods[(obj_type, cls)] = func
        cls._invalidate_resolved_methods(obj_type)
        return func

    return decorator

get_applicable_types staticmethod

get_applicable_types() -> tuple[type, ...]

Get all object types that can be applied by this Functional.

Parameters:

Name Type Description Default
cls Type[Functional]

Functional class whose direct registrations should be inspected.

required

Returns:

Type Description
Tuple[Type, ...]

A tuple of all registered object types that this Functional can handle.

Source code in src/qten/abstracts.py
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
@staticmethod
def get_applicable_types(cls) -> Tuple[Type, ...]:
    """
    Get all object types that can be applied by this [`Functional`][qten.abstracts.Functional].

    Parameters
    ----------
    cls : Type[Functional]
        Functional class whose direct registrations should be inspected.

    Returns
    -------
    Tuple[Type, ...]
        A tuple of all registered object types that this [`Functional`][qten.abstracts.Functional] can handle.
    """
    types = set()
    for obj_type, functional_type in cls._registered_methods.keys():
        if functional_type is cls:
            types.add(obj_type)
    return tuple(types)

allows

allows(obj: Any) -> bool

Check if this Functional can be applied on the given object.

Parameters:

Name Type Description Default
obj Any

The object to check for applicability.

required

Returns:

Type Description
bool

True if this Functional can be applied on the object, False otherwise.

Notes

Applicability is checked using the same inherited dispatch rules as invoke(): both the object's MRO and the functional-class MRO are searched.

Source code in src/qten/abstracts.py
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
def allows(self, obj: Any) -> bool:
    """
    Check if this [`Functional`][qten.abstracts.Functional] can be applied on the given object.

    Parameters
    ----------
    obj : Any
        The object to check for applicability.

    Returns
    -------
    bool
        True if this [`Functional`][qten.abstracts.Functional] can be applied on the object, False otherwise.

    Notes
    -----
    Applicability is checked using the same inherited dispatch rules as
    [`invoke()`][qten.abstracts.Functional.invoke]: both the object's MRO
    and the functional-class MRO are searched.
    """
    return self._resolve_method(type(obj), type(self)) is not None

invoke

invoke(v: _T, **kwargs: Any) -> _T | Multiple[_T]

Apply the operator while preserving QTen's symbolic output invariants.

Parameters:

Name Type Description Default
v _T

Input object to transform.

required
**kwargs Any

Extra keyword arguments forwarded to the resolved registration.

{}

Returns:

Type Description
_T | Multiple[_T]

Transformed object, or a factored result carrying an explicit scalar coefficient.

Raises:

Type Description
AssertionError

If a registered implementation returns a value outside the expected same-type / Multiple[same-type] contract.

Source code in src/qten/symbolics/hilbert_space.py
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
@override
def invoke(  # type: ignore[override]
    self, v: _T, **kwargs
) -> Union[_T, Multiple[_T]]:
    """
    Apply the operator while preserving QTen's symbolic output invariants.

    Parameters
    ----------
    v : _T
        Input object to transform.
    **kwargs : Any
        Extra keyword arguments forwarded to the resolved registration.

    Returns
    -------
    _T | Multiple[_T]
        Transformed object, or a factored result carrying an explicit
        scalar coefficient.

    Raises
    ------
    AssertionError
        If a registered implementation returns a value outside the expected
        same-type / `Multiple[same-type]` contract.
    """
    if type(v) is Multiple:
        result = super().invoke(v.base, **kwargs)
        if type(result) is Multiple:
            return Multiple((v.coef * result.coef).simplify(), result.base)
        return Multiple(v.coef, result)
    result = super().invoke(v, **kwargs)
    if isinstance(v, (U1Basis, U1Span, HilbertSpace)):
        assert type(result) is not Multiple, (
            f"Operator {type(self)} acting on {type(v).__name__} should not yield a Multiple!"
        )
    assert isinstance(result, type(v)) or (
        type(result) is Multiple and isinstance(result.base, type(v))
    ), (
        f"Operator {type(self)} acting on {type(v).__name__} should yield same typed object"
        f"or Multiple[{type(v).__name__}]"
    )
    return result

__call__

__call__(obj: Any, **kwargs) -> Any

Apply this functional to obj.

This is a thin wrapper around invoke().

Parameters:

Name Type Description Default
obj Any

Runtime object to dispatch on.

required
**kwargs Any

Additional keyword arguments forwarded to the resolved implementation.

{}

Returns:

Type Description
Any

Result produced by the resolved registered method.

Raises:

Type Description
NotImplementedError

If no registration exists for the runtime pair after MRO fallback.

See Also

invoke(obj, **kwargs) Full dispatch method used by this call wrapper.

Source code in src/qten/abstracts.py
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
def __call__(self, obj: Any, **kwargs) -> Any:
    """
    Apply this functional to `obj`.

    This is a thin wrapper around [`invoke()`][qten.abstracts.Functional.invoke].

    Parameters
    ----------
    obj : Any
        Runtime object to dispatch on.
    **kwargs : Any
        Additional keyword arguments forwarded to the resolved
        implementation.

    Returns
    -------
    Any
        Result produced by the resolved registered method.

    Raises
    ------
    NotImplementedError
        If no registration exists for the runtime pair after MRO fallback.

    See Also
    --------
    [`invoke(obj, **kwargs)`][qten.abstracts.Functional.invoke]
        Full dispatch method used by this call wrapper.
    """
    return self.invoke(obj, **kwargs)