예제 #1
0
        def character(self, R=None):
            """
            Returns the character of this crystal.

            INPUT:

            - ``R`` -- a :class:`WeylCharacterRing`
              (default: the default :class:`WeylCharacterRing` for this Cartan type)

            Returns the character of ``self`` as an element of ``R``.

            EXAMPLES::

                sage: C = crystals.Tableaux("A2", shape=[2,1])
                sage: chi = C.character(); chi
                A2(2,1,0)

                sage: T = crystals.TensorProduct(C,C)
                sage: chiT = T.character(); chiT
                A2(2,2,2) + 2*A2(3,2,1) + A2(3,3,0) + A2(4,1,1) + A2(4,2,0)
                sage: chiT == chi^2
                True

            One may specify an alternate :class:`WeylCharacterRing`::

                sage: R = WeylCharacterRing("A2", style="coroots")
                sage: chiT = T.character(R); chiT
                A2(0,0) + 2*A2(1,1) + A2(0,3) + A2(3,0) + A2(2,2)
                sage: chiT in R
                True

            It should have the same Cartan type and use the same
            realization of the weight lattice as ``self``::

                sage: R = WeylCharacterRing("A3", style="coroots")
                sage: T.character(R)
                Traceback (most recent call last):
                ...
                ValueError: Weyl character ring does not have the right Cartan type

            """
            from sage.combinat.root_system.weyl_characters import WeylCharacterRing
            if R is None:
                R = WeylCharacterRing(self.cartan_type())
            if not R.cartan_type() == self.cartan_type():
                raise ValueError(
                    "Weyl character ring does not have the right Cartan type")
            assert R.basis().keys() == self.weight_lattice_realization()

            return R.sum_of_monomials(x.weight()
                                      for x in self.highest_weight_vectors())
