Generating longer FC elements

1445 days ago by tixu6187

Question 1: Let (W,S,M) be a Coxeter system, let w be the reduced word of an FC element, and let s\in S. Under what conditions is sw still the reduced word of an FC element?

We'll split Question 1 into two questions. First, under what conditions is sw still reduced. This is easy, and the answer is 'if and only if s is not a left descent of w', which can be detected easily by our descent test. Second, if sw is still reduced, under what conditions does sw still represent an FC element? Throughout the rest of the summer, when we call a factorization w=xy 'reduced', we mean we have l(w)=l(x)+l(y) where l is the Coxeter length.


To answer the second question, let's set up some notation. Let w_1 be the beginning segment of w where all letters commute with s. For example, in our usual setup for type A, if s=3 and w= 1564732, then w_1=156. Note that we can easily obtain w_1 from w via a slicing operation, namely, w_1= w[:i] where i it the minimum index for which m(w[i],s) != 2.
Let's also recall that a convex chain in a poset P is an chain of elements x_1,x_2,...,x_k such that
(i) [the 'chain' condition] x_i < x_{i+1} for all i\in {1,...,k-1};
(ii)[the 'convex' condition] if some two elements x_i, x_j from the chain and some element x from the poset P satisfies x_i < x < x_j in the partial order, then x is itself in the chain, i.e., x \in {x_1,...,x_k}.
Finally, let's recall Lemma 4.1 from Stembridge's paper and use a left-side analog of that lemma, which says that if sw is still reduced but no longer represents an FC element, then there is a unique t\in S such that m(s,t)>2 and the heap H(w) of w contains a convex chain
(*) t_1 < s_1 < t_2 < s_2 <...
which has m(s,t)-1 elements in it, where for s_1 stands for the first (=leftmost) (occurrence of) t in the word w, s_1 is the first s in w, t_2 is the second t in w, etc. In fact the proof of the lemma says a bit more, namely, in the heap H(sw) of sw, the 'new' s, which we'll call s_0, must form a convex chain
(**) s_0 < (t_1 < s_1 < t_2 < s_2 <...)
with the chain in (*).


