def weyl_group_representation(self): r""" Transforms the weights in the LS path ``self`` to elements in the Weyl group. Each LS path can be written as the piecewise linear map: .. MATH:: \pi(t) = \sum_{u'=1}^{u-1} (\sigma_{u'} - \sigma_{u'-1}) \nu_{u'} + (t-\sigma_{u-1}) \nu_{u} for `0<\sigma_1<\sigma_2<\cdots<\sigma_s=1` and `\sigma_{u-1} \le t \le \sigma_{u}` and `1 \le u \le s`. Each weight `\nu_u` is also associated to a Weyl group element. This method returns the list of Weyl group elements associated to the `\nu_u` for `1\le u\le s`. EXAMPLES:: sage: R = RootSystem(['C',3,1]) sage: La = R.weight_space().basis() sage: LS = CrystalOfProjectedLevelZeroLSPaths(La[1]+La[3]) sage: b = LS.module_generators[0] sage: c = b.f(1).f(3).f(2) sage: c.weyl_group_representation() [s2*s3*s1, s3*s1] """ cartan = self.parent().weight.parent().cartan_type().classical() I = cartan.index_set() W = WeylGroup(cartan,prefix='s') return [W.from_reduced_word(x.to_dominant_chamber(index_set=I, reduced_word=True)[1]) for x in self.value]
def _homogeneous_generators_noncommutative_variables_zero_Hecke(self, r): r""" Returns the ``r^{th}`` homogeneous generator, viewed as an element inside the affine zero Hecke algebra. This is the sum of all cyclicly decreasing elements of order ``r``. INPUT: - ``r`` -- A positive integer OUTPUT: - An element of the affine zero Hecke algebra. EXAMPLES:: sage: g = SymmetricFunctions(QQ).kBoundedSubspace(3,1).K_kschur() sage: g._homogeneous_generators_noncommutative_variables_zero_Hecke(2) T1*T0 + T2*T0 + T0*T3 + T3*T2 + T3*T1 + T2*T1 sage: g._homogeneous_generators_noncommutative_variables_zero_Hecke(0) 1 """ from sage.combinat.root_system.weyl_group import WeylGroup from sage.algebras.iwahori_hecke_algebra import IwahoriHeckeAlgebraT W = WeylGroup(['A',self.k,1]) H = IwahoriHeckeAlgebraT(W, 0, base_ring = self.base_ring()) Hgens = H.algebra_generators() S = [w.reduced_word() for w in W.pieri_factors() if w.length() == r] return sum( (prod((Hgens[i] for i in w), 1) for w in S), 0 )
def __classcall_private__(cls, w, n, x=None, k=None): r""" Classcall to mend the input. TESTS:: sage: A = crystals.AffineFactorization([[3,1],[1]], 4, k=3); A Crystal on affine factorizations of type A3 associated to s3*s2*s1 sage: AC = crystals.AffineFactorization([Core([4,1],4),Core([1],4)], 4, k=3) sage: AC is A True """ if k is not None: from sage.combinat.core import Core from sage.combinat.partition import Partition W = WeylGroup(['A', k, 1], prefix='s') if isinstance(w[0], Core): w = [w[0].to_bounded_partition(), w[1].to_bounded_partition()] else: w = [Partition(w[0]), Partition(w[1])] w0 = W.from_reduced_word(w[0].from_kbounded_to_reduced_word(k)) w1 = W.from_reduced_word(w[1].from_kbounded_to_reduced_word(k)) w = w0 * (w1.inverse()) return super(AffineFactorizationCrystal, cls).__classcall__(cls, w, n, x)
def __classcall_private__(cls, W, q1, q2=-1, base_ring=None, prefix="T"): """ TESTS:: sage: H = IwahoriHeckeAlgebraT("A2", 1) sage: H.coxeter_group() == WeylGroup("A2") True sage: H.cartan_type() == CartanType("A2") True sage: H.base_ring() == ZZ True sage: H._q2 == -1 True """ if W not in CoxeterGroups(): W = WeylGroup(W) if base_ring is None: base_ring = q1.parent() q2 = base_ring(q2) return super(IwahoriHeckeAlgebraT, cls).__classcall__(cls, W, q1=q1, q2=q2, base_ring=base_ring, prefix=prefix)
def __init__(self, root_system, hot_start=None): self.root_system = root_system if hot_start is None: self.W = WeylGroup(root_system) self.weyl_dic = self._compute_weyl_dictionary() else: self.W = hot_start["W"] self.weyl_dic = hot_start["weyl_dic"] self.domain = self.W.domain() self.reduced_words = sorted(self.weyl_dic.keys(), key=len) self.simple_roots = self.domain.simple_roots().values() self.rank = len(self.simple_roots) self.rho = self.domain.rho() self.pos_roots = self.domain.positive_roots() # Matrix of all simple roots, for faster matrix solving self.simple_root_matrix = matrix( [list(s.to_vector()) for s in self.simple_roots]).transpose() self.action_dic, self.rho_action_dic = self.get_action_dic()
def weyl_group(self): """ Return the Weyl group of ``self``. EXAMPLES:: sage: L = LieAlgebra(QQ, cartan_type=['A', 2]) sage: L.weyl_group() Weyl Group of type ['A', 2] (as a matrix group acting on the ambient space) """ from sage.combinat.root_system.weyl_group import WeylGroup return WeylGroup(self._cartan_type)
def __classcall__(cls, W): """ EXAMPLES:: sage: from sage.monoids.j_trivial_monoids import * sage: HeckeMonoid(['A',3]).cardinality() 24 """ from sage.categories.coxeter_groups import CoxeterGroups if not W in CoxeterGroups(): from sage.combinat.root_system.weyl_group import WeylGroup W = WeylGroup(W) # CoxeterGroup(W) return super(PiMonoid, cls).__classcall__(cls, W)
def weyl_group(self, prefix=None): """ Returns the Weyl group associated to self. EXAMPLES:: sage: RootSystem(['F',4]).ambient_space().weyl_group() Weyl Group of type ['F', 4] (as a matrix group acting on the ambient space) sage: RootSystem(['F',4]).root_space().weyl_group() Weyl Group of type ['F', 4] (as a matrix group acting on the root space) """ from sage.combinat.root_system.weyl_group import WeylGroup return WeylGroup(self, prefix=prefix)
def maximal_elements(self): r""" The current algorithm uses the fact that the maximal Pieri factors of affine type A,B,C, or D either contain a finite Weyl group element, or contain an affine Weyl group element whose reflection by `s_0` gets a finite Weyl group element, and that either of these finite group elements will serve as a maximal element for finite Pieri factors. A better algorithm is desirable. EXAMPLES:: sage: PF = WeylGroup(['A',5]).pieri_factors() sage: [v.reduced_word() for v in PF.maximal_elements()] [[5, 4, 3, 2, 1]] sage: WeylGroup(['B',4]).pieri_factors().maximal_elements() [ [-1 0 0 0] [ 0 1 0 0] [ 0 0 1 0] [ 0 0 0 1] ] """ ct = self.W.cartan_type() # The following line may need to be changed when generalizing to more than types A and B. if ct.type() != 'A' and ct.type() != 'B': raise NotImplementedError( "currently only implemented for finite types A and B") ct_aff = ct.dual().affine() max_elts_affine = WeylGroup(ct_aff).pieri_factors().maximal_elements() for w in max_elts_affine: if 0 not in w.reduced_word(): return [self.W.from_reduced_word(w.reduced_word())] for w in max_elts_affine: if 0 not in w.apply_simple_reflection(0).reduced_word(): return [ self.W.from_reduced_word( w.apply_simple_reflection(0).reduced_word()) ]
def stanley_symm_poly_weight(self,w): r""" Weight used in computing Stanley symmetric polynomials of type `B`. The weight for finite type B is the number of components of the support of an element minus the number of occurrences of `n` in a reduced word. EXAMPLES:: sage: W = WeylGroup(['B',5]) sage: PF = W.pieri_factors() sage: PF.stanley_symm_poly_weight(W.from_reduced_word([3,1,5])) 2 sage: PF.stanley_symm_poly_weight(W.from_reduced_word([3,4,5])) 0 sage: PF.stanley_symm_poly_weight(W.from_reduced_word([1,2,3,4,5,4])) 0 """ r = w.reduced_word().count(self.W.n) return WeylGroup(self.W.cartan_type().dual().affine()).pieri_factors().stanley_symm_poly_weight(w) - r
def __init__(self, n, R=ZZ, prefix='a'): """ Initiates the affine nilTemperley Lieb algebra over the ring `R`. EXAMPLES:: sage: A = AffineNilTemperleyLiebTypeA(3, prefix="a"); A The affine nilTemperley Lieb algebra A3 over the ring Integer Ring sage: TestSuite(A).run() sage: A = AffineNilTemperleyLiebTypeA(3, QQ); A The affine nilTemperley Lieb algebra A3 over the ring Rational Field """ if not isinstance(R, Ring): raise TypeError("Argument R must be a ring.") self._cartan_type = CartanType(['A', n - 1, 1]) self._n = n W = WeylGroup(self._cartan_type) self._prefix = prefix self._index_set = W.index_set() self._base_ring = R category = AlgebrasWithBasis(R) CombinatorialFreeModule.__init__(self, R, W, category=category)
def energy_function(self): r""" Return the energy function of ``self``. The energy function `D(\pi)` of the level zero LS path `\pi \in \mathbb{B}_\mathrm{cl}(\lambda)` requires a series of definitions; for simplicity the root system is assumed to be untwisted affine. The LS path `\pi` is a piecewise linear map from the unit interval `[0,1]` to the weight lattice. It is specified by "times" `0=\sigma_0<\sigma_1<\dotsm<\sigma_s=1` and "direction vectors" `x_u \lambda` where `x_u \in W/W_J` for `1\le u\le s`, and `W_J` is the stabilizer of `\lambda` in the finite Weyl group `W`. Precisely, .. MATH:: \pi(t)=\sum_{u'=1}^{u-1} (\sigma_{u'}-\sigma_{u'-1})x_{u'}\lambda+(t-\sigma_{u-1})x_{u}\lambda for `1\le u\le s` and `\sigma_{u-1} \le t \le \sigma_{u}`. For any `x,y\in W/W_J` let .. MATH:: d: x= w_{0} \stackrel{\beta_{1}}{\leftarrow} w_{1} \stackrel{\beta_{2}}{\leftarrow} \cdots \stackrel{\beta_{n}}{\leftarrow} w_{n}=y be a shortest directed path in the parabolic quantum Bruhat graph. Define .. MATH:: \mathrm{wt}(d):=\sum_{\substack{1\le k\le n \\ \ell(w_{k-1})<\ell(w_k)}} \beta_{k}^{\vee} It can be shown that `\mathrm{wt}(d)` depends only on `x,y`; call its value `\mathrm{wt}(x,y)`. The energy function `D(\pi)` is defined by .. MATH:: D(\pi)=-\sum_{u=1}^{s-1} (1-\sigma_{u}) \langle \lambda,\mathrm{wt}(x_u,x_{u+1}) \rangle For more information, see [LNSSS2013]_. REFERENCES: .. [LNSSS2013] C. Lenart, S. Naito, D. Sagaki, A. Schilling, M. Shimozono, A uniform model for Kirillov-Reshetikhin crystals. Extended abstract. DMTCS proc, to appear ( {{{:arXiv:`1211.6019`}}} ) .. NOTE:: In the dual-of-untwisted case the parabolic quantum Bruhat graph that is used is obtained by exchanging the roles of roots and coroots. Moreover, in the computation of the pairing the short roots must be doubled (or tripled for type `G`). This factor is determined by the translation factor of the corresponding root. Type `BC` is viewed as untwisted type, whereas the dual of `BC` is viewed as twisted. Except for the untwisted cases, these formulas are currently still conjectural. EXAMPLES:: sage: R = RootSystem(['C',3,1]) sage: La = R.weight_space().basis() sage: LS = CrystalOfProjectedLevelZeroLSPaths(La[1]+La[3]) sage: b = LS.module_generators[0] sage: c = b.f(1).f(3).f(2) sage: c.energy_function() 0 sage: c=b.e(0) sage: c.energy_function() 1 sage: R = RootSystem(['A',2,1]) sage: La = R.weight_space().basis() sage: LS = CrystalOfProjectedLevelZeroLSPaths(2*La[1]) sage: b = LS.module_generators[0] sage: c = b.e(0) sage: c.energy_function() 1 sage: [c.energy_function() for c in sorted(LS.list())] [0, 1, 0, 0, 0, 1, 0, 1, 0] The next test checks that the energy function is constant on classically connected components:: sage: R = RootSystem(['A',2,1]) sage: La = R.weight_space().basis() sage: LS = CrystalOfProjectedLevelZeroLSPaths(2*La[1]+La[2]) sage: G = LS.digraph(index_set=[1,2]) sage: C = G.connected_components() sage: [all(c[0].energy_function()==a.energy_function() for a in c) for c in C] [True, True, True, True] sage: R = RootSystem(['D',4,2]) sage: La = R.weight_space().basis() sage: LS = CrystalOfProjectedLevelZeroLSPaths(La[2]) sage: J = R.cartan_type().classical().index_set() sage: hw = [x for x in LS if x.is_highest_weight(J)] sage: [(x.weight(), x.energy_function()) for x in hw] [(-2*Lambda[0] + Lambda[2], 0), (-2*Lambda[0] + Lambda[1], 1), (0, 2)] sage: G = LS.digraph(index_set=J) sage: C = G.connected_components() sage: [all(c[0].energy_function()==a.energy_function() for a in c) for c in C] [True, True, True] sage: R = RootSystem(CartanType(['G',2,1]).dual()) sage: La = R.weight_space().basis() sage: LS = CrystalOfProjectedLevelZeroLSPaths(La[1]+La[2]) sage: G = LS.digraph(index_set=[1,2]) sage: C = G.connected_components() sage: [all(c[0].energy_function()==a.energy_function() for a in c) for c in C] [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True] sage: ct = CartanType(['BC',2,2]).dual() sage: R = RootSystem(ct) sage: La = R.weight_space().basis() sage: LS = CrystalOfProjectedLevelZeroLSPaths(2*La[1]+La[2]) sage: G = LS.digraph(index_set=R.cartan_type().classical().index_set()) sage: C = G.connected_components() sage: [all(c[0].energy_function()==a.energy_function() for a in c) for c in C] [True, True, True, True, True, True, True, True, True, True, True] sage: R = RootSystem(['BC',2,2]) sage: La = R.weight_space().basis() sage: LS = CrystalOfProjectedLevelZeroLSPaths(2*La[1]+La[2]) sage: G = LS.digraph(index_set=R.cartan_type().classical().index_set()) sage: C = G.connected_components() sage: [all(c[0].energy_function()==a.energy_function() for a in c) for c in C] [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True] """ weight = self.parent().weight P = weight.parent() c_weight = P.classical()(weight) ct = P.cartan_type() cartan = ct.classical() Qv = RootSystem(cartan).coroot_lattice() W = WeylGroup(cartan,prefix='s') J = tuple(weight.weyl_stabilizer()) L = self.weyl_group_representation() if ct.is_untwisted_affine() or ct.type() == 'BC': untwisted = True G = W.quantum_bruhat_graph(J) else: untwisted = False cartan_dual = cartan.dual() Wd = WeylGroup(cartan_dual, prefix='s') G = Wd.quantum_bruhat_graph(J) Qd = RootSystem(cartan_dual).root_lattice() dualize = lambda x: Qv.from_vector(x.to_vector()) L = [Wd.from_reduced_word(x.reduced_word()) for x in L] def stretch_short_root(a): # stretches roots by translation factor if ct.dual().type() == 'BC': return ct.c()[a.to_simple_root()]*a return ct.dual().c()[a.to_simple_root()]*a #if a.is_short_root(): # if cartan_dual.type() == 'G': # return 3*a # else: # return 2*a #return a paths = [G.shortest_path(L[i+1],L[i]) for i in range(len(L)-1)] paths_labels = [[G.edge_label(p[i],p[i+1]) for i in range(len(p)-1) if p[i].length()+1 != p[i+1].length()] for p in paths] scalars = self.scalar_factors() if untwisted: s = sum((1-scalars[i])*c_weight.scalar( Qv.sum(root.associated_coroot() for root in paths_labels[i]) ) for i in range(len(paths_labels))) if ct.type() == 'BC': return 2*s else: return s else: s = sum((1-scalars[i])*c_weight.scalar( dualize (Qd.sum(stretch_short_root(root) for root in paths_labels[i])) ) for i in range(len(paths_labels))) if ct.dual().type() == 'BC': return s/2 else: return s
def string_parameters(self, word=None): r""" Return the string parameters of ``self`` corresponding to the reduced word ``word``. Given a reduced expression `w = s_{i_1} \cdots s_{i_k}`, the string parameters of `b \in B` corresponding to `w` are `(a_1, \ldots, a_k)` such that .. MATH:: \begin{aligned} e_{i_m}^{a_m} \cdots e_{i_1}^{a_1} b & \neq 0 \\ e_{i_m}^{a_m+1} \cdots e_{i_1}^{a_1} b & = 0 \end{aligned} for all `1 \leq m \leq k`. For connected components isomorphic to `B(\lambda)` or `B(\infty)`, if `w = w_0` is the longest element of the Weyl group, then the path determined by the string parametrization terminates at the highest weight vector. INPUT: - ``word`` -- a word in the alphabet of the index set; if not specified and we are in finite type, then this will be some reduced expression for the long element determined by the Weyl group EXAMPLES:: sage: B = crystals.infinity.NakajimaMonomials(['A',3]) sage: mg = B.highest_weight_vector() sage: w0 = [1,2,1,3,2,1] sage: mg.string_parameters(w0) [0, 0, 0, 0, 0, 0] sage: mg.f_string([1]).string_parameters(w0) [1, 0, 0, 0, 0, 0] sage: mg.f_string([1,1,1]).string_parameters(w0) [3, 0, 0, 0, 0, 0] sage: mg.f_string([1,1,1,2,2]).string_parameters(w0) [1, 2, 2, 0, 0, 0] sage: mg.f_string([1,1,1,2,2]) == mg.f_string([1,1,2,2,1]) True sage: x = mg.f_string([1,1,1,2,2,1,3,3,2,1,1,1]) sage: x.string_parameters(w0) [4, 1, 1, 2, 2, 2] sage: x.string_parameters([3,2,1,3,2,3]) [2, 3, 7, 0, 0, 0] sage: x == mg.f_string([1]*7 + [2]*3 + [3]*2) True :: sage: B = crystals.infinity.Tableaux("A5") sage: b = B(rows=[[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,6,6,6,6,6,6], ....: [2,2,2,2,2,2,2,2,2,4,5,5,5,6], ....: [3,3,3,3,3,3,3,5], ....: [4,4,4,6,6,6], ....: [5,6]]) sage: b.string_parameters([1,2,1,3,2,1,4,3,2,1,5,4,3,2,1]) [0, 1, 1, 1, 1, 0, 4, 4, 3, 0, 11, 10, 7, 7, 6] sage: B = crystals.infinity.Tableaux("G2") sage: b = B(rows=[[1,1,1,1,1,3,3,0,-3,-3,-2,-2,-1,-1,-1,-1],[2,3,3,3]]) sage: b.string_parameters([2,1,2,1,2,1]) [5, 13, 11, 15, 4, 4] sage: b.string_parameters([1,2,1,2,1,2]) [7, 12, 15, 8, 10, 0] :: sage: C = crystals.Tableaux(['C',2], shape=[2,1]) sage: mg = C.highest_weight_vector() sage: lw = C.lowest_weight_vectors()[0] sage: lw.string_parameters([1,2,1,2]) [1, 2, 3, 1] sage: lw.string_parameters([2,1,2,1]) [1, 3, 2, 1] sage: lw.e_string([2,1,1,1,2,2,1]) == mg True sage: lw.e_string([1,2,2,1,1,1,2]) == mg True TESTS:: sage: B = crystals.infinity.NakajimaMonomials(['B',3]) sage: mg = B.highest_weight_vector() sage: mg.string_parameters() [0, 0, 0, 0, 0, 0, 0, 0, 0] sage: w0 = WeylGroup(['B',3]).long_element().reduced_word() sage: def f_word(params): ....: return reversed([index for i, index in enumerate(w0) ....: for _ in range(params[i])]) sage: all(mg.f_string( f_word(x.value.string_parameters(w0)) ) == x.value ....: for x in B.subcrystal(max_depth=4)) True sage: B = crystals.infinity.NakajimaMonomials(['A',2,1]) sage: mg = B.highest_weight_vector() sage: mg.string_parameters() Traceback (most recent call last): ... ValueError: the word must be specified because the Weyl group is not finite """ if word is None: if not self.cartan_type().is_finite(): raise ValueError("the word must be specified because" " the Weyl group is not finite") from sage.combinat.root_system.weyl_group import WeylGroup word = WeylGroup( self.cartan_type()).long_element().reduced_word() x = self params = [] for i in word: count = 0 y = x.e(i) while y is not None: x = y y = x.e(i) count += 1 params.append(count) return params
def CoxeterGroup(data, implementation="reflection", base_ring=None, index_set=None): """ Return an implementation of the Coxeter group given by ``data``. INPUT: - ``data`` -- a Cartan type (or coercible into; see :class:`CartanType`) or a Coxeter matrix or graph - ``implementation`` -- (default: ``'reflection'``) can be one of the following: * ``'permutation'`` - as a permutation representation * ``'matrix'`` - as a Weyl group (as a matrix group acting on the root space); if this is not implemented, this uses the "reflection" implementation * ``'coxeter3'`` - using the coxeter3 package * ``'reflection'`` - as elements in the reflection representation; see :class:`~sage.groups.matrix_gps.coxeter_groups.CoxeterMatrixGroup` - ``base_ring`` -- (optional) the base ring for the ``'reflection'`` implementation - ``index_set`` -- (optional) the index set for the ``'reflection'`` implementation EXAMPLES: Now assume that ``data`` represents a Cartan type. If ``implementation`` is not specified, the reflection representation is returned:: sage: W = CoxeterGroup(["A",2]) sage: W Finite Coxeter group over Universal Cyclotomic Field with Coxeter matrix: [1 3] [3 1] sage: W = CoxeterGroup(["A",3,1]); W Coxeter group over Universal Cyclotomic Field with Coxeter matrix: [1 3 2 3] [3 1 3 2] [2 3 1 3] [3 2 3 1] sage: W = CoxeterGroup(['H',3]); W Finite Coxeter group over Universal Cyclotomic Field with Coxeter matrix: [1 3 2] [3 1 5] [2 5 1] We now use the ``implementation`` option:: sage: W = CoxeterGroup(["A",2], implementation = "permutation") # optional - chevie sage: W # optional - chevie Permutation Group with generators [(1,3)(2,5)(4,6), (1,4)(2,3)(5,6)] sage: W.category() # optional - chevie Join of Category of finite permutation groups and Category of finite coxeter groups sage: W = CoxeterGroup(["A",2], implementation="matrix") sage: W Weyl Group of type ['A', 2] (as a matrix group acting on the ambient space) sage: W = CoxeterGroup(["H",3], implementation="matrix") sage: W Finite Coxeter group over Universal Cyclotomic Field with Coxeter matrix: [1 3 2] [3 1 5] [2 5 1] sage: W = CoxeterGroup(["H",3], implementation="reflection") sage: W Finite Coxeter group over Universal Cyclotomic Field with Coxeter matrix: [1 3 2] [3 1 5] [2 5 1] sage: W = CoxeterGroup(["A",4,1], implementation="permutation") Traceback (most recent call last): ... NotImplementedError: Coxeter group of type ['A', 4, 1] as permutation group not implemented We use the different options for the "reflection" implementation:: sage: W = CoxeterGroup(["H",3], implementation="reflection", base_ring=RR) sage: W Finite Coxeter group over Real Field with 53 bits of precision with Coxeter matrix: [1 3 2] [3 1 5] [2 5 1] sage: W = CoxeterGroup([[1,10],[10,1]], implementation="reflection", index_set=['a','b'], base_ring=SR) sage: W Finite Coxeter group over Symbolic Ring with Coxeter matrix: [ 1 10] [10 1] TESTS:: sage: W = groups.misc.CoxeterGroup(["H",3]) """ if implementation not in [ "permutation", "matrix", "coxeter3", "reflection", None ]: raise ValueError("invalid type implementation") try: cartan_type = CartanType(data) except ( TypeError, ValueError ): # If it is not a Cartan type, try to see if we can represent it as a matrix group return CoxeterMatrixGroup(data, base_ring, index_set) if implementation is None: implementation = "matrix" if implementation == "reflection": return CoxeterMatrixGroup(cartan_type, base_ring, index_set) if implementation == "coxeter3": try: from sage.libs.coxeter3.coxeter_group import CoxeterGroup except ImportError: raise RuntimeError("coxeter3 must be installed") else: return CoxeterGroup(cartan_type) if implementation == "permutation" and is_chevie_available() and \ cartan_type.is_finite() and cartan_type.is_irreducible(): return CoxeterGroupAsPermutationGroup(cartan_type) elif implementation == "matrix": if cartan_type.is_crystallographic(): return WeylGroup(cartan_type) return CoxeterMatrixGroup(cartan_type, base_ring, index_set) raise NotImplementedError( "Coxeter group of type {} as {} group not implemented".format( cartan_type, implementation))
def __init__(self, root_system, pickle_directory=None): self.root_system = root_system self.W = WeylGroup(root_system) self.domain = self.W.domain() self.LA = LieAlgebra(QQ, cartan_type=root_system) self.PBW = PoincareBirkhoffWittBasis(self.LA, None, "PBW", cache_degree=5) # self.PBW = self.LA.pbw_basis() self.PBW_alg_gens = self.PBW.algebra_generators() self.lattice = self.domain.root_system.root_lattice() self.S = self.W.simple_reflections() self.T = self.W.reflections() self.signs = None self.cycles = None self._compute_weyl_dictionary() self._construct_BGG_graph() self.find_cycles() self.simple_roots = self.domain.simple_roots().values() self.rank = len(self.simple_roots) # for PBW computations we need to put the right order on the negative roots. # This order coincides with that of the sagemath source code. lie_alg_order = {k: i for i, k in enumerate(self.LA.basis().keys())} ordered_roots = sorted( [ self._weight_to_alpha_sum(r) for r in self.domain.negative_roots() ], key=lambda rr: lie_alg_order[rr], ) self.neg_roots = [-self._alpha_sum_to_array(r) for r in ordered_roots] self.alpha_to_index = { self._weight_to_alpha_sum(-self._tuple_to_weight(r)): i for i, r in enumerate(self.neg_roots) } self.zero_root = self.domain.zero() self.pickle_directory = pickle_directory if pickle_directory is None: self.pickle_maps = False else: self.pickle_maps = True if self.pickle_maps: self._maps = self._read_maps() else: self._maps = dict() self.rho = self.domain.rho() self._action_dic = dict() for s, w in self.reduced_word_dic.items(): self._action_dic[s] = { i: self._weight_to_alpha_sum(w.action(mu)) for i, mu in dict(self.domain.simple_roots()).items() } self._rho_action_dic = dict() for s, w in self.reduced_word_dic.items(): self._rho_action_dic[s] = self._weight_to_alpha_sum( w.action(self.rho) - self.rho)
def CoxeterGroup(cartan_type, implementation=None): """ INPUT: - ``cartan_type`` -- a cartan type (or coercible into; see :class:`CartanType`) - ``implementation`` -- "permutation", "matrix", "coxeter3", or None (default: None) Returns an implementation of the Coxeter group of type ``cartan_type``. EXAMPLES: If ``implementation`` is not specified, a permutation representation is returned whenever possible (finite irreducible Cartan type, with the GAP3 Chevie package available):: sage: W = CoxeterGroup(["A",2]) sage: W # optional - chevie Permutation Group with generators [(1,3)(2,5)(4,6), (1,4)(2,3)(5,6)] Otherwise, a Weyl group is returned:: sage: W = CoxeterGroup(["A",3,1]) sage: W Weyl Group of type ['A', 3, 1] (as a matrix group acting on the root space) We now use the ``implementation`` option:: sage: W = CoxeterGroup(["A",2], implementation = "permutation") # optional - chevie sage: W # optional - chevie Permutation Group with generators [(1,3)(2,5)(4,6), (1,4)(2,3)(5,6)] sage: W.category() # optional - chevie Join of Category of finite permutation groups and Category of finite coxeter groups sage: W = CoxeterGroup(["A",2], implementation = "matrix") sage: W Weyl Group of type ['A', 2] (as a matrix group acting on the ambient space) sage: W = CoxeterGroup(["H",3], implementation = "matrix") Traceback (most recent call last): ... NotImplementedError: Coxeter group of type ['H', 3] as matrix group not implemented sage: W = CoxeterGroup(["A",4,1], implementation = "permutation") Traceback (most recent call last): ... NotImplementedError: Coxeter group of type ['A', 4, 1] as permutation group not implemented """ assert implementation in ["permutation", "matrix", "coxeter3", None] cartan_type = CartanType(cartan_type) if implementation is None: if cartan_type.is_finite() and cartan_type.is_irreducible( ) and is_chevie_available(): implementation = "permutation" else: implementation = "matrix" if implementation == "coxeter3": try: from sage.libs.coxeter3.coxeter_group import CoxeterGroup except ImportError: raise RuntimeError, "coxeter3 must be installed" else: return CoxeterGroup(cartan_type) if implementation == "permutation" and is_chevie_available() and \ cartan_type.is_finite() and cartan_type.is_irreducible(): return CoxeterGroupAsPermutationGroup(cartan_type) elif implementation == "matrix" and cartan_type.is_crystalographic(): return WeylGroup(cartan_type) else: raise NotImplementedError, "Coxeter group of type %s as %s group not implemented " % ( cartan_type, implementation)