Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
doc revision
Browse files Browse the repository at this point in the history
  • Loading branch information
dwbump committed Jun 30, 2020
1 parent db2eaa8 commit b1eff35
Showing 1 changed file with 168 additions and 43 deletions.
211 changes: 168 additions & 43 deletions src/sage/combinat/root_system/fusion_ring.py
Expand Up @@ -104,19 +104,28 @@ class FusionRing(WeylCharacterRing):
[B22(0,0), B22(1,0), B22(0,1), B22(2,0), B22(1,1), B22(0,2)]
The fusion ring has a number of methods that reflect its role
as the Grothendieck ring of a modular tensor category. These
as the Grothendieck ring of a *modular tensor category*. These
include a twist method :meth:`Element.twist` for its elements related
to the ribbon structure, and the S-matrix :meth:`s_ij`.
There are two natural normalizations of the S-matrix. Both
are explained in Chapter 3 of [BaKi2001]_. The one that is computed
by the method :meth:`s_matrix`, or whose individual entries
are computed by :meth:`s_ij` is denoted `\tilde{s}` in
[BaKi2001]_. It is not unitary. To make it unitary, one would
divide by the square root of `D = \sum_V d_i(V)^2` where the sum
is over all simple objects `V` and `d_i(V)` is the quantum dimension
of `V` computed by the method :meth:`Element.q_dimension`. The quantity `D`
is computed by :meth:`global_q_dimension`.
[BaKi2001]_. It is not unitary.
The unitary S-matrix is `s=D^{-1/2}\tilde{s}` where
.. MATH::
D = \sum_V d_i(V)^2.
The sum is over all simple objects `V` with
`d_i(V)` the *quantum dimension*. We will call quantity `D`
the *global quantum dimension* and `\sqrt{D}` the
*total quantum order*. They are computed by :meth:`global_q_dimension`
and :meth:`total_q_order`. The unitary S-matrix `s` may be obtained
using :meth:`s_matrix` with the option ``unitary=True``.
Let us check the Verlinde formula, which is [DFMS1996]_ (16.3). This
famous identity states that
Expand Down Expand Up @@ -187,6 +196,8 @@ class FusionRing(WeylCharacterRing):
[0, 1, 1/8]
sage: I.global_q_dimension()
4
sage: I.total_q_order()
2
sage: [x.q_dimension()^2 for x in b]
[1, 1, 2]
sage: I.s_matrix()
Expand All @@ -198,6 +209,55 @@ class FusionRing(WeylCharacterRing):
[1 1 2]
[2 2 0]
The term *modular tensor category* refers to the fact that associated
with the category there is a projective representation of the modular
group `SL(2,\mathbb{Z})`. We recall that this group is generated by
.. MATH::
S = \begin{pmatrix} & -1\\1\end{pmatrix},\qquad
T = \begin{pmatrix} 1 & 1\\ &1 \end{pmatrix}
subject tot the relations `(ST)^3=S^2`, `S^2T=TS^2`, `S^4=I`.
Let `s` be the normalized S-matrix, and
`t` the diagonal matrix whose entries are the twists of the simple
objects. Let `s` the unitary S-matrix and `t` the matrix of twists,
and `C` the conjugation matrix :meth:`cc_matrix`. Let
.. MATH::
D_+ = \sum_i d_i^2\theta_i, \qquad D_- = d_i^2\theta_i^{-1}.
Let `c` be the virasoro central charge, a rational number that
is computed in :meth:`virasoro_central_charge`. It is known that
.. MATH::
\sqrt{\frac{D_+}{D_-}}=e^{i\pi c/4}.
It is proved in [BaKi2001]_, equation (3.1.17) that
.. MATH::
(st)^3= e^{i\pi c/4} s^2,\qquad s^2=C,\qquad C^2=1,\qquad Ct=tC.
Therefore `S\mapsto s, T\mapsto t` is a projective representation
of `SL(2,\mathbb{Z})`. Let us confirm these identities for the Fibonacci MTC
``FusionRing("G2",1)``::
sage: R = FusionRing("G2",1)
sage: S = R.s_matrix(unitary=True)
sage: T = R.twists_matrix()
sage: C = R.cc_matrix()
sage: c = R.virasoro_central_charge(); c
14/5
sage: (S*T)^3 == R.to_field(c/4)*S^2
True
sage: S^2 == C
True
sage: C*T == T*C
True
"""
@staticmethod
def __classcall__(cls, ct, k, base_ring=ZZ, prefix=None, style="coroots", conjugate=False, cyclotomic_order=None):
Expand Down Expand Up @@ -260,6 +320,16 @@ def _test_verlinde(self, **options):
v = sum(self.s_ij(x,w) * self.s_ij(y,w) * self.s_ij(z,w) / self.s_ij(i0,w) for w in B)
tester.assertEqual(v, c * self.N_ijk(x,y,z))

def _test_total_q_order(self, **options):
"""
The total quantum order is the positive square root
of the global quantum dimension. Check that it is
real and positive. This indirectly test the
Virasoro central charge.
"""
tester = self._tester(**options)
tqo = self.total_q_order()
return tqo.is_real_positive() and tqo**2 == self.global_q_dimension()

def fusion_labels(self, labels=None, inject_variables=False):
r"""
Expand Down Expand Up @@ -351,7 +421,16 @@ def to_field(self, r):
INPUT:
= ``i`` -- a rational number
= ``r`` -- a rational number
EXAMPLES::
sage: A11=FusionRing("A1",1)
sage: A11.field()
Cyclotomic Field of order 24 and degree 8
sage: [A11.to_field(2/x) for x in [1..7]]
[1, -1, zeta24^4 - 1, zeta24^6, None, zeta24^4, None]
"""

n = 2 * r * self._cyclotomic_order
Expand Down Expand Up @@ -446,6 +525,8 @@ def virasoro_central_charge(self):
\frac{k\dim\mathfrak{g}}{k+h^\vee}
where `k` is the level and `h^\vee` is the dual Coxeter number.
See [DFMS1996]_ equation (15.61).
By Proposition 2.3 in [RoStWa2009]_ there exists
a rational number c such that `D_+/\sqrt{D}=e^{i\pi c/4}`
where `D_+=\sum d_i^2\theta_i` is computed in
Expand Down Expand Up @@ -496,27 +577,18 @@ def twists_matrix(self):

def cc_matrix(self):
r"""
Return the conjugation matrix, the permutation matrix
for the conjugation operation on basis elements.
"""
b = self.basis().list()
return matrix([[i==j.dual() for i in b] for j in b])

def q_dims(self):
r"""
Return a list of quantum dimensions of the simple objects.
Return the conjugation matrix, which is the permutation matrix
for the conjugation (dual) operation on basis elements.
EXAMPLES::
sage: F41 = FusionRing('F4',1,conjugate=True)
sage: F41.q_dims()
[1, -zeta80^24 + zeta80^16 + 1]
sage: B22 = FusionRing("B2",2)
sage: B22.q_dims()
[1, 2, -2*zeta40^12 + 2*zeta40^8 + 1, 1, -2*zeta40^12 + 2*zeta40^8 + 1, 2]
sage: FusionRing("A2",1).cc_matrix()
[1 0 0]
[0 0 1]
[0 1 0]
"""
b = self.basis()
return [b[x].q_dimension() for x in self.get_order()]
b = self.basis().list()
return matrix([[i==j.dual() for i in b] for j in b])

@cached_method
def N_ijk(self, elt_i, elt_j, elt_k):
Expand Down Expand Up @@ -599,40 +671,47 @@ def s_ij(self, elt_i, elt_j):
ijtwist = elt_i.twist() + elt_j.twist()
return sum(k.q_dimension() * self.Nk_ij(elt_i, k, elt_j) * self.to_field(k.twist() - ijtwist) for k in self.basis())

def s_matrix(self):
def s_matrix(self, unitary=False):
r"""
Return the S-matrix of this FusionRing.
.. NOTE::
OPTIONAL:
- ``unitary`` -- (default: False) set True to obtain the unitary S-matrix.
This is the matrix denoted `\widetilde{s}` in [BaKi2001]_.
It is not normalized to be unitary. To obtain a unitary
matrix, divide by `\sqrt{D}` where `D` is computed
by :meth:`global_q_dimension`.
Without the `unitary` parameter, this is the matrix denoted
`\widetilde{s}` in [BaKi2001]_.
EXAMPLES::
sage: D91 = FusionRing('D9', 1)
sage: D91 = FusionRing("D9", 1)
sage: D91.s_matrix()
[ 1 1 1 1]
[ 1 1 -1 -1]
[ 1 -1 -zeta136^34 zeta136^34]
[ 1 -1 zeta136^34 -zeta136^34]
sage: D41 = FusionRing('D4', 1)
sage: D41.s_matrix()
[ 1 1 1 1]
[ 1 1 -1 -1]
[ 1 -1 1 -1]
[ 1 -1 -1 1]
sage: S = D91.s_matrix(unitary=True); S
[ 1/2 1/2 1/2 1/2]
[ 1/2 1/2 -1/2 -1/2]
[ 1/2 -1/2 -1/2*zeta136^34 1/2*zeta136^34]
[ 1/2 -1/2 1/2*zeta136^34 -1/2*zeta136^34]
sage: S*S.conjugate()
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]
"""
b = self.basis()
return matrix([[self.s_ij(b[x], b[y]) for x in self.get_order()] for y in self.get_order()])

S = matrix([[self.s_ij(b[x], b[y]) for x in self.get_order()] for y in self.get_order()])
if unitary:
return S/self.total_q_order()
else:
return S

def global_q_dimension(self):
r"""
Return `\sum d_i^2`, where the sum is over all simple objects
and `d_i` is the quantum dimension.
and `d_i` is the quantum dimension. It is a positive real number.
EXAMPLES::
Expand All @@ -641,17 +720,63 @@ def global_q_dimension(self):
"""
return sum(x.q_dimension()**2 for x in self.basis())

def total_q_order(self):
"""
Return the positive square root of ``self.global_q_dimension()``
as an element of ``self.field()``.
EXAMPLES::
sage: F = FusionRing("G2",1)
sage: tqo=F.total_q_order(); tqo
zeta60^15 - zeta60^11 - zeta60^9 + 2*zeta60^3 + zeta60
sage: tqo.is_real_positive()
True
sage: tqo^2 == F.global_q_dimension()
True
"""
c = self.virasoro_central_charge()
return self.D_plus() * self.to_field(-c/4)

def D_plus(self):
r"""
Return `\sum d_i^2\theta_i` where `i` runs through the simple objects and
`theta_i` is the twist.
`\theta_i` is the twist. This is denoted `p_+` in [BaKi2001]_ Chapter 3.
EXAMPLES::
sage: B31=FusionRing("B3",1)
sage: Dp = B31.D_plus(); Dp
2*zeta48^13 - 2*zeta48^5
sage: Dm = B31.D_minus(); Dm
-2*zeta48^3
sage: Dp*Dm == B31.global_q_dimension()
True
sage: c = B31.virasoro_central_charge(); c
7/2
sage: Dp/Dm == B31.to_field(c/2)
True
"""
return sum((x.q_dimension())**2*self.to_field(x.twist()) for x in self.basis())

def D_minus(self):
r"""
Return `\sum d_i^2\theta_i^{-1}` where `i` runs through the simple objects and
`theta_i` is the twist.
`\theta_i` is the twist. This is denoted `p_-` in [BaKi2001]_ Chapter 3.
EXAMPLES::
sage: E83=FusionRing("E8",3,conjugate=True)
sage: [Dp,Dm] = [E83.D_plus(), E83.D_minus()]
sage: Dp*Dm == E83.global_q_dimension()
True
sage: c = E83.virasoro_central_charge(); c
-248/11
sage: Dp*Dm == E83.global_q_dimension()
True
"""
return sum((x.q_dimension())**2*self.to_field(-x.twist()) for x in self.basis())

Expand Down

0 comments on commit b1eff35

Please sign in to comment.