Esempio n. 1
0
        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]
Esempio n. 2
0
    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 )
Esempio n. 3
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)
Esempio n. 4
0
    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)
Esempio n. 5
0
    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)
Esempio n. 7
0
    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)
Esempio n. 8
0
    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)
Esempio n. 9
0
    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())
                ]
Esempio n. 10
0
    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
Esempio n. 11
0
    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)
Esempio n. 12
0
        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
Esempio n. 13
0
        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
Esempio n. 14
0
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))
Esempio n. 15
0
    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)
Esempio n. 16
0
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)