Skip to content

qten.geometries.basis_transform

Module reference for qten.geometries.basis_transform.

basis_transform

Basis-change operators for direct and reciprocal lattice geometry.

This module defines the linear basis-transform machinery used to re-express geometric objects under a change of lattice basis without moving the underlying physical points in space. The central idea is that a matrix M changes the coordinate description attached to an AffineSpace, Lattice, or ReciprocalLattice, and the corresponding Offset and Momentum coordinates are then rebased into the transformed spaces.

Two complementary conventions are implemented:

  • BasisTransform is the forward-view transform, acting on a direct-lattice basis as \(A \mapsto A M\). In repository usage, this is the supercell-building convention. In code, the corresponding matrix product is basis @ M.
  • InverseBasisTransform is the paired inverse-view transform, acting as \(A \mapsto A M^{-1}\). In repository usage, this is the primitive-cell recovery or unfolding convention. In code, this uses products with M.inv().

The registrations in this module keep direct and reciprocal lattices consistent with one another. When a direct lattice basis changes, the reciprocal basis transforms contragrediently, offsets are rebased into the new direct space, and momenta are rebased into the new reciprocal space. For bounded lattices, the boundary-identification matrix is transformed together with the lattice basis so that the same finite torus is described in the new coordinate system.

Repository usage

This module underpins two major workflows in QTen:

  • Geometry-level supercell construction and recovery, where a lattice and its unit-cell offsets are rewritten in a new basis.
  • Band-structure folding and unfolding via bandfold and bandunfold, which rely on these transforms to map between primitive and transformed Brillouin-zone descriptions.
Notes

The concrete lattice registrations in this module currently support PeriodicBoundary explicitly. For transformed periodic systems, the transformed boundary basis must remain integral so that the finite quotient lattice is still represented exactly.

AbstractBasisTransform dataclass

AbstractBasisTransform(M: ImmutableDenseMatrix)

Bases: Functional, ABC

Abstract linear basis-change operator parameterized by a matrix M.

AbstractBasisTransform represents a change of coordinates or basis on geometric objects such as affine spaces, lattices, offsets, and momenta. Concrete subclasses decide whether M should be interpreted as the forward transform or as its inverse-view companion.

Parameters:

Name Type Description Default
M ImmutableDenseMatrix

Square transformation matrix describing the basis change.

required

Attributes:

Name Type Description
M ImmutableDenseMatrix

Square transformation matrix describing the basis change.

Notes

Concrete actions are provided through Functional registrations on supported geometric object types.

inv abstractmethod

inv() -> AbstractBasisTransform

Return the opposite-view basis transform.

Returns:

Type Description
AbstractBasisTransform

Transform that undoes this view convention, without inverting the stored matrix eagerly unless required by the concrete subclass.

Source code in src/qten/geometries/basis_transform.py
111
112
113
114
115
116
117
118
119
120
121
122
@abstractmethod
def inv(self) -> "AbstractBasisTransform":
    """
    Return the opposite-view basis transform.

    Returns
    -------
    AbstractBasisTransform
        Transform that undoes this view convention, without inverting the
        stored matrix eagerly unless required by the concrete subclass.
    """
    pass

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(obj: Any, **kwargs) -> Any

Apply this functional to obj using registered multimethod dispatch.

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 (type(obj), type(self)) after MRO fallback.

Source code in src/qten/abstracts.py
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
def invoke(self, obj: Any, **kwargs) -> Any:
    """
    Apply this functional to `obj` using registered multimethod dispatch.

    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
        `(type(obj), type(self))` after MRO fallback.
    """
    functional_class = type(self)
    obj_class = type(obj)
    method = self._resolve_method(obj_class, functional_class)

    if method is None:
        raise NotImplementedError(
            f"No function registered for {obj_class.__name__} "
            f"with {functional_class.__name__}"
        )

    return method(self, obj, **kwargs)

__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)

BasisTransform dataclass

BasisTransform(M: ImmutableDenseMatrix)

Bases: AbstractBasisTransform

Forward-view basis transform acting with matrix M.

This is the "build a supercell / change to a coarser Lattice basis" convention used throughout the geometry and band-folding code. For a direct-lattice basis matrix A, the transformed basis is

