Пример #1
0
    def __init__(self, W_types, index_set=None, hyperplane_index_set=None, reflection_index_set=None):
        r"""
        Initialize ``self``.

        TESTS::

            sage: W = ReflectionGroup(['A',3])                          # optional - gap3
            sage: TestSuite(W).run()                                    # optional - gap3
        """
        W_types = tuple([tuple(W_type) if isinstance(W_type, (list, tuple)) else W_type for W_type in W_types])
        cartan_types = []
        for W_type in W_types:
            W_type = CartanType(W_type)
            if not W_type.is_finite() or not W_type.is_irreducible():
                raise ValueError("the given Cartan type of a component is not irreducible and finite")
            cartan_types.append(W_type)
        if len(W_types) == 1:
            cls = IrreducibleComplexReflectionGroup
        else:
            cls = ComplexReflectionGroup
        cls.__init__(
            self,
            W_types,
            index_set=index_set,
            hyperplane_index_set=hyperplane_index_set,
            reflection_index_set=reflection_index_set,
        )
    def _element_constructor_(self, cartan_type, **kwds):
        """
        The element constructor.

        This method is called internally when we try to convert
        something into an element. In this case, the only thing that
        can be converted into an associahedron is the Cartan type.

        EXAMPLES::

            sage: from sage.combinat.root_system.associahedron import Associahedra
            sage: parent = Associahedra(QQ,2)
            sage: parent(['A',2])
            Generalized associahedron of type ['A', 2] with 5 vertices
            sage: parent._element_constructor_(['A',2])
            Generalized associahedron of type ['A', 2] with 5 vertices
        """
        cartan_type = CartanType(cartan_type)
        assert cartan_type.is_finite()
        root_space = cartan_type.root_system().root_space()
        # TODO: generalize this as a method of root lattice realization
        rhocheck = sum(beta.associated_coroot()
                       for beta in root_space.positive_roots()) / 2
        I = root_space.index_set()
        inequalities = []
        for orbit in root_space.almost_positive_roots_decomposition():
            c = rhocheck.coefficient(orbit[0].leading_support())
            for beta in orbit:
                inequalities.append([c] + [beta.coefficient(i) for i in I])
        associahedron = super(Associahedra, self)._element_constructor_(
            None, [inequalities, []])
        associahedron._cartan_type = cartan_type
        return associahedron
Пример #3
0
    def __init__(self,
                 W_types,
                 index_set=None,
                 hyperplane_index_set=None,
                 reflection_index_set=None):
        r"""
        Initialize ``self``.

        TESTS::

            sage: W = ReflectionGroup(['A',3])                          # optional - gap3
            sage: TestSuite(W).run()                                    # optional - gap3
        """
        W_types = tuple([
            tuple(W_type) if isinstance(W_type, (list, tuple)) else W_type
            for W_type in W_types
        ])
        cartan_types = []
        for W_type in W_types:
            W_type = CartanType(W_type)
            if not W_type.is_finite() or not W_type.is_irreducible():
                raise ValueError(
                    "the given Cartan type of a component is not irreducible and finite"
                )
            cartan_types.append(W_type)
        if len(W_types) == 1:
            cls = IrreducibleComplexReflectionGroup
        else:
            cls = ComplexReflectionGroup
        cls.__init__(self,
                     W_types,
                     index_set=index_set,
                     hyperplane_index_set=hyperplane_index_set,
                     reflection_index_set=reflection_index_set)
Пример #4
0
    def _element_constructor_(self, cartan_type, **kwds):
        """
        The element constructor.

        This method is called internally when we try to convert
        something into an element. In this case, the only thing that
        can be converted into an associahedron is the Cartan type.

        EXAMPLES::

            sage: from sage.combinat.root_system.associahedron import Associahedra
            sage: parent = Associahedra(QQ,2)
            sage: parent(['A',2])
            Generalized associahedron of type ['A', 2] with 5 vertices
            sage: parent._element_constructor_(['A',2])
            Generalized associahedron of type ['A', 2] with 5 vertices
        """
        cartan_type = CartanType(cartan_type)
        if not cartan_type.is_finite():
            raise ValueError("the Cartan type must be finite")
        root_space = cartan_type.root_system().root_space()
        # TODO: generalize this as a method of root lattice realization
        rhocheck = sum(beta.associated_coroot()
                       for beta in root_space.positive_roots()) / 2
        I = root_space.index_set()
        inequalities = []
        for orbit in root_space.almost_positive_roots_decomposition():
            c = rhocheck.coefficient(orbit[0].leading_support())
            for beta in orbit:
                inequalities.append([c] + [beta.coefficient(i) for i in I])
        associahedron = super(Associahedra, self)._element_constructor_(None, [inequalities, []])
        associahedron._cartan_type = cartan_type
        return associahedron
Пример #5
0
    def __classcall_private__(cls,
                              ct,
                              c=1,
                              t=None,
                              base_ring=None,
                              prefix=('a', 's', 'ac')):
        """
        Normalize input to ensure a unique representation.

        EXAMPLES::

            sage: R1 = algebras.RationalCherednik(['B',2], 1, 1, QQ)
            sage: R2 = algebras.RationalCherednik(CartanType(['B',2]), [1,1], 1, QQ, ('a', 's', 'ac'))
            sage: R1 is R2
            True
        """
        ct = CartanType(ct)
        if not ct.is_finite():
            raise ValueError("the Cartan type must be finite")
        if base_ring is None:
            if t is None:
                base_ring = QQ
            else:
                base_ring = t.parent()
        if t is None:
            t = base_ring.one()
        else:
            t = base_ring(t)

        # Normalize the parameter c
        if isinstance(c, (tuple, list)):
            if ct.is_simply_laced():
                if len(c) != 1:
                    raise ValueError(
                        "1 parameter c_s must be given for simply-laced types")
                c = (base_ring(c[0]), )
            else:
                if len(c) != 2:
                    raise ValueError(
                        "2 parameters c_s must be given for non-simply-laced types"
                    )
                c = (base_ring(c[0]), base_ring(c[1]))
        else:
            c = base_ring(c)
            if ct.is_simply_laced():
                c = (c, )
            else:
                c = (c, c)

        return super(RationalCherednikAlgebra,
                     cls).__classcall__(cls, ct, c, t, base_ring,
                                        tuple(prefix))
    def __init__(self, R, ct, names=None, prefix=None, bracket=None):
        """
        Initialize self.

        TESTS::

            sage: V = lie_conformal_algebras.Affine(QQ,'A1')
            sage: TestSuite(V).run()
        """
        if type(ct) is str:
            from sage.combinat.root_system.cartan_type import CartanType
            try:
                ct = CartanType(ct)
            except IndexError:
                raise ValueError("ct must be a valid Cartan Type")
        if not (ct.is_finite() and ct.is_irreducible):
            raise ValueError(
                "only affine algebras of simple finite dimensional"
                "Lie algebras are implemented")
        hv = Integer(ct.dual_coxeter_number())
        g = LieAlgebra(R, cartan_type=ct)
        B = g.basis()
        S = B.keys()
        gdict = {}
        for k1 in S:
            for k2 in S:
                if S.rank(k2) <= S.rank(k1):
                    myb = B[k1].bracket(B[k2]).monomial_coefficients()
                    myf = R(2).inverse_of_unit()*R(hv).inverse_of_unit()\
                          *g.killing_form(B[k1],B[k2])
                    if myb or myf:
                        gdict[(k1, k2)] = {}
                        if myb:
                            gdict[(k1,k2)][0] = {(nk,0):v for nk,v in \
                                                                    myb.items()}
                        if myf:
                            gdict[(k1, k2)][1] = {('K', 0): myf}

        weights = (1, ) * B.cardinality()
        self._ct = ct
        if prefix is None and names is None:
            prefix = 'B'

        GradedLieConformalAlgebra.__init__(self,
                                           R,
                                           gdict,
                                           index_set=S,
                                           central_elements=('K', ),
                                           weights=weights,
                                           names=names,
                                           prefix=prefix,
                                           bracket=bracket)