Proposition: Let w be the reduced word of an element and let s\in S. Suppose sw is still reduced. Let w_1 be as defined before, and let u_1 be the remaining part of w, so that w=w_1u_1. Let t be the first letter of u_1 (so m(s,t)\ge 3 by the definition of w_1). Then sw no longer represents an FC element if and only if the following conditions simultaneously hold:
    (1) t is a left descent of u_1.
    (2) s is a left descent of the result of removing the t of Step (1) from u_1; we'll call this result u_2. For example, if u_1 = 4732 and t=4, then u_2=732. By our setup, in this case the t from 1 would be the very first letter in u_1.
    (3) t is a left descent of the result of removing the s of Step (2) from u_2; we'll call this result u_3.
    ...
    (m-1) the appropriate element x from {s,t} (the thing we'd naturally get when alternating in s and t in these m-1 steps, depending on parity of m) is a left descent of the result of removing the descent in of Step (m-2) from u_{m-2}; we'll call this result u_{m-1}.
    
Proof: We've explained how the 'if' direction is easy, for if (1)--(m-1) all hold we can move the new s to the right until it's immediately left to the t from (1), then use (1)--(m-1) to successively move the left descents in steps (2)--(m-1) to the left to form a convex chain stst..., which implies that sw no longer expresses an FC element.
So it remains to prove the 'only if' direction. To do so we invoke Stembridge's lemma. If sw no longer represents an FC element, then we can find the convex chain t_1<s_1<t_2... as in the lemma. Let's rename the chain x_1, x_2,..., x_{m-2}, x_{m-1}, so that x_1 is t_1, x_2 is s_1, ... . We claim that
(a) if y is a letter which appears in the word w between x_1 and x_{m-2}, then y commutes with s and also with t;
(b) if y is a letter which appears in the word w between x_{m-2} and x_{m-1}, then y commutes with x_{m-1}.
Note that the claim certainly implies (1)--(m-1), with x_i sufficing as the left descent desired in Step (i) for each i.

The observation is easy to prove, too. If m(s,t)=3, (a) is vacuously true and we just need to show (b), i.e., that between x_1=t_1 and x_2=s_1 every letter y commutes with x_2, which is an s. If this is not the case, y would be an element in H(w) outside the chain s_0<t_1<s_1 with the property that s_0<x<s_1, contradicting convexity of the chain (**). Now assume m(s,t)>4. Then to check (a), note that there must be at least one s from the chain (**), say s_i, which appears before y in w and at least one s from (**), say s_j, which appears after y in w, so y must commute with s, for otherwise we'd get the same violation of convexity with the chain s_i-y-s_j. Similarly, there's at least one t from (**) before y and after y, so y must commute with t, proving (a). Finally, to prove (b), note that if y doesn't commute with x_{m-1} then it also doesn't commute with x_{m-3}, whence the chain x_{m-3}-y-x_{m-1} would violate the convexity of (**), contradiction. The proof is now complete (though you can probably simplify this last paragraph a bit).
 
   

TODO: Write a function still_reduced_fc(s,w,M) to test if sw is still reduced using the criteria from the above discussion.

def commutes_through(s, w, M): r""" Returns if the letter s commutes with every letter in w INPUT: - ``s`` -- integer; the generator letter to test commutation against. - ``w`` -- integer tuple; the word to test commutation against. - ``M`` -- coxeter matrix; the matrix representing the coxeter group that s and w correspond to. OUTPUT: boolean, whether s commutes with every letter in w EXAMPLES: sage: M = CoxeterMatrix(['A',4]) sage: commutes_through(1, (2,3), M) False sage: commutes_through(1, (3,4), M) True """ for t in w: if M[s,t] != 2: return False return True 
       
def still_reduced_FC(s, w, M): r""" Returns whether the word w is still reduced and fully commutative after prepending the letter s. w is assumed to be reduced and fully commutative. INPUT: - ``s`` -- integer; the generator letter to be prepended to w. - ``w`` -- integer tuple; the original reduced FC word to prepend s to. - ``M`` -- coxeter matrix; the matrix representing the Coxeter Group that s and w are elements of. OUTPUT: boolean, whether sw is reduced and FC or not. EXAMPLES: sage: M = CoxeterMatrix(['A',4]) sage: still_reduced_FC(1, (2,1), M) false sage: still_reduced_FC(1, (3,1), M) false sage: still_reduced_FC(1, (2,3), M) true """ def split(w, loc): r""" Splits w into the subword strictly before loc and the subword strictly after loc. Helper function for still_reduced_FC. """ return w[:loc], w[loc+1:] if ld_check(s,w,M): return False loc = -1 t = -1 for i,l in enumerate(w): if M[s,l] != 2: t = l loc = i break if t == -1: return True x = w[loc + 1:] p1 = () # p2 = () for _ in range(M[s,t]-2): try: loc = x.index(s) except: return True p1 = p2 p2, x = split(x, loc) if not commutes_through(s, p1+p2, M): return True s,t = t,s return False 
       
# Left descent check from last time def is_left_descent_fc(s, w, m): r""" Determine if a letter is a left descent of a reduced FC word w. INPUT: - ``s`` -- integer; the letter to test - ``w`` -- tuple; a reduced FC word (== reduced word of an FC element) - ``m`` -- CoxeterMatrix; the matrix of the Coxeter group to which w belongs. OUTPUT: Boolean; whether or not s is a left descent of w. EXAMPLES: A basic usage :: sage: ld_check(3, (1, 4, 3, 5, 4, 2), CoxeterMatrix(['A', 5])) False sage: ld_check(4, (1, 4, 3, 5, 4, 2), CoxeterMatrix(['A', 5])) True """ i = w.index(s) if s in w else None if i is None: return False else: return not any(m[x,s] >= 3 for x in w[:i]) def still_reduced_FC_b(s, w, m): r""" Returns whether the word sw is still reduced and fully commutative given a reduced FC word w. This version is a more direct translation of the criterion discussed at the beginning of this notebook. INPUT: - ``s`` -- integer; the generator letter to be prepended to w. - ``w`` -- integer tuple; the original reduced FC word to prepend s to. - ``M`` -- CoxeterMatrix; the matrix representing the Coxeter Group that s and w are elements of. OUTPUT: boolean, whether sw is reduced and FC or not. EXAMPLES: Some basic uses :: sage: M = CoxeterMatrix(['A',4]) sage: still_reduced_FC_b(3, (2, 4, 1, 3, 2), CoxeterMatrix(['A', 4])) True sage: still_reduced_FC_b(2, (1,2), CoxeterMatrtix(['A', 4]) False """ if is_left_descent_fc(s, w, m): return False # Find the first letter in w that doesn't commute with s. (j, t) = next(((i, x) for (i, x) in enumerate(w) if m[s,x] >= 3), (None, None)) if j is None: return True u = list(w[j:]) for i in range(m[s,t] - 1): letter = t if i % 2 == 0 else s if is_left_descent_fc(letter, u, m): u.remove(letter) else: return True return False 
       
 
       
def fc_elems(M): r""" Generates the set of reduced fully commutative elements of the Coxeter Group corresponding to the matrix M, in canonical form. The group is expected to be FC finite. Violation of this assumption will cause an infinite loop. INPUT: - ``M`` -- coxeter matrix; the matrix representing the Coxeter Group from which elements are generated. OUTPUT: a python set containing the canonical forms of all reduced FC elements in the group. EXAMPLES: sage: fc_elems(CoxeterMatrix(['A',3])) sage: fc_elems(CoxeterMatrix(['B',9])) """ n = M.rank() can_words = {()} recent_words = {()} while True: new_words = set() for w in recent_words: for s in range(1,n+1): if still_reduced_FC(s, w, M): new_words.add(can_word2((s,)+w, M)) if len(new_words) == 0: break can_words.update(new_words) recent_words = new_words return can_words 
       
fc_elems(CoxeterMatrix(['A',3])) 
       
Traceback (click to the left of this block for traceback)
...
NameError: global name 'ld_check' is not defined
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "_sage_input_9.py", line 10, in <module>
    exec compile(u'open("___code___.py","w").write("# -*- coding: utf-8 -*-\\n" + _support_.preparse_worksheet_cell(base64.b64decode("ZmNfZWxlbXMoQ294ZXRlck1hdHJpeChbJ0EnLDNdKSk="),globals())+"\\n"); execfile(os.path.abspath("___code___.py"))
  File "", line 1, in <module>
    
  File "/tmp/tmpUMyORb/___code___.py", line 3, in <module>
    exec compile(u"fc_elems(CoxeterMatrix(['A',_sage_const_3 ]))" + '\n', '', 'single')
  File "", line 1, in <module>
    
  File "/tmp/tmp1eTAEo/___code___.py", line 28, in fc_elems
    if still_reduced_FC(s, w, M):
  File "/tmp/tmpxS_ALs/___code___.py", line 40, in still_reduced_FC
    if ld_check(s,w,M):
NameError: global name 'ld_check' is not defined