示例#1
0
        def _generate_hall_set(self, k):
            """
            Generate the Hall set of grade ``k``.

            OUTPUT:

            A sorted tuple of :class:`GradedLieBracket` elements.

            EXAMPLES::

                sage: L = LieAlgebra(QQ, 3, 'x')
                sage: H = L.Hall()
                sage: H._generate_hall_set(3)
                ([x0, [x0, x1]],
                 [x0, [x0, x2]],
                 [x1, [x0, x1]],
                 [x1, [x0, x2]],
                 [x1, [x1, x2]],
                 [x2, [x0, x1]],
                 [x2, [x0, x2]],
                 [x2, [x1, x2]])
            """
            if k <= 0:
                return ()
            if k == 1:
                return tuple(map(LieGenerator, self.variable_names()))
            if k == 2:
                basis = self._generate_hall_set(1)
                ret = []
                for i,a in enumerate(basis):
                    for b in basis[i+1:]:
                        ret.append( GradedLieBracket(a, b, 2) )
                return tuple(ret)

            # We don't want to do the middle when we're even, so we add 1 and
            #   take the floor after dividing by 2.
            ret = [GradedLieBracket(a, b, k) for i in range(1, (k+1) // 2)
                   for a in self._generate_hall_set(i)
                   for b in self._generate_hall_set(k-i)
                   if b._left <= a]

            # Special case for when k = 4, we get the pairs [[a, b], [x, y]]
            #    where a,b,x,y are all grade 1 elements. Thus if we take
            #    [a, b] < [x, y], we will always be in the Hall set.
            if k == 4:
                basis = self._generate_hall_set(2)
                for i,a in enumerate(basis):
                    for b in basis[i+1:]:
                        ret.append(GradedLieBracket(a, b, k))
            # Do the middle case when we are even and k > 4
            elif k % 2 == 0:
                basis = self._generate_hall_set(k // 2) # grade >= 2
                for i,a in enumerate(basis):
                    for b in basis[i+1:]:
                        if b._left <= a:
                            ret.append(GradedLieBracket(a, b, k))

            # We sort the returned tuple in order to make computing the higher
            #   graded parts of the Hall set easier.
            return tuple(sorted(ret))
        def _rewrite_bracket(self, l, r):
            """
            Rewrite the bracket ``[l, r]`` in terms of the Hall basis.

            INPUT:

            - ``l``, ``r`` -- two keys of the Hall basis with ``l < r``

            OUTPUT:

            A dictionary ``{b: c}`` where ``b`` is a Hall basis key
            and ``c`` is the corresponding coefficient.

            EXAMPLES::

                sage: L = LieAlgebra(QQ, 'x,y,z')
                sage: H = L.Hall()
                sage: x,y,z = H.gens()
                sage: H([x, [y, [z, x]]]) # indirect doctest
                -[y, [x, [x, z]]] - [[x, y], [x, z]]
            """
            # NOTE: If r is not a graded Lie bracket, then l cannot be a
            #   graded Lie bracket by the order respecting the grading
            if not isinstance(r, GradedLieBracket) or r._left <= l:
                # Compute the grade of the new element
                grade = 0
                # If not a graded Lie bracket, it must be a generator so the grade is 1
                if isinstance(l, GradedLieBracket):
                    grade += l._grade
                else:
                    grade += 1
                if isinstance(r, GradedLieBracket):
                    grade += r._grade
                else:
                    grade += 1
                return {GradedLieBracket(l, r, grade): self.base_ring().one()}

            ret = {}

            # Rewrite [a, [b, c]] = [b, [a, c]] + [[a, b], c] with a < b < c
            # Compute the left summand
            for m, inner_coeff in self._rewrite_bracket(l, r._right).items():
                if r._left == m:
                    continue
                elif r._left < m:
                    x, y = r._left, m
                else:  # r._left > m
                    x, y = m, r._left
                    inner_coeff = -inner_coeff
                for b_elt, coeff in self._rewrite_bracket(x, y).items():
                    ret[b_elt] = ret.get(b_elt, 0) + coeff * inner_coeff

            # Compute the right summand
            for m, inner_coeff in self._rewrite_bracket(l, r._left).items():
                if m == r._right:
                    continue
                elif m < r._right:
                    x, y = m, r._right
                else:  # m > r._right
                    x, y = r._right, m
                    inner_coeff = -inner_coeff
                for b_elt, coeff in self._rewrite_bracket(x, y).items():
                    ret[b_elt] = ret.get(b_elt, 0) + coeff * inner_coeff

            return ret