Пример #7
0
    def __classcall__(cls, cartan_type):
        """
        Normalize input to ensure a unique representation.

        EXAMPLES::

            sage: B1 = crystals.infinity.PBW(['A', 2])
            sage: B2 = crystals.infinity.PBW("A2")
            sage: B3 = crystals.infinity.PBW(CartanType("A2"))
            sage: B1 is B2 and B2 is B3
            True
        """
        cartan_type = CartanType(cartan_type)
        if not cartan_type.is_finite():
            raise NotImplementedError("only implemented for finite types")
        return super(PBWCrystal, cls).__classcall__(cls, cartan_type)
Пример #8
0
    def __classcall__(cls, cartan_type):
        """
        Normalize input to ensure a unique representation.

        EXAMPLES::

            sage: B1 = crystals.infinity.PBW(['A', 2])
            sage: B2 = crystals.infinity.PBW("A2")
            sage: B3 = crystals.infinity.PBW(CartanType("A2"))
            sage: B1 is B2 and B2 is B3
            True
        """
        cartan_type = CartanType(cartan_type)
        if not cartan_type.is_finite():
            raise NotImplementedError("only implemented for finite types")
        return super(PBWCrystal, cls).__classcall__(cls, cartan_type)
Пример #9
0
    def __classcall_private__(cls, ct, c=1, t=None, base_ring=None, prefix=('a', 's', 'ac')):
        """
        Normalize input to ensure a unique representation.

        EXAMPLES::

            sage: R1 = algebras.RationalCherednik(['B',2], 1, 1, QQ)
            sage: R2 = algebras.RationalCherednik(CartanType(['B',2]), [1,1], 1, QQ, ('a', 's', 'ac'))
            sage: R1 is R2
            True
        """
        ct = CartanType(ct)
        if not ct.is_finite():
            raise ValueError("the Cartan type must be finite")
        if base_ring is None:
            if t is None:
                base_ring = QQ
            else:
                base_ring = t.parent()
        if t is None:
            t = base_ring.one()
        else:
            t = base_ring(t)

        # Normalize the parameter c
        if isinstance(c, (tuple, list)):
            if ct.is_simply_laced():
                if len(c) != 1:
                    raise ValueError("1 parameter c_s must be given for simply-laced types")
                c = (base_ring(c[0]),)
            else:
                if len(c) != 2:
                    raise ValueError("2 parameters c_s must be given for non-simply-laced types")
                c = (base_ring(c[0]), base_ring(c[1]))
        else:
            c = base_ring(c)
            if ct.is_simply_laced():
                c = (c,)
            else:
                c = (c, c)

        return super(RationalCherednikAlgebra, cls).__classcall__(cls, ct, c, t, base_ring, tuple(prefix))
Пример #10
0
    def __classcall_private__(cls, R, cartan_type):
        """
        Return the correct parent based on input.

        EXAMPLES::

            sage: lie_algebras.ClassicalMatrix(QQ, ['A', 4])
            Special linear Lie algebra of rank 5 over Rational Field
            sage: lie_algebras.ClassicalMatrix(QQ, CartanType(['B',4]))
            Special orthogonal Lie algebra of rank 9 over Rational Field
            sage: lie_algebras.ClassicalMatrix(QQ, 'C4')
            Symplectic Lie algebra of rank 8 over Rational Field
            sage: lie_algebras.ClassicalMatrix(QQ, cartan_type=['D',4])
            Special orthogonal Lie algebra of rank 8 over Rational Field
        """
        if isinstance(cartan_type, (CartanMatrix, DynkinDiagram_class)):
            cartan_type = cartan_type.cartan_type()
        else:
            cartan_type = CartanType(cartan_type)

        if not cartan_type.is_finite():
            raise ValueError("only for finite types")

        if cartan_type.type() == 'A':
            return sl(R, cartan_type.rank() + 1)
        if cartan_type.type() == 'B':
            return so(R, 2*cartan_type.rank() + 1)
        if cartan_type.type() == 'C':
            return sp(R, 2*cartan_type.rank())
        if cartan_type.type() == 'D':
            return so(R, 2*cartan_type.rank())
        if cartan_type.type() == 'E':
            if cartan_type.rank() == 6:
                return e6(R)
            if cartan_type.rank() in [7,8]:
                raise NotImplementedError("not yet implemented")
        if cartan_type.type() == 'F' and cartan_type.rank() == 4:
            return f4(R)
        if cartan_type.type() == 'G' and cartan_type.rank() == 2:
            return g2(R)
        raise ValueError("invalid Cartan type")