\(A' = A M\).

The same physical point is then re-expressed in the new basis rather than moved in space. In other words, BasisTransform changes coordinates by changing the basis objects attached to the geometry.

Supported Actions

BasisTransform is registered on the following object types:

The registrations are coordinated so that Lattice and ReciprocalLattice objects remain dual to each other.

Mathematical Action

Let A denote a Lattice-basis matrix and \(B = 2\pi A^{-\mathsf{T}}\) the corresponding ReciprocalLattice-basis matrix.

On AffineSpace : \(A' = A M\).

On Lattice : the lattice basis becomes \(A M\), while periodic boundary generators are re-expressed as \(M^{-1}G\) so that the same physical torus is described in the transformed basis. For integer \(M\) with positive determinant, this typically produces a supercell with \(\lvert\det M\rvert\) sites in the transformed unit cell.

On ReciprocalLattice : because reciprocal bases transform contragrediently, \(B' = B M^{-\mathsf{T}}\).

On Offset : an offset with Lattice-fractional coordinates \(r\) is rebased into the transformed space, giving \(r' = M^{-1} r\).

On Momentum : a momentum with ReciprocalLattice- fractional coordinates \(\kappa\) are rebased into the transformed reciprocal space, giving \(\kappa' = M^{\mathsf{T}}\kappa\).

In implementation terms, these rules correspond to matrix products such as A @ M, B @ M.inv().T, M.inv() @ r, and M.T @ kappa.

Repository Usage

In this repository, BasisTransform is used in two main ways:

  • Geometry-level supercell construction via BasisTransform(lat), which enlarges the Lattice unit cell and propagates the corresponding boundary and ReciprocalLattice changes.
  • Band folding via bandfold, where the transform maps a primitive Brillouin zone onto the Brillouin zone of the transformed lattice and enlarges the Hilbert-space legs to match the folded unit cell.
Notes

This class does not store \(M^{-1}\). It stores M and applies the forward convention consistently across dispatches. The opposite convention is represented by InverseBasisTransform.

inv

inv() -> InverseBasisTransform

Return the inverse-view transform associated with the same matrix M.

This switches from the forward convention \(A \mapsto A M\) to the inverse convention \(A \mapsto A M^{-1}\) without changing the stored parameter M. The returned object therefore represents the basis-change view that reverses the action of this BasisTransform on supported geometry objects.

Returns:

Type Description
InverseBasisTransform

InverseBasisTransform carrying the same matrix M.

Notes

This method does not replace M by \(M^{-1}\) in the dataclass field. Instead, it returns the companion transform class whose dispatch rules interpret the same matrix using the opposite basis-change convention.

For example, if this transform maps a Lattice basis as \(A \mapsto A M\), then the returned transform maps it as \(A \mapsto A M^{-1}\). Likewise, applying self.inv().inv() returns a new BasisTransform with the original matrix M.

Source code in src/qten/geometries/basis_transform.py
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
def inv(self) -> "InverseBasisTransform":
    r"""
    Return the inverse-view transform associated with the same matrix `M`.

    This switches from the forward convention
    \(A \mapsto A M\) to the inverse convention
    \(A \mapsto A M^{-1}\) without changing the stored parameter `M`.
    The returned object therefore represents the basis-change view that
    reverses the action of this [`BasisTransform`][qten.geometries.basis_transform.BasisTransform]
    on supported geometry objects.

    Returns
    -------
    InverseBasisTransform
        [`InverseBasisTransform`][qten.geometries.basis_transform.InverseBasisTransform]
        carrying the same matrix `M`.

    Notes
    -----
    This method does not replace `M` by \(M^{-1}\) in the dataclass field.
    Instead, it returns the companion transform class whose dispatch rules
    interpret the same matrix using the opposite basis-change convention.

    For example, if this transform maps a
    [`Lattice`][qten.geometries.spatials.Lattice] basis as
    \(A \mapsto A M\), then the returned transform maps it as
    \(A \mapsto A M^{-1}\). Likewise,
    applying `self.inv().inv()` returns a new
    [`BasisTransform`][qten.geometries.basis_transform.BasisTransform]
    with the original matrix `M`.
    """
    return InverseBasisTransform(self.M)

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(obj: Any, **kwargs) -> Any

Apply this functional to obj using registered multimethod dispatch.

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 (type(obj), type(self)) after MRO fallback.

Source code in src/qten/abstracts.py
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
def invoke(self, obj: Any, **kwargs) -> Any:
    """
    Apply this functional to `obj` using registered multimethod dispatch.

    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
        `(type(obj), type(self))` after MRO fallback.
    """
    functional_class = type(self)
    obj_class = type(obj)
    method = self._resolve_method(obj_class, functional_class)

    if method is None:
        raise NotImplementedError(
            f"No function registered for {obj_class.__name__} "
            f"with {functional_class.__name__}"
        )

    return method(self, obj, **kwargs)

__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)

InverseBasisTransform dataclass

InverseBasisTransform(M: ImmutableDenseMatrix)

Bases: AbstractBasisTransform

Inverse-view basis transform paired with BasisTransform.

InverseBasisTransform(M) uses the same stored matrix as BasisTransform, but it interprets that matrix as the inverse change of basis. For a Lattice-basis matrix A, the transformed basis is

\(A' = A M^{-1}\).

This is the "undo the supercell / recover the primitive description" convention used when unfolding folded lattices, offsets, and band structures back into their primitive representation.

Supported Actions

InverseBasisTransform directly registers specialized implementations for:

Through the shared AbstractBasisTransform registrations, it also acts on:

Mathematical Action

Let A denote a Lattice-basis matrix and \(B = 2\pi A^{-\mathsf{T}}\) the corresponding ReciprocalLattice-basis matrix.

On AffineSpace : \(A' = A M^{-1}\).

On Lattice : the lattice basis becomes \(A M^{-1}\), while periodic boundary generators are mapped as \(G \mapsto M G\). For lattices produced by BasisTransform, this reconstructs the primitive-cell description and merges folded unit-cell labels back onto primitive labels when possible.

On ReciprocalLattice : duality gives \(B' = B M^{\mathsf{T}}\).

On Offset : Lattice-fractional coordinates are rebased by \(r' = M r\).

On Momentum : ReciprocalLattice- fractional coordinates are rebased by \(\kappa' = M^{-\mathsf{T}}\kappa\).

In implementation terms, these rules correspond to matrix products such as A @ M.inv(), B @ M.T, M @ r, and M.inv().T @ kappa.

Repository Usage

In this repository, InverseBasisTransform is primarily used for:

  • Recovering primitive lattices from supercells created by BasisTransform.
  • Band unfolding via bandunfold, which requires an InverseBasisTransform explicitly so the direction of the operation is unambiguous at runtime.
Notes

InverseBasisTransform(M).inv() returns BasisTransform(M). The two classes therefore share the same matrix parameter while differing only in which side of the basis-change convention they represent.

inv

inv() -> BasisTransform

Return the forward-view transform associated with the same matrix M.

This switches from the inverse convention \(A \mapsto A M^{-1}\) back to the forward convention \(A \mapsto A M\) without changing the stored parameter M. The returned object is the companion BasisTransform used for supercell construction and band folding.

Returns:

Type Description
BasisTransform

BasisTransform carrying the same matrix M.

Notes

This method does not explicitly invert the stored matrix field. Instead, it returns the paired transform class whose registrations interpret M in the forward basis-change convention.

For example, if this transform maps a Lattice basis as \(A \mapsto A M^{-1}\), then the returned transform maps it as \(A \mapsto A M\). Likewise, applying self.inv().inv() returns a new InverseBasisTransform with the original matrix M.

Source code in src/qten/geometries/basis_transform.py
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
def inv(self) -> BasisTransform:
    r"""
    Return the forward-view transform associated with the same matrix `M`.

    This switches from the inverse convention
    \(A \mapsto A M^{-1}\) back to the forward convention
    \(A \mapsto A M\) without changing the stored parameter `M`.
    The returned object is the companion
    [`BasisTransform`][qten.geometries.basis_transform.BasisTransform]
    used for supercell construction and band folding.

    Returns
    -------
    BasisTransform
        [`BasisTransform`][qten.geometries.basis_transform.BasisTransform]
        carrying the same matrix `M`.

    Notes
    -----
    This method does not explicitly invert the stored matrix field.
    Instead, it returns the paired transform class whose registrations
    interpret `M` in the forward basis-change convention.

    For example, if this transform maps a
    [`Lattice`][qten.geometries.spatials.Lattice] basis as
    \(A \mapsto A M^{-1}\), then the returned transform maps it as
    \(A \mapsto A M\). Likewise,
    applying `self.inv().inv()` returns a new
    [`InverseBasisTransform`][qten.geometries.basis_transform.InverseBasisTransform]
    with the original matrix `M`.
    """
    return BasisTransform(self.M)

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(obj: Any, **kwargs) -> Any

Apply this functional to obj using registered multimethod dispatch.

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 (type(obj), type(self)) after MRO fallback.

Source code in src/qten/abstracts.py
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
def invoke(self, obj: Any, **kwargs) -> Any:
    """
    Apply this functional to `obj` using registered multimethod dispatch.

    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
        `(type(obj), type(self))` after MRO fallback.
    """
    functional_class = type(self)
    obj_class = type(obj)
    method = self._resolve_method(obj_class, functional_class)

    if method is None:
        raise NotImplementedError(
            f"No function registered for {obj_class.__name__} "
            f"with {functional_class.__name__}"
        )

    return method(self, obj, **kwargs)

__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)