Specifying symmetry#

YASTN specifies symmetry through any object that is a plain Python module or class which defines

  1. SYM_ID string label specyfying the symmetry,

  2. NSYM number of elements in the charge vector. For example, NSYM=1 for \(U(1)\) or \(Z_2\) group. For product groups such as \(U(1)\times U(1)\) instead NSYM=2.

  3. how to add up charges by implementing a fuse function.

Parent class for defining symmetry rules.

class yastn.sym.sym_abelian.sym_abelian[source]#

Interface to be subclassed for concrete symmetry implementations.

classmethod add_charges(*charges, s=None, new_s=1)[source]#

Auxiliary function for adding tensor charges. It employs fuse function and returns resulting charge as a tuple.

Parameters:
  • charges (tuple[int, …]) – Sequence of charges to be added.

  • s (None | Sequence[int]) – The default None uses signature 1 for all charges. For subtraction, it is possible to provide signatures by hand.

  • new_s (int) – The default is 1.

Returns:

resulting tuple of charges

Return type:

tuple

classmethod fuse(charges, signatures, new_signature)[source]#

Fusion rule for abelian symmetry.

An i-th row charges[i,:,:] contains m length-NSYM charge vectors, where m is the number of legs being fused. For each row, the charge vectors are added up (fused) with selected signatures according to the group addition rules.

Parameters:
  • charges (numpy.ndarray(int)) – \(k imes m imes nsym\) matrix, where \(k\) is the number of independent blocks, and \(m\) is the number of fused legs.

  • signatures (numpy.ndarray(int)) – integer vector with \(m\) elements in \({-1, +1}\).

  • new_signature (int) – new signature for a new leg from fused legs.

Returns:

integer matrix with shape (k, NSYM) of fused charges; includes multiplication by new_signature.

Return type:

numpy.ndarray(int)

classmethod zero()[source]#

Zero charge.

Example symmetries defined in YASTN#

  • \(U(1)\) symmetry

class sym_U1(sym_abelian):
    """U1 symmetry"""

    SYM_ID = 'U1'
    NSYM = 1  # single int is used to distinguish symmetry sectors

    @classmethod
    def fuse(cls, charges, signatures, new_signature):
        """ Fusion rule for U1 symmetry. """
        return new_signature * (charges.swapaxes(1, 2) @ signatures)
  • \(Z_2\) symmetry

class sym_Z2(sym_abelian):
    """Z2 symmetry"""

    SYM_ID = 'Z2'
    NSYM = 1  # single int is used to distinguish symmetry sectors

    @classmethod
    def fuse(cls, charges, signatures, new_signature):
        """ Fusion rule for Z2 symmetry. """
        return np.mod(new_signature * (charges.swapaxes(1, 2) @ signatures), 2)
  • \(Z_2\times U(1)\)

class sym_Z2xU1(sym_abelian):
    """ Z2xU1 symmetry; for testing"""
    SYM_ID = "Z2xU1"
    NSYM = 2

    def fuse(charges, signatures, new_signature):
        """ Fusion rule for Z2xU1 symmetry. """
        teff = new_signature * (charges.swapaxes(1,2) @ signatures)
        teff[:, 0] = np.mod(teff[:, 0], 2)
        return teff