Пример #11
0
def WeylGroup(x, prefix=None, implementation='matrix'):
    """
    Returns the Weyl group of the root system defined by the Cartan
    type (or matrix) ``ct``.

    INPUT:

    - ``x`` - a root system or a Cartan type (or matrix)

    OPTIONAL:

    - ``prefix`` -- changes the representation of elements from matrices
      to products of simple reflections

    - ``implementation`` -- one of the following:
      * ``'matrix'`` - as matrices acting on a root system
      * ``"permutation"`` - as a permutation group acting on the roots

    EXAMPLES:

    The following constructions yield the same result, namely
    a weight lattice and its corresponding Weyl group::

        sage: G = WeylGroup(['F',4])
        sage: L = G.domain()

    or alternatively and equivalently::

        sage: L = RootSystem(['F',4]).ambient_space()
        sage: G = L.weyl_group()
        sage: W = WeylGroup(L)

    Either produces a weight lattice, with access to its roots and
    weights.

    ::

        sage: G = WeylGroup(['F',4])
        sage: G.order()
        1152
        sage: [s1,s2,s3,s4] = G.simple_reflections()
        sage: w = s1*s2*s3*s4; w
        [ 1/2  1/2  1/2  1/2]
        [-1/2  1/2  1/2 -1/2]
        [ 1/2  1/2 -1/2 -1/2]
        [ 1/2 -1/2  1/2 -1/2]
        sage: type(w) == G.element_class
        True
        sage: w.order()
        12
        sage: w.length() # length function on Weyl group
        4

    The default representation of Weyl group elements is as matrices.
    If you prefer, you may specify a prefix, in which case the
    elements are represented as products of simple reflections.

    ::

        sage: W=WeylGroup("C3",prefix="s")
        sage: [s1,s2,s3]=W.simple_reflections() # lets Sage parse its own output
        sage: s2*s1*s2*s3
        s1*s2*s3*s1
        sage: s2*s1*s2*s3 == s1*s2*s3*s1
        True
        sage: (s2*s3)^2==(s3*s2)^2
        True
        sage: (s1*s2*s3*s1).matrix()
        [ 0  0 -1]
        [ 0  1  0]
        [ 1  0  0]

    ::

        sage: L = G.domain()
        sage: fw = L.fundamental_weights(); fw
        Finite family {1: (1, 1, 0, 0), 2: (2, 1, 1, 0), 3: (3/2, 1/2, 1/2, 1/2), 4: (1, 0, 0, 0)}
        sage: rho = sum(fw); rho
        (11/2, 5/2, 3/2, 1/2)
        sage: w.action(rho) # action of G on weight lattice
        (5, -1, 3, 2)

    We can also do the same for arbitrary Cartan matrices::

        sage: cm = CartanMatrix([[2,-5,0],[-2,2,-1],[0,-1,2]])
        sage: W = WeylGroup(cm)
        sage: W.gens()
        (
        [-1  5  0]  [ 1  0  0]  [ 1  0  0]
        [ 0  1  0]  [ 2 -1  1]  [ 0  1  0]
        [ 0  0  1], [ 0  0  1], [ 0  1 -1]
        )
        sage: s0,s1,s2 = W.gens()
        sage: s1*s2*s1
        [ 1  0  0]
        [ 2  0 -1]
        [ 2 -1  0]
        sage: s2*s1*s2
        [ 1  0  0]
        [ 2  0 -1]
        [ 2 -1  0]
        sage: s0*s1*s0*s2*s0
        [ 9  0 -5]
        [ 2  0 -1]
        [ 0  1 -1]

    Same Cartan matrix, but with a prefix to display using simple reflections::

        sage: W = WeylGroup(cm, prefix='s')
        sage: s0,s1,s2 = W.gens()
        sage: s0*s2*s1
        s2*s0*s1
        sage: (s1*s2)^3
        1
        sage: (s0*s1)^5
        s0*s1*s0*s1*s0*s1*s0*s1*s0*s1
        sage: s0*s1*s2*s1*s2
        s2*s0*s1
        sage: s0*s1*s2*s0*s2
        s0*s1*s0

    TESTS::

        sage: TestSuite(WeylGroup(["A",3])).run()
        sage: TestSuite(WeylGroup(["A",3,1])).run() # long time

        sage: W = WeylGroup(['A',3,1])
        sage: s = W.simple_reflections()
        sage: w = s[0]*s[1]*s[2]
        sage: w.reduced_word()
        [0, 1, 2]
        sage: w = s[0]*s[2]
        sage: w.reduced_word()
        [2, 0]
        sage: W = groups.misc.WeylGroup(['A',3,1])
    """
    if implementation == "permutation":
        return WeylGroup_permutation(x, prefix)
    elif implementation != "matrix":
        raise ValueError("invalid implementation")

    if x in RootLatticeRealizations:
        return WeylGroup_gens(x, prefix=prefix)

    try:
        ct = CartanType(x)
    except TypeError:
        ct = CartanMatrix(x)  # See if it is a Cartan matrix
    if ct.is_finite():
        return WeylGroup_gens(ct.root_system().ambient_space(), prefix=prefix)
    return WeylGroup_gens(ct.root_system().root_space(), prefix=prefix)
Пример #12
0
def FundamentalGroupOfExtendedAffineWeylGroup(cartan_type,
                                              prefix='pi',
                                              general_linear=None):
    r"""
    Factory for the fundamental group of an extended affine Weyl group.

    INPUT:

    - ``cartan_type`` -- a Cartan type that is either affine or finite, with the latter being a
      shorthand for the untwisted affinization
    - ``prefix`` (default: 'pi') -- string that labels the elements of the group
    - ``general_linear`` -- (default: None, meaning False) In untwisted type A, if True, use the
      universal central extension

    .. RUBRIC:: Fundamental group

    Associated to each affine Cartan type `\tilde{X}` is an extended affine Weyl group `E`.
    Its subgroup of length-zero elements is called the fundamental group `F`.
    The group `F` can be identified with a subgroup of the group of automorphisms of the
    affine Dynkin diagram. As such, every element of `F` can be viewed as a permutation of the
    set `I` of affine Dynkin nodes.

    Let `0 \in I` be the distinguished affine node; it is the one whose removal produces the
    associated finite Cartan type (call it `X`). A node `i \in I` is called *special*
    if some automorphism of the affine Dynkin diagram, sends `0` to `i`.
    The node `0` is always special due to the identity automorphism.
    There is a bijection of the set of special nodes with the fundamental group. We denote the
    image of `i` by `\pi_i`. The structure of `F` is determined as follows.

    - `\tilde{X}` is untwisted -- `F` is isomorphic to `P^\vee/Q^\vee` where `P^\vee` and `Q^\vee` are the
      coweight and coroot lattices of type `X`. The group `P^\vee/Q^\vee` consists of the cosets `\omega_i^\vee + Q^\vee`
      for special nodes `i`, where `\omega_0^\vee = 0` by convention. In this case the special nodes `i`
      are the *cominuscule* nodes, the ones such that `\omega_i^\vee(\alpha_j)` is `0` or `1` for all `j\in I_0 = I \setminus \{0\}`.
      For `i` special, addition by `\omega_i^\vee+Q^\vee` permutes `P^\vee/Q^\vee` and therefore permutes the set of special nodes.
      This permutation extends uniquely to an automorphism of the affine Dynkin diagram.
    - `\tilde{X}` is dual untwisted -- (that is, the dual of `\tilde{X}` is untwisted) `F` is isomorphic to `P/Q`
      where `P` and `Q` are the weight and root lattices of type `X`. The group `P/Q` consists of the cosets
      `\omega_i + Q` for special nodes `i`, where `\omega_0 = 0` by convention. In this case the special nodes `i`
      are the *minuscule* nodes, the ones such that `\alpha_j^\vee(\omega_i)` is `0` or `1` for all `j \in I_0`.
      For `i` special, addition by `\omega_i+Q` permutes `P/Q` and therefore permutes the set of special nodes.
      This permutation extends uniquely to an automorphism of the affine Dynkin diagram.
    - `\tilde{X}` is mixed -- (that is, not of the above two types) `F` is the trivial group.

    EXAMPLES::

        sage: from sage.combinat.root_system.fundamental_group import FundamentalGroupOfExtendedAffineWeylGroup
        sage: F = FundamentalGroupOfExtendedAffineWeylGroup(['A',3,1]); F
        Fundamental group of type ['A', 3, 1]
        sage: F.cartan_type().dynkin_diagram()
        0
        O-------+
        |       |
        |       |
        O---O---O
        1   2   3
        A3~
        sage: F.special_nodes()
        (0, 1, 2, 3)
        sage: F(1)^2
        pi[2]
        sage: F(1)*F(2)
        pi[3]
        sage: F(3)^(-1)
        pi[1]

        sage: F = FundamentalGroupOfExtendedAffineWeylGroup("B3"); F
        Fundamental group of type ['B', 3, 1]
        sage: F.cartan_type().dynkin_diagram()
            O 0
            |
            |
        O---O=>=O
        1   2   3
        B3~
        sage: F.special_nodes()
        (0, 1)

        sage: F = FundamentalGroupOfExtendedAffineWeylGroup("C2"); F
        Fundamental group of type ['C', 2, 1]
        sage: F.cartan_type().dynkin_diagram()
        O=>=O=<=O
        0   1   2
        C2~
        sage: F.special_nodes()
        (0, 2)

        sage: F = FundamentalGroupOfExtendedAffineWeylGroup("D4"); F
        Fundamental group of type ['D', 4, 1]
        sage: F.cartan_type().dynkin_diagram()
            O 4
            |
            |
        O---O---O
        1   |2  3
            |
            O 0
        D4~
        sage: F.special_nodes()
        (0, 1, 3, 4)
        sage: (F(4), F(4)^2)
        (pi[4], pi[0])

        sage: F = FundamentalGroupOfExtendedAffineWeylGroup("D5"); F
        Fundamental group of type ['D', 5, 1]
        sage: F.cartan_type().dynkin_diagram()
          0 O   O 5
            |   |
            |   |
        O---O---O---O
        1   2   3   4
        D5~
        sage: F.special_nodes()
        (0, 1, 4, 5)
        sage: (F(5), F(5)^2, F(5)^3, F(5)^4)
        (pi[5], pi[1], pi[4], pi[0])
        sage: F = FundamentalGroupOfExtendedAffineWeylGroup("E6"); F
        Fundamental group of type ['E', 6, 1]
        sage: F.cartan_type().dynkin_diagram()
                O 0
                |
                |
                O 2
                |
                |
        O---O---O---O---O
        1   3   4   5   6
        E6~
        sage: F.special_nodes()
        (0, 1, 6)
        sage: F(1)^2
        pi[6]

        sage: F = FundamentalGroupOfExtendedAffineWeylGroup(['D',4,2]); F
        Fundamental group of type ['C', 3, 1]^*
        sage: F.cartan_type().dynkin_diagram()
        O=<=O---O=>=O
        0   1   2   3
        C3~*
        sage: F.special_nodes()
        (0, 3)

    We also implement a fundamental group for `GL_n`. It is defined to be the group of integers, which is the
    covering group of the fundamental group Z/nZ for affine `SL_n`::

        sage: F = FundamentalGroupOfExtendedAffineWeylGroup(['A',2,1], general_linear=True); F
        Fundamental group of GL(3)
        sage: x = F.an_element(); x
        pi[5]
        sage: x*x
        pi[10]
        sage: x.inverse()
        pi[-5]
        sage: wt = F.cartan_type().classical().root_system().ambient_space().an_element(); wt
        (2, 2, 3)
        sage: x.act_on_classical_ambient(wt)
        (2, 3, 2)
        sage: w = WeylGroup(F.cartan_type(),prefix="s").an_element(); w
        s0*s1*s2
        sage: x.act_on_affine_weyl(w)
        s2*s0*s1
    """
    cartan_type = CartanType(cartan_type)
    if cartan_type.is_finite():
        cartan_type = cartan_type.affine()
    if not cartan_type.is_affine():
        raise NotImplementedError("Cartan type is not affine")
    if general_linear is True:
        if cartan_type.is_untwisted_affine() and cartan_type.type() == "A":
            return FundamentalGroupGL(cartan_type, prefix)
        else:
            raise ValueError(
                "General Linear Fundamental group is untwisted type A")
    return FundamentalGroupOfExtendedAffineWeylGroup_Class(cartan_type,
                                                           prefix,
                                                           finite=True)
