Skip to content

qten.pointgroups.elements

Module reference for qten.pointgroups.elements.

elements

Symbolic point-group element representations.

This module defines the core single-element objects used by QTen's symmetry machinery. PointGroupElement stores an exact linear representation (irrep on the model, optional rotation3 in \(O(3)\), and a construction-time spin policy), derives Euclidean polynomial bases, and computes symbolic eigen-basis sectors. PointGroupOpr couples that linear action with an affine offset. Polynomial sector labels live in PointGroupBasis.

Repository usage

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

PointGroupElement dataclass

PointGroupElement(
    irrep: ImmutableDenseMatrix,
    axes: tuple[Symbol, ...],
    rotation3: ImmutableDenseMatrix | None = None,
    spin: str = "electron",
)

Bases: Opr

Linear point operation represented on Cartesian coordinate functions.

PointGroupElement 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 (PointGroupBasis). A single element may belong to an abelian or a non-abelian group.

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
rotation3 ImmutableDenseMatrix | None

The same physical operation as a Cartesian \(O(3)\) matrix, used to lift spin-1/2. Three-dimensional groups may leave this unset and use irrep. Lower-dimensional groups must set it at construction.

None
spin str

Construction-time spin policy. "electron" lifts rotation3; "trivial" uses \(u(g)=I\).

`"electron"`

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.

rotation3 ImmutableDenseMatrix | None

Stored 3D rotation used for the \(SU(2)\) lift, or None when irrep is already that 3D matrix.

spin str

"electron" or "trivial", fixed at construction.

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 PointGroupBasis 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

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

PointGroupElement @ PointGroupElement 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. Both operands must share the same spin policy, and either both store rotation3 or neither does.

The group_order() and basis_table utilities assume the represented element has finite order. They apply to a single finite-order operation, not only to abelian groups, and 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.

rotation3 class-attribute instance-attribute

rotation3: ImmutableDenseMatrix | None = None

The same physical operation as a Cartesian \(O(3)\) matrix, used to lift spin-1/2. Three-dimensional groups may leave this unset and use irrep. Lower-dimensional groups must set it at construction; it is not inferred by padding irrep at lift time.

spin class-attribute instance-attribute

spin: str = 'electron'

Spin policy fixed at construction. "electron" uses the \(SU(2)\) lift of rotation3. "trivial" uses \(u(g)=I\).

basis_table cached property

basis_table: FrozenDict[Expr, PointGroupBasis]

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 PointGroupBasis.

Raises:

Type Description
ValueError

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

with_irrep

with_irrep(
    irrep: ImmutableDenseMatrix,
    axes: tuple[Symbol, ...] | None = None,
    *,
    rotation3: ImmutableDenseMatrix | None | object = ...,
) -> PointGroupElement

Return a copy with a new spatial matrix, keeping spin metadata.

Source code in src/qten/pointgroups/elements.py
202
203
204
205
206
207
208
209
210
211
212
213
214
215
def with_irrep(
    self,
    irrep: sy.ImmutableDenseMatrix,
    axes: Tuple[sy.Symbol, ...] | None = None,
    *,
    rotation3: sy.ImmutableDenseMatrix | None | object = ...,
) -> "PointGroupElement":
    """Return a copy with a new spatial matrix, keeping spin metadata."""
    return PointGroupElement(
        irrep=irrep,
        axes=self.axes if axes is None else axes,
        rotation3=self.rotation3 if rotation3 is ... else rotation3,
        spin=self.spin,
    )

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/elements.py
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
@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/elements.py
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
@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/elements.py
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
384
385
386
387
388
389
390
391
392
@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() -> PointGroupElement

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/elements.py
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
@lru_cache
def inv(self) -> "PointGroupElement":
    """
    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.
    """
    rotation3 = None
    if self.rotation3 is not None:
        rotation3 = sy.ImmutableDenseMatrix(sy.simplify(self.rotation3.inv()))
    return self.with_irrep(
        sy.ImmutableDenseMatrix(sy.simplify(self.irrep.inv())),
        rotation3=rotation3,
    )

basis cached

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

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 PointGroupBasis eigenfunction. Normalization is fixed by dividing by the first non-zero coefficient in each eigenvector.

Source code in src/qten/pointgroups/elements.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
440
441
442
443
@lru_cache
def basis(self, order: int) -> FrozenDict:
    """
    Compute abelian eigen-basis functions from [`euclidean_repr(order)`][qten.pointgroups.elements.PointGroupElement.euclidean_repr] eigenvectors.

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

    Returns
    -------
    FrozenDict
        Mapping from eigenvalue to normalized [`PointGroupBasis`][qten.pointgroups.basis.PointGroupBasis] 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] = PointGroupBasis.from_rep(
            rep=sy.ImmutableDenseMatrix(vec),
            euclidean_basis=self.euclidean_basis(order),
            axes=self.axes,
            order=order,
            irrep=sy.simplify(v),
        )

    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
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
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
@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)

PointGroupOpr dataclass

PointGroupOpr(
    g: PointGroupElement, offset: Offset | None = None
)

Bases: Opr, HasBase[AffineSpace]

Affine point operation acting on polynomial coordinate functions.

This class combines a linear PointGroupElement with a translation: \(x \mapsto gx + t\), where \(t\) is stored on offset. The linear part may belong to an abelian or a non-abelian group.

Parameters:

Name Type Description Default
g PointGroupElement

Linear part of the affine transformation.

required
offset Offset | None

Not accepted as a constructor argument. Passing a value raises TypeError. The constructor always starts at the origin; call fixpoint_at afterwards. The offset attribute stores the resulting translation.

None

Attributes:

Name Type Description
g PointGroupElement

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(...). Applying the operator to a Spin label or a spinful U1Basis raises: a generic \(SU(2)\) factor produces a superposition. Use expand_spin or hilbert_repr.

Source code in src/qten/pointgroups/elements.py
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
def __init__(
    self,
    g: PointGroupElement,
    offset: Offset | None = None,
):
    if offset is not None:
        raise TypeError(
            "PointGroupOpr does not accept offset=... directly. "
            "Construct PointGroupOpr(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: PointGroupElement

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/elements.py
665
666
667
668
669
670
671
672
673
674
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) -> PointGroupOpr

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
PointGroupOpr

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

Source code in src/qten/pointgroups/elements.py
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
@lru_cache(maxsize=None)
def rebase(self, new_base: AffineSpace) -> "PointGroupOpr":
    """
    Re-express this transform in a different affine space basis.

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

    Returns
    -------
    PointGroupOpr
        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 PointGroupOpr._from_parts(
        g=self.g.with_irrep(sy.ImmutableDenseMatrix(new_irrep)),
        offset=self.offset.rebase(new_base),
    )

fixpoint_at

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

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
PointGroupOpr

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

Source code in src/qten/pointgroups/elements.py
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
def fixpoint_at(self, r: Offset, rebase: bool = False) -> "PointGroupOpr":
    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
    -------
    PointGroupOpr
        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 PointGroupOpr._from_parts(
        g=t.g.with_irrep(irrep),
        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
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
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
@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)