Source code for groups.su3

import torch
from math import factorial, sqrt
from tn_interface import einsum
import numpy as np

[docs]class SU3_DEFINING(): def __init__(self, p=1, q=0, dtype=torch.complex128, device='cpu'): r""" :param p: (p,q) labels of the highest weight state of su(3) representation. For defining representation ``p=1, q=0``. :type p: int :param q: :type q: int :param dtype: data type of matrix representation of operators :param device: device on which the torch.tensor objects are stored :type J: int :type dtype: torch.dtype :type device: int Build the defining representation :math:`\bf{3}` of su(3) Lie algebra using the Cartan-Weyl (C-W) basis. In terms of the standard Gell-Mann matrices :math:`\lambda`, the C-W basis is: .. math:: \begin{align*} T^\pm &= \frac{1}{2} (\lambda_1 \pm i\lambda_2) = (F_1 \pm iF_2)\\ T^z &= \frac{1}{2} \lambda_3 = F_3\\ V^\pm &= \frac{1}{2} (\lambda_4 \pm i\lambda_5) = (F_4 \pm iF_5)\\ U^\pm &= \frac{1}{2} (\lambda_6 \pm i\lambda_7) = (F_6 \pm iF_7)\\ Y &= \frac{1}{\sqrt{3}} \lambda_8 = \frac{2}{\sqrt{3}} F_8 \end{align*} The quadratic Casimir operator of su(3) can be expressed in terms of the C-W basis, defined as follow. .. math:: \begin{align*} C_1 = \sum_{k}{F_k F_k} &= \frac{1}{2} (T^+ T^- + T^- T^+ + V^+ V^- + V^- V^+ + U^+ U^- + U^- U^+) \\ &+ T^z T^z + \frac{3}{4} Y Y \end{align*} """ assert p==1 and q==0, "su(3) irrep ("+str(p)+","+str(q)+") not implemented." self.p = p self.q = q self.dtype = dtype self.device = device
[docs] def I(self): r""" :return: Identity operator of irrep :rtype: torch.tensor """ return get_op("I", pq=(self.p,self.q), dtype=self.dtype, device=self.device)
[docs] def TZ(self): r""" :return: :math:`T^z` operator of irrep :rtype: torch.tensor """ return get_op("tz", pq=(self.p,self.q), dtype=self.dtype, device=self.device)
[docs] def Y(self): r""" :return: :math:`Y` operator of irrep :rtype: torch.tensor """ return get_op("y", pq=(self.p,self.q), dtype=self.dtype, device=self.device)
[docs] def TP(self): r""" :return: :math:`T^+` operator of irrep :rtype: torch.tensor """ return get_op("tp", pq=(self.p,self.q), dtype=self.dtype, device=self.device)
[docs] def TM(self): r""" :return: :math:`T^-` operator of irrep :rtype: torch.tensor """ return get_op("tm", pq=(self.p,self.q), dtype=self.dtype, device=self.device)
[docs] def VP(self): r""" :return: :math:`V^+` operator of irrep :rtype: torch.tensor """ return get_op("vp", pq=(self.p,self.q), dtype=self.dtype, device=self.device)
[docs] def VM(self): r""" :return: :math:`V^-` operator of irrep :rtype: torch.tensor """ return get_op("vm", pq=(self.p,self.q), dtype=self.dtype, device=self.device)
[docs] def UP(self): r""" :return: :math:`U^+` operator of irrep :rtype: torch.tensor """ return get_op("up", pq=(self.p,self.q), dtype=self.dtype, device=self.device)
[docs] def UM(self): r""" :return: :math:`U^-` operator of irrep :rtype: torch.tensor """ return get_op("um", pq=(self.p,self.q), dtype=self.dtype, device=self.device)
[docs] def Cartan_Weyl(self): r""" :return: vector of generators forming Cartan-Weyl basis ordered as [T^+, T^-, T^z, V^+, V^-, U^+, U^-, Y]. :rtype: torch.tensor Returns a rank-3 tensor with first index running over generators. """ J = torch.zeros(8, 3, 3, dtype=self.dtype, device=self.device) J[0, :, :] = self.TP() J[1, :, :] = self.TM() J[2, :, :] = self.TZ() J[3, :, :] = self.VP() J[4, :, :] = self.VM() J[5, :, :] = self.UP() J[6, :, :] = self.UM() J[7, :, :] = self.Y() return J
[docs] def J_Gell_Mann(self): r""" :return: :math:`\vec{\lambda}` vector of Gell-Mann matrices :rtype: torch.tensor Returns a rank-3 tensor with first index running over generators. """ J = torch.zeros(8, 3, 3, dtype=self.dtype, device=self.device) J[0, :, :] = self.TP() + self.TM() J[1, :, :] = -1j * (self.TP() - self.TM()) J[2, :, :] = 2 * self.TZ() J[3, :, :] = self.VP() + self.VM() J[4, :, :] = -1j * (self.VP() - self.VM()) J[5, :, :] = self.UP() + self.UM() J[6, :, :] = -1j * (self.UP() - self.UM()) J[7, :, :] = np.sqrt(3) * self.Y() return J
[docs] def C1(self): r""" :return: The quadratic Casimir of su(3) as rank-4 for tensor :rtype: torch.tensor """ expr_kron = 'ij,ab->iajb' # spin-spin interaction \sum_k{\vec{F}_{1,k}\vec{S}_{2,k}} between F-spins on sites 1 and 2 C1 = einsum(expr_kron, self.TZ(), self.TZ()) + 0.75 * einsum(expr_kron, self.Y(), self.Y())\ + 0.5 * (einsum(expr_kron, self.TP(), self.TM()) + einsum(expr_kron, self.TM(), self.TP()) + einsum(expr_kron, self.VP(), self.VM()) + einsum(expr_kron, self.VM(), self.VP()) + einsum(expr_kron, self.UP(), self.UM()) + einsum(expr_kron, self.UM(), self.UP())) return C1
[docs] def C2(self): r""" :return: The cubic Casimir of su(3) as rank-6 for tensor :rtype: torch.tensor """ expr_kron = 'ia,jb,kc->ijkabc' Fs = dict() Fs["f1"] = 0.5 * (self.TP() + self.TM()) Fs["f2"] = - 0.5j * (self.TP() - self.TM()) Fs["f3"] = self.TZ() Fs["f4"] = 0.5 * (self.VP() + self.VM()) Fs["f5"] = - 0.5j * (self.VP() - self.VM()) Fs["f6"] = 0.5 * (self.UP() + self.UM()) Fs["f7"] = - 0.5j * (self.UP() - self.UM()) Fs["f8"] = np.sqrt(3.0) / 2 * self.Y() C2 = torch.zeros((3, 3, 3, 3, 3, 3), dtype=torch.complex128, device='cpu') # C2 = None for i in range(8): for j in range(8): for k in range(8): d = 2 * torch.trace((Fs[f"f{i+1}"]@Fs[f"f{j+1}"]+Fs[f"f{j+1}"]@Fs[f"f{i+1}"])@Fs[f"f{k+1}"]) C2 += d * einsum(expr_kron, Fs[f"f{i+1}"], Fs[f"f{j+1}"], Fs[f"f{k+1}"]) return C2
def get_op(op, pq=(1,0), dtype=torch.complex128, device='cpu', dbg=False): assert pq==(1,0),"Unsupported irrep" if op == "I": if dbg: print(">>>>> Constructing 1sO: Id <<<<<") return torch.eye(3, dtype=dtype, device=device) elif op == "tz": if dbg: print(">>>>> Constructing 1sO: T^z <<<<<") res = torch.zeros((3, 3), dtype=dtype, device=device) res[0, 0] = 0.5 res[1, 1] = -0.5 return res elif op == "y": if dbg: print(">>>>> Constructing 1sO: Y <<<<<") res = torch.zeros((3, 3), dtype=dtype, device=device) res[0, 0] = 1.0 / 3.0 res[1, 1] = 1.0 / 3.0 res[2, 2] = - 2.0 / 3.0 return res elif op == "tp": if dbg: print(">>>>> Constructing 1sO: T^+ <<<<<") res = torch.zeros((3, 3), dtype=dtype, device=device) res[0, 1] = 1.0 return res elif op == "tm": if dbg: print(">>>>> Constructing 1sO: T^- <<<<<") res = torch.zeros((3, 3), dtype=dtype, device=device) res[1, 0] = 1.0 return res elif op == "vp": if dbg: print(">>>>> Constructing 1sO: V^+ <<<<<") res = torch.zeros((3, 3), dtype=dtype, device=device) res[0, 2] = 1.0 return res elif op == "vm": if dbg: print(">>>>> Constructing 1sO: V^- <<<<<") res = torch.zeros((3, 3), dtype=dtype, device=device) res[2, 0] = 1.0 return res elif op == "up": if dbg: print(">>>>> Constructing 1sO: U^+ <<<<<") res = torch.zeros((3, 3), dtype=dtype, device=device) res[1, 2] = 1.0 return res elif op == "um": if dbg: print(">>>>> Constructing 1sO: U^- <<<<<") res = torch.zeros((3, 3), dtype=dtype, device=device) res[2, 1] = 1.0 return res else: raise Exception("Unsupported operator requested: " + op) #TODO: CG series of su(3), i.e., the expansion of the tensor product of two irrep into direct sum of irreps