Пример #13
0
    def __classcall_private__(cls, R=None, arg0=None, arg1=None, names=None,
                              index_set=None, abelian=False, **kwds):
        """
        Select the correct parent based upon input.

        TESTS::

            sage: LieAlgebra(QQ, abelian=True, names='x,y,z')
            Abelian Lie algebra on 3 generators (x, y, z) over Rational Field
            sage: LieAlgebra(QQ, {('e','h'): {'e':-2}, ('f','h'): {'f':2},
            ....:                 ('e','f'): {'h':1}}, names='e,f,h')
            Lie algebra on 3 generators (e, f, h) over Rational Field
        """
        # Parse associative algebra input
        # -----

        assoc = kwds.get("associative", None)
        if assoc is not None:
            return LieAlgebraFromAssociative(assoc, names=names, index_set=index_set)

        # Parse input as a Cartan type
        # -----

        ct = kwds.get("cartan_type", None)
        if ct is not None:
            from sage.combinat.root_system.cartan_type import CartanType
            ct = CartanType(ct)
            if ct.is_affine():
                from sage.algebras.lie_algebras.affine_lie_algebra import AffineLieAlgebra
                return AffineLieAlgebra(R, cartan_type=ct,
                                        kac_moody=kwds.get("kac_moody", True))
            if not ct.is_finite():
                raise NotImplementedError("non-finite types are not implemented yet, see trac #14901 for details")
            rep = kwds.get("representation", "bracket")
            if rep == 'bracket':
                from sage.algebras.lie_algebras.classical_lie_algebra import LieAlgebraChevalleyBasis
                return LieAlgebraChevalleyBasis(R, ct)
            if rep == 'matrix':
                from sage.algebras.lie_algebras.classical_lie_algebra import ClassicalMatrixLieAlgebra
                return ClassicalMatrixLieAlgebra(R, ct)
            raise ValueError("invalid representation")

        # Parse the remaining arguments
        # -----

        if R is None:
            raise ValueError("invalid arguments")

        check_assoc = lambda A: (isinstance(A, (Ring, MatrixSpace))
                                 or A in Rings()
                                 or A in Algebras(R).Associative())
        if arg0 in ZZ or check_assoc(arg1):
            # Check if we need to swap the arguments
            arg0, arg1 = arg1, arg0

        # Parse the first argument
        # -----

        if isinstance(arg0, dict):
            if not arg0:
                from sage.algebras.lie_algebras.abelian import AbelianLieAlgebra
                return AbelianLieAlgebra(R, names, index_set)
            elif isinstance(next(iter(arg0.keys())), (list, tuple)):
                # We assume it is some structure coefficients
                arg1, arg0 = arg0, arg1

        if isinstance(arg0, (list, tuple)):
            if all(isinstance(x, str) for x in arg0):
                # If they are all strings, then it is a list of variables
                names = tuple(arg0)

        if isinstance(arg0, str):
            names = tuple(arg0.split(','))
        elif isinstance(names, str):
            names = tuple(names.split(','))

        # Parse the second argument

        if isinstance(arg1, dict):
            # Assume it is some structure coefficients
            from sage.algebras.lie_algebras.structure_coefficients import LieAlgebraWithStructureCoefficients
            return LieAlgebraWithStructureCoefficients(R, arg1, names, index_set, **kwds)

        # Otherwise it must be either a free or abelian Lie algebra

        if arg1 in ZZ:
            if isinstance(arg0, str):
                names = arg0
            if names is None:
                index_set = list(range(arg1))
            else:
                if isinstance(names, str):
                    names = tuple(names.split(','))
                    if arg1 != 1 and len(names) == 1:
                        names = tuple('{}{}'.format(names[0], i)
                                      for i in range(arg1))
                if arg1 != len(names):
                    raise ValueError("the number of names must equal the"
                                     " number of generators")

        if abelian:
            from sage.algebras.lie_algebras.abelian import AbelianLieAlgebra
            return AbelianLieAlgebra(R, names, index_set)

        # Otherwise it is the free Lie algebra
        rep = kwds.get("representation", "bracket")
        if rep == "polynomial":
            # Construct the free Lie algebra from polynomials in the
            #   free (associative unital) algebra
            # TODO: Change this to accept an index set once FreeAlgebra accepts one
            from sage.algebras.free_algebra import FreeAlgebra
            F = FreeAlgebra(R, names)
            if index_set is None:
                index_set = F.variable_names()
            # TODO: As part of #16823, this should instead construct a
            #   subclass with specialized methods for the free Lie algebra
            return LieAlgebraFromAssociative(F, F.gens(), names=names, index_set=index_set)

        raise NotImplementedError("the free Lie algebra has only been"
                                  " implemented using polynomials in the"
                                  " free algebra, see trac ticket #16823")