예제 #2
0
        def character(self, R=None):
            """
            Returns the character of this crystal.

            INPUT:

              - ``R`` -- a :class:`WeylCharacterRing`
                (default: the default :class:`WeylCharacterRing` for this Cartan type)

            Returns the character of ``self`` as an element of ``R``.

            EXAMPLES::

                sage: C = CrystalOfTableaux("A2", shape=[2,1])
                sage: chi = C.character(); chi
                A2(2,1,0)

                sage: T = TensorProductOfCrystals(C,C)
                sage: chiT = T.character(); chiT
                A2(2,2,2) + 2*A2(3,2,1) + A2(3,3,0) + A2(4,1,1) + A2(4,2,0)
                sage: chiT == chi^2
                True

            One may specify an alternate :class:`WeylCharacterRing`::

                sage: R = WeylCharacterRing("A2", style="coroots")
                sage: chiT = T.character(R); chiT
                A2(0,0) + 2*A2(1,1) + A2(0,3) + A2(3,0) + A2(2,2)
                sage: chiT in R
                True

            It should have the same cartan type and use the same
            realization of the weight lattice as ``self``::

                sage: R = WeylCharacterRing("A3", style="coroots")
                sage: T.character(R)
                Traceback (most recent call last):
                ...
                ValueError: Weyl character ring does not have the right Cartan type

            """
            from sage.combinat.root_system.weyl_characters import WeylCharacterRing
            if R == None:
                R = WeylCharacterRing(self.cartan_type())
            if not R.cartan_type() == self.cartan_type():
                raise ValueError, "Weyl character ring does not have the right Cartan type"
            assert R.basis().keys() == self.weight_lattice_realization()

            return R.sum_of_monomials( x.weight() for x in self.highest_weight_vectors() )
    def branch(self, i=None, weyl_character_ring=None, sequence=None, depth=5):
        r"""
        Return the branching rule on ``self``.

        Removing any node from the extended Dynkin diagram of the affine
        Lie algebra results in the Dynkin diagram of a classical Lie
        algebra, which is therefore a Lie subalgebra. For example
        removing the `0` node from the Dynkin diagram of type ``[X, r, 1]``
        produces the classical Dynkin diagram of ``[X, r]``.

        Thus for each `i` in the index set, we may restrict ``self`` to
        the corresponding classical subalgebra. Of course ``self`` is
        an infinite dimensional representation, but each weight `\mu`
        is assigned a grading by the number of times the simple root
        `\alpha_i` appears in `\Lambda-\mu`. Thus the branched
        representation is graded and we get sequence of finite-dimensional
        representations which this method is able to compute.

        OPTIONAL:

        - ``i`` -- (default: 0) an element of the index set
        - ``weyl_character_ring`` -- a WeylCharacterRing
        - ``sequence`` -- a dictionary
        - ``depth`` -- (default: 5) an upper bound for `k` determining
          how many terms to give

        In the default case where `i = 0`, you do not need to specify
        anything else, though you may want to increase the depth if
        you need more terms.

        EXAMPLES::

            sage: Lambda = RootSystem(['A',2,1]).weight_lattice(extended=true).fundamental_weights()
            sage: V = IntegrableRepresentation(2*Lambda[0])
            sage: b = V.branch(); b
            [A2(0,0),
             A2(1,1),
             A2(0,0) + 2*A2(1,1) + A2(2,2),
             2*A2(0,0) + 2*A2(0,3) + 4*A2(1,1) + 2*A2(3,0) + 2*A2(2,2),
             4*A2(0,0) + 3*A2(0,3) + 10*A2(1,1) + 3*A2(3,0) + A2(1,4) + 6*A2(2,2) + A2(4,1),
             6*A2(0,0) + 9*A2(0,3) + 20*A2(1,1) + 9*A2(3,0) + 3*A2(1,4) + 12*A2(2,2) + 3*A2(4,1) + A2(3,3)]

        If the parameter ``weyl_character_ring`` is omitted, the ring may be recovered
        as the parent of one of the branched coefficients::

            sage: A2 = b[0].parent(); A2
            The Weyl Character Ring of Type A2 with Integer Ring coefficients

        If `i` is not zero then you should specify the :class:`WeylCharacterRing` that you
        are branching to. This is determined by the Dynkin diagram::

            sage: Lambda = RootSystem(['B',3,1]).weight_lattice(extended=true).fundamental_weights()
            sage: V = IntegrableRepresentation(Lambda[0])
            sage: V.cartan_type().dynkin_diagram()
                O 0
                |
                |
            O---O=>=O
            1   2   3   
            B3~

        In this example, we observe that removing the `i=2` node from the
        Dynkin diagram produces a reducible diagram of type ``A1xA1xA1``.
        Thus we have a branching to
        `\mathfrak{sl}(2) \times \mathfrak{sl}(2) \times \mathfrak{sl}(2)`::

            sage: A1xA1xA1 = WeylCharacterRing("A1xA1xA1",style="coroots")
            sage: V.branch(i=2,weyl_character_ring=A1xA1xA1)
            [A1xA1xA1(1,0,0),
             A1xA1xA1(0,1,2),
             A1xA1xA1(1,0,0) + A1xA1xA1(1,2,0) + A1xA1xA1(1,0,2),
             A1xA1xA1(2,1,2) + A1xA1xA1(0,1,0) + 2*A1xA1xA1(0,1,2),
             3*A1xA1xA1(1,0,0) + 2*A1xA1xA1(1,2,0) + A1xA1xA1(1,2,2) + 2*A1xA1xA1(1,0,2) + A1xA1xA1(1,0,4) + A1xA1xA1(3,0,0),
             A1xA1xA1(2,1,0) + 3*A1xA1xA1(2,1,2) + 2*A1xA1xA1(0,1,0) + 5*A1xA1xA1(0,1,2) + A1xA1xA1(0,1,4) + A1xA1xA1(0,3,2)]

        If the nodes of the two Dynkin diagrams are not in the same order, you
        must specify an additional parameter, ``sequence`` which gives a dictionary
        to the affine Dynkin diagram to the classical one.

        EXAMPLES::

            sage: Lambda = RootSystem(['F',4,1]).weight_lattice(extended=true).fundamental_weights()
            sage: V = IntegrableRepresentation(Lambda[0])
            sage: V.cartan_type().dynkin_diagram()
            O---O---O=>=O---O
            0   1   2   3   4   
            F4~
            sage: A1xC3=WeylCharacterRing("A1xC3",style="coroots")
            sage: A1xC3.dynkin_diagram()
            O
            1   
            O---O=<=O
            2   3   4   
            A1xC3

        Observe that removing the `i=1` node from the ``F4~`` Dynkin diagram
        gives the ``A1xC3`` diagram, but the roots are in a different order.
        The nodes `0, 2, 3, 4` of ``F4~`` correspond to ``1, 4, 3, 2``
        of ``A1xC3`` and so we encode this in a dictionary::

            sage: V.branch(i=1,weyl_character_ring=A1xC3,sequence={0:1,2:4,3:3,4:2}) # long time
            [A1xC3(1,0,0,0),
             A1xC3(0,0,0,1),
             A1xC3(1,0,0,0) + A1xC3(1,2,0,0),
             A1xC3(2,0,0,1) + A1xC3(0,0,0,1) + A1xC3(0,1,1,0),
             2*A1xC3(1,0,0,0) + A1xC3(1,0,1,0) + 2*A1xC3(1,2,0,0) + A1xC3(1,0,2,0) + A1xC3(3,0,0,0),
             2*A1xC3(2,0,0,1) + A1xC3(2,1,1,0) + A1xC3(0,1,0,0) + 3*A1xC3(0,0,0,1) + 2*A1xC3(0,1,1,0) + A1xC3(0,2,0,1)]

        The branch method gives a way of computing the graded dimension of the integrable representation::

            sage: Lambda = RootSystem("A1~").weight_lattice(extended=true).fundamental_weights()
            sage: V=IntegrableRepresentation(Lambda[0])
            sage: r = [x.degree() for x in V.branch(depth=15)]; r
            [1, 3, 4, 7, 13, 19, 29, 43, 62, 90, 126, 174, 239, 325, 435, 580]
            sage: oeis(r)                                                        # optional -- internet
            0: A029552: Expansion of phi(x) / f(-x) in powers of x where phi(), f() are Ramanujan theta functions.

        """
        if i is None:
            i = self._cartan_type.special_node()
        if i == self._cartan_type.special_node() or self._cartan_type.type(
        ) == 'A':
            if weyl_character_ring is None:
                weyl_character_ring = WeylCharacterRing(
                    self._cartan_type.classical(), style="coroots")
            if weyl_character_ring.cartan_type(
            ) != self._cartan_type.classical():
                raise ValueError(
                    "Cartan type of WeylCharacterRing must be %s" %
                    self.cartan_type().classical())
        elif weyl_character_ring is None:
            raise ValueError(
                "the argument weyl_character_ring cannot be omitted if i != 0")
        if sequence is None:
            sequence = {}
            for j in self._index_set:
                if j < i:
                    sequence[j] = j + 1
                elif j > i:
                    sequence[j] = j

        def next_level(x):
            ret = []
            for j in self._index_set:
                t = list(x[0])
                t[j] += 1
                t = tuple(t)
                m = self.m(t)
                if m > 0 and t[i] <= depth:
                    ret.append((t, m))
            return ret

        hwv = (tuple([0 for j in self._index_set]), 1)
        terms = RecursivelyEnumeratedSet([hwv], next_level)
        fw = weyl_character_ring.fundamental_weights()
        P = self.weight_lattice()
        ret = []
        for l in range(depth + 1):
            lterms = [x for x in terms if x[0][i] == l]
            ldict = {}
            for x in lterms:
                mc = P(self.to_weight(x[0])).monomial_coefficients()
                contr = sum(fw[sequence[j]] * mc.get(j, 0)
                            for j in self._index_set if j != i).coerce_to_sl()
                if contr in ldict:
                    ldict[contr] += x[1]
                else:
                    ldict[contr] = x[1]
            ret.append(weyl_character_ring.char_from_weights(ldict))
        return ret
