Specifying symmetry#
YASTN specifies symmetry through any object that is a plain Python module or class which defines
SYM_ID
string label specyfying the symmetry
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)\), NSYM=2
fuse
function that specifies the addition of charges
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, signatures=None, new_signature=1) tuple[int, ...] [source]#
Auxiliary function for adding tensor charges. It employs
fuse()
function and returns resulting charge as a tuple of integers.- Parameters:
charges (Sequence[tuple[int, …]]) – Sequence of charges to be added.
signatures (None | Sequence[int]) – Signature for provided charges. The default None uses signature 1 for all charges.
new_signature (int) – Signature for the addition result. The default is 1.
- classmethod fuse(charges, signatures, new_signature) ndarray[int64] [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 selectedsignatures
according to the group addition rules.- Parameters:
charges (np.ndarray[int]) – \(k \times m \times nsym\) matrix, where \(k\) is the number of independent blocks, and \(m\) is the number of fused legs.
signatures (np.ndarray[int]) – integer vector with \(m\) elements in \({-1, +1}\).
new_signature (int) – new signature for a new leg from fused legs.
- Returns:
matrix of integers with shape (k, NSYM) of fused charges; includes multiplication by
new_signature
.- Return type:
np.ndarray[int]
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"""
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