Пример #14
0
class Associahedron(Polyhedron):
    r"""
    The generalized associahedron is a polytopal complex with vertices in one-to-one correspondence
    with clusters in the cluster complex, and with edges between two vertices if and only if the associated two
    clusters intersect in codimension 1.

    The associahedron of type `A_n` is one way to realize the classical associahedron as defined in

    http://en.wikipedia.org/wiki/Associahedron.

    A polytopal realization of the associahedron can be found in [CFZ].
    The implementation is based on [CFZ, Theorem 1.5, Remark 1.6, and Corollary 1.9.].

    EXAMPLES::

        sage: Asso = Associahedron(['A',2]); Asso
        Generalized associahedron of type ['A', 2] with 5 vertices
        sage: sorted(Asso.Hrepresentation(), key=repr)
        [An inequality (-1, 0) x + 1 >= 0, An inequality (0, -1) x + 1 >= 0, An inequality (0, 1) x + 1 >= 0, An inequality (1, 0) x + 1 >= 0, An inequality (1, 1) x + 1 >= 0]
        sage: Asso.Vrepresentation()
        [A vertex at (-1, 1), A vertex at (1, 1), A vertex at (1, -1), A vertex at (0, -1), A vertex at (-1, 0)]

        sage: Associahedron(['B',2])
        Generalized associahedron of type ['B', 2] with 6 vertices

   The two pictures of [CFZ] can be recovered with::

        sage: Asso = Associahedron(['A',3]); Asso
        Generalized associahedron of type ['A', 3] with 14 vertices
        sage: Asso.plot()

        sage: Asso = Associahedron(['B',3]); Asso
        Generalized associahedron of type ['B', 3] with 20 vertices
        sage: Asso.plot()

    TESTS::

        sage: sorted(Associahedron(['A',3]).vertices())
        [[-3/2, 0, -1/2], [-3/2, 0, 3/2], [-3/2, 1, -3/2], [-3/2, 2, -3/2], [-3/2, 2, 3/2], [-1/2, -1, -1/2], [-1/2, 0, -3/2], [1/2, -2, 1/2], [1/2, -2, 3/2], [3/2, -2, 1/2], [3/2, -2, 3/2], [3/2, 0, -3/2], [3/2, 2, -3/2], [3/2, 2, 3/2]]
        sage: sorted(Associahedron(['B',3]).vertices())
        [[-3, 0, 0], [-3, 0, 3], [-3, 2, -2], [-3, 4, -3], [-3, 5, -3], [-3, 5, 3], [-2, 1, -2], [-2, 3, -3], [-1, -2, 0], [-1, -1, -1], [1, -4, 1], [1, -3, 0], [2, -5, 2], [2, -5, 3], [3, -5, 2], [3, -5, 3], [3, -3, 0], [3, 3, -3], [3, 5, -3], [3, 5, 3]]

        sage: Associahedron(['A',4]).f_vector()
        (1, 42, 84, 56, 14, 1)
        sage: Associahedron(['B',4]).f_vector()
        (1, 70, 140, 90, 20, 1)

    REFERENCES:

    - [CFZ] Chapoton, Fomin, Zelevinsky - Polytopal realizations of generalized associahedra, arXiv:0202004.
    """
    def __init__(self, cartan_type):
        """
        TESTS::

            sage: Asso = Associahedron(['A',2]); Asso
            Generalized associahedron of type ['A', 2] with 5 vertices
            sage: TestSuite(Asso).run()

        """
        self._cartan_type = CartanType( cartan_type )
        assert self._cartan_type.is_finite()
        root_space = self._cartan_type.root_system().root_space()
        # TODO: generalize this as a method of root lattice realization
        rhocheck = sum( beta.associated_coroot() for beta in root_space.positive_roots() )/2
        I = root_space.index_set()
        inequalities = []
        for orbit in root_space.almost_positive_roots_decomposition():
            c = rhocheck.coefficient(orbit[0].leading_support())
            for beta in orbit:
                inequalities.append( [c] + [ beta.coefficient(i) for i in I ] )
        Polyhedron.__init__(self,ieqs=inequalities)
        # check that there are non non trivial facets
        assert self.n_facets() == len(inequalities)

    def _repr_(self):
        r"""
        Returns a string representation of self.

        EXAMPLES::

            sage: Associahedron(['A',3])._repr_()
            "Generalized associahedron of type ['A', 3] with 14 vertices"
        """
        return 'Generalized associahedron of type %s with %s vertices'%(self._cartan_type,self.n_vertices())

    def cartan_type(self):
        r"""
        Returns the Cartan type of self.

        EXAMPLES::

            sage: Associahedron(['A',3]).cartan_type()
            ['A', 3]
        """
        return self._cartan_type

    def vertices_in_root_space(self):
        r"""
        Returns the vertices of ``self`` as elements in the root space

        EXAMPLES::

            sage: Asso = Associahedron(['A',2])

            sage: Asso.vertices()
            [[-1, 1], [1, 1], [1, -1], [0, -1], [-1, 0]]

            sage: Asso.vertices_in_root_space()
            [-alpha[1] + alpha[2], alpha[1] + alpha[2], alpha[1] - alpha[2], -alpha[2], -alpha[1]]
        """
        root_space = self._cartan_type.root_system().root_space()
        return [ root_space.from_vector(vector(V)) for V in self.vertex_generator() ]