예제 #4
0
    def branch(self, i=None, weyl_character_ring=None, sequence=None, depth=5):
        r"""
        Return the branching rule on ``self``.

        Removing any node from the extended Dynkin diagram of the affine
        Lie algebra results in the Dynkin diagram of a classical Lie
        algebra, which is therefore a Lie subalgebra. For example
        removing the `0` node from the Dynkin diagram of type ``[X, r, 1]``
        produces the classical Dynkin diagram of ``[X, r]``.

        Thus for each `i` in the index set, we may restrict ``self`` to
        the corresponding classical subalgebra. Of course ``self`` is
        an infinite dimensional representation, but each weight `\mu`
        is assigned a grading by the number of times the simple root
        `\alpha_i` appears in `\Lambda-\mu`. Thus the branched
        representation is graded and we get sequence of finite-dimensional
        representations which this method is able to compute.

        OPTIONAL:

        - ``i`` -- (default: 0) an element of the index set
        - ``weyl_character_ring`` -- a WeylCharacterRing
        - ``sequence`` -- a dictionary
        - ``depth`` -- (default: 5) an upper bound for `k` determining
          how many terms to give

        In the default case where `i = 0`, you do not need to specify
        anything else, though you may want to increase the depth if
        you need more terms.

        EXAMPLES::

            sage: Lambda = RootSystem(['A',2,1]).weight_lattice(extended=true).fundamental_weights()
            sage: V = IntegrableRepresentation(2*Lambda[0])
            sage: b = V.branch(); b
            [A2(0,0),
             A2(1,1),
             A2(0,0) + 2*A2(1,1) + A2(2,2),
             2*A2(0,0) + 2*A2(0,3) + 4*A2(1,1) + 2*A2(3,0) + 2*A2(2,2),
             4*A2(0,0) + 3*A2(0,3) + 10*A2(1,1) + 3*A2(3,0) + A2(1,4) + 6*A2(2,2) + A2(4,1),
             6*A2(0,0) + 9*A2(0,3) + 20*A2(1,1) + 9*A2(3,0) + 3*A2(1,4) + 12*A2(2,2) + 3*A2(4,1) + A2(3,3)]

        If the parameter ``weyl_character_ring`` is omitted, the ring may be recovered
        as the parent of one of the branched coefficients::

            sage: A2 = b[0].parent(); A2
            The Weyl Character Ring of Type A2 with Integer Ring coefficients

        If `i` is not zero then you should specify the :class:`WeylCharacterRing` that you
        are branching to. This is determined by the Dynkin diagram::

            sage: Lambda = RootSystem(['B',3,1]).weight_lattice(extended=true).fundamental_weights()
            sage: V = IntegrableRepresentation(Lambda[0])
            sage: V.cartan_type().dynkin_diagram()
                O 0
                |
                |
            O---O=>=O
            1   2   3   
            B3~

        In this example, we observe that removing the `i=2` node from the
        Dynkin diagram produces a reducible diagram of type ``A1xA1xA1``.
        Thus we have a branching to
        `\mathfrak{sl}(2) \times \mathfrak{sl}(2) \times \mathfrak{sl}(2)`::

            sage: A1xA1xA1 = WeylCharacterRing("A1xA1xA1",style="coroots")
            sage: V.branch(i=2,weyl_character_ring=A1xA1xA1)
            [A1xA1xA1(1,0,0),
             A1xA1xA1(0,1,2),
             A1xA1xA1(1,0,0) + A1xA1xA1(1,2,0) + A1xA1xA1(1,0,2),
             A1xA1xA1(2,1,2) + A1xA1xA1(0,1,0) + 2*A1xA1xA1(0,1,2),
             3*A1xA1xA1(1,0,0) + 2*A1xA1xA1(1,2,0) + A1xA1xA1(1,2,2) + 2*A1xA1xA1(1,0,2) + A1xA1xA1(1,0,4) + A1xA1xA1(3,0,0),
             A1xA1xA1(2,1,0) + 3*A1xA1xA1(2,1,2) + 2*A1xA1xA1(0,1,0) + 5*A1xA1xA1(0,1,2) + A1xA1xA1(0,1,4) + A1xA1xA1(0,3,2)]

        If the nodes of the two Dynkin diagrams are not in the same order, you
        must specify an additional parameter, ``sequence`` which gives a dictionary
        to the affine Dynkin diagram to the classical one.

        EXAMPLES::

            sage: Lambda = RootSystem(['F',4,1]).weight_lattice(extended=true).fundamental_weights()
            sage: V = IntegrableRepresentation(Lambda[0])
            sage: V.cartan_type().dynkin_diagram()
            O---O---O=>=O---O
            0   1   2   3   4   
            F4~
            sage: A1xC3=WeylCharacterRing("A1xC3",style="coroots")
            sage: A1xC3.dynkin_diagram()
            O
            1   
            O---O=<=O
            2   3   4   
            A1xC3

        Observe that removing the `i=1` node from the ``F4~`` Dynkin diagram
        gives the ``A1xC3`` diagram, but the roots are in a different order.
        The nodes `0, 2, 3, 4` of ``F4~`` correspond to ``1, 4, 3, 2``
        of ``A1xC3`` and so we encode this in a dictionary::

            sage: V.branch(i=1,weyl_character_ring=A1xC3,sequence={0:1,2:4,3:3,4:2}) # long time
            [A1xC3(1,0,0,0),
             A1xC3(0,0,0,1),
             A1xC3(1,0,0,0) + A1xC3(1,2,0,0),
             A1xC3(2,0,0,1) + A1xC3(0,0,0,1) + A1xC3(0,1,1,0),
             2*A1xC3(1,0,0,0) + A1xC3(1,0,1,0) + 2*A1xC3(1,2,0,0) + A1xC3(1,0,2,0) + A1xC3(3,0,0,0),
             2*A1xC3(2,0,0,1) + A1xC3(2,1,1,0) + A1xC3(0,1,0,0) + 3*A1xC3(0,0,0,1) + 2*A1xC3(0,1,1,0) + A1xC3(0,2,0,1)]

        The branch method gives a way of computing the graded dimension of the integrable representation::

            sage: Lambda = RootSystem("A1~").weight_lattice(extended=true).fundamental_weights()
            sage: V=IntegrableRepresentation(Lambda[0])
            sage: r = [x.degree() for x in V.branch(depth=15)]; r
            [1, 3, 4, 7, 13, 19, 29, 43, 62, 90, 126, 174, 239, 325, 435, 580]
            sage: oeis(r)                                                        # optional -- internet
            0: A029552: Expansion of phi(x) / f(-x) in powers of x where phi(), f() are Ramanujan theta functions.

        """
        if i is None:
            i = self._cartan_type.special_node()
        if i == self._cartan_type.special_node() or self._cartan_type.type() == 'A':
            if weyl_character_ring is None:
                weyl_character_ring = WeylCharacterRing(self._cartan_type.classical(), style="coroots")
            if weyl_character_ring.cartan_type() != self._cartan_type.classical():
                raise ValueError("Cartan type of WeylCharacterRing must be %s"%self.cartan_type().classical())
        elif weyl_character_ring is None:
            raise ValueError("the argument weyl_character_ring cannot be omitted if i != 0")
        if sequence is None:
            sequence = {}
            for j in self._index_set:
                if j < i:
                    sequence[j] = j+1
                elif j > i:
                    sequence[j] = j
        def next_level(x):
            ret = []
            for j in self._index_set:
                t = list(x[0])
                t[j] += 1
                t = tuple(t)
                m = self.m(t)
                if m > 0 and t[i] <= depth:
                    ret.append((t,m))
            return ret
        hwv = (tuple([0 for j in self._index_set]), 1)
        terms = RecursivelyEnumeratedSet([hwv], next_level)
        fw = weyl_character_ring.fundamental_weights()
        P = self.weight_lattice()
        ret = []
        for l in range(depth+1):
            lterms = [x for x in terms if x[0][i] == l]
            ldict = {}
            for x in lterms:
                mc = P(self.to_weight(x[0])).monomial_coefficients()
                contr = sum(fw[sequence[j]]*mc.get(j,0)
                            for j in self._index_set if j != i).coerce_to_sl()
                if contr in ldict:
                    ldict[contr] += x[1]
                else:
                    ldict[contr] = x[1]
            ret.append(weyl_character_ring.char_from_weights(ldict))
        return ret