def _setup_tableaux(self): if self.is_symplectic: z = Permutation.get_fpf_grassmannian(*self.mu) ell = z.fpf_involution_length + self.excess words = [ w for w in z.get_symplectic_hecke_words(length_bound=ell) if len(w) == ell ] else: z = Permutation.get_inv_grassmannian(*self.mu) ell = z.involution_length + self.excess words = [ w for w in z.get_involution_hecke_words(length_bound=ell) if len(w) == ell ] self.tableaux = [] self.arrays = [] for word in words: for f in WordCrystalGenerator.get_increasing_factorizations( word, self.rank, not self.multisetvalued): w, i = WordCrystalGenerator.factorization_tuple_to_array(f) p, q = self.forward(w, i) assert self.insertion_tableau is None or self.insertion_tableau == p self.insertion_tableau = p self.tableaux.append(q) # a = Tableau() for j in range(len(w)): a = a.add(2, j + 1, w[j]) a = a.add(1, j + 1, i[j]) self.arrays.append(a)
def test_atoms(): y = Permutation(3, 4, 1, 2, 7, 9, 5, 10, 6, 8, 12, 11) assert y.get_min_atom() in y.get_atoms() y = Permutation(3, 4, 1, 2) assert Permutation(3, 1, 4, 2).inverse() in y.get_atoms() assert Permutation(3, 1, 4, 2) not in y.get_atoms()
def representative_m(mu): a = 0 w = Permutation() for b in Partition.transpose(mu): for i in range(b // 2): w *= Permutation.transposition(a + i + 1, a + b - i) a += b return w
def test_descents(): w = Permutation(3, 5, -6, 1, -2, 4) assert w.right_descent_set == {2, 4} assert w.left_descent_set == {1, 4, 5} w = Permutation.identity() assert w.right_descent_set == set() assert w.left_descent_set == set()
def test_transitions_finite(): n = 4 for w in Permutation.all(n): for r in range(1, n + 1): phi_plus = {w * Permutation.transposition(r, j) for j in w.upper_transitions(r)} phi_minus = {w * Permutation.transposition(i, r) for i in w.lower_transitions(r)} assert all(w in v.bruhat_covers() for v in phi_plus) assert all(w in v.bruhat_covers() for v in phi_minus)
def test_fpf_transitions_simple(): y = Permutation(2, 1, 4, 3) p = 1 q = 2 def t(i, j): return Permutation.transposition(i, j) phi_plus = {t(q, j) * y * t(q, j) for j in y.upper_fpf_involution_transitions(q)} assert phi_plus == {Permutation(3, 4, 1, 2)}
def test_multiplication(): s = Permutation.s_i(1) t = Permutation.s_i(2) u = Permutation.s_i(3) assert s * s == Permutation.identity() assert s % s == s assert s * t * u == s % t % u assert s * t * s * t == t * s assert s % t % s % t == s * t * s == t * s * t
def test_involution_words(): w = Permutation.identity() assert set(w.get_involution_words()) == {tuple()} assert set(w.involution_words) == {tuple()} r = Permutation.s_i(1) s = Permutation.s_i(2) t = Permutation.s_i(3) # can only access this property for affine permutations which are involutions try: set((r * s).involution_words) assert False except: pass assert set(r.involution_words) == {(1,)} assert set((s * r * s).involution_words) == {(1, 2), (2, 1)} assert set((t * s * r * s * t).involution_words) == {(1, 2, 3), (2, 1, 3), (2, 3, 1), (3, 2, 1)} n = 5 w = Permutation(*reversed(range(1, n + 1))) words = set(w.get_involution_words()) assert len(words) == 80 for e in words: v = Permutation.identity() for i in e: s = Permutation.s_i(i) v = s % v % s assert v == w
def test_transitions_all(): n = 4 for w in Permutation.all(n): for r in range(1, n + 1): phi_plus = {w * Permutation.transposition(r, j, n) for j in w.upper_transitions(r)} phi_minus = {w * Permutation.transposition(i, r, n) for i in w.lower_transitions(r)} assert all(w in v.bruhat_covers() for v in phi_plus) assert all(w in v.bruhat_covers() for v in phi_minus) print (w.get_reduced_word()) print(r) print([x.get_reduced_word() for x in phi_plus]) print([x.get_reduced_word() for x in phi_minus])
def test_inverse(): r = Permutation.s_i(1) s = Permutation.s_i(2) t = Permutation.s_i(3) assert r.inverse() == r assert (r * s).inverse() == s * r assert (r * s * t).inverse() == t * s * r assert (r * s * t * r).inverse() == r * t * s * r assert (r * s * t * r * s).inverse() == s * r * t * s * r assert (r * s * t * r * s * t).inverse() == t * s * r * t * s * r w = r * s * t * r * s * t assert w.inverse() == w**-1
def representative_n(mu): shape = {(i, j): (i, min(j, mu[i - 1] + 1 - j)) if j != (mu[i - 1] + 1 - j) else (2 * ((i + 1) // 2), j) for (i, j) in Partition.shape(mu)} word = [ shape[key] for key in sorted(shape, key=lambda ij: (ij[1], -ij[0])) ] pairs = defaultdict(list) for i, key in enumerate(word): pairs[key].append(i + 1) w = Permutation() for pair in pairs.values(): i, j = tuple(pair) w *= Permutation.transposition(i, j) return w
def des_n(pi): ans = set() for i in range(1, pi.rank): s = Permutation.s_i(i) if len(s * pi * s) >= len(pi): ans.add(i) return ans
def all(cls, n, k, l, decreasing=False): for w in Permutation.all(n): if w(n) == n: continue cg = cls(w.oneline, k, l, decreasing) if cg.edges: cg.generate()
def test_grothendieck(): n = 3 w = Permutation(4, 3, 2, 1) f = G(n, (3, 2, 1)) print(f) g = G(n, w) print(g) assert f == g
def test_grothendieck_s(): n = 3 w = Permutation(-1) f = GS(n, (1, )) print(f) g = GS(n, w) print(g) assert f == g
def test_irsk(n=6): for w in Permutation.involutions(n): p, q = rsk(w) t = irsk(w) print(w) print(p) print(q) print(t) assert t == p == q
def test_generate(): assert set(Permutation.fpf_involutions(2)) == {Permutation(2, 1)} assert set(Permutation.fpf_involutions(3)) == set() assert set(Permutation.fpf_involutions(4)) == { Permutation(2, 1, 4, 3), Permutation(3, 4, 1, 2), Permutation(4, 3, 2, 1), }
def test_bidirected_edges_m(n=8): for w in Permutation.fpf_involutions(n): p, _ = rsk(w) for y, i in set(bidirected_edges_m(w)): print(w, '<--', i, '-->', y) q, _ = rsk(y) print(p) print(q) print() assert q == dual_equivalence(p, i)
def test_get_molecules_n(n=8): ans = {} fpf = set(Permutation.fpf_involutions(n)) bns = get_molecules_n(n) for mu in bns: molecule = molecule_n(mu) fpf -= molecule ans[mu] = molecule assert len(fpf) == 0 assert all(ans[mu] == bns[mu] for mu in bns)
def print_involution_operation(n=6): for w in Permutation.involutions(n): tab = irsk(w).transpose() v = dual_irsk_inverse(tab) print(w, '->', v) print(tab) print() print() print() print()
def bidirected_edges_m(w): n = w.rank for i in range(2, n): s = Permutation.s_i(i - 1) t = Permutation.s_i(i) y = s * w * s if len(t * w * t) <= len(w) < len(y) < len(t * y * t): yield y, i if len(t * w * t) > len(w) > len(y) >= len(t * y * t): yield y, i y = t * w * t if len(s * w * s) <= len(w) < len(y) < len(s * y * s): yield y, i if len(s * w * s) > len(w) > len(y) >= len(s * y * s): yield y, i
def test_fpf_atoms(): y = Permutation(4, 3, 2, 1) s = Permutation.s_i(1) t = Permutation.s_i(2) u = Permutation.s_i(3) assert set(y.get_fpf_atoms()) == {t * s, t * u} n = 6 for w in Permutation.fpf_involutions(n): atoms = set() for word in w.get_fpf_involution_words(): atoms.add(Permutation.from_word(word)) assert atoms == set(w.get_fpf_atoms())
def bidirected_edges_n(w): assert w.is_fpf_involution() n = w.rank for i in range(2, n): s = Permutation.s_i(i - 1) t = Permutation.s_i(i) y = s * w * s if len(t * w * t) < len(w) < len(y) <= len(t * y * t): yield y, i if len(t * w * t) >= len(w) > len(y) > len(t * y * t): yield y, i y = t * w * t if len(s * w * s) < len(w) < len(y) <= len(s * y * s): yield y, i if len(s * w * s) >= len(w) > len(y) > len(s * y * s): yield y, i
def test_s_i(): assert Permutation.s_i(1) == Permutation(2, 1) assert Permutation.s_i(1) == Permutation(2, 1, 3) assert Permutation.s_i(2) == Permutation(1, 3, 2) w = Permutation.s_i(5) assert w(5) == 6 assert w(6) == 5 assert w(55) == 55 assert w(56) == 56
def __init__(self, oneline, k, length, decreasing=False): self.oneline = oneline self.words = [ w for w in Permutation(*oneline).get_hecke_words(length_bound=length) if len(w) == length ] self.num_factors = k self.max_length = length self._factorizations = None self._edges = None self._components = None self._decreasing = decreasing
def test_length(): w = Permutation.identity() assert len(w) == w.length == 0 assert w.involution_length == 0 r = Permutation.s_i(1) s = Permutation.s_i(2) t = Permutation.s_i(3) assert len(r) == 1 assert len(r * s) == 2 assert len(r * s * t) == 3 assert len(r * s * t * r) == 4 assert len(r * s * t * r * s) == 5 assert len(r * s * t * r * s * t) == 4 assert r.involution_length == 1 assert (s * r * s).involution_length == 2 assert (t * s * r * s * t).involution_length == 3 assert (r * t * s * r * s * t * r).involution_length == 2 assert (s * r * t * s * r * s * t * r * s).involution_length == 1 assert (t * s * r * t * s * r * s * t * r * s * t).involution_length == 1
def test_get_molecules_m(n=8): ans = {} inv = set(Permutation.fpf_involutions(n)) while inv: w = inv.pop() mu = rsk(w)[0].shape() molecule = molecule_m(mu) inv -= molecule assert mu not in ans ans[mu] = molecule bns = get_molecules_m(n) assert all(ans[mu] == bns[mu] for mu in bns) assert all(representative_m(mu) in bns[mu] for mu in bns)
def get_molecules_m(n, verbose=False): ans = {} nn = double_fac(n - 1) for i, w in enumerate(Permutation.fpf_involutions(n)): mu = rsk(w)[0].shape() if mu not in ans: ans[mu] = set() ans[mu].add(w) if verbose: a = nn - i if a % 100 == 0: print(a) return ans
def contain(self, sigma): decomposition = [] id = Permutation(list(range(self.n))) for i in range(len(self.base)): u = sigma.perm[self.base[i]] if u not in self.chain[i].orbit: return False, None h = ~self.chain[i].orbit[u] sigma = h * sigma decomposition.extend( self.chain[i].decomposition[self.chain[i].orbit[u]]) if sigma == id: return True, decomposition return False, None
def test_constructor(): try: Permutation(3) assert False except: pass # valid constructions w = Permutation(1, 2) assert all(w(i) == i for i in range(10)) w = Permutation(-2, 1) assert w(1) == -2 assert w(-1) == 2 assert w(0) == 0 assert w(2) == 1 assert w(-2) == -1 # input args must represent each congruence class exactly once try: Permutation(3, 2, 5, 15) assert False except: pass