Пример #15
0
def FundamentalGroupOfExtendedAffineWeylGroup(cartan_type, prefix='pi', general_linear=None):
    r"""
    Factory for the fundamental group of an extended affine Weyl group.

    INPUT:

    - ``cartan_type`` -- a Cartan type that is either affine or finite, with the latter being a
      shorthand for the untwisted affinization
    - ``prefix`` (default: 'pi') -- string that labels the elements of the group
    - ``general_linear`` -- (default: None, meaning False) In untwisted type A, if True, use the
      universal central extension

    .. RUBRIC:: Fundamental group

    Associated to each affine Cartan type `\tilde{X}` is an extended affine Weyl group `E`.
    Its subgroup of length-zero elements is called the fundamental group `F`.
    The group `F` can be identified with a subgroup of the group of automorphisms of the
    affine Dynkin diagram. As such, every element of `F` can be viewed as a permutation of the
    set `I` of affine Dynkin nodes.

    Let `0 \in I` be the distinguished affine node; it is the one whose removal produces the
    associated finite Cartan type (call it `X`). A node `i \in I` is called *special*
    if some automorphism of the affine Dynkin diagram, sends `0` to `i`.
    The node `0` is always special due to the identity automorphism.
    There is a bijection of the set of special nodes with the fundamental group. We denote the
    image of `i` by `\pi_i`. The structure of `F` is determined as follows.

    - `\tilde{X}` is untwisted -- `F` is isomorphic to `P^\vee/Q^\vee` where `P^\vee` and `Q^\vee` are the
      coweight and coroot lattices of type `X`. The group `P^\vee/Q^\vee` consists of the cosets `\omega_i^\vee + Q^\vee`
      for special nodes `i`, where `\omega_0^\vee = 0` by convention. In this case the special nodes `i`
      are the *cominuscule* nodes, the ones such that `\omega_i^\vee(\alpha_j)` is `0` or `1` for all `j\in I_0 = I \setminus \{0\}`.
      For `i` special, addition by `\omega_i^\vee+Q^\vee` permutes `P^\vee/Q^\vee` and therefore permutes the set of special nodes.
      This permutation extends uniquely to an automorphism of the affine Dynkin diagram.
    - `\tilde{X}` is dual untwisted -- (that is, the dual of `\tilde{X}` is untwisted) `F` is isomorphic to `P/Q`
      where `P` and `Q` are the weight and root lattices of type `X`. The group `P/Q` consists of the cosets
      `\omega_i + Q` for special nodes `i`, where `\omega_0 = 0` by convention. In this case the special nodes `i`
      are the *minuscule* nodes, the ones such that `\alpha_j^\vee(\omega_i)` is `0` or `1` for all `j \in I_0`.
      For `i` special, addition by `\omega_i+Q` permutes `P/Q` and therefore permutes the set of special nodes.
      This permutation extends uniquely to an automorphism of the affine Dynkin diagram.
    - `\tilde{X}` is mixed -- (that is, not of the above two types) `F` is the trivial group.

    EXAMPLES::

        sage: from sage.combinat.root_system.fundamental_group import FundamentalGroupOfExtendedAffineWeylGroup
        sage: F = FundamentalGroupOfExtendedAffineWeylGroup(['A',3,1]); F
        Fundamental group of type ['A', 3, 1]
        sage: F.cartan_type().dynkin_diagram()
        0
        O-------+
        |       |
        |       |
        O---O---O
        1   2   3
        A3~
        sage: F.special_nodes()
        (0, 1, 2, 3)
        sage: F(1)^2
        pi[2]
        sage: F(1)*F(2)
        pi[3]
        sage: F(3)^(-1)
        pi[1]

        sage: F = FundamentalGroupOfExtendedAffineWeylGroup("B3"); F
        Fundamental group of type ['B', 3, 1]
        sage: F.cartan_type().dynkin_diagram()
            O 0
            |
            |
        O---O=>=O
        1   2   3
        B3~
        sage: F.special_nodes()
        (0, 1)

        sage: F = FundamentalGroupOfExtendedAffineWeylGroup("C2"); F
        Fundamental group of type ['C', 2, 1]
        sage: F.cartan_type().dynkin_diagram()
        O=>=O=<=O
        0   1   2
        C2~
        sage: F.special_nodes()
        (0, 2)

        sage: F = FundamentalGroupOfExtendedAffineWeylGroup("D4"); F
        Fundamental group of type ['D', 4, 1]
        sage: F.cartan_type().dynkin_diagram()
            O 4
            |
            |
        O---O---O
        1   |2  3
            |
            O 0
        D4~
        sage: F.special_nodes()
        (0, 1, 3, 4)
        sage: (F(4), F(4)^2)
        (pi[4], pi[0])

        sage: F = FundamentalGroupOfExtendedAffineWeylGroup("D5"); F
        Fundamental group of type ['D', 5, 1]
        sage: F.cartan_type().dynkin_diagram()
          0 O   O 5
            |   |
            |   |
        O---O---O---O
        1   2   3   4
        D5~
        sage: F.special_nodes()
        (0, 1, 4, 5)
        sage: (F(5), F(5)^2, F(5)^3, F(5)^4)
        (pi[5], pi[1], pi[4], pi[0])
        sage: F = FundamentalGroupOfExtendedAffineWeylGroup("E6"); F
        Fundamental group of type ['E', 6, 1]
        sage: F.cartan_type().dynkin_diagram()
                O 0
                |
                |
                O 2
                |
                |
        O---O---O---O---O
        1   3   4   5   6
        E6~
        sage: F.special_nodes()
        (0, 1, 6)
        sage: F(1)^2
        pi[6]

        sage: F = FundamentalGroupOfExtendedAffineWeylGroup(['D',4,2]); F
        Fundamental group of type ['C', 3, 1]^*
        sage: F.cartan_type().dynkin_diagram()
        O=<=O---O=>=O
        0   1   2   3
        C3~*
        sage: F.special_nodes()
        (0, 3)

    We also implement a fundamental group for `GL_n`. It is defined to be the group of integers, which is the
    covering group of the fundamental group Z/nZ for affine `SL_n`::

        sage: F = FundamentalGroupOfExtendedAffineWeylGroup(['A',2,1], general_linear=True); F
        Fundamental group of GL(3)
        sage: x = F.an_element(); x
        pi[5]
        sage: x*x
        pi[10]
        sage: x.inverse()
        pi[-5]
        sage: wt = F.cartan_type().classical().root_system().ambient_space().an_element(); wt
        (2, 2, 3)
        sage: x.act_on_classical_ambient(wt)
        (2, 3, 2)
        sage: w = WeylGroup(F.cartan_type(),prefix="s").an_element(); w
        s0*s1*s2
        sage: x.act_on_affine_weyl(w)
        s2*s0*s1
    """
    cartan_type = CartanType(cartan_type)
    if cartan_type.is_finite():
        cartan_type = cartan_type.affine()
    if not cartan_type.is_affine():
        raise NotImplementedError("Cartan type is not affine")
    if general_linear is True:
        if cartan_type.is_untwisted_affine() and cartan_type.type() == "A":
            return FundamentalGroupGL(cartan_type, prefix)
        else:
            raise ValueError("General Linear Fundamental group is untwisted type A")
    return FundamentalGroupOfExtendedAffineWeylGroup_Class(cartan_type,prefix,finite=True)
Пример #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_crystallographic():
        return WeylGroup(cartan_type)
    else:
        raise NotImplementedError, "Coxeter group of type %s as %s group not implemented "%(cartan_type, implementation)
