0:
return f
elif len(f.coeffs)>-f.val:
return lpol([f.coeffs[i] for i in range(-f.val+1,len(f.coeffs))],
1,f.vname)
else:
return 0
def nonnegpart(f):
if type(f)==type(0):
return f
elif f.val>=0:
return f
elif len(f.coeffs)>=-f.val:
return lpol([f.coeffs[i] for i in range(-f.val,len(f.coeffs))],
0,f.vname)
else:
return 0
def zeropart(f):
if type(f)==type(0):
return f
elif f.val<=0 and len(f.coeffs)>-f.val:
return f.coeffs[-f.val]
else:
return 0
def barpart(f):
if type(f)==type(0):
return f
else:
return lpol(f.coeffs[::-1],-f.degree,f.vname)
# klpolynomials
def klpolynomials(W,weightL,v):
"""returns the matrix of all Kazhdan-Lusztig polynomials, and further
information on the corresponding left cells, with respect to a given
weight function. The result is a dictionary with components:
elms : all elements of W (as reduced words, in increasing order)
klpols : the Kazhdan-Lusztig polynomials
mpols : the mue-polynomials
klmat : a matrix indexed by pairs of elements of W, whose entries
are strings encoding information on Kazhdan-Lusztig and
mue polynomials. If y<=w (Bruhat-Chevalley order), then
klmat[w][y] is of the form 'ccc ...' where
refers to a polynomial in 'klpols' and , refer
to the polynomials in 'mpols' for the generators labelled
by 0,1,... Otherwise, klmat[w][y] equals 'f'.
arrows : a complete list of all pairs (w,y) where y,w in W are such
that C_y occurs in C_sC_w for some simple reflection s.
lcells : the partition of W into left cells
duflo : the corresponding distinguished involutions, together with
their a-invariants and the sign n_d.
lorder : the partial order on left cells (given as an incidence
matrix)
lcells : the partition of W into left cells
rcells : the partition of W into right cells
tcells : the partition of W into two-sided cells
As in 'ainvariants', a weight function is given by a sequence of
non-negative integers corresponding to the simple reflections of W,
where weights for simple reflections which are conjugate in W have
to be equal. This gives rise to a weight function L from W to the
integers in the sense of Lusztig; given w in W, we have
L(w) = weightL[s_1] + weightL[s_2] + ... + weightL[s_k]
where w=(s_1,...,s_k) is a reduced expression for w. It is allowed
that weightL is just an integer, in which case all weights will be
set equal to that integer.
>>> W=coxeter("B",2)
>>> kl=klpolynomials(W,[2,1],v)
#I Number of elements = 8
#I Initialising (Bruhat-Chevalley order etc.) ....
#I Computing KL polynomials for elements of length:
#I 1 2 3 4
#I 10 arrows >> 6 left cells >> checks are True
>>> kl['klpols']
[1, 1-v**2, 1+v**2] # negative coefficients do occur!
>>> kl['lcells']
[[0], [1, 4], [2], [3, 6], [5], [7]] # elements represented by
# their index in 'elms'
>>> [[kl['elms'][w] for w in c] for c in kl['lcells']]
[[[]],
[[0], [1, 0]],
[[1]],
[[0, 1], [1, 0, 1]],
[[0, 1, 0]],
[[0, 1, 0, 1]]]
>>> kl['elms'][5]
[0, 1, 0]
>>> kl['elms'][0]
[]
>>> kl['klmat'][5][0]
'c1cc'
>>> kl['klpols'][int(kl['klmat'][5][0][1])]
1-v**2
(Thus, we have P_{[],[0,1,0]}=1-v**2.)
In general, P_{elms[y],elms[w]} is given by
kl['klpols'][int(kl['klmat'][w][y].split('c')[1])]
If weightL[s]>0 and sy>> kl['duflo']
[[0, 0, 1], [1, 2, 1], [2, 1, 1], [6, 2, 1], [5, 3, -1], [7, 6, 1]]
Here, each triple consists of d,a(d),n_d where d is the index of the
distinguished involution in the list 'elms', a(d) is the degree of
the Kazhdan-Lusztig polynomial P_{1,d} and n_d the coefficient of
the highest power of v in P_{1,d}. In the course of the computation,
it is checked if n_d is 1 or -1, and also if the function w -> a(w)
reaches its mimumum at exactly one element of a left cell (which is
supposed to be the involution d). -- No counter examples are known!
If one is merely interested in the partition of W into left cells
(and not in knowing all the Kazhdan-Lusztig polynomials), then it is
much more efficient to use the function 'klcells'.
See also 'klcells', 'relklpols' and 'wgraph'.
"""
if type(weightL)==type([]):
poids=weightL
else:
poids=len(W.rank)*[weightL]
if all(i==1 for i in poids):
uneq=False
else:
uneq=True
ap=allwords(W)
Lw=[sum([poids[s] for s in w]) for w in ap]
lw=[len(w) for w in ap]
a=[W.wordtocoxelm(c) for c in ap]
inva=[a.index(W.wordtocoxelm(c[::-1])) for c in ap]
inva1=[a[c] for c in inva]
w0=longestperm(W)
aw0=[a.index(tuple([w0[i] for i in p])) for p in a]
lprint('#I Initialising (Bruhat-Chevalley order etc.) ')
lft=[[inva1.index(tuple([s[i] for i in p]))
for s in W.permgens] for p in inva1]
mat=[['c0'+len(W.rank)*'c']]
for w in range(1,len(a)):
if lw[w]>lw[w-1]:
lprint('.')
s=0
while lft[w][s]>w: s+=1
b=['c']
for y in range(1,w):
if lw[y]==lw[w]:
b.append('f')
elif lw[w]+lw[y]>W.N:
b.append(mat[aw0[y]][aw0[w]])
else:
if (lft[y][s]y and
y<=lft[w][s] and mat[lft[w][s]][y]=='c'):
b.append('c')
else:
b.append('f')
b.append('c')
mat.append(b[:])
lprint('\n#I Computing KL polynomials for elements of length:\n')
lprint('#I ')
klpol=[1]
klstar=[1]
mues=[[0] for s in W.rank]
for w in range(1,len(a)):
if lw[w]>lw[w-1]:
lprint(str(lw[w])+' ')
for y in range(w,-1,-1):
if mat[w][y][0]=='c':
if y==w:
h=1
elif inva[w]y):
h=klpol[int(mat[inva[w]][inva[y]].split('c')[1])]
else:
s=0
while sw): s+=1
if siw): s+=1
if sw: s+=1
if uneq:
for t in W.rank:
if lft[w][t]0 and lft[y][s]w:
if lw[y]+lw[w]>W.N:
if (lw[w]-lw[y])%2==0:
m=-mues[s][int(mat[aw0[y]][aw0[w]].split('c')[s+2])]
else:
m=mues[s][int(mat[aw0[y]][aw0[w]].split('c')[s+2])]
elif poids[s]==1:
m=zeropart(v**(1+Lw[y]-Lw[w])*h)
else:
m=nonnegpart(v**(poids[s]+Lw[y]-Lw[w])*h)
for z in range(w-1,y,-1):
if lft[z][s]w:
if not m in mues[s]:
mat[w][y]+='c'+str(len(mues[s]))
mues[s].append(m)
else:
mat[w][y]+='c'+str(mues[s].index(m))
else:
mat[w][y]+='c'
lprint('\n#I ')
pp=[]
for w in range(len(a)):
for s in W.rank:
if poids[s]==0 or (lft[w][s]>w and poids[s]>0):
pp.append((w,lft[w][s]))
for y in range(w):
if mat[w][y][0]=='c':
if any(poids[s]>0 and lft[y][s]w and
mues[s][int(mat[w][y].split('c')[s+2])]!=0 for s in W.rank):
pp.append((w,y))
lprint(str(len(pp))+' arrows ')
adelta=[]
ndelta=[]
for w in range(len(a)):
p=v**(-Lw[w])*klpol[int(mat[w][0].split('c')[1])]
if p==0:
adelta.append(-1)
ndelta.append(0)
else:
adelta.append(-p.degree)
ndelta.append(p.coeffs[-1])
lprint('>')
pp0=[[w] for w in range(len(a))]
for p in pp:
pp0[p[0]].append(p[1])
pp1=[p[:] for p in pp0]
for z in pp1:
for w in z:
for y in pp0[w]:
if not y in z:
z.append(y)
z.sort()
lprint('>')
rest=list(range(len(a)))
lcells=[]
duflo=[]
checks=True
while rest!=[]:
l=[x for x in pp1[rest[0]] if rest[0] in pp1[x]]
i0=0
while ndelta[l[i0]]==0: i0+=1
d=l[i0]
for w in l[i0:]:
if ndelta[w]!=0 and adelta[w]1:
checks=False
if not (ndelta[d]==1 or ndelta[d]==-1):
checks=False
duflo.append([d,adelta[d],ndelta[d]])
lcells.append(l)
for w in l:
rest.remove(w)
lprint(' '+str(len(lcells))+' left cells ')
lorder=[[d2[0] in pp1[d1[0]] for d2 in duflo] for d1 in duflo]
for c1 in range(len(lcells)):
for c2 in range(len(lcells)):
if c1!=c2 and lorder[c1][c2]==True and duflo[c1][1]>=duflo[c2][1]:
checks=False
lprint('>')
rcells=[[inva[w] for w in l] for l in lcells]
il,ir=[],[]
for w in range(len(a)):
i=0
while not w in lcells[i]: i+=1
il.append(i)
i=0
while not w in rcells[i]: i+=1
ir.append(i)
rest=list(range(len(a)))
tcells=[]
while rest!=[]:
t=[rest[0]]
for w in t:
for y in rest:
if (not y in t) and (il[w]==il[y] or ir[w]==ir[y]):
t.append(y)
t.sort()
tcells.append(t)
for w in t:
rest.remove(w)
lprint('> checks are '+str(checks)+'\n')
return {'elms':ap,'klpols':klpol,'mpols':mues,'klmat':mat,'arrows':pp,
'lcells':lcells,'duflo':duflo,'lorder':lorder, 'rcells':rcells,
'tcells':tcells,'klstar':klstar}
def klpoly1(W,weightL,v):
"""returns the left cells in a form which can be used as input to
the function 'wgraph'.
See also 'klpolynomials' and 'wgraph'.
"""
k=klpolynomials(W,weightL,v)
return [{'elms':[k['elms'][x] for x in c],
'mpols':k['mpols'],'klpols':k['klpols'],
'klmat':[[k['klmat'][c[w]][c[y]] for y in range(w+1)]
for w in range(len(c))]} for c in k['lcells']]
def relmue(lw,ly,p):
if p==0:
return 0
elif type(p)==type(0):
if lw-ly==1:
return p
else:
return 0
elif p.degree==lw-ly-1:
return p.coeffs[-1]
else:
return 0
#F relklpols
def relklpols(W,W1,cell1,weightL,q):
"""returns the matrix of relative Kazhdan-Lusztig polynomials with
respect to a left cell in a parabolic subgroup, following
M. Geck, On the induction of Kazhdan--Lusztig cells, Bull. London
Math. Soc. 35 (2003), 608--614.
(This version is for equal parameters only.)
More precisely, let W be a Coxeter group with generating S. Let J be
a subset of S and W1 be the parabolic subgroup generated by J. Let X
be the set of minimal left coset representatives of W1 in W. For y
in X and v in W1, we can write uniquely
C_{yv}' = T_yC_v' + sum_{x,u} p_{xu,yv}^* T_xC_u'
where the sum runs over all x in X and u in W1 such that x>> W=coxeter("A",3); W1=reflectionsubgroup(W,[0,1])
>>> k1=klcells(W1,1,v); k1
[wgraph(coxeter('A',2), [1, 1], [[]]),
wgraph(coxeter('A',2), [1, 1], [[1], [0, 1]]),
wgraph(coxeter('A',2), [1, 1], [[0], [1, 0]]),
wgraph(coxeter('A',2), [1, 1], [[0, 1, 0]])]
(Thus, W1 of type A2 has 4 left cells: {}, {1,01}, {0,10}, {010}.)
We induce the first left cell to W and decompose the associated
W-graph into its indecomposable components:
>>> r=relklpols(W,W1,k1[0].wgraphtoklmat(),1,v)
>>> G=wgraph(W,1,r,v).decompose()
[wgraph(coxeter('A',3), [1, 1, 1], [[]]),
wgraph(coxeter('A',3), [1, 1, 1], [[2], [1, 2], [0, 1, 2]])]
(Thus, the induced graph has 2 components.)
See also 'klpolynomials', 'klcells', 'wgraph' and 'allrelklpols'.
"""
if type(weightL)==type([]):
poids=weightL
else:
poids=len(W.rank)*[weightL]
if all(i==1 for i in poids):
uneq=False
else:
uneq=True
J=W1.fusions[W.cartanname]['subJ']
X1w=[W.coxelmtoword(c) for c in redleftcosetreps(W,J)]
X1=[W.wordtoperm(w) for w in X1w]
Lw=[sum([poids[s] for s in w]) for w in X1w]
lft=[]
for s in W.rank:
ls=[]
for w in X1:
sw=tuple([w[i] for i in W.permgens[s]])
if sw in X1:
ls.append(X1.index(sw))
else:
t=0
while tuple([W.permgens[t][i] for i in w])!=sw: t+=1
ls.append(-t-1)
lft.append(ls)
Lw1=[sum([poids[J[s]] for s in w]) for w in cell1['elms']]
p1=[W1.wordtoperm(w) for w in cell1['elms']]
lft1={}
for t in W1.rank:
l=[]
for w in p1:
w1=tuple([w[i] for i in W1.permgens[t]])
if w1 in p1:
l.append(p1.index(w1))
else:
if w[t]>=W1.N: # tww
l.append(len(p1))
lft1[J[t]]=l
bruhatX=[]
for y in range(len(X1)):
bruhatX.append([bruhatperm(W,X1[x],X1[y],lx=Lw[x],ly=Lw[y])
for x in range(y+1)])
mat={}
mues=[0,1]
for y in range(len(X1)):
for x in range(y):
if bruhatX[y][x]:
mat[y,x]=[len(p1)*['f'] for i in range(len(p1))]
for v in range(len(p1)):
for u in range(len(p1)):
if (x==y and u==v) or Lw[x]+Lw1[u]x]
fs1=[s1 for s1 in ldy if 0<=lft[s1][x]0: # case syx and sx in X
s=fs[0]
for v in range(len(p1)):
for u in range(len(p1)):
if mat[y,x][v][u][0]=='c':
if bruhatX[y][lft[s][x]] and mat[y,lft[s][x]][v][u][0]=='c':
mat[y,x][v][u]+=mat[y,lft[s][x]][v][u].split('c')[1]
rk=mat[y,x][v][u].split('c')[1]
if rk!='0':
m=relmue(Lw[y]+Lw1[v],Lw[x]+Lw1[u],rklpols[int(rk)])
if m in mues:
mat[y,x][v][u]+='c'+str(mues.index(m))
else:
mat[y,x][v][u]+='c'+str(len(mues))
mues.append(m)
else:
mat[y,x][v][u]+='c0'
else:
mat[y,x][v][u]+='0c0'
else:
for u in range(len(p1)):
if any(lft[s1][x]<0 and u0:
s=fs1[0]
#lprint('!')
else:
s=ldy[0]
sx,sy=lft[s][x],lft[s][y]
for v in range(len(p1)):
if mat[y,x][v][u][0]=='c':
h=0
for z in range(x,sy):
sz=lft[s][z]
if sz=0 or lft1[-1-sz][w]w and (mat[sy,x][v][w][0]=='c' and
cell1['klmat'][w][u][0]=='c'):
m=mues[int(mat[0,0][w][u].split('c')[2])]
if m!=0:
rk=mat[sy,x][v][w].split('c')[1]
if rk!='0':
h+=q**(Lw1[w]-Lw1[u]+1)*rklpols[int(rk)]*m
else: # case sx=W1.N: # tww
l.append(len(p1))
lft1[J[t]]=l
bruhatX=[]
for y in range(len(X1)):
bruhatX.append([bruhatperm(W,X1[x],X1[y],lx=len(X1w[x]),
ly=len(X1w[y])) for x in range(y+1)])
mues=[[0,1] for s in W.rank]
rklpols=[0,1]
mat={}
for y in range(len(X1)):
for x in range(y):
if bruhatX[y][x]:
mat[y,x]=[len(p1)*['f'] for i in range(len(p1))]
for v in range(len(p1)):
for u in range(len(p1)):
if len(X1w[x])+lw1[u]0 and lft[s][y]<0:
t=-1-lft[s][y]
if lft1[t][i]>i and lft1[t][j]x and poids[s]>0]
fs1=[s1 for s1 in ldy if 0<=lft[s1][x]0]
if len(fs0)>0: # case sy=0:
if sx<=sy and bruhatX[sy][sx] and mat[sy,sx][v][u][0]=='c':
mat[y,x][v][u]+=mat[sy,sx][v][u].split('c')[1]
else:
mat[y,x][v][u]+='0'
else:
tu=lft1[-1-sx][u]
if 0<=tu0: # case syx and sx in X
s=fs[0]
for v in range(len(p1)):
for u in range(len(p1)):
if mat[y,x][v][u][0]=='c':
if bruhatX[y][lft[s][x]] and mat[y,lft[s][x]][v][u][0]=='c':
mat[y,x][v][u]+=mat[y,lft[s][x]][v][u].split('c')[1]
else:
mat[y,x][v][u]+='0'
else:
for u in range(len(p1)):
if any(lft[s1][x]<0 and u0:
s=fs1[0]
#lprint('!')
else:
s=ldy[0]
sx,sy=lft[s][x],lft[s][y]
for v in range(len(p1)):
if mat[y,x][v][u][0]=='c':
h=0
for z in range(x,sy):
sz=lft[s][z]
if sz=0 or lft1[-1-sz][w]w and (mat[sy,x][v][w][0]=='c' and
cell1['klmat'][w][u][0]=='c'):
m1=cell1['mpols'][J.index(t)][int(cell1['klmat'][
w][u].split('c')[J.index(t)+2])]
if m1!=0:
rk=mat[sy,x][v][w].split('c')[1]
if rk!='0':
h+=q**(Lw1[w]-Lw1[u]+poids[t])*rklpols[int(rk)]*m1
else: # case sx0 and (lft[r][y]>y or (lft[r][y]<0 and
v=0 and mat[y,x][v][lft1[t][u]][0]=='c':
# rk=mat[y,x][v][lft1[t][u]].split('c')[1]
# if rk!='0':
# pis-=nonnegpart(q**(Lw1[u]+Lw[x]-Lw1[v]-Lw[y]-
# poids[t])*rklpols[int(rk)])
for w in range(u+1,len(p1)):
if w>> W=coxeter("B",2)
>>> relklpols(W,[0],1,v)
{'allelms': [[],[0],[1],[0,1],[1,0],[0,1,0],[1,0,1],[0,1,0,1]],
'elmsX': [[],[1],[0,1],[1,0,1]],
'elmsJ': [[],[0]],
'klpols': [1],
'rklpols': [0, 1],
'mues': [0, 1],
'relklmat': {(0, 0): [['c1c0', 'f' ], ['c0c1', 'c1c0']],
(1, 0): [['c1c1', 'f' ], ['c0c0', 'c1c1']],
(1, 1): [['c1c0', 'f' ], ['c0c1', 'c1c0']],
(2, 0): [['c0c0', 'c1c1'], ['c0c0', 'c1c0']],
(2, 1): [['c1c1', 'f' ], ['c0c0', 'c1c1']],
(2, 2): [['c1c0', 'f' ], ['c0c1', 'c1c0']],
(3, 0): [['c0c0', 'c1c0'], ['c0c0', 'c1c0']],
(3, 1): [['c0c0', 'c1c1'], ['c0c0', 'c1c0']],
(3, 2): [['c1c1', 'f' ], ['c0c0', 'c1c1']],
(3, 3): [['c1c0', 'f' ], ['c0c1', 'c1c0']],
'arrows': [(0,1), (0,2), (1,4), (2,3), (4,5), (4,1), (3,6), (3,2),
(5,7), (5,4), (6,7), (6,3)]}
(Conventions in relklmat similar to those in 'klpolynomials'.
See also 'klpolynomials' and 'klcells'.
"""
if type(weightL)==type([]):
poids=weightL
else:
poids=len(W.rank)*[weightL]
if all(i==1 for i in poids):
uneq=False
else:
uneq=True
ap=allwords(W)
W1=reflectionsubgroup(W,J)
m1=klpolynomials(W1,[poids[s] for s in J],q)
wa1=[[J[s] for s in c] for c in m1['elms']]
a1=[W.wordtoperm(w) for w in wa1]
X1=[W.coxelmtoperm(c) for c in redleftcosetreps(W,J)]
Lw1=[sum([poids[s] for s in w]) for w in wa1]
X1w=[W.permtoword(p) for p in X1]
Lw=[sum([poids[s] for s in w]) for w in X1w]
lft=[]
for s in W.rank:
ls=[]
for w in X1:
sw=tuple([w[i] for i in W.permgens[s]])
if sw in X1:
ls.append(X1.index(sw))
else:
t=0
while tuple([W.permgens[t][i] for i in w])!=sw: t+=1
ls.append(-t-1)
lft.append(ls)
lft1={}
for t in J:
lft1[t]=[a1.index(tuple([w[i] for i in W.permgens[t]])) for w in a1]
mat={}
lprint('#I Initialising ')
mues=[0]
for y in range(len(X1)):
if y%100==0:
lprint('.')
for x in range(y):
if bruhatperm(W,X1[x],X1[y]):
#if x==y or Lw[x]x]
fs1=[s1 for s1 in ldy if 0<=lft[s1][x]0: # case syx and sx in X
s=fs[0]
for v in range(len(a1)):
for u in range(len(a1)):
if mat[y,x][v][u][0]=='c':
if mat[y,lft[s][x]][v][u][0]=='c':
mat[y,x][v][u]+=mat[y,lft[s][x]][v][u].split('c')[1]
rk=mat[y,x][v][u].split('c')[1]
if rk!='0':
m=relmue(Lw[y]+Lw1[v],Lw[x]+Lw1[u],rklpols[int(rk)])
if m in mues:
mat[y,x][v][u]+='c'+str(mues.index(m))
else:
mat[y,x][v][u]+='c'+str(len(mues))
mues.append(m)
else:
mat[y,x][v][u]+='c0'
else:
mat[y,x][v][u]+='0c0'
else:
for u in range(len(a1)):
if any(lft[s1][x]<0 and lft1[-1-lft[s1][x]][u]>u for s1 in ldy):
for v in range(len(a1)):
if mat[y,x][v][u][0]=='c':
mat[y,x][v][u]+='0c0'
else:
#fs1=list(filter(lambda s2:lft[s2][x]<0 and
# lft1[-1-lft[s2][x]][u]0:
s=fs1[0]
#lprint('!')
else:
s=ldy[0]
sx,sy=lft[s][x],lft[s][y]
for v in range(len(a1)):
if mat[y,x][v][u][0]=='c':
h=0
for z in range(x,sy):
if lft[s][z]=0 or lft1[-1-lft[s][z]][w]w and (mat[sy,x][v][w][0]=='c' and
m1['klmat'][w][u][0]=='c'):
m=mues[int(mat[0,0][w][u].split('c')[2])]
if m!=0:
rk=mat[sy,x][v][w].split('c')[1]
if rk!='0':
h+=q**(Lw1[w]-Lw1[u]+1)*rklpols[int(rk)]*m
else: # case sxy:
pp.append((bij[y,v],bij[lft[s][y],v]))
elif lft[s][y]<0 and lft1[-1-lft[s][y]][v]>v:
pp.append((bij[y,v],bij[y,lft1[-1-lft[s][y]][v]]))
for x in range(y+1):
for u in range(len(a1)):
rk=mat[y,x][v][u]
if rk[0]=='c' and rk.split('c')[2]!='0':
if any((0<=lft[s][x]y or (lft[s][y]<0
and lft1[-1-lft[s][y]][v]>v)) for s in W.rank):
pp.append((bij[y,v],bij[x,u]))
lprint(str(len(pp))+' arrows \n');
klpols=[]
for y in range(len(X1)):
for x in range(y+1):
for v in range(len(a1)):
for u in range(len(a1)):
if x==y and u<=v and m1['klmat'][v][u][0]=='c':
h=m1['klpols'][int(m1['klmat'][v][u].split('c')[1])]
else:
rk=mat[y,x][v][u]
if rk[0]=='c':
h=rklpols[int(rk.split('c')[1])]
for w in range(u+1,len(a1)):
rk1=m1['klmat'][w][u]
if rk1[0]=='c':
rk2=mat[y,x][v][w]
if rk2[0]=='c' and rk2[1]!='0':
h+=m1['klpols'][int(rk1.split('c')[1])]*rklpols[
int(rk2.split('c')[1])]
if h!=0 and not h in klpols:
klpols.append(h)
return {'allelms':ap,'elmsJ':wa1,'elmsX':X1w,'rklpols':rklpols,
'mues':mues,'relklmat':mat,'klpols':klpols,'arrows':pp}
#F klstaroperation
def klstaroperation(W,s,t,pcell):
"""returns the list containing the elements w^* for w in cell, where
w^* is obtained by the Kazhdan-Lusztig star operation with respect
to the generators s,t in S such that st has order 3. Here, cell
is assumed to be a list of elements in W which all have the same
right descent set (and which are given as full permutations). The
function returns 'False' if the star operation with respect to
s,t is not defined for the elements in the given set.
>>> W=coxeter("D",4); W.coxetermat
[[1, 2, 3, 2], [2, 1, 3, 2], [3, 3, 1, 3], [2, 2, 3, 1]]
>>> k=klcells(W,1,v);k[0][2]
>>> k[0][2] # example of a left cell
c[[3], [2, 3], [0, 2, 3], [1, 2, 3]]
>>> klstaroperation(W,0,2,[W.wordtoperm(p) for p in k[0][2]]);
False
>>> klstaroperation(W,1,2,[W.wordtoperm(p) for p in k[0][2]])
False
>>> st=klstaroperation(W,2,3,[W.wordtoperm(p) for p in k[0][2]])
>>> st==False
False
>>> [W.permtoword(p) for p in st]
[[3, 2], [2], [0, 2], [1, 2]]
See also 'klstarorbit' and 'wgraphstarorbit'.
"""
pw1=perminverse(pcell[0])
if (pw1[s]>=W.N and pw1[t]>=W.N) or (pw1[s]=W.N and wsi[t]=W.N and wsi[s]>> W=coxeter("A",3);k=klcells(W,1,v)
>>> k[1]
wgraph(coxeter('A',3), [1, 1, 1], [[2], [1, 2], [0, 1, 2]])
>>> klstarorbit(W,k[1].X)
[[[2], [1, 2], [0, 1, 2]],
[[2, 1], [1], [0, 1]],
[[2, 1, 0], [1, 0], [0]]]
See also 'klstaroperation' and 'klcells'.
"""
if gens=='each':
gens=list(W.rank)
orb=[[W.wordtoperm(x) for x in l]]
for cell in orb:
for s in range(len(gens)):
for t in range(s):
if W.coxetermat[gens[s]][gens[t]]==3:
nc=klstaroperation(W,gens[s],gens[t],cell)
if nc!=False and not any(nc[0] in c for c in orb):
orb.append(nc)
return [[W.permtoword(p) for p in o] for o in orb]
#F klstarorbitperm
def klstarorbitperm(W,l,gens='each'):
"""same as klstarorbit but the function returns the elements as
full permutations.
"""
if gens=='each':
gens=list(W.rank)
orb=[[W.wordtoperm(x) for x in l]]
for cell in orb:
for s in range(len(gens)):
for t in range(s):
if W.coxetermat[gens[s]][gens[t]]==3:
nc=klstaroperation(W,gens[s],gens[t],cell)
if nc!=False and not any(nc[0] in c for c in orb):
orb.append(nc)
return orb
#F leftklstar
def leftklstar(W,pw,s,t):
"""applies the left star operation with respect to generators
s and t to an element pw; here, it is already assumed that
the product st has order 3 and that the star operation is
known to apply to pw.
"""
if pw[s]>=W.N and pw[t]=W.N:
return sw
else:
return tuple([pw[i] for i in W.permgens[t]])
else:
sw=tuple([pw[i] for i in W.permgens[t]])
if sw[s]>=W.N:
return sw
else:
return tuple([pw[i] for i in W.permgens[s]])
#F generalisedtau
def generalisedtau(W,pw,maxd=10):
"""returns Vogan's generalised tau-invariant of an element of
a finite Coxeter group. It is known that two elements which
belong to the same left cell (in the equal parameter case)
must have the same generalised tau-invariant. The optional
argument 'maxd' can be used to set to specify the depth to
which the star operations will be applied (default 10).
"""
#pw=W.wordtoperm(w)
orb=[pw]
o=0
while o1:
return [[l[i] for i in range(len(l)) if rnd[i]==s]
for s in srnd]
elif not any(nc[0] in c for c in orb):
orb.append(nc)
return [l]
def gentauorbits(W,startset=[],pr=True):
"""returns the partition of a set of elements into equivalence
classes under the relation given by Vogan's generalised
tau-invariant (which amounts to repeated application of the
star operations). If the startset is not specified, then
all elements of W will be taken.
>>> W=coxeter("E",6)
>>> g=gentauorobits(W)
>>> len(g)
652
(In this case, the result is precisely the partition of W
into left cells. The same also happens for W of type A.)
See also 'klstaroperation', 'klstarorbit' and 'precells'.
"""
if startset==[]:
pset=[W.wordtoperm(w) for w in allwords(W)]
else:
if type(startset[0])==type(W.permgens[0]) and len(startset[0])==2*W.N:
pset=startset
else:
pset=[W.wordtoperm(w) for w in startset]
rd=[tuple(W.rightdescentsetperm(pw)) for pw in pset]
rest=[[pset[i] for i in range(len(pset)) if rd[i]==s] for s in set(rd)]
res=[]
weiter=True
if pr:
lprint('#I tau-ells: ')
while weiter:
cg=[gentauorbit2(W,i) for i in rest]
weiter=False
rest=[]
for i in range(len(cg)):
if len(cg[i])==1:
#res.append([W.permtoword(w) for w in cg[i][0]])
res.append(cg[i][0])
else:
rest.extend(cg[i])
weiter=True
if pr:
lprint(str(len(res))+' ')
if pr:
lprint('\n')
return res
# klcellw0
def klcellw0(W,wgr):
"""returns the W-graph of a left cell multiplied by the longest
element. (For the time being, only for equal parameters.)
"""
w0=longestperm(W)
pc=[W.wordtoperm(w) for w in wgr.X]
np=[permmult(p,w0) for p in pc]
if np[0] in pc:
return wgr
else:
ni=[W.leftdescentsetperm(p) for p in np]
nmat={}
for k in wgr.mmat.keys():
nmat[(k[1],k[0])]=wgr.mmat[k]
return wgraph(W,wgr.weights,[W.permtoword(p) for p in np],wgr.var,
ni,nmat,wgr.mpols,[p[:len(W.rank)] for p in np]).normalise()
# wgraphstarorbit
def wgraphstarorbit(W,wgr,gens='each'):
"""returns the orbit of a W-graph under the relation generated by the
Kazhdan-Lusztig star operation. (Only works in the case of equal
parameters.)
>>> W=coxeter("A",2); k=klcells(W,1,v); k
#I 4 left cells (3 non-equivalent)
[[[[]], [[0, 1, 0]], [[1], [0, 1]], [[1, 0], [0]]],
[wgraph(coxeter('A',2), [1, 1], [[]]),
wgraph(coxeter('A',2), [1, 1], [[0, 1, 0]]),
wgraph(coxeter('A',2), [1, 1], [[1], [0, 1]])]]
>>> flatlist([wgraphstarorbit(W,g) for g in k[1]])
[wgraph(coxeter('A',2), [1, 1], [[]]),
wgraph(coxeter('A',2), [1, 1], [[0, 1, 0]]),
wgraph(coxeter('A',2), [1, 1], [[1], [0, 1]]),
wgraph(coxeter('A',2), [1, 1], [[0], [1, 0]])]
See also 'klstaroperation', 'wgraph' and 'klcells'.
"""
return [wgraph(W,wgr.weights,[W.permtoword(p) for p in l],wgr.var,wgr.Isets,
wgr.mmat,wgr.mpols,[p[:len(W.rank)] for p in l]).normalise()
for l in klstarorbitperm(W,wgr.X,gens)]
#F klcellsun
def klcellsun(W,weightL,v,pr=True):
if type(weightL)==type([]):
poids=weightL
else:
poids=len(W.rank)*[weightL]
if len(W.rank)==0:
cr1=[wgraph(W,poids,[[]],v,[[]],{},[],[()])]
else:
J=list(W.rank)
if W.cartantype[0][0]=='E':
J.remove(0)
else:
J.remove(len(W.rank)-1)
W1=reflectionsubgroup(W,J)
kk=klcellsun(W1,[poids[s] for s in J],v,pr=False)
if len(W.rank)>0:
lprint('#I ')
lprint('('+str(len(kk))+') ')
cr1=[]
allmues=[[] for s in W.rank]
for i in kk:
lprint('+')
rk=relklpolsuneq(W,W1,i.wgraphtoklmat(),poids,v)
for s in W.rank:
for m in rk['mpols'][s]:
if m!=0 and not m in allmues[s]:
allmues[s].append(m)
ind=wgraph(W,poids,rk,v).decompose()
lprint(str(len(ind)))
for ii in ind:
cr1.append(ii)
lprint('\n')
if pr==True and len(W.rank)>0:
lprint('#I '+str(len(cr1))+' left cells, mues: ')
for s in W.rank:
lprint('['+', '.join([repr(i) for i in allmues[s]])+'] ')
lprint('\n')
cr1.sort(key=(lambda c:len(c.X)))
return cr1
#F klcells
def klcells(W,weightL,v,allcells=True,pr=True):
"""returns the partition of a finite Coxeter group into left cells
together with the corresponding W-graphs.
In the equal parameter case (where all weights are equal to 1),
the function returns a pair [l,l1] where l is a list describing
the partition of W into left cells and l1 is a list containing
the W-graphs for a set of a representatives of the left cells
under the equivalence relation given by the star operation. (It
is known that star equivalent left cells give rise to the same
W-graphs.) The computation is done recursively, using induction
of left cells from proper parabolic subgroups (see the function
'relklpols'). This works very efficiently for groups of rank up
to 6, including types H4 and E6. If one is willing to wait for
a few hours, then type E7 is also possible. If the optional
argument 'allcells' is set to 'False', then for each left cell
the function only returns those elements whose inverses also
lie in that left cell.
In the case of unequal parameters, we just return the W-graphs
corresponding to all the left cells of W.
See also 'klpolynomials', 'wgraphstarorbit', 'reklpols',
'wgraph' and 'precells'.
>>> klcells(coxeter("B",3),[2,1,1],v) # unequal parameters
#I Number of elements = 48
#I Initialising (Bruhat-Chevalley order etc.) .........
#I Computing KL polynomials for elements of length:
#I 1 2 3 4 5 6 7 8 9
#I 120 arrows >> 16 left cells >> checks are True
[wgraph(coxeter('B',3),[2,1,1],[[]]),
wgraph(coxeter('B',3),[2,1,1],[[0],[1,0],[2,1,0]]),
wgraph(coxeter('B',3),[2,1,1],[[1],[2,1]]),
wgraph(coxeter('B',3),[2,1,1],[[2],[1,2]]),
wgraph(coxeter('B',3),[2,1,1],[[0,1],[1,0,1],[2,1,0,1]]),
wgraph(coxeter('B',3),[2,1,1],[[0,2],[1,0,2],[0,1,0,2],
[1,2,1,0],[0,1,2,1,0],[1,0,1,2,1,0]]),
wgraph(coxeter('B',3),[2,1,1],[[0,1,0],[0,2,1,0],[1,0,2,1,0],
[0,1,0,2,1,0]]),
wgraph(coxeter('B',3),[2,1,1],[[0,1,2],[1,0,1,2],[2,1,0,1,2]]),
wgraph(coxeter('B',3),[2,1,1],[[0,2,1],[1,0,2,1],[0,1,0,2,1],
[1,2,1,0,1],[0,1,2,1,0,1],[1,0,1,2,1,0,1]]),
wgraph(coxeter('B',3),[2,1,1],[[1,2,1],[0,1,2,1],[1,0,1,2,1],
[1,2,1,0,1,2]]),
wgraph(coxeter('B',3),[2,1,1],[[0,1,0,1],[0,2,1,0,1],
[1,0,2,1,0,1]]),
wgraph(coxeter('B',3),[2,1,1],[[0,1,0,1,2],[0,2,1,0,1,2],
[1,0,2,1,0,1,2]]),
wgraph(coxeter('B',3),[2,1,1],[[0,1,0,1,2,1],[0,1,2,1,0,1,2],
[1,0,1,2,1,0,1,2]]),
wgraph(coxeter('B',3),[2,1,1],[[0,1,0,1,2,1,0],[0,1,0,2,1,0,1,2]]),
wgraph(coxeter('B',3),[2,1,1],[[0,1,0,2,1,0,1],[0,1,0,1,2,1,0,1]]),
wgraph(coxeter('B',3),[2,1,1],[[0,1,0,1,2,1,0,1,2]])]
Here are some examples for equal parameters, where the more
efficient algorithm based on 'relklpols' is used.
>>> klcells(coxeter("I5",2),1,v)
#I 4 left cells (4 non-equivalent), mues: 1
[[[[]],
[[0,1,0,1,0]],
[[1], [0,1], [1,0,1], [0,1,0,1]],
[[0], [1,0], [0,1,0], [1,0,1,0]]],
[wgraph(coxeter('I5',2), [1,1], [[]]),
wgraph(coxeter('I5',2), [1,1], [[0,1,0,1,0]]),
wgraph(coxeter('I5',2), [1,1], [[1], [0,1], [1,0,1], [0,1,0,1]]),
wgraph(coxeter('I5',2), [1,1], [[0], [1,0], [0,1,0], [1,0,1,0]])]]
>>> k=klcells(coxeter("H",4),1,v) # takes < 7 minutes
#I 206 left cells (90 non-equivalent), mues: 1,2,3
>>> set([len(c) for c in k[0]])
set([32,1,36,326,8,392,18,436,25])
(Thus, W has left cells of size 1,8,18,25,33,36,326,392,436.)
The left cells in type H4 were first determined by
D. Alvis: The left cells of the Coxeter group of type H_4,
J. Algebra 107 (1987), 160-168; see also
http://mypage.iusb.edu/~alvis/h4data
(I have checked that the result of 'klcells' indeed coincides
with Alvis' tables. Note that Alvis can actually compute all
the Kazhdan-Lusztig polynomials in type H4, which would take
a very long time with 'klpolynomials'. If one is interested
in reproducing this information, then it is better to use
DuCloux's Coxeter programe. Alternatively, one can also build
all Kazhdan-Lusztig polynomials from the relative polynomials
returned by 'allrelklpols'; this takes about 1 day cpu time.)
>>> k=klcells(coxeter("E",6),1,v) # takes about 45 seconds
#I 652 left cells (21 non-equivalent), mues: 1
>>> set([len(c) for c in k[0]])
set([64,1,230,6,45,81,20,150,24,60,280])
(I have checked that the result of 'klcells' coincides with
the result for E6 produced by DuCloux's Coxeter programme.)
>>> k=klcells(coxeter("D",7),1,v) # takes < 4 minutes
#I 2416 left cells (49 non-equivalent), mues: 1
>>> set([len(c) for c in k[0]])
set([1,98,35,6,7,105,231,140,15,112,49,210,147,20,21,56,84,
154,175,63])
>>> k=klcells(coxeter("E",7),1,v) # takes about 4 hours
#I 6364 left cells (56 non-equivalent), mues: 1,2,3,4,6,5
>>> set([len(c) for c in k[0]])
set([1024,1,27,7,168,105,756,135,77,910,621,504,210,594,21,
225,665,378,91,189,875])
>>> k=klcells(coxeter("D",8),1,v) # takes about 4 hours
#I 11504 left cells (90 non-equivalent), mues: 1,2
set([1,7,8,140,21,1302,280,28,35,168,176,392,434,56,315,700,
448,68,714,76,336,184,980,728,350,230,616,490,364,238,
112,504,250,252])
>>> k=klcells(coxeter("A",9),1,v) # takes about 50 minutes
#I 9496 left cells (42 non-equivalent), mues: 1
>>> set([len(c) for c in k[0]])
set([768,1,9,525,160,35,36,42,300,567,315,448,288,450,75,210,
84,90,350,225,252,126])
The program essentially works in all cases where one can
afford to keep a complete list of all elements of W in the
main memory. Thus, type B8 with its 10,321,920 elements is
about the limit: it takes some 58 hours and 9GB memory to
compute the 15304 left cells and the corresponding W-graphs.
"""
if type(weightL)==type([]):
poids=weightL
else:
poids=len(W.rank)*[weightL]
if any(i<0 for i in poids):
print('#W All parameters must be non-negative')
return False
if all(i==1 for i in poids):
#if pr==True and len(W.rank)>0:
# lprint('#I')
if len(W.rank)==0:
nc=[[[]]]
cr1=[wgraph(W,poids,[[]],v,[[]],{},[],[()])]
creps=[()]
else:
allmues=[]
J=list(W.rank)
if W.cartantype[0][0]=='E':
J.remove(0)
else:
J.remove(len(W.rank)-1)
W1=reflectionsubgroup(W,J)
X1p=[W.coxelmtoword(x1) for x1 in redleftcosetreps(W,J)]
kk=klcells(W1,[poids[s] for s in J],v,pr=False,allcells=False)
if len(W.rank)>0:
lprint('#I ')
lprint('('+str(len(kk[0]))+':'+str(len(kk[1]))+') ')
nc,cr1,creps=[],[],[]
celms=set([])
i,tot=0,0
while tot300:
if len(rk['perm'])>1500:
rht=[generalisedtau(W,p,maxd=3*len(W.rank)) for p in rk['perm']]
else:
rht=[tuple(W.rightdescentsetperm(p)) for p in rk['perm']]
srht=list(set(rht))
ind1=wgraph(W,poids,rk,v)
lprint(str(len(srht))+'!')
ind=[]
for rh in srht:
l=list(filter(lambda x:rht[x]==rh,range(len(rht))))
x1=[ind1.X[ih] for ih in l]
x1r=[ind1.Xrep[ih] for ih in l]
i1=[ind1.Isets[ih] for ih in l]
m1={}
for kh in ind1.mmat.keys():
if kh[0] in l and kh[1] in l:
m1[(l.index(kh[0]),l.index(kh[1]))]=ind1.mmat[kh]
ind.extend(wgraph(ind1.W,ind1.weights,x1,ind1.var,i1,
m1,ind1.mpols,x1r).decompose())
else:
ind=wgraph(W,poids,rk,v).decompose()
lprint(str(len(ind)))
for ii in ind:
if tot0:
lprint('#I '+str(len(nc))+' left cells (')
lprint(str(len(creps))+' non-equivalent), ')
lprint('mues: '+','.join([str(i) for i in allmues])+'\n')
#nc.sort(key=(lambda c:len(c)))
ct=chartable(W)
if allcells==True and len(nc)!=sum([ct['irreducibles'][i][0]
for i in range(len(ct['a'])) if ct['a'][i]==ct['b'][i]]):
print("Mist!")
return False
cr1.sort(key=(lambda c:len(c.X)))
return [nc,cr1]
else:
return klcellsun(W,weightL,v,pr=True)
#k=klpolynomials(W,weightL,v)
#return [wgraph(W,poids,{'elms':[k['elms'][x] for x in c],
# 'mpols':k['mpols'],'klpols':k['klpols'],
# 'klmat':[[k['klmat'][c[w]][c[y]] for y in range(w+1)]
# for w in range(len(c))]},v) for c in k['lcells']]
def zeroterm(p):
if type(p)==type(0):
return p
else:
if p.val>0 or p.coeffs==[]:
return 0
else:
return p.coeffs[0]
#def zeroterm(p):
# if type(p)==type(0):
# return p
# else:
# return p.value(0)
#F leadingcoefficients
def leadingcoefficients(W,weightL,lw,clpols=[]):
"""returns the leading coefficients (as defined by Lusztig) of the
character values of the generic Iwahori-Hecke algebra associated with
W and given list of weights. For an irreducible representation E and
w in W, the coefficient c_{w,E} is defined by
Tr(T_w,E) = c_{w,E} v^(-a_E) + higher powers of v,
where a_E is the a-invariant of E (see 'ainvariants'). The argument
lw contains the list of elements, given as reduced expressions,
for which the leading values are to be computed. The weights are
specified as described in 'ainvariants'. The computations use the
character table of the Iwahori--Hecke algebra (see 'heckechartable')
and the class polynomials (see 'heckecharvalues').
(Note that Lusztig actually further multiplies c_{w,E} by (-1)^l(w),
but we omit this sign here.)
The argument weightL specifies a weight function as explained
in 'ainvariants'; in particular, the programme also works for
unequal parameters.
>>> W=coxeter("B",2)
>>> a=allwords(W); a;
[[], [0], [1], [0, 1], [1, 0], [0, 1, 0], [1, 0, 1], [0, 1, 0, 1]]
>>> leadingcoefficients(W,[1,1],a)
[[ 0, 0, 0, 1, 0],
[-1,-1, 0, 0, 0],
[ 0,-1, 0, 0,-1],
[ 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0],
[ 1,-1, 0, 0, 0],
[ 0,-1, 0, 0,-1],
[ 0, 0, 1, 0, 0]]
See also 'leftcellleadingcoeffs'.
"""
v=lpol([1],1,'v')
if type(weightL)==type(0):
poids=len(W.rank)*[weightL]
else:
poids=weightL[:]
ti=heckechartable(W,[v**i for i in poids])['irreducibles']
ainv=ainvariants(W,poids)
maxl=max([len(w) for w in lw])
if clpols==[]:
cpmat=allclasspolynomials(W,[v**(2*p) for p in poids],maxl)
else:
cpmat=clpols
lc=[]
for w in lw:
cind=0
for i in w:
cind+=poids[i]
cp=cpmat[W.wordtocoxelm(w)]
#lc.append([zeroterm((-1)**len(w)*v**(ainv[i]-cind)*sum(cp[j]*ti[i][j]
# for j in range(len(ainv)))) for i in range(len(ainv))])
lc.append([zeroterm(v**(ainv[i]-cind)*sum(cp[j]*ti[i][j]
for j in range(len(ainv)))) for i in range(len(ainv))])
return lc
#F leftcellleadingcoeffs
def leftcellleadingcoeffs(W,weightL,v,cell,clpols=[]):
"""returns a dictionary with information concerning the leading
coefficients in a given left cell. The components are:
elms : the list of all w in the cell such that w^(-1) also
lies in the cell;
ti : the associated character table;
distinv : the distinguished involution in the cell;
nd : the corresponding sign;
special : the character for which all values are positive;
char : decomposition into irreducible characters of W.
More precisely, let C be a left cell. Then we consider the
subalgebra of the asymptotic algebra J which is spanned by all
basis elements t_w where both w and its inverse lie in C. The
associated character table is the table of values
((-1)^l(d) n_d c_{w,E})_{E,w}
where w runs over all w in C such that w^{-1} in C, and E runs
over all E in Irr(W) such that E occurs in the left cell module
given by C. Here, c_{w,E} are the leading coefficients of the
character values of the corresponding generic Iwahori-Hecke
algebra as defined by
G. Lusztig, Leading coefficients of character values of Hecke
algebras, Proc. Symp. Pure Math. 47, AMS, 1987, pp. 235-262.
(This article also contains a detailed study of the character
tables (c_{w,E}) in the equal parameter case.)
The distinguished involution d and the corresponding sign 'nd'
are uniquely determined by the condition that nd*t_d is the
identity element of the above subalgebra. It is known that nd=1
in the equal parameter case; in the general unequal parameter
case, these properties are conjectural. (In fact, the function
checks if such a distinguished involution exists.)
The argument weightL specifies a weight function as explained
in 'ainvariants'; in particular, the programme also works for
unequal parameters.
>>> v=lpol([1],1,'v')
>>> W=coxeter("B",2)
>>> [leftcellleadingcoeffs(W,1,v,l)
for l in klcells(W,1,v)[0]] # equal parameters
#I 4 left cells (4 non-equivalent), mues: 1
[{'elms': [[]], 'nd': 1, 'special': ('[[2], []]',),
'distinv': [], 'ti': [[('[[2], []]',), [1]]]},
{'elms': [[0, 1, 0, 1]], 'nd': 1, 'special': ('[[], [1, 1]]',),
'distinv': [0, 1, 0, 1], 'ti': [[('[[], [1, 1]]',), [1]]]},
{'elms': [[1], [1, 0, 1]], 'nd': 1, 'special': ('[[1], [1]]',),
'distinv': [1], 'ti': [[('[[1], [1]]',), [1, 1]],
[('[[], [2]]',), [1, -1]]]},
{'elms': [[0], [0, 1, 0]], 'nd': 1, 'special': ('[[1], [1]]',),
'distinv': [0], 'ti': [[('[[1, 1], []]',), [1, -1]],
[('[[1], [1]]',), [1, 1]]]}]
>>> leftcellleadingcoeffs(W,[2,1],v,l.X)
for l in klcells(W,[2,1],v)] # unequal parameters
#I 10 arrows >> 6 left cells >> checks are True
[{'elms': [[]], 'nd': 1, 'special': ('[[2], []]',),
'distinv': [], 'ti': [[('[[2], []]',), [1]]]},
{'elms': [[0]], 'nd': 1, 'special': ('[[1], [1]]',),
'distinv': [0], 'ti': [[('[[1], [1]]',), [1]]]},
{'elms': [[1]], 'nd': 1, 'special': ('[[], [2]]',),
'distinv': [1], 'ti': [[('[[], [2]]',), [1]]]},
{'elms': [[1, 0, 1]], 'nd': 1, 'special': ('[[1], [1]]',),
'distinv': [1, 0, 1], 'ti': [[('[[1], [1]]',), [1]]]},
{'elms': [[0, 1, 0]], 'nd': -1, 'special': ('[[1, 1], []]',),
'distinv': [0, 1, 0], 'ti': [[('[[1, 1], []]',), [1]]]},
{'elms': [[0, 1, 0, 1]], 'nd': 1, 'special': ('[[], [1, 1]]',),
'distinv': [0, 1, 0, 1], 'ti': [[('[[], [1, 1]]',), [1]]]}]
(Note the negative value for nd.)
Remark: The normalisiation by the sign (-1)^l(d)*n_d has the
effect that the above table has a row in which all entries are
strictly positive numbers. (There can be at most one row with
this property.) It is known that, in the equal parameter case,
this row is labelled by the unique special character (in the
sense of Lusztig) which appears in the left cell representation
carried by C.
>>> W=coxeter("F",4); k=klcells(W,1,v)
>>> l=leftcellleadingcoeffs(W,1,v,k[0][64]); l['ti']
[[('4_1',), [1,-1,-1, 1, 1, 0,-1,-1, 1]],
[('9_2',), [1, 1,-1,-1,-1, 0,-1, 1, 1]],
[('9_3',), [1,-1, 1,-1,-1, 0, 1,-1, 1]],
[('6_2',), [1, 1, 1, 1, 1,-2, 1, 1, 1]],
[('12',), [1, 1, 1, 1, 1, 4, 1, 1, 1]],
[('16',), [2, 0, 0, 0, 0, 0, 0, 0,-2]]]}
>>> l['special']
('12',)
>>> t=chartable(W); t['charnames'].index('12')
15
>>> t['a'][15]; t['b'][15]
4
4
(Thus, indeed, the character labelled by '12' is special in the
sense originally defined by Lusztig.)
See also 'chartable', 'leadingcoeffients', 'klcells',
'allcellsleadingcoeffs' and 'distinguishedinvolutions'.
"""
if type(weightL)==type(0):
poids=len(W.rank)*[weightL]
else:
poids=weightL[:]
ch=chartable(W,chars=False)['charnames']
fshi=[s.coeffs[0] for s in schurelms(W,[v**p for p in poids])]
pcell=[W.wordtoperm(w) for w in cell]
lw=[cell[i] for i in range(len(cell)) if perminverse(pcell[i]) in pcell]
if clpols==[]:
cpmat=allclasspolynomials(W,[v**(2*p) for p in poids],
max([len(w) for w in lw]))
else:
cpmat=clpols
lc=transposemat(leadingcoefficients(W,weightL,lw,cpmat))
ii=list(filter(lambda i:any(x!=0 for x in lc[i]),range(len(fshi))))
ftot=1
for i in ii:
ftot*=fshi[i]
cof=[]
for i in ii:
cf=1
for j in ii:
if i!=j:
cf*=fshi[j]
cof.append(cf)
nd=[(-1)**len(lw[w])*sum(cof[i]*lc[ii[i]][w]
for i in range(len(ii)))//ftot for w in range(len(lw))]
#nd1=[(-1)**len(lw[w])*sum((W.order*lc[i][w])//fshi[i]
# for i in range(len(fshi)))//W.order for w in range(len(lw))]
#if nd1!=nd:
# print('mist!')
# return False
if nd.count(0)!=len(nd)-1:
print("no distinguished involution!")
return nd
i=0
while nd[i]==0: i+=1
di=i
if nd[di]**2!=1:
print("no distinguished involution!!")
return [di,nd,nd[di]**2]
if nd[di]==-1:
lc=[[-i for i in l] for l in lc]
if len(lw[di])%2==1:
lc=[[-i for i in l] for l in lc]
#if set([(len(x)-len(lw[di]))%2 for x in lw])!=set([0]):
# lprint('#W odd lengths ')
sp=0
while sp0 for x in lc[ii[sp]]):
sp+=1
if sp==len(ii):
print('no special character!')
chi=[]
for i in range(len(fshi)):
if i in ii:
chi.append(lc[i][di])
else:
chi.append(0)
return {'ti':[[ch[i],lc[i]] for i in ii],'distinv':lw[di],
'nd':nd[di],'elms':lw,'special':ch[ii[sp]],'char':chi}
#F poltostr
def poltostr(f):
if type(f)==type(0):
return ('0.'+str(f))
elif f.coeffs==[]:
return ('0.0')
else:
return str(f.val)+'.'+'.'.join([str(i) for i in f.coeffs])
#F strtopol
def strtopol(sp,vnam):
spl=sp.split('.')
return lpol([int(i) for i in spl[1:]],val=int(spl[0]),vname=vnam)
#F distinguishedinvolutions
def distinguishedinvolutions(W,weightL,distonly=True):
"""returns the list of distinguished involutions with respect to a
weight function, plus some additional information (as explained
below). Here, we use the following definition:
An element w in W is called distinguished if
n_w := (-1)^l(w) * sum_{E in Irr(W)} f_E^(-1) c_{w,E}
is non-zero, where c_{w,E} are the leading coefficients of the
character values of the generic Iwahori-Hecke algebra and f_E
are defined in terms of the corresponding Schur elements. This
definition appeared in
M. Geck, Leading coefficients and cellular bases of Hecke
algebras, Proc. Edinburgh Math. Soc. 52 (2009), 653--677.
(This is equivalent to Lusztig's original definition in the
case of equal parameters and also in types I_2(m), F_4 for any
choice of parameters; it is conjectured that this equivalence
holds in general.)
One expects that all distinguished elements are involutions and
that every left cell with respect to the given weight function
contains exactly one distinguished element. (This is known to
be true in the equal parameter case where it is also known that
n_d=1 for all distinguished d in W.)
The function returns a list whose first component is the list
of distinguished involutions and the second component is a list
of pairs
(E_i, c_{d,E_i}) where E_i in Irr(W) and c_{d,E_i}<>0.
If not all n_d are equal to 1, then there is a third component
containing the values n_d.
>>> W=coxeter("I8",2)
>>> distinguishedinvolutions(W,[1,2]) # unequal parameters
#I Number of distinguished involutions = 6 (4)
[[[], [1], [0], [0,1,0], [1,0,1,0,1,0,1], [0,1,0,1,0,1,0,1]],
[[[('phi_{1,0}',),1]],
[[('phi_{2,3}',),-1],[('phi_{2,2}',),-1], [('phi_{2,1}',),-1]],
[[("phi_{1,4}''",),-1]],
[[('phi_{2,3}',),-1],[('phi_{2,2}',),-1], [('phi_{2,1}',),-1]],
[[("phi_{1,4}'",),1]],
[[('phi_{1,8}',),1]]],
[1, 1, 1, 1, -1, 1]]
>>> W=coxeter("G",2)
>>> distinguishedinvolutions(W,1) # equal parameters
#I Number of distinguished involutions = 4 (4)
[[[], [1], [0], [0,1,0,1,0,1]],
[[[('phi_{1,0}',),1]],
[[('phi_{2,2}',),-1], [('phi_{2,1}',),-1], [("phi_{1,3}''",),-1]],
[[('phi_{2,2}',),-1], [('phi_{2,1}',),-1], [("phi_{1,3}'",),-1]],
[[('phi_{1,6}',),1]]]]
(Here, all signs n_d are known to be equal to 1.)
This function even works for W of large rank: For type H4, it
takes about 25s; for type E6, about 45s; for type E7, about
40min; for type E8, about 18 days (and 22GB main memory).
See also 'distinguishedinvolutions_eq' (optimised for equal
parameters), 'libdistinv', 'leadingcoefficients', 'schurelms'
and 'leftcellleadingcoeffs'.
Final remark: There is an optional argument 'distonly'. If this
is set to 'False', then the function returns similar lists as
described above, but now the first list contains all elements w
such that c_{w,E} is non-zero for some E in Irr(W). Hence, this
yields the complete table of all leading coefficients c_{w,E}.
"""
if type(weightL)==type(0):
poids=len(W.rank)*[weightL]
else:
poids=weightL[:]
v=lpol([1],1,'v')
poin=poincarepol(W,v).coeffs
w0=longestperm(W)
ct=chartable(W)
lcl=[len(w) for w in conjugacyclasses(W)['reps']]
vs=[v**p for p in poids]
ti=heckechartable(W,vs)['irreducibles']
schur=schurelms(W,vs)
fshi=[s.coeffs[0] for s in schur]
ainv=[-s.val//2 for s in schur]
tup=[[i,ainv[i]] for i in range(len(ainv))]
tup.sort(key=(lambda i:i[1]),reverse=True)
ti=[ti[tup[i][0]] for i in range(len(ainv))]
fshi=[fshi[tup[i][0]] for i in range(len(ainv))]
ainv=[ainv[tup[i][0]] for i in range(len(ainv))]
chn=[ct['charnames'][tup[i][0]] for i in range(len(ainv))]
ti1=[ct['irreducibles'][tup[i][0]] for i in range(len(ainv))]
signchar=[(-1)**lw for lw in lcl]
signp=[ti1.index([l[j]*signchar[j] for j in range(len(lcl))]) for l in ti1]
maxl=W.N
if W.N in lcl:
iw0=lcl.index(W.N)
eps=[x[iw0]//x[0] for x in ct['irreducibles']]
eps=[eps[tup[i][0]] for i in range(len(ainv))]
maxl=W.N//2
distinv,nvec=[[]],[1]
lc=[zeroterm(v**(ainv[i])*ti[i][0]) for i in range(len(ainv))]
char=[]
for i in range(len(ainv)):
if lc[i]!=0:
char.append([chn[i],lc[i]])
#if lc[i]>0:
# char.append([chn[i],lc[i]])
#elif lc[i]<0:
# char.append([chn[i],-lc[i]])
charvec=[char[::-1]]
if maxl==W.N or all(p==0 for p in poids):
distinv0,nvec0,charvec0=[],[],[]
else:
distinv0,nvec0=[W.permtoword(w0)],[1]
Lw0=ainv[ti1.index(signchar)]
lc0=[zeroterm(v**(ainv[i]-Lw0)*ti[i][iw0]) for i in range(len(ainv))]
char0=[]
for i in range(len(ainv)):
if lc0[i]!=0:
char0.append([chn[i],lc0[i]])
#if lc0[i]>0:
# char0.append([chn[i],lc0[i]])
#elif lc0[i]<0:
# char0.append([chn[i],-lc0[i]])
charvec0=[char0[::-1]]
cpmat=[]
cp=len(ainv)*[0]
cp[0]=1
cpmat.append({mybytes(W.rank):';'.join([poltostr(f) for f in cp])})
cps={}
nega=False
zael=0
lprint('#I length 0 - 1 element, 1 class polynomial; 1 distinv\n')
for l in range(maxl):
if l<9:
lprint('#I length '+str(l+1))
else:
lprint('#I length '+str(l+1))
nl=set([])
if l==0:
ol=[]
else:
ol=set(cpmat[l-1].keys())
for w in cpmat[l].keys():
for s in W.permgens:
nw=mybytes([s[i] for i in w])
if not nw in ol:
nl.add(nw)
if len(nl)==poin[l+1]:
break
cps={}
lprint(' - ')
ll=len(nl)
spols=[]
while nl!=set([]):
w=W.coxelmtoword(next(iter(nl)))
pw=W.wordtoperm(w)
pw1=perminverse(pw)
t=testcyclicshift1(W,w,pw)
if t[0]==1:
cp=len(ainv)*[0]
cp[t[2]]=1
else:
cp1=[strtopol(f,'v') for f in cpmat[l-1][mybytes(t[2])].split(';')]
cp2=[strtopol(f,'v') for f in cpmat[l][mybytes([W.permgens[t[3]][i]
for i in t[2]])].split(';')]
if poids[t[3]]==1:
cp=[v*cp1[i]+(v-1)*cp2[i] for i in range(len(ainv))]
else:
cp=[v**(poids[t[3]])*cp1[i]+(v**(poids[t[3]])-1)*cp2[i]
for i in range(len(ainv))]
strcp=';'.join([poltostr(f) for f in cp])
ic=len(spols)-1
while ic>=0:
if strcp==spols[ic]:
break
ic-=1
if ic==-1:
spols.append(strcp)
for x in t[1]:
cx=x[:len(W.rank)]
cps[mybytes(cx)]=spols[ic]
nl.remove(mybytes(cx))
if not pw1 in t[1]:
for x in t[1]:
cx=perminverse(x)[:len(W.rank)]
cps[mybytes(cx)]=spols[ic]
nl.remove(mybytes(cx))
if len(t[1])==1 and (any(p!=1 for p in poids) or W.permorder(pw)==2
or generalisedtau(W,pw,maxd=len(W.rank)**2)==
generalisedtau(W,pw1,maxd=len(W.rank)**2)):
zael+=1
cpv=[]
for j in range(len(ainv)):
if type(cp[j])==type(0):
cpv.append(cp[j])
elif cp[j].coeffs==[]:
cpv.append(0)
else:
cpv.append(cp[j].value(v**2))
cind=0
for i in w:
cind+=poids[i]
lc=[]
nonz=-1
for i in range(len(ainv)):
if ainv[i]>cind or (nonz!=-1 and nonz!=ainv[i]):
lcc=0
else:
lcc=zeroterm(v**(ainv[i]-cind)*sum(cpv[j]*ti[i][j]
for j in range(len(ainv)) if cpv[j]!=0))
if nonz==-1 and lcc!=0:
nonz=ainv[i]
lc.append(lcc)
ii=[i for i in range(len(ainv)) if lc[i]!=0]
if ii!=[]:
ftot=1
for i in ii:
ftot*=fshi[i]
cof=[]
for i in ii:
cf=1
for j in ii:
if i!=j:
cf*=fshi[j]
cof.append(cf)
nd=(-1)**len(w)*sum(cof[i]*lc[ii[i]] for i in range(len(ii)))
if nd%ftot==0:
nd=nd//ftot
else:
print("Mist!")
return False
if nd!=0 or distonly!=True:
distinv.append(w)
nvec.append(nd)
char=[]
for i in range(len(ainv)):
if lc[i]!=0:
char.append([chn[i],lc[i]])
#if lc[i]>0:
# char.append([chn[i],lc[i]])
#elif lc[i]<0:
# char.append([chn[i],-lc[i]])
charvec.append(char[::-1])
if nega==False and nd!=1:
nega=True
if maxl==W.N//2 and (W.N%2==1 or l0:
# char0.append([signp[i],lc[i]])
#elif lc[i]<0:
# char0.append([signp[i],-lc[i]])
char0.sort(key=(lambda i:i[0]),reverse=True)
charvec0.append([[chn[i[0]],i[1]] for i in char0])
if nega==False and nd!=1:
nega=True
lprint(str(ll)+' elements, '+str(len(spols))+' class polynomials; ')
lprint(str(len(distinv)+len(distinv0))+' distinvs\n')
if l>0:
cpmat[l-1]=0
cpmat.append(cps)
distinv=distinv+distinv0[::-1]
nvec=nvec+nvec0[::-1]
charvec=charvec+charvec0[::-1]
#d1=distinguishedinvolutions(W,poids)
#d1=libdistinv(W,poids)
#if not (len(distinv)==len(d1) and all(i in d1 for i in distinv)):
# print("Mist!")
# return [distinv,d1]
#else:
# lprint('True')
lprint('#I Number of distinguished involutions = '+str(len(distinv)))
lprint(' ('+str(zael)+')\n')
if nega==True:
return [distinv,charvec,nvec]
else:
return [distinv,charvec]
#F starorbitinv (for use in distinguishedinvolutions_eq and libdistinv)
def starorbitinv(W,pw):
"""returns double star orbit of an involution.
"""
orb=[pw[:]]
for d in orb:
for s in W.rank:
for t in range(s):
if W.coxetermat[s][t]==3:
if (d[s]>=W.N and d[t]=W.N):
d1=leftklstar(W,perminverse(leftklstar(W,d,s,t)),s,t)
if not d1 in orb:
orb.append(d1)
if W.permorder(d1)!=2:
print("Mist!")
return False
return orb
def starorbitinv1(W,distinv):
"""decomposes list of distinguished involutions into orbits
under the star operation.
"""
rest=[W.wordtoperm(w) for w in distinv]
reps=[]
while rest!=[]:
orb=starorbitinv(W,rest[0])
for x in orb:
rest.remove(x)
l=W.permlength(orb[0])
r=orb[0]
for x in orb[1:]:
lx=W.permlength(x)
if lx=0:
if strcp==spols[ic]:
break
ic-=1
if ic==-1:
spols.append(strcp)
for x in t[1]:
cx=x[:len(W.rank)]
cps[mybytes(cx)]=spols[ic]
nl.remove(mybytes(cx))
if not pw1 in t[1]:
for x in t[1]:
cx=perminverse(x)[:len(W.rank)]
cps[mybytes(cx)]=spols[ic]
nl.remove(mybytes(cx))
if W.permorder(pw)==2 and pw in repsinv and not pw in distinv:
cpv=[]
for j in range(len(ainv)):
if type(cp[j])==type(0):
cpv.append(cp[j])
elif cp[j].coeffs==[]:
cpv.append(0)
else:
cpv.append(cp[j].value(v**2))
lc=[]
nonz=-1
for i in range(len(ainv)):
if ainv[i]>len(w) or (nonz!=-1 and nonz!=ainv[i]):
lcc=0
else:
lcc=zeroterm(v**(ainv[i]-len(w))*sum(cpv[j]*ti[i][j]
for j in range(len(ainv)) if cpv[j]!=0))
if nonz==-1 and lcc!=0:
nonz=ainv[i]
lc.append(lcc)
ii=[i for i in range(len(ainv)) if lc[i]!=0]
ftot=1
for i in ii:
ftot*=fshi[i]
cof=[]
for i in ii:
cf=1
for j in ii:
if i!=j:
cf*=fshi[j]
cof.append(cf)
nd=(-1)**len(w)*sum(cof[i]*lc[ii[i]] for i in range(len(ii)))
if nd%ftot==0:
nd=nd//ftot
else:
print("Mist!")
return False
#nd=(-1)**len(w)*sum((W.order*lc[i])//fshi[i]
# for i in range(len(fshi)))//W.order
if nd!=0:
sto=starorbitinv(W,pw)
distinv.extend(sto)
char=[]
for i in range(len(ainv)):
if lc[i]!=0:
char.append([chn[i],lc[i]])
#if lc[i]>0:
# char.append([chn[i],lc[i]])
#elif lc[i]<0:
# char.append([chn[i],-lc[i]])
char=char[::-1]
for i in sto:
charvec.append(char)
pw0=permmult(pw,w0)
if all(f%2==0 for f in W.degrees) and not pw0 in distinv:
nd=sum(eps[ii[i]]*cof[i]*lc[ii[i]] for i in range(len(ii)))
if nd%ftot==0:
nd=nd//ftot
else:
print("Mist!")
return False
if nd!=0:
sto0=starorbitinv(W,pw0)
distinv.extend(sto0)
char0=[]
for i in range(len(ainv)):
if lc[i]!=0:
char0.append([signp[i],(-1)**(W.N+len(w))*eps[i]*lc[i]])
#if lc[i]>0:
# char0.append([signp[i],lc[i]])
#elif lc[i]<0:
# char0.append([signp[i],-lc[i]])
char0.sort(key=(lambda i:i[0]),reverse=True)
char0=[[chn[i[0]],i[1]] for i in char0]
for i in sto0:
charvec.append(char0)
lprint(str(ll)+' elements, '+str(len(spols))+' class polynomials; ')
lprint(str(len(distinv))+' distinvs\n')
if l>0:
cpmat[l-1]=0
cpmat.append(cps)
if len(distinv)==maxn:
break
res=[[W.permtoword(distinv[i]),charvec[i]] for i in range(len(distinv))]
res.sort(key=(lambda x:len(x[0])))
#d1=distinguishedinvolutions(W,poids)
#d1=libdistinv(W,1)
#if not (len(distinv)==len(d1) and all(i in d1 for i in distinv)):
# print("Grosser Mist!")
# return [distinv,d1]
#else:
# lprint('True')
lprint('#I Number of distinguished involutions = '+str(len(res))+'\n')
return [list(l) for l in zip(*res)]
#F allcellsleadingcoeffs
def allcellsleadingcoeffs(W,weightL,v):
"""returns a list which contains the pairwise different results of
'leftcellleadingcoeffs' as we run over all left cells of W with
at least two irreducible components.
>>> allcellsleadingcoeffs(coxeter("H",3),1,v)
[[[[("3_s'",), 1, ir5], [("overline{3}_s'",), 1, 1-ir5]],
[[('3_s',), ir5, 1], [('overline{3}_s',), 1-ir5, 1]],
[[("4_r'",), 1, -1], [('4_r',), 1, 1]]],
[[[], 1], # all distinguished involutions with signs
[[0, 1, 0, 1, 0, 2, 1, 0, 1, 0, 2, 1, 0, 1, 2], 1],
[[2, 1, 0, 1, 0, 2, 1, 0, 1, 2], 1],
[[0, 1, 0, 1, 0], 1],
[[1, 0, 2, 1], 1],
[[0, 1, 0, 2, 1, 0, 1, 0, 2, 1, 0], 1],
[[1, 0, 2, 1, 0, 1, 0, 2, 1], 1],
[[0, 1, 0, 2, 1, 0], 1],
[[2], 1],
[[0, 1, 0, 1, 0, 2, 1, 0, 1, 0, 2, 1, 0, 1], 1],
[[1, 0, 1, 0, 2, 1, 0, 1, 0, 2, 1, 0, 1, 2], 1],
[[0], 1], [[1, 2, 1], 1],
[[0, 1, 0, 1, 2, 1, 0, 1, 0], 1], [[1, 0, 1, 2, 1, 0, 1], 1]],
[("5_r'",), ("3_s'",), ("1_r'",), ('3_s',), # special characters
('1_r',), ('5_r',), ("4_r'",)]]
>>>allcellsleadingcoeffs(coxeter("B",3),[2,1,1],v)
[[[[('[[1, 1], [1]]',), 1, 1],
[('[[1], [2]]',), 1, -1]],
[[('[[1], [2]]',), 1, -1],
[('[[], [3]]',), 1, 1]],
[[('[[1, 1, 1], []]',), 1, -1],
[('[[1, 1], [1]]',), 1, 1]]],
[[[], 1],
[[0], 1],
[[1], 1],
[[2], 1],
[[1, 0, 1], 1],
[[0, 2], 1],
[[0, 1, 0], -1],
[[2, 1, 0, 1, 2], 1],
[[1, 0, 2, 1], 1],
[[1, 2, 1], 1],
[[0, 1, 0, 1], 1],
[[0, 2, 1, 0, 1, 2], 1],
[[1, 0, 1, 2, 1, 0, 1, 2], 1],
[[0, 1, 0, 2, 1, 0, 1, 2], -1],
[[0, 1, 0, 1, 2, 1, 0, 1], -1],
[[0, 1, 0, 1, 2, 1, 0, 1, 2], 1]]
[('[[1], [2]]',), ('[[1], [1, 1]]',), ('[[1, 1, 1], []]',),
('[[2], [1]]',), ('[[], [2, 1]]',), ('[[], [1, 1, 1]]',),
('[[3], []]',), ('[[2, 1], []]',)]]
See also 'klcells' and 'leftcellleadingcoeffs'.
"""
if type(weightL)==type(0):
poids=len(W.rank)*[weightL]
else:
poids=weightL[:]
if all(p==1 for p in poids):
kl=[c.X for c in klcells(W,poids,v,allcells=False)[1]]
else:
kl=[c.X for c in klcellsun(W,poids,v)]
cp=allclasspolynomials(W,[v**(2*i) for i in poids]);
ch=chartable(W,chars=False)['charnames']
nlc,dlc=[],[]
slc=set([])
lprint('#I ')
for l1 in kl:
l=leftcellleadingcoeffs(W,poids,v,l1,clpols=cp)
lprint(str(l['nd']))
dlc.append([l['distinv'],l['nd']])
slc.add(ch.index(l['special']))
if len(l['ti'])>1:
tl=transposemat([flatlist(i) for i in l['ti']])
ok=True
for m in nlc:
if len(m)==len(tl) and all(m.count(r)==tl.count(r) for r in m):
ok=False
if ok:
nlc.append(tl)
lprint('\n')
slc=list(slc)
slc.sort()
slc=[ch[i] for i in slc]
for l in nlc:
#if len(list(filter(lambda i:i in slc,l[0])))!=1:
if len([i for i in l[0] if i in slc])!=1:
print('multiple special in cell')
return l
return [[transposemat(l) for l in nlc],dlc,slc]
#F libdistinv
def libdistinv(W,weightL,unpack=True):
"""returns a pre-computed and explicitly stored list of distinguished
involutions. Among other properties, these elements form a set of
representatives for the left cells of W with respect to the given
weight function. This function only works for W of type I_2(m),
F_4 (any weight function) and H_3, H_4, E_6, E_7, E8 (equal
parameters) and only if all the weights are strictly positive.
One can reproduce these data using 'distinguishedinvolutions' but
this will take some time. Also, some further arguments are needed
to deal with all choices of unequal parameters for I_2(m) and F_4.
Here, we rely on the results and techniques in
M. Geck, Computing Kazhdan-Lusztig cells for unequal parameters,
J. Algebra 281 (2004), 342--365.
For the large groups of exceptional type, we only store a set of
representatives under N. Xi's 'double' star operation; this shows
that, if d is distinguished and the star operation is defined for d
(with respect to generators s,t such that st has order 3), then the
element ((d^*)^{-1})^* is also distinguished. -- So it will take a
couple of minutes or so to unpack these data. For example, for W
of type E8 there are 101796 distinguished involutions but only
106 orbits under the 'double' star operation. The 'unpacking' is
done by the function 'starorbitinv'.
>>> W=coxeter('H',4);
>>> libdistinv(W,1)==distinguishedinvolutions(W,1)
True
>>> W=coxeter("E",8);
>>> d=timer(libdistinv,W,1)
188.06
>>> len(d)
101796
See also 'distinguishedinvolutions'.
"""
if type(weightL)==type(0):
poids=len(W.rank)*[weightL]
else:
poids=weightL[:]
if len(W.cartantype)>1:
print('#W Sorry, only irreducible W of exceptional type')
return False
if all(p==0 for p in poids):
return [[]]
typ=W.cartantype[0][0]
rk=list(W.cartantype[0][1])
if typ=='H' and rk==[0,1,2]:
l=['', '0', '1', '2', '02', '121', '1021', '01010', '01210', '010210',
'1012101', '0210102', '10102101', '010121010', '102101021',
'2101021012', '01021010210', '1010210102101', '01010210102101',
'01012101021012', '10102101021012', '010102101021012']
chrs0=['1.1', '7.1c6.1', '7.1c6.1', '7.1c6.1', '3.1', '9.1c8.1', '3.1',
'2.1', '9.1c8.1', '3.1', '9.1c8.1', '2.1', '3.1', '9.1c8.1', '2.1',
'3.1', '2.1', '2.1', '5.1c4.1', '5.1c4.1', '5.1c4.1', '0.1']
ch=chartable(W,chars=False)['charnames']
chars=[[[ch[int(k.split('.')[0])],int(k.split('.')[1])]
for k in i.split('c')] for i in chrs0]
if unpack==True:
return [[int(s) for s in i] for i in l]
else:
return [[[int(s) for s in l[i]],chars[i]] for i in range(len(l))]
elif typ=='H' and rk==[0,1,2,3]:
l=['', '0', '1', '2', '3', '02', '03', '13', '121', '232', '1021',
'0232', '2132', '01010', '01210', '12321', '010210', '010103',
'102321', '121321', '1012101', '0210102', '0123210', '10102101',
'02101032', '12101321', '01023210', '01213210', '010121010',
'102101021', '101232101', '032101023', '2101021012', '1021010321',
'0121013210', '1010232101', '1012132101', '0232101023', '01021010210',
'01012321010', '21012321012', '10321010213', '010210103210',
'101210132101', '010121321010', '121012321012', '210102321012',
'102321010213', '321010210123', '1010210102101', '0210123210102',
'0103210102103', '2103210102132', '01010210102101', '01012101021012',
'10102101021012', '10102101032101', '01012101321010',
'12101021321012', '01210123210102', '01023210102103',
'23210102101232', '010102101021012', '102101232101021',
'101032101021013', '021032101021032', '0121010213210102',
'1012101232101021', '1010232101021013', '0101321010210123',
'1010321010210123', '1232101021012321', '01021012321010210',
'10210321010210321', '01010321010210123', '21010321010210132',
'101210102132101021', '010121012321010210', '210102321010210132',
'210103210102101232', '012321010210123210', '1010210123210102101',
'1210103210102101321', '0102103210102103210', '0210103210102101232',
'01012101021321010210', '10123210102101232101',
'210102101232101021012', '012101032101021013210',
'102101032101021012321', '101021032101021032101',
'2101232101021012321012', '0101232101021012321010',
'21010210321010210321012', '01021010321010210123210',
'10121010321010210132101', '32101021012321010210123',
'021012321010210123210102', '1010210103210102101232101',
'1210102103210102101321012', '0101210103210102101321010',
'2321010210123210102101232', '01010210102101232101021012',
'10210123210102101232101021', '121010210132101021012321012',
'012101021032101021013210102', '010102101032101021012321010',
'123210102101232101021012321', '0102101232101021012321010210',
'0101032101021012321010210123', '01210102101321010210123210102',
'10121010210321010210132101021', '01232101021012321010210123210',
'12132101021013210102103210123', '101021012321010210123210102101',
'021010321010210123210102101232', '0101210102103210102101321010210',
'1012101021013210102101232101021', '1012321010210123210102101232101',
'0121321010210123210102103210123', '21010210123210102101232101021012',
'10210103210102101232101021012321',
'010121010210132101021012321010210',
'210123210102101232101021012321012',
'010123210102101232101021012321010',
'101213210102101232101021013210123',
'0101021010210123210102101321010210',
'0102101032101021012321010210123210',
'3210102101232101021012321010210123',
'01010210102101321010210123210102101',
'12101232101021012321010210123210123',
'02101232101021012321010210123210102',
'01012132101021012321010210132101023',
'101021010321010210123210102101232101',
'010102321010210123210102101321010213',
'0101021321010210123210102101321010213',
'0121012321010210123210102101232101023',
'1021012321010210123210102101232101021',
'12101021013210102101232101021012321012',
'01010210103210102101232101021012321010',
'02101023210102101232101021013210102132',
'021010213210102101232101021013210102132',
'101210123210102101232101021012321010213',
'010210123210102101232101021012321010210',
'0121010210132101021012321010210123210102',
'1021010232101021012321010210123210102132',
'1210321010210123210102101232101021012321',
'10210102132101021012321010210123210102132',
'10102101232101021012321010210123210102101',
'01012101232101021012321010210123210102103',
'101210102101321010210123210102101232101021',
'010210102321010210123210102101232101021032',
'012103210102101232101021012321010210123210',
'0102101021321010210123210102101232101021032',
'0101021012321010210123210102101232101021013',
'2101021012321010210123210102101232101021012',
'01012101021013210102101232101021012321010210',
'10102101023210102101232101021012321010210321',
'10121032101021012321010210123210102101232101',
'021010210123210102101232101021012321010210132',
'101021010213210102101232101021012321010210321',
'321010210123210102101232101021012321010210123',
'0101021010210132101021012321010210123210102101',
'0101021010232101021012321010210123210102103210',
'1210102101232101021012321010210123210102101321',
'0101210321010210123210102101232101021012321010',
'1210102321010210123210102101232101021012321012',
'01010210102132101021012321010210123210102103210',
'10210102101232101021012321010210123210102101321',
'02321010210123210102101232101021012321010210123',
'010102101021012321010210123210102101232101021012',
'012101021012321010210123210102101232101021013210',
'010102101321010210123210102101232101021012321010',
'012101023210102101232101021012321010210123210102',
'121321010210123210102101232101021012321010210123',
'0102101021012321010210123210102101232101021013210',
'1021321010210123210102101232101021012321010210123',
'10121010210123210102101232101021012321010210132101',
'02101021013210102101232101021012321010210123210102',
'10121010232101021012321010210123210102101232101021',
'01010321010210123210102101232101021012321010210123',
'01210321010210123210102101232101021012321010210123',
'101021010210123210102101232101021012321010210132101',
'010210321010210123210102101232101021012321010210123',
'0101021010210132101021012321010210123210102101321010',
'0101210102101232101021012321010210123210102101321010',
'1021010210132101021012321010210123210102101232101021',
'0101210102321010210123210102101232101021012321010210',
'1012101321010210123210102101232101021012321010210123',
'0210102321010210123210102101232101021012321010210123',
'10102101321010210123210102101232101021012321010210123',
'010210102101321010210123210102101232101021012321010210',
'010121010321010210123210102101232101021012321010210123',
'102101021321010210123210102101232101021012321010210123',
'2101021012321010210123210102101232101021012321010210123',
'01010210102103210102101232101021012321010210123210102101',
'10102101021013210102101232101021012321010210123210102101',
'01021010210321010210123210102101232101021012321010210123',
'0101210102101232101021012321010210123210102101232101021012',
'1010210102101232101021012321010210123210102101232101021012',
'1010210102101321010210123210102101232101021012321010210123',
'01010210102101232101021012321010210123210102101232101021012',
'01010210102101321010210123210102101232101021012321010210123',
'01012101021012321010210123210102101232101021012321010210123',
'10102101021012321010210123210102101232101021012321010210123',
'010102101021012321010210123210102101232101021012321010210123']
chrs0=['0.1', '4.1c2.1', '4.1c2.1', '4.1c2.1', '4.1c2.1', '12.1c10.1',
'12.1c10.1', '12.1c10.1', '19.1c17.1', '19.1c17.1', '12.1c10.1',
'26.1', '12.1c10.1', '30.1', '19.1c17.1', '19.1c17.1', '12.1c10.1',
'33.2c32.2c29.1c28.1c25.1c24.1c23.1c22.1c21.1c16.1c15.1c14.1',
'26.1', '33.2c32.1c29.1c28.1c25.1c24.1c23.1c22.1c21.1c9.1c8.1',
'19.1c17.1', '30.1', '19.1c17.1', '12.1c10.1',
'33.2c32.2c29.1c28.1c25.1c24.1c23.1c22.1c21.1c16.1c15.1c14.1',
'26.1', '26.1',
'33.2c32.1c29.1c28.1c25.1c24.1c23.1c22.1c21.1c9.1c8.1',
'19.1c17.1', '30.1', '19.1c17.1', '30.1', '12.1c10.1',
'33.2c32.2c29.1c28.1c25.1c24.1c23.1c22.1c21.1c16.1c15.1c14.1',
'26.1', '26.1',
'33.2c32.1c29.1c28.1c25.1c24.1c23.1c22.1c21.1c9.1c8.1',
'33.2c32.2c29.1c28.1c25.1c24.1c23.1c22.1c21.1c16.1c15.1c14.1',
'30.1', '19.1c17.1', '19.1c17.1', '30.1',
'33.2c32.2c29.1c28.1c25.1c24.1c23.1c22.1c21.1c16.1c15.1c14.1',
'26.1', '33.2c32.1c29.1c28.1c25.1c24.1c23.1c22.1c21.1c9.1c8.1',
'33.2c32.1c29.1c28.1c25.1c24.1c23.1c22.1c21.1c9.1c8.1', '26.1',
'33.2c32.2c29.1c28.1c25.1c24.1c23.1c22.1c21.1c16.1c15.1c14.1',
'12.1c10.1', '30.1', '19.1c17.1', '30.1', '30.1',
'33.2c32.2c29.2c28.2c25.1c24.1c23.1c22.1c16.1c15.1c7.1c6.1',
'33.2c32.2c29.2c28.2c25.1c24.1c23.1c22.1c16.1c15.1c7.1c6.1',
'33.2c32.2c29.2c28.2c25.1c24.1c23.1c22.1c16.1c15.1c7.1c6.1',
'33.2c32.2c29.1c28.1c25.1c24.1c23.1c22.1c21.1c16.1c15.1c14.1',
'26.1', '26.1',
'33.2c32.1c29.1c28.1c25.1c24.1c23.1c22.1c21.1c9.1c8.1',
'33.2c32.2c29.1c28.1c25.1c24.1c23.1c22.1c21.1c16.1c15.1c14.1',
'26.1', '31.1', '19.1c17.1', '30.1', '30.1', '26.1',
'33.2c32.1c29.1c28.1c25.1c24.1c23.1c22.1c21.1c9.1c8.1',
'33.2c32.2c29.1c28.1c25.1c24.1c23.1c22.1c21.1c16.1c15.1c14.1',
'33.2c32.2c29.2c28.2c25.1c24.1c23.1c22.1c16.1c15.1c7.1c6.1',
'33.2c32.2c29.2c28.2c25.1c24.1c23.1c22.1c16.1c15.1c7.1c6.1',
'26.1', '19.1c17.1', '30.1', '31.1', '30.1', '26.1',
'33.2c32.1c29.1c28.1c25.1c24.1c23.1c22.1c21.1c9.1c8.1',
'33.2c32.2c29.1c28.1c25.1c24.1c23.1c22.1c21.1c16.1c15.1c14.1',
'33.2c32.2c29.2c28.2c25.1c24.1c23.1c22.1c16.1c15.1c7.1c6.1',
'26.1', '19.1c17.1', '30.1', '30.1', '31.1', '26.1', '26.1',
'19.1c17.1', '30.1', '31.1', '30.1', '26.1', '26.1', '30.1',
'31.1', '30.1', '19.1c17.1', '26.1', '31.1', '30.1', '30.1',
'30.1', '27.1', '26.1', '31.1', '30.1', '31.1', '30.1', '26.1',
'27.1', '31.1', '30.1', '30.1', '31.1', '26.1', '27.1', '30.1',
'31.1', '30.1', '31.1', '26.1', '27.1', '31.1', '30.1', '30.1',
'31.1', '20.1c18.1', '27.1', '26.1', '31.1', '31.1', '30.1',
'31.1', '27.1', '20.1c18.1', '31.1', '31.1', '30.1', '27.1',
'27.1', '20.1c18.1', '31.1', '31.1', '30.1', '27.1', '20.1c18.1',
'27.1', '31.1', '30.1', '31.1', '27.1', '20.1c18.1', '27.1',
'31.1', '31.1', '30.1', '27.1', '20.1c18.1', '27.1', '31.1',
'31.1', '30.1', '27.1', '20.1c18.1', '20.1c18.1', '27.1', '27.1',
'31.1', '31.1', '31.1', '13.1c11.1', '20.1c18.1', '27.1', '27.1',
'20.1c18.1', '31.1', '31.1', '20.1c18.1', '27.1', '27.1',
'13.1c11.1', '20.1c18.1', '31.1', '31.1', '20.1c18.1',
'20.1c18.1', '27.1', '27.1', '20.1c18.1', '13.1c11.1', '31.1',
'27.1', '20.1c18.1', '13.1c11.1', '31.1', '13.1c11.1', '27.1',
'13.1c11.1', '13.1c11.1', '13.1c11.1', '13.1c11.1', '5.1c3.1',
'5.1c3.1', '5.1c3.1', '5.1c3.1', '1.1']
ch=chartable(W,chars=False)['charnames']
chars=[[[ch[int(k.split('.')[0])],int(k.split('.')[1])]
for k in i.split('c')] for i in chrs0]
if unpack==True:
return [[int(s) for s in i] for i in l]
else:
return [[[int(s) for s in l[i]],chars[i]] for i in range(len(l))]
elif typ=='F' and rk==[0,1,2,3]:
l1111=['', '0', '1', '2', '3', '02', '03', '13', '010', '232', '1021',
'1212', '0103', '0232', '2132', '02102', '12321', '012102',
'210212', '021032', '102321', '121321', '132123', '1021021',
'0123210', '2123212', '0321023', '01021021', '10210321',
'01213210', '21023212', '21232123', '01321023', '32102123',
'010210212', '121232123', '021232102', '103210213', '01212321023',
'10212321021', '21032102132', '01032102123', '2102123210212',
'0102123210213', '0210321021232', '1210321021321',
'021021232102132', '012103210213210', '102103210212321',
'321021232102123', '0102102123210212', '1210232102123212',
'10210212321021321', '01021032102123210', '12102132102123212',
'02321021232102123', '012102321021232102', '010321021232102123',
'0102102123210213210', '0121021321021232102', '1021321021232102123',
'1212321021232102123', '01021023210212321021', '02102321021232102123',
'010210213210212321021', '010210321021232102123',
'012102321021232102123', '210212321021232102123',
'0121021232102123210212', '1021021232102123210212',
'1021021321021232102123', '010210212321021232102123']
l1122=['', '0', '1', '2', '3', '02', '03', '13', '010', '121', '212',
'232', '1021', '1212', '0103', '0232', '2132', '01210', '12321',
'32123', '012102', '021032', '102321', '121321', '132123', '232123',
'0123210', '2123212', '01021021', '01210212', '10210212', '10210321',
'01023210', '01213210', '12123212', '21023212', '12132123', '21232123',
'01321023', '010210212', '121232123', '021232102', '0102103210',
'0121232102', '0210232102', '0121321023', '0212321023', '0103210213',
'0132102123', '1032102123', '01212321023', '10212321021',
'01032102123', '010212321021', '102102321021', '102123210213',
'021032102132', '2102123210212', '0102123210213', '0210321021232',
'21021232102132', '10210321021321', '21232102123212',
'021021232102132', '102103210212321', '321021232102123',
'1210212321021321', '0102103210213210', '0212321021232102',
'2321021232102123', '10210212321021321', '01021032102123210',
'12102132102123212', '02321021232102123', '012102123210213210',
'102123210212321021', '121321021232102123', '212321021232102123',
'0102102123210213210', '0121021321021232102', '1021321021232102123',
'1212321021232102123', '21021232102123210212', '01210321021232102123',
'010210213210212321021', '010210321021232102123',
'012102321021232102123', '01021021232102123210212',
'01021021321021232102123', '01210212321021232102123',
'10210212321021232102123', '010210212321021232102123']
l1133=['', '0', '1', '2', '3', '02', '03', '13', '010', '121', '212',
'232', '1021', '1212', '0103', '0232', '2132', '01210', '02102',
'12321', '32123', '010210', '012102', '210212', '021032', '102321',
'121321', '132123', '232123', '1021021', '0123210', '2123212',
'0321023', '01021021', '01210212', '10210212', '10210321', '01023210',
'01213210', '12123212', '21023212', '12132123', '21232123',
'01321023', '32102123', '010210212', '121232123', '021232102',
'103210213', '0102103210', '0121232102', '0210232102', '0121321023',
'0212321023', '0103210213', '0132102123', '1032102123', '01212321023',
'10212321021', '21032102132', '01032102123', '010212321021',
'102102321021', '102123210213', '021032102132', '2102123210212',
'0102123210213', '0210321021232', '1210321021321', '21021232102132',
'10210321021321', '21232102123212', '021021232102132',
'012103210213210', '102103210212321', '321021232102123',
'0102102123210212', '1210212321021321', '0102103210213210',
'1210232102123212', '0212321021232102', '2321021232102123',
'10210212321021321', '01021032102123210', '12102132102123212',
'02321021232102123', '012102123210213210', '012102321021232102',
'102123210212321021', '010321021232102123', '121321021232102123',
'212321021232102123', '0102102123210213210', '0121021321021232102',
'1021321021232102123', '1212321021232102123', '01021023210212321021',
'21021232102123210212', '01210321021232102123',
'02102321021232102123', '010210213210212321021',
'010210321021232102123', '012102321021232102123',
'210212321021232102123', '0121021232102123210212',
'1021021232102123210212', '1021021321021232102123',
'01021021232102123210212', '01021021321021232102123',
'01210212321021232102123', '10210212321021232102123',
'010210212321021232102123']
if poids[0]==poids[2]:
return [[int(s) for s in i] for i in l1111]
elif poids[0]>0 and poids[2]>poids[0]:
if poids[2]==2*poids[0]:
return [[int(s) for s in i] for i in l1122]
else:
return [[int(s) for s in i] for i in l1133]
elif poids[2]>0 and poids[0]>poids[2]:
J=[3,2,1,0]
W=coxeter("F",4)
if poids[0]==2*poids[2]:
return [W.reducedword([J[int(s)] for s in i],W) for i in l1122]
else:
return [W.reducedword([J[int(s)] for s in i],W) for i in l1133]
else:
print('#W Sorry, not yet implemented')
return False
elif typ[0]=='E' and rk==[0,1,2,3,4,5]:
reps=['', '3', '12', '015', '232', '1315', '01454', '020454', '020320',
'0131431', '0120454', '1314315431', '23123431234', '01203120325',
'123123431234', '020320432054320', '02031203431203243',
'01203120324312032431', '020312043120324315431203243',
'0120312032431203243154312032431',
'012031203243120324315431203243154320']
chrs0=['0.1', '3.1', '10.1', '14.1c8.1', '14.1c6.1', '21.1', '19.1',
'12.1', '23.1', '18.1c17.1c16.1', '17.1c16.1c2.1', '24.1',
'18.2c17.1c5.1', '20.1', '13.1', '15.1c9.1', '22.1', '11.1',
'15.1c7.1', '4.1', '1.1']
ch=chartable(W,chars=False)['charnames']
chars=[[[ch[int(k.split('.')[0])],int(k.split('.')[1])]
for k in l.split('c')] for l in chrs0]
if unpack==True:
f=[W.permtoword(x) for x in flatlist([starorbitinv(W,
W.wordtoperm([int(i) for i in r])) for r in reps])]
f.sort(key=(lambda x:len(x)))
else:
f=[[[int(i) for i in reps[r]],chars[r]] for r in range(len(reps))]
return f
elif typ[0]=='E' and rk==[0,1,2,3,4,5,6]:
reps=['', '2', '12', '020', '124', '146', '0120', '1246', '01204',
'020320', '020454', '012046', '0131431', '0120454', '1314316',
'01314316', '020320565', '0120312032', '0120454654',
'12312343123', '01203120325', '123123431234', '123123431236',
'1231234312346', '0120312032565', '020320432054320',
'231243123565432', '131431543165431', '123431235654312',
'0131431543165431', '01203120324312032', '01203435436543120',
'012031203243120326', '01203120324312032431',
'12312343543126543123', '012031203243120324316',
'020320432054320654320', '123120343120543126543123',
'232432543123456543123456', '020312043120324315431203243',
'1234312032543654312032431546', '12312343123454312345654312345',
'123123431234543123456543123456',
'0120312032431203243154312032431',
'0120343254312036543120324315465',
'0131431543120654312032431543654',
'0203204320543120345654312032435465',
'012031203243120324315431203243154320',
'123123431234543120324315432654312345',
'123123431203243543265431203243154326',
'02032043120543120326543120324315432065432',
'123120324312032431543123456543120324315432',
'123123431203243154312032431543206543120324315432',
'01203120324312032431543120324315432065431203243154320',
'01203120324312032431543120324315432065431203243154320654312345',
'012031203243120324315431203243154320654312032431543206543123456']
chrs0=['0.1', '3.1', '10.1', '17.1c6.1', '17.1c14.1', '9.1',
'28.1c23.1', '28.1c5.1', '35.1', '38.1', '30.1', '24.1',
'49.1c46.1c45.1', '49.1c46.1c19.1', '37.1', '54.1c43.1', '53.1',
'56.1c51.1', '40.1', '49.1c45.2c13.1', '59.1c58.1', '26.1',
'54.1c32.1', '57.1c21.1', '41.1', '55.1c42.1', '53.1', '27.1',
'35.1', '48.1c47.1c18.1', '57.1c50.1', '59.1c58.1', '52.1',
'36.1', '56.1c20.1', '31.1', '25.1', '40.1', '48.1c47.1c44.1',
'55.1c33.1', '24.1', '39.1', '16.1c15.1', '29.1c22.1', '41.1',
'25.1', '34.1', '8.1', '34.1', '52.1', '29.1c4.1',
'48.1c44.2c12.1', '16.1c7.1', '11.1', '2.1', '1.1']
ch=chartable(W,chars=False)['charnames']
chars=[[[ch[int(k.split('.')[0])],int(k.split('.')[1])]
for k in l.split('c')] for l in chrs0]
if unpack==True:
f=[W.permtoword(x) for x in flatlist([starorbitinv(W,
W.wordtoperm([int(i) for i in r])) for r in reps])]
f.sort(key=(lambda x:len(x)))
else:
f=[[[int(i) for i in reps[r]],chars[r]] for r in range(len(reps))]
return f
elif typ[0]=='E' and rk==[0,1,2,3,4,5,6,7]:
reps=['', '7', '12', '020', '146', '0205', '1246', '14547', '232432',
'020454', '012046', '0204547', '0565765', '01204676', '12454654',
'131431676', '0120454654', '2324325432', '04546547654',
'23123431234', '124546547654', '131234312346', '123123431234',
'123123565765', '1231234312346', '0204546547654', '12312343123676',
'01204546547654', '231243123565432', '343543654376543',
'123123431234676', '123431235654312', '0120312032565765',
'0131431543165431', '13143123454312345', '01203435436543120',
'012031203243120326', '01203120324312032676',
'01203120324312032431', '12312343543126543123',
'232432543265432765432', '012031203243120324316',
'0131431543165431765431', '13124312354312346765431',
'12343123543123467654312', '01203120324312032431676',
'131431543123456543123456', '124543206543120324315465',
'123120343120324354312032431', '012034312354312034676543120',
'1312043120324543120324315437', '0131234312032435657654312034',
'1234312032543654312032431546', '0203204320543206543207654320',
'12312343123454312345654312345', '123123431234543123456543123456',
'123123431234546543123765431234',
'1231203431203243543120324315432',
'0131431543120654312032431543654',
'0120343254312036543120324315465',
'01203120324312032431543120324317',
'13143154316543123456765431234567',
'0203204320543120345654312032435465',
'0131431543165431234567654312034567',
'012031203243120324315431203243154320',
'123123431234543120324315432654312345',
'123120345431203243654312032431543265',
'012034312354312032431546765431203245',
'0120312032431203243154312032431543207',
'232431234543123456543123456765431234567',
'02032043120543120326543120324315432065432',
'12312034543654312034765431203243154326576',
'123123431234543123456543123456765431234567',
'123120324312032431543123456543120324315432',
'0203204312054312032654312032431543207654320',
'013143125431236543120324315432065432765431203456',
'123123431203243154312032431543206543120324315432',
'020320431203254312032431654312032431543207654320',
'123123431203454312032435465432076543120324315432',
'2312431235431234654312032431543206543176543123456',
'0131234312032435436543120347654312032431543206543176',
'01203120324312032431543120324315432065431203243154320',
'02032043205431206543120327654312032431543206543276543',
'012031203243120324315431236543123476543120324315432067',
'012034354312032431654312032431543206543176543120324315465',
'0120312032431203243154312032431565431234765431203243154320',
'0131431235431234654312032435467654312032431543206543176543',
'02031203243120324315431203243154320654312032431543206543123456',
'012031203243120324315431203243154320654312032431543206543123456',
'123120343120324354312032431543265431234576543120324315432654317',
'1231203431203243543120324315432654312345676543120324315432654317',
'12312343123454312032431565431203243154320654327654312032431543'+\
'265431',
'12312343120324354312365431203243154676543120324315432065431237'+\
'6543123',
'12312343120345431203243546543120324315432065431234576543120324'+\
'31543265431',
'01203120324312032431543120324315432065431234567654312032431543'+\
'206543123457',
'02032043205431203265431203243156765431203243154320654312345676'+\
'54312032435465',
'12312343123454312345654312032431543206765431203243154320654312'+\
'345676543123456',
'01203120324312032431543120324316543120324315432654317654312032'+\
'4315432065431234',
'12312034312032435431203243154326543120324315432065431234576543'+\
'12032431543265431',
'01203120324312032431543120324315432065431203243154326543176543'+\
'1203243154320654312345',
'12312032431203243154312032431543206543120324315432076543120324'+\
'315432065431234576543120324315432',
'12312343123454312032431565431203243154320654327654312032431543'+\
'2065431234567654312032431543265431',
'12312343120324315431203243154320654312032431543206543123456765'+\
'43120324315432065431234576543120324315432',
'01203120324312032431543120324315432065431203243154320654312345'+\
'6765431203243154320654312345765431203243154320',
'01203120324312032431543120324315432065431203243154320654312345'+\
'676543120324315432065431234567654312032431543206543123456',
'01203120324312032431543120324315432065431203243154320654312345'+\
'6765431203243154320654312345676543120324315432065431234567']
chrs0=['0.1', '67.1', '4.1', '71.1c2.1', '71.1c9.1', '73.1c14.1',
'14.1c7.1', '80.1', '23.1', '28.1c17.1', '76.1c28.1',
'92.1c78.1c39.1', '92.1c85.1c39.1', '42.1c36.1c12.1',
'44.1c42.1c36.1', '99.1', '90.1c50.1', '88.1c53.1', '104.1c61.1',
'92.1c85.2c69.1', '101.1c63.1', '44.2c42.1c19.1', '21.1',
'63.1c31.1', '96.1c26.1', '108.1', '83.1c50.1', '56.1', '99.1',
'110.1c59.1', '106.1', '80.1',
'103.1c87.1c82.1c52.1c49.1c46.1c16.1',
'103.2c98.1c87.1c58.1c55.1c52.1c49.1c46.1c41.1', '96.1c47.1',
'104.1c61.1', '65.1', '103.1c98.1c82.1c58.1c52.1c49.1c46.1c25.1',
'38.1', '53.1c34.1', '107.1', '111.1c60.1', '57.1', '106.1',
'99.1', '109.1', '103.2c98.2c58.2c55.2c52.1c49.1c41.1c33.1c30.1',
'90.1c50.1', '110.1c94.1', '99.1',
'103.1c98.2c75.1c58.2c55.1c52.1c46.1c33.1c25.1', '101.1c63.1',
'76.1c28.1', '91.1c51.1', '111.1c95.1', '54.1c35.1',
'103.1c98.1c82.1c58.1c55.1c52.1c49.2c30.1c11.1', '97.1c48.1',
'107.1', '108.1', '105.1c62.1', '102.1c64.1', '66.1',
'102.1c64.1', '22.1', '66.1', '65.1', '90.1c50.1',
'93.1c79.1c40.1', '100.1', '97.1c27.1', '108.1', '77.1c29.1',
'103.1c98.2c75.1c58.3c55.3c52.1c33.3c30.2c6.1', '109.1', '57.1',
'89.1c54.1', '105.1c62.1', '91.1c51.1', '109.1', '56.1',
'93.1c86.1c40.1', '100.1', '64.1c32.1', '106.1', '84.1c51.1',
'91.1c51.1', '24.1', '72.1c10.1', '100.1', '77.1c29.1',
'45.1c43.1c37.1', '107.1', '100.1', '29.1c18.1', '43.1c37.1c13.1',
'81.1', '45.2c43.1c20.1', '81.1', '74.1c15.1', '93.1c86.2c70.1',
'15.1c8.1', '72.1c3.1', '5.1', '68.1', '1.1']
ch=chartable(W,chars=False)['charnames']
chars=[[[ch[int(k.split('.')[0])],int(k.split('.')[1])]
for k in l.split('c')] for l in chrs0]
if unpack==True:
f=[W.permtoword(x) for x in flatlist([starorbitinv(W,
W.wordtoperm([int(i) for i in r])) for r in reps])]
f.sort(key=(lambda x:len(x)))
else:
f=[[[int(i) for i in reps[r]],chars[r]] for r in range(len(reps))]
return f
elif typ[0]=='I' and rk==[0,1]:
m=int(typ[1:])
if m%2==1:
if poids[0]>0:
w0=[0]
for i in range((m-1)//2):
w0.extend([1,0])
return [[], [0], [1], w0]
else:
print('#W Sorry, not yet implemented')
return False
else:
w1=[]
for i in range((m-2)//2):
w1.extend([0,1])
if poids[0]==poids[1] and poids[0]>0:
return [[], [0], [1], w1+[0,1]]
elif poids[0]>poids[1] and poids[1]>0:
return [[],[0],[1],[1,0,1],w1+[0],w1+[0,1]]
elif poids[0]0:
return [[],[0],[1],[0,1,0],[1]+w1,w1+[0,1]]
else:
print('#W Sorry, not yet implemented')
return False
else:
return False
#F precells
def precells(W,lw):
"""returns the partition of a set of elements into pieces which
are unions of left cells (in the equal parameter case) and which
are as small as possible with respect to
(1) the induction of cells from parabolic subgroups and
(2) Vogan's generalised tau-invariant.
For example, in type A_n (any n) or E_6, this yields exactly the
partition into left cells.
>>> W=coxeter('E',6)
>>> len(precells(W,involutions(W))
652
(This is the number of left cells in type E_6.)
See also 'klcells', 'distinguishedinvolutions' and 'gentauorbits'.
"""
p=['' for w in lw]
for s in W.rank:
J=list(W.rank)
J.remove(s)
H=reflectionsubgroup(W,J)
c1=[[W.wordtocoxelm([J[i] for i in w]) for w in l]
for l in klcells(H,1,v)[0]]
for i in range(len(lw)):
pw=lw[i]
h=permmult(redinrightcoset(W,H,perminverse(pw)[:len(W.rank)]),pw)
j=0
while not h in c1[j]:
j+=1
p[i]+=str(j)+'.'
reps=set(p)
lprint('#I '+str(len(p))+' : '+str(len(reps))+' ---> ')
np=[[lw[i] for i in range(len(lw)) if p[i]==r] for r in reps]
if len(W.cartantype)==1 and (W.cartantype[0][1]==list(W.rank) and
W.cartantype[0][0] in ['E','F','H','I']):
distinv=[W.wordtoperm(x) for x in libdistinv(W,1)]
else:
distinv=[W.wordtoperm(x) for x in distinguishedinvolutions(W,1)[0]]
res,npi=[],[]
for l in range(len(np)):
if len([x for x in np[l] if x in distinv])==1:
res.append(np[l])
npi.append(0)
else:
npi.append(1)
np=[np[l] for l in range(len(np)) if npi[l]==1]
lprint(' '+str(len(np))+' ---> ')
nonc=0
for l in range(len(np)):
if l%100==0:
lprint('.')
g=gentauorbits(W,np[l],pr=False)
res.extend(g)
for lg in g:
if len([x for x in lg if x in distinv])>1:
nonc+=1
lprint(' '+str(len(res))+' ('+str(nonc)+')\n')
return [[''.join([str(i) for i in W.permtoword(x)]) for x in l ]
for l in res]
##########################################################################
##
#Y Section 5: Tests
##
#F timer
def timer(func,*pargs,**kargs):
"""returns the result of applying a function and prints the time used
in seconds. (Taken from M. Lutz's "Learning Python" book.)
>>> t=timer(klcells,coxeter("F",4),1,v)
#I 72 left cells (29 non-equivalent)
1.02
"""
import time
start=time.clock()
ret=func(*pargs,**kargs)
elapsed=time.clock()-start
print(elapsed)
return ret
#F checksh
def checksh(W,paramL):
"""checks if the relation characterising the Schur elements is true;
see the help to 'schurelms'. (This is a good test for various
functions: 'heckechartable', 'schurelms', 'lpol', 'zeta5', ...;
it does not yet work for type I_2(m), n>7, because some operations
for the general cyclotomic arithmetic are not implemented.)
"""
p=lcmschurelms(W,paramL)
if type(paramL)==type([]):
vs=paramL[:]
else:
vs=len(W.rank)*[paramL]
gd=[divmod(p,s)[0] for s in schurelms(W,vs)]
ti=heckechartable(W,vs)['irreducibles']
res=[sum(gd[i]*ti[i][j] for i in range(len(gd))) for j in range(len(gd))]
return res[0]==p and all(i==0 for i in res[1:len(gd)])
#F test
def test():
"""runs a test suite.
"""
lprint('# ==> Should finish in less than 1 minute CPU time\n')
v=lpol([1],1,'v')
somechecks=[]
# test all cartan types (finite and affine)
W=coxeter('A',1);
chartable(W)
W=coxeter('A',2);
chartable(W)
W=coxeter('A',3)
chartable(W)
somechecks.append(checksh(W,v))
W=coxeter('A',4)
t=chartable(W)
somechecks.append(ainvariants(W,1)==t['a'])
somechecks.append(checksh(W,v))
W=coxeter('B',2)
chartable(W)
somechecks.append(checksh(W,[v**2,v]))
W=coxeter('B',3)
chartable(W)
somechecks.append(checksh(W,[v**2,v,v]))
somechecks.append(checksh(W,[v**2,v**3,v**3]))
W=coxeter('B',4)
somechecks.append(checksh(W,v))
t=chartable(W)
somechecks.append(ainvariants(W,1)==t['a'])
lprint(str(t['a'])+'\n')
W=coxeter('B',5)
chartable(W)
W=coxeter('C',2)
somechecks.append(checksh(W,[v**2,v]))
chartable(W)
W=coxeter('C',3)
chartable(W)
W=coxeter('C',4)
t=chartable(W)
somechecks.append(checksh(W,v))
somechecks.append(ainvariants(W,1)==t['a'])
W=coxeter('C',5)
chartable(W)
W=coxeter('D',4)
somechecks.append(checksh(W,v))
t=chartable(W)
somechecks.append(ainvariants(W,1)==t['a'])
W=coxeter('D',5)
t=chartable(W)
#somechecks.append(ainvariants(W,1)==t['a'])
W=coxeter('D',6)
W=coxeter('D',7)
W=coxeter('D',8)
W=coxeter('G',2)
chartable(W)
somechecks.append(checksh(W,[v**2,v]))
W=coxeter('I5',2)
chartable(W)
somechecks.append(checksh(W,v))
somechecks.append(sum(x[1] for x in specialpieces(W,v))==v**(2*W.N))
W=coxeter('F',4)
t=chartable(W)
somechecks.append(ainvariants(W,1)==t['a'])
somechecks.append(checksh(W,[v**2,v**2,v,v]))
somechecks.append(sum(x[1] for x in specialpieces(W,v))==v**(2*W.N))
W=coxeter('I5',2)
chartable(W)
W=coxeter('H',3)
chartable(W)
somechecks.append(checksh(W,v))
W=coxeter('H',4)
chartable(W)
W=coxeter('E',6)
t=chartable(W)
#somechecks.append(ainvariants(W,1)==t['a'])
somechecks.append(checksh(W,v))
W=coxeter('E',7)
chartable(W)
W=coxeter('E',8)
chartable(W)
W=coxeter(affinecartanmat("A",1))
W=coxeter(affinecartanmat("A",2))
W=coxeter(affinecartanmat("A",3))
W=coxeter(affinecartanmat("A",4))
W=coxeter(affinecartanmat("B",3))
W=coxeter(affinecartanmat("B",4))
W=coxeter(affinecartanmat("B",5))
W=coxeter(affinecartanmat("C",2))
W=coxeter(affinecartanmat("C",3))
W=coxeter(affinecartanmat("C",4))
W=coxeter(affinecartanmat("D",4))
W=coxeter(affinecartanmat("D",5))
W=coxeter(affinecartanmat("D",6))
W=coxeter(affinecartanmat("G",2))
W=coxeter(affinecartanmat("F",4))
W=coxeter(affinecartanmat("E",6))
W=coxeter(affinecartanmat("E",7))
W=coxeter(affinecartanmat("E",8))
# mixed finite and affine type:
W=coxeter([[2,0,-3,0,0,0],[0,2,-1,0,0,0],[-1,-1,2,0,0,0],
[0,0,0,2,-1,0],[0,0,0,-1,2,-1],[0,0,0,0,-1,2]])
lprint(str(W.cartantype)+'\n')
lprint(str(W.cartanname)+'\n')
# check all functions on this example:
W=coxeter([[2,0,0,0,0,0,0,0,0,0,0,-1,0,0,-2],
[0,2,0,0,0,0,0,0,-1,0,0,0,-1,-1,0],
[0,0,2,0,0,0,0,0,0,-1,0,0,0,0,0],
[0,0,0,2,0,0,0,0,0,0,0,0,0,0,-1],
[0,0,0,0,2,0,0,0,0,-1,0,0,0,0,0],
[0,0,0,0,0,2,-1,0,0,0,-1,0,0,0,0],
[0,0,0,0,0,-1,2,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,2,0,-1,-1,0,0,0,0],
[0,-1,0,0,0,0,0,0,2,0,0,0,0,0,0],
[0,0,-1,0,-1,0,0,-1,0,2,0,0,0,0,0],
[0,0,0,0,0,-1,0,-1,0,0,2,0,0,0,0],
[-1,0,0,0,0,0,0,0,0,0,0,2,0,0,0],
[0,-1,0,0,0,0,0,0,0,0,0,0,2,0,0],
[0,-1,0,0,0,0,0,0,0,0,0,0,0,2,0],
[-1,0,0,-1,0,0,0,0,0,0,0,0,0,0,2]])
lprint(str(W.cartantype)+'\n')
lprint(str(W.cartanname)+'\n')
lprint(str(W.order)+'\n')
somechecks.append(W.cartan==cartantypetomat(cartantotype(W.cartan)))
c=conjugacyclasses(W);
r=reflections(W)
l=longestperm(W)
a=allelmchain(W)
H=reflectionsubgroup(W,[0,1,2,3,4,5,6,7,W.N-1])
lH=H.permtoword(longestperm(H))
lW=H.reducedword(lH,W);
W=coxeter([[2,0,-1,0,0,0,0,0,0],[0,2,0,0,-1,0,0,0,0],
[-2,0,2,0,0,0,0,0,0],[0,0,0,2,-1,0,-1,0,0],[0,-1,0,-1,2,0,0,-1,0],
[0,0,0,0,0,2,0,0,-1],[0,0,0,-1,0,0,2,0,0],[0,0,0,0,-1,0,0,2,0],
[0,0,0,0,0,-3,0,0,2]])
lprint(str(W.cartantype)+'\n')
lprint(str(W.cartanname)+'\n')
lprint(str(W.order)+'\n')
somechecks.append(W.cartan==cartantypetomat(cartantotype(W.cartan)))
cl=conjugacyclasses(W)
H=reflectionsubgroup(W,[0,1,2,3,4,5,6,7,W.N-1])
# test embedding of reflections
W=coxeter("F",4)
c=coxeterclasses(W)
rw=[W.coxelmtoword(r) for r in reflections(W)]
for r in range(W.N):
H=reflectionsubgroup(W,[r])
somechecks.append(rw[r]==H.reducedword([0],W))
somechecks.append(ainvariants(W,1)==chartable(W)['a'])
W=coxeter(affinecartanmat("F",4))
a=[[W.mattoword(m) for m in l] for l in allmats(W,3)]
W=coxeter("E",8)
c=coxeterclasses(W)
e=allelmchain(W)
W.coxelmlength(longestperm(W))
H=reflectionsubgroup(W,[0,1,2,3,4,5,6])
f=fusionconjugacyclasses(H,W)
t=inductiontable(H,W)
lprint('# ==> looks good ... \n')
W=coxeter("H",4)
f=lusztigfamilies(W,1)
somechecks.append(ainvariants(W,1)==chartable(W)['a'])
c=coxeterclasses(W)
c1=conjugacyclasses(W)
e=allelmchain(W)
d=redleftcosetreps(W,[0,1,2])
#ca=redleftcosetreps(W)
#wa=[W.coxelmtoword(c) for c in ca]
#ls=[W.coxelmlength(c) for c in ca] # does not work
lprint('# ==> seems ok ! ... \n')
#somechecks.append(ca==[W.wordtocoxelm(w) for w in wa])
W=coxeter("B",3)
lc=[]
for i in range(4):
kl=klpolynomials(W,[i,1,1,1],v)
lc.append(len(kl['lcells']))
somechecks.append(lc==[10,14,16,20])
k=[i.matrices(True) for i in klcells(W,1,v)[1]]
somechecks.append(all([type(m)==type([]) for m in k])==True)
k=[i.matrices(True) for i in klcells(W,[3,2,2],v)]
somechecks.append(all([type(m)==type([]) for m in k])==True)
W=coxeter("I14",2)
k=[i.matrices(True) for i in klcells(W,1,v)[1]]
somechecks.append(all([type(m)==type([]) for m in k])==True)
k=[i.matrices(True) for i in klcells(W,[5,3],v)]
somechecks.append(all([type(m)==type([]) for m in k])==True)
# test all conversions:
W=coxeter("H",3)
gh3=[[[]],[[0],[0,1,0]],[[0,1,0,2,1,0]],[[0,1,0,1,2,1,0,1,0],[0,1,0,1,2,
1,0,1,0,2,1,0]],[[0,1,0,1,0]],[[0,1,0,1,0,2,1,0,1,0],[0,1,0,1,0,2,1,0,
1,0,2,1,0,1]],[[0,1,0,1,0,2,1,0,1,0,2,1,0,1,2]],[[0,2]],[[0,1,2,1,0],
[0,1,2,1,0,1,0,2]],[[0,2,1,0,1,0,2]],[[0,1,0,2,1,0,1,0,2,1,0]],[[0,1,
2,1,0,1,0,2,1,0,1,2],[0,1,0,1,2,1,0,1,0,2,1,0,1,2]],[[1],[1,0,1]],[[1,
0,2,1]],[[1,0,1,2,1,0,1],[1,0,1,2,1,0,1,0,2,1]],[[1,0,1,0,2,1,0,1]],
[[1,0,1,0,2,1,0,1,0,2,1,0,1]],[[1,2,1],[1,2,1,0,1,2]],[[1,0,2,1,0,1,0,
2,1]],[[1,0,2,1,0,1,0,2,1,0,1,2],[1,0,1,0,2,1,0,1,0,2,1,0,1,2]],[[2],
[2,1,0,1,2]],[[2,1,0,1,0,2,1,0,1,2]]]
cl=allclasspolynomials(W,v**2)
l=[]
for x in gh3:
y=leftcellleadingcoeffs(W,1,v,x,cl)
l.append(y['ti'])
somechecks.append(l==[[[('1_r',), [1]]], [[("3_s'",), [1, ir5]],
[("overline{3}_s'",), [1, 1-ir5]]], [[('5_r',), [1]]],
[[("4_r'",), [1, 1]], [('4_r',), [1, -1]]], [[("5_r'",), [1]]],
[[('3_s',), [ir5, 1]], [('overline{3}_s',), [1-ir5, 1]]],
[[("1_r'",), [1]]], [[('5_r',), [1]]], [[("4_r'",), [1, 1]],
[('4_r',), [1, -1]]], [[("5_r'",), [1]]], [[("5_r'",), [1]]],
[[('3_s',), [ir5, 1]], [('overline{3}_s',), [1-ir5, 1]]],
[[("3_s'",), [1, ir5]], [("overline{3}_s'",), [1, 1-ir5]]],
[[('5_r',), [1]]], [[("4_r'",), [1, 1]], [('4_r',), [1, -1]]],
[[('5_r',), [1]]], [[("5_r'",), [1]]], [[("4_r'",), [1, 1]],
[('4_r',), [1, -1]]], [[("5_r'",), [1]]], [[('3_s',), [ir5, 1]],
[('overline{3}_s',), [1-ir5, 1]]], [[("3_s'",), [1, ir5]],
[("overline{3}_s'",), [1, 1-ir5]]], [[('5_r',), [1]]]])
c=allcellsleadingcoeffs(W,1,v)
c=constructible(W,1)
ah=redleftcosetreps(W)
ap=[W.coxelmtoperm(c) for c in ah]
aw=[W.coxelmtoword(c) for c in ah]
am=[W.coxelmtomat(c) for c in ah]
alc=[W.coxelmlength(c) for c in ah]
alm=[W.matlength(m) for m in am]
somechecks.append(alc==[len(w) for w in aw])
somechecks.append(alc==alm)
somechecks.append(ah==[c[:len(W.rank)] for c in ap])
somechecks.append(am==[W.coxelmtomat(c) for c in ah])
somechecks.append(aw==[W.coxelmtoword(c) for c in ah])
somechecks.append(aw==[W.permtoword(c) for c in ap])
somechecks.append(ap==[W.coxelmtoperm(c) for c in ah])
somechecks.append(ap==[W.mattoperm(m) for m in am])
somechecks.append(ah==[W.mattocoxelm(m) for m in am])
somechecks.append(aw==[W.mattoword(m) for m in am])
somechecks.append(ah==[W.wordtocoxelm(w) for w in aw])
somechecks.append(am==[W.wordtomat(w) for w in aw])
somechecks.append(ap==[W.wordtoperm(w) for w in aw])
somechecks.append(aw==[W.reducedword(w,W) for w in aw])
aa=allwords(W)
somechecks.append(set([w in aa for w in aw])==set([True]))
aa=[W.stringtoword(x) for x in allwordstrings(W)]
somechecks.append(set([w in aa for w in aw])==set([True]))
w=W.wordtoperm([0,1,0,2]);
b1=list(filter(lambda x: bruhatcoxelm(W,x,w),ah))
b1a=list(filter(lambda x: bruhat(W,x,w),ah))
elms=[W.coxelmtoperm(c) for c in ah]
b2=list(filter(lambda x: bruhatperm(W,x,w),elms))
b2a=list(filter(lambda x: bruhat(W,x,w),elms))
mats=[W.coxelmtomat(c) for c in ah]
b3a=list(filter(lambda x: bruhat(W,x,w),elms))
somechecks.append([W.coxelmtoword(p)
for p in b2]==[W.coxelmtoword(p) for p in b1])
somechecks.append([W.coxelmtoword(p)
for p in b2a]==[W.coxelmtoword(p) for p in b1a])
W=coxeter('F',4)
f=lusztigfamilies(W,0)
f=lusztigfamilies(W,1)
f=lusztigfamilies(W,[3,3,2,2])
f=lusztigfamilies(W,[2,2,1,1])
c=constructible(W,[2,2,1,1])
f=lusztigfamilies(W,[3,3,1,1])
lprint('#I ')
p=[3,2,1,0]
nc=[[W.cartan[i][j] for j in p] for i in p]
somechecks.append(nc==cartantypetomat(cartantotype(nc)))
aa=redleftcosetreps(W)
w1=[0,2,1,0,2,3,2,1,0,2,1,2,3,2,1,0,2,1,2,3]
lb4=[]
for l in range(1,21):
l1=len(list(filter(lambda x:bruhatperm(W,W.coxelmtoperm(x),
W.wordtoperm(w1[:l])),aa)))
lb4.append(l1)
lprint(str(l1)+' ')
lprint('\n#####################################')
lprint('\n# ==> ')
somechecks.append(lb4==[2,4,8,12,20,40,60,96,132,196,244,272,
396,456,508,680,720,828,912,972])
b5=list(filter(lambda x: W.coxelmlength(x)<=len(w1),aa))
somechecks.append(len(b5)==1122)
lprint(str(len(somechecks))+' true/false checks performed\n')
lprint('#####################################\n')
if False in somechecks:
lprint('# ==> !!! There are problems !!!\n')
return False
else:
lprint('# ==> Tests ok\n')
return True