Tutorial: Cokernels

This page appears both rendered to HTML in the docs, and as an interactive notebook in the /examples folder in the repository.

[1]:
from bggcohomology.bggcomplex import BGGComplex
from bggcohomology.la_modules import LieAlgebraCompositeModule, ModuleFactory, BGGCohomology
import numpy as np

This notebook will explain how to do computations with quotients of modules, given by cokernels of some maps. This is fairly technical in practice.

As an example consider the following exact sequence

\[0\to\wedge^2\mathfrak b\to\mathfrak b\otimes\mathfrak b\to\operatorname{Sym}^2\mathfrak b\to 0\]

Here \(\mathfrak b\) plays no particular role, and there is a such an exact sequence for any module. This sequence tells us in particular that

\[\operatorname{Sym}^2\mathfrak b \cong \operatorname{coker}\left(\wedge^2\mathfrak b\to\mathfrak b\otimes\mathfrak b\right)\]

Let’s start by defining the three modules \(\wedge^2\mathfrak b,\,\mathfrak b\otimes\mathfrak b,\,\operatorname{Sym}^2\mathfrak b\). We pick the root system \(G_2\), but it also serves no particular role.

[2]:
BGG = BGGComplex('G2')
factory = ModuleFactory(BGG.LA)

component_dic = {'b':factory.build_component('b','coad',subset=[])}

wedge_components = [[("b",2,'wedge')]]
wedge_module = LieAlgebraCompositeModule(factory,wedge_components,component_dic)

tensor_components = [[("b",1,'wedge'),('b',1,'wedge')]]
tensor_module = LieAlgebraCompositeModule(factory,tensor_components,component_dic)

sym_components = [[("b",2,'sym')]]
sym_module = LieAlgebraCompositeModule(factory,sym_components,component_dic)

Let’s start by first computing the cohomology of the three modules. Note that since the exact sequence splits, we see that \(H^\bullet(\mathfrak b\otimes\mathfrak b) = H^\bullet(\wedge^2\mathfrak b)\oplus H^\bullet(\operatorname{Sym}^2\mathfrak b)\), so this is not a particularly useful example.

[3]:
BGGCohomology(BGG, wedge_module).cohomology_LaTeX(complex_string = r'\wedge^2\mathfrak b')
print('-'*10)

BGGCohomology(BGG, tensor_module).cohomology_LaTeX(complex_string = r'\mathfrak b\otimes\mathfrak b')
print('-'*10)

BGGCohomology(BGG, sym_module).cohomology_LaTeX(complex_string = r'\operatorname{Sym}^2\mathfrak b')
$$\mathrm H^{1}(\wedge^2\mathfrak b)=\mathbb{C}$$
----------
$$\mathrm H^{1}(\mathfrak b\otimes\mathfrak b)=\mathbb{C}$$
$$\mathrm H^{2}(\mathfrak b\otimes\mathfrak b)=L\left( 2\alpha_{1}+\alpha_{2}\right)$$
----------
$$\mathrm H^{2}(\operatorname{Sym}^2\mathfrak b)=L\left( 2\alpha_{1}+\alpha_{2}\right)$$

Now let us define the cokernel of the map \(\wedge^2\mathfrak b\to\mathfrak b\otimes\mathfrak b\). Since this is a map of modules, we can consider each weight component seperately. In a basis the map is defined by \(f_i\wedge f_j\mapsto f_i\otimes f_j - f_j\otimes f_i\). To turn this into a matrix we use the basis of both modules, and then we simple compute the cokernel of this matrix.

[4]:
# Store cokernel in a dictionary
# each key is a weight, each entry is a matrix encoding the basis of the cokernel
T = dict()


for mu in wedge_module.weight_components.keys():
    # Basis of the weight component mu of the wedge module
    wedge_basis = wedge_module.weight_components[mu][0][1]

    # Build the matrix as a sparse matrix
    sparse_mat = dict()

    for wedge_index, wedge_row in enumerate(wedge_basis):
        a,b = wedge_row # each row consists of two indices

        # dictionary sending tuples of (a,b,0) to their index in the basis of tensor product module
        target_dic = tensor_module.weight_comp_index_numbers[mu]

        # look up index of a\otimes b and b\otimes a, and assign respective signs +1, -1
        index_1 = target_dic[(a,b,0)]
        index_2 = target_dic[(b,a,0)]
        sparse_mat[(wedge_index,index_1)] = 1
        sparse_mat[(wedge_index,index_2)] = -1

    # Build a matrix from these relations
    M = matrix(ZZ,sparse_mat,nrows = wedge_module.dimensions[mu], ncols = tensor_module.dimensions[mu], sparse=True)

    # Cokernel is kernel of transpose
    T[mu]=M.transpose().kernel().basis_matrix()

Then to compute the cohomology of the cokernel, we insantiate the cohomology of the module \(\mathfrak b\otimes\mathfrak b\) and give the cokernel as optional argument.

[5]:
complex_string = r'\operatorname{coker}\left(\wedge^2\mathfrak b\to\mathfrak b\otimes\mathfrak b\right)'
BGGCohomology(BGG, tensor_module, coker=T).cohomology_LaTeX(complex_string = complex_string)
$$\mathrm H^{2}(\operatorname{coker}\left(\wedge^2\mathfrak b\to\mathfrak b\otimes\mathfrak b\right))=L\left( 2\alpha_{1}+\alpha_{2}\right)$$

This method can be used to compute the BGG cohomology for much more complicated modules, but in general defining this cokernel can be technically involved.