Пример #17
0
def WeylGroup(x, prefix=None, implementation='matrix'):
    """
    Returns the Weyl group of the root system defined by the Cartan
    type (or matrix) ``ct``.

    INPUT:

    - ``x`` - a root system or a Cartan type (or matrix)

    OPTIONAL:

    - ``prefix`` -- changes the representation of elements from matrices
      to products of simple reflections

    - ``implementation`` -- one of the following:
      * ``'matrix'`` - as matrices acting on a root system
      * ``"permutation"`` - as a permutation group acting on the roots

    EXAMPLES:

    The following constructions yield the same result, namely
    a weight lattice and its corresponding Weyl group::

        sage: G = WeylGroup(['F',4])
        sage: L = G.domain()

    or alternatively and equivalently::

        sage: L = RootSystem(['F',4]).ambient_space()
        sage: G = L.weyl_group()
        sage: W = WeylGroup(L)

    Either produces a weight lattice, with access to its roots and
    weights.

    ::

        sage: G = WeylGroup(['F',4])
        sage: G.order()
        1152
        sage: [s1,s2,s3,s4] = G.simple_reflections()
        sage: w = s1*s2*s3*s4; w
        [ 1/2  1/2  1/2  1/2]
        [-1/2  1/2  1/2 -1/2]
        [ 1/2  1/2 -1/2 -1/2]
        [ 1/2 -1/2  1/2 -1/2]
        sage: type(w) == G.element_class
        True
        sage: w.order()
        12
        sage: w.length() # length function on Weyl group
        4

    The default representation of Weyl group elements is as matrices.
    If you prefer, you may specify a prefix, in which case the
    elements are represented as products of simple reflections.

    ::

        sage: W=WeylGroup("C3",prefix="s")
        sage: [s1,s2,s3]=W.simple_reflections() # lets Sage parse its own output
        sage: s2*s1*s2*s3
        s1*s2*s3*s1
        sage: s2*s1*s2*s3 == s1*s2*s3*s1
        True
        sage: (s2*s3)^2==(s3*s2)^2
        True
        sage: (s1*s2*s3*s1).matrix()
        [ 0  0 -1]
        [ 0  1  0]
        [ 1  0  0]

    ::

        sage: L = G.domain()
        sage: fw = L.fundamental_weights(); fw
        Finite family {1: (1, 1, 0, 0), 2: (2, 1, 1, 0), 3: (3/2, 1/2, 1/2, 1/2), 4: (1, 0, 0, 0)}
        sage: rho = sum(fw); rho
        (11/2, 5/2, 3/2, 1/2)
        sage: w.action(rho) # action of G on weight lattice
        (5, -1, 3, 2)

    We can also do the same for arbitrary Cartan matrices::

        sage: cm = CartanMatrix([[2,-5,0],[-2,2,-1],[0,-1,2]])
        sage: W = WeylGroup(cm)
        sage: W.gens()
        (
        [-1  5  0]  [ 1  0  0]  [ 1  0  0]
        [ 0  1  0]  [ 2 -1  1]  [ 0  1  0]
        [ 0  0  1], [ 0  0  1], [ 0  1 -1]
        )
        sage: s0,s1,s2 = W.gens()
        sage: s1*s2*s1
        [ 1  0  0]
        [ 2  0 -1]
        [ 2 -1  0]
        sage: s2*s1*s2
        [ 1  0  0]
        [ 2  0 -1]
        [ 2 -1  0]
        sage: s0*s1*s0*s2*s0
        [ 9  0 -5]
        [ 2  0 -1]
        [ 0  1 -1]

    Same Cartan matrix, but with a prefix to display using simple reflections::

        sage: W = WeylGroup(cm, prefix='s')
        sage: s0,s1,s2 = W.gens()
        sage: s0*s2*s1
        s2*s0*s1
        sage: (s1*s2)^3
        1
        sage: (s0*s1)^5
        s0*s1*s0*s1*s0*s1*s0*s1*s0*s1
        sage: s0*s1*s2*s1*s2
        s2*s0*s1
        sage: s0*s1*s2*s0*s2
        s0*s1*s0

    TESTS::

        sage: TestSuite(WeylGroup(["A",3])).run()
        sage: TestSuite(WeylGroup(["A",3,1])).run() # long time

        sage: W = WeylGroup(['A',3,1])
        sage: s = W.simple_reflections()
        sage: w = s[0]*s[1]*s[2]
        sage: w.reduced_word()
        [0, 1, 2]
        sage: w = s[0]*s[2]
        sage: w.reduced_word()
        [2, 0]
        sage: W = groups.misc.WeylGroup(['A',3,1])
    """
    if implementation == "permutation":
        return WeylGroup_permutation(x, prefix)
    elif implementation != "matrix":
        raise ValueError("invalid implementation")

    if x in RootLatticeRealizations:
        return WeylGroup_gens(x, prefix=prefix)

    try:
        ct = CartanType(x)
    except TypeError:
        ct = CartanMatrix(x)  # See if it is a Cartan matrix
    if ct.is_finite():
        return WeylGroup_gens(ct.root_system().ambient_space(), prefix=prefix)
    return WeylGroup_gens(ct.root_system().root_space(), prefix=prefix)
Пример #18
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)
Пример #19
0
class Associahedron(Polyhedron_QQ_ppl):
    r"""
    The generalized associahedron is a polytopal complex with vertices in one-to-one correspondence
    with clusters in the cluster complex, and with edges between two vertices if and only if the associated two
    clusters intersect in codimension 1.

    The associahedron of type `A_n` is one way to realize the classical associahedron as defined in

    http://en.wikipedia.org/wiki/Associahedron.

    A polytopal realization of the associahedron can be found in [CFZ].
    The implementation is based on [CFZ, Theorem 1.5, Remark 1.6, and Corollary 1.9.].

    EXAMPLES::

        sage: Asso = Associahedron(['A',2]); Asso
        Generalized associahedron of type ['A', 2] with 5 vertices
        sage: sorted(Asso.Hrepresentation(), key=repr)
        [An inequality (-1, 0) x + 1 >= 0, An inequality (0, -1) x + 1 >= 0, An inequality (0, 1) x + 1 >= 0, An inequality (1, 0) x + 1 >= 0, An inequality (1, 1) x + 1 >= 0]
        sage: Asso.Vrepresentation()
        (A vertex at (1, -1), A vertex at (1, 1), A vertex at (-1, 1), A vertex at (-1, 0), A vertex at (0, -1))

        sage: Associahedron(['B',2])
        Generalized associahedron of type ['B', 2] with 6 vertices

   The two pictures of [CFZ] can be recovered with::

        sage: Asso = Associahedron(['A',3]); Asso
        Generalized associahedron of type ['A', 3] with 14 vertices
        sage: Asso.plot()

        sage: Asso = Associahedron(['B',3]); Asso
        Generalized associahedron of type ['B', 3] with 20 vertices
        sage: Asso.plot()

    TESTS::

        sage: sorted(Associahedron(['A',3]).vertices())
        [[-3/2, 0, -1/2], [-3/2, 0, 3/2], [-3/2, 1, -3/2], [-3/2, 2, -3/2], [-3/2, 2, 3/2], [-1/2, -1, -1/2], [-1/2, 0, -3/2], [1/2, -2, 1/2], [1/2, -2, 3/2], [3/2, -2, 1/2], [3/2, -2, 3/2], [3/2, 0, -3/2], [3/2, 2, -3/2], [3/2, 2, 3/2]]
        sage: sorted(Associahedron(['B',3]).vertices())
        [[-3, 0, 0], [-3, 0, 3], [-3, 2, -2], [-3, 4, -3], [-3, 5, -3], [-3, 5, 3], [-2, 1, -2], [-2, 3, -3], [-1, -2, 0], [-1, -1, -1], [1, -4, 1], [1, -3, 0], [2, -5, 2], [2, -5, 3], [3, -5, 2], [3, -5, 3], [3, -3, 0], [3, 3, -3], [3, 5, -3], [3, 5, 3]]

        sage: Associahedron(['A',4]).f_vector()
        (1, 42, 84, 56, 14, 1)
        sage: Associahedron(['B',4]).f_vector()
        (1, 70, 140, 90, 20, 1)

    REFERENCES:

    - [CFZ] Chapoton, Fomin, Zelevinsky - Polytopal realizations of generalized associahedra, arXiv:0202004.
    """
    def __init__(self, cartan_type):
        """
        TESTS::

            sage: Asso = Associahedron(['A',2]); Asso
            Generalized associahedron of type ['A', 2] with 5 vertices
            sage: TestSuite(Asso).run()

        """
        self._cartan_type = CartanType(cartan_type)
        assert self._cartan_type.is_finite()
        root_space = self._cartan_type.root_system().root_space()
        # TODO: generalize this as a method of root lattice realization
        rhocheck = sum(beta.associated_coroot()
                       for beta in root_space.positive_roots()) / 2
        I = root_space.index_set()
        inequalities = []
        for orbit in root_space.almost_positive_roots_decomposition():
            c = rhocheck.coefficient(orbit[0].leading_support())
            for beta in orbit:
                inequalities.append([c] + [beta.coefficient(i) for i in I])
        Polyhedron_QQ_ppl.__init__(self, len(I), None, [inequalities, []])
        # check that there are non non trivial facets
        assert self.n_facets() == len(inequalities)

    def _repr_(self):
        r"""
        Returns a string representation of self.

        EXAMPLES::

            sage: Associahedron(['A',3])._repr_()
            "Generalized associahedron of type ['A', 3] with 14 vertices"
        """
        return 'Generalized associahedron of type %s with %s vertices' % (
            self._cartan_type, self.n_vertices())

    def cartan_type(self):
        r"""
        Returns the Cartan type of self.

        EXAMPLES::

            sage: Associahedron(['A',3]).cartan_type()
            ['A', 3]
        """
        return self._cartan_type

    def vertices_in_root_space(self):
        r"""
        Returns the vertices of ``self`` as elements in the root space

        EXAMPLES::

            sage: Asso = Associahedron(['A',2])
            sage: Asso.vertices()
            [[1, -1], [1, 1], [-1, 1], [-1, 0], [0, -1]]

            sage: Asso.vertices_in_root_space()
            (alpha[1] - alpha[2], alpha[1] + alpha[2], -alpha[1] + alpha[2], -alpha[1], -alpha[2])
        """
        root_space = self._cartan_type.root_system().root_space()
        return tuple(
            root_space.from_vector(vector(V)) for V in self.vertex_generator())
Пример #20
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))
Пример #21
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))
Пример #22
0
    def __classcall_private__(cls,
                              R=None,
                              arg0=None,
                              arg1=None,
                              names=None,
                              index_set=None,
                              abelian=False,
                              **kwds):
        """
        Select the correct parent based upon input.

        TESTS::

            sage: LieAlgebra(QQ, abelian=True, names='x,y,z')
            Abelian Lie algebra on 3 generators (x, y, z) over Rational Field
            sage: LieAlgebra(QQ, {('e','h'): {'e':-2}, ('f','h'): {'f':2},
            ....:                 ('e','f'): {'h':1}}, names='e,f,h')
            Lie algebra on 3 generators (e, f, h) over Rational Field
        """
        # Parse associative algebra input
        # -----

        assoc = kwds.get("associative", None)
        if assoc is not None:
            return LieAlgebraFromAssociative(assoc,
                                             names=names,
                                             index_set=index_set)

        # Parse input as a Cartan type
        # -----

        ct = kwds.get("cartan_type", None)
        if ct is not None:
            from sage.combinat.root_system.cartan_type import CartanType
            ct = CartanType(ct)
            if ct.is_affine():
                from sage.algebras.lie_algebras.affine_lie_algebra import AffineLieAlgebra
                return AffineLieAlgebra(R,
                                        cartan_type=ct,
                                        kac_moody=kwds.get("kac_moody", True))
            if not ct.is_finite():
                raise NotImplementedError(
                    "non-finite types are not implemented yet, see trac #14901 for details"
                )
            rep = kwds.get("representation", "bracket")
            if rep == 'bracket':
                from sage.algebras.lie_algebras.classical_lie_algebra import LieAlgebraChevalleyBasis
                return LieAlgebraChevalleyBasis(R, ct)
            if rep == 'matrix':
                from sage.algebras.lie_algebras.classical_lie_algebra import ClassicalMatrixLieAlgebra
                return ClassicalMatrixLieAlgebra(R, ct)
            raise ValueError("invalid representation")

        # Parse the remaining arguments
        # -----

        if R is None:
            raise ValueError("invalid arguments")

        check_assoc = lambda A: (isinstance(A, (Ring, MatrixSpace)) or A in
                                 Rings() or A in Algebras(R).Associative())
        if arg0 in ZZ or check_assoc(arg1):
            # Check if we need to swap the arguments
            arg0, arg1 = arg1, arg0

        # Parse the first argument
        # -----

        if isinstance(arg0, dict):
            if not arg0:
                from sage.algebras.lie_algebras.abelian import AbelianLieAlgebra
                return AbelianLieAlgebra(R, names, index_set)
            elif isinstance(next(iter(arg0.keys())), (list, tuple)):
                # We assume it is some structure coefficients
                arg1, arg0 = arg0, arg1

        if isinstance(arg0, (list, tuple)):
            if all(isinstance(x, str) for x in arg0):
                # If they are all strings, then it is a list of variables
                names = tuple(arg0)

        if isinstance(arg0, str):
            names = tuple(arg0.split(','))
        elif isinstance(names, str):
            names = tuple(names.split(','))

        # Parse the second argument

        if isinstance(arg1, dict):
            # Assume it is some structure coefficients
            from sage.algebras.lie_algebras.structure_coefficients import LieAlgebraWithStructureCoefficients
            return LieAlgebraWithStructureCoefficients(R, arg1, names,
                                                       index_set, **kwds)

        # Otherwise it must be either a free or abelian Lie algebra

        if arg1 in ZZ:
            if isinstance(arg0, str):
                names = arg0
            if names is None:
                index_set = list(range(arg1))
            else:
                if isinstance(names, str):
                    names = tuple(names.split(','))
                    if arg1 != 1 and len(names) == 1:
                        names = tuple('{}{}'.format(names[0], i)
                                      for i in range(arg1))
                if arg1 != len(names):
                    raise ValueError("the number of names must equal the"
                                     " number of generators")

        if abelian:
            from sage.algebras.lie_algebras.abelian import AbelianLieAlgebra
            return AbelianLieAlgebra(R, names, index_set)

        # Otherwise it is the free Lie algebra
        rep = kwds.get("representation", "bracket")
        if rep == "polynomial":
            # Construct the free Lie algebra from polynomials in the
            #   free (associative unital) algebra
            # TODO: Change this to accept an index set once FreeAlgebra accepts one
            from sage.algebras.free_algebra import FreeAlgebra
            F = FreeAlgebra(R, names)
            if index_set is None:
                index_set = F.variable_names()
            # TODO: As part of #16823, this should instead construct a
            #   subclass with specialized methods for the free Lie algebra
            return LieAlgebraFromAssociative(F,
                                             F.gens(),
                                             names=names,
                                             index_set=index_set)

        raise NotImplementedError("the free Lie algebra has only been"
                                  " implemented using polynomials in the"
                                  " free algebra, see trac ticket #16823")