Example #1
0
 def __classcall_private__(cls, R, names, index_set=None):
     """
     Normalize input to ensure a unique representation.
     """
     names, index_set = standardize_names_index_set(names, index_set)
     return super(NotAFreeLieAlgebra,
                  cls).__classcall__(cls, R, names, index_set)
Example #2
0
    def __init__(self,
                 R,
                 ngens=1,
                 weights=None,
                 parity=None,
                 names=None,
                 index_set=None):
        """
        Initialize self.

        EXAMPLES::

            sage: V = lie_conformal_algebras.Abelian(QQ)
            sage: TestSuite(V).run()
        """
        if (names is None) and (index_set is None):
            names = 'a'
            self._latex_names = tuple(r'a_{%d}' % i for i in range(ngens))

        names, index_set = standardize_names_index_set(names=names,
                                                       index_set=index_set,
                                                       ngens=ngens)
        abeliandict = {}

        GradedLieConformalAlgebra.__init__(self,
                                           R,
                                           abeliandict,
                                           names=names,
                                           index_set=index_set,
                                           weights=weights,
                                           parity=parity)
Example #3
0
    def __classcall_private__(cls,
                              R,
                              classification,
                              s_coeff,
                              names,
                              index_set=None,
                              category=None,
                              **kwds):
        r"""
        Normalize input to ensure a unique representation.
        """
        names, index_set = standardize_names_index_set(names, index_set)
        s_coeff = LieAlgebraWithStructureCoefficients._standardize_s_coeff(
            s_coeff, index_set)

        cat = LieAlgebras(R).FiniteDimensional().WithBasis().Nilpotent()
        category = cat.or_subcategory(category)

        return super(ClassifiedNilpotentLieAlgebra,
                     cls).__classcall__(cls,
                                        R,
                                        classification,
                                        s_coeff,
                                        names,
                                        index_set,
                                        category=category,
                                        **kwds)
Example #4
0
    def __classcall_private__(cls, R, s_coeff, names=None, index_set=None,
                              category=None, **kwds):
        """
        Normalize input to ensure a unique representation.

        EXAMPLES:

        If the variable order is specified, the order of structural
        coefficients does not matter::

            sage: from sage.algebras.lie_algebras.nilpotent_lie_algebra import NilpotentLieAlgebra_dense
            sage: L1.<x,y,z> = NilpotentLieAlgebra_dense(QQ, {('x','y'): {'z': 1}})
            sage: L2.<x,y,z> = NilpotentLieAlgebra_dense(QQ, {('y','x'): {'z': -1}})
            sage: L1 is L2
            True

        If the variables are implicitly defined by the structural coefficients,
        the ordering may be different and the Lie algebras will be considered
        different::

            sage: from sage.algebras.lie_algebras.nilpotent_lie_algebra import NilpotentLieAlgebra_dense
            sage: L1 = NilpotentLieAlgebra_dense(QQ, {('x','y'): {'z': 1}})
            sage: L2 = NilpotentLieAlgebra_dense(QQ, {('y','x'): {'z': -1}})
            sage: L1
            Nilpotent Lie algebra on 3 generators (x, y, z) over Rational Field
            sage: L2
            Nilpotent Lie algebra on 3 generators (y, x, z) over Rational Field
            sage: L1 is L2
            False

        Constructed using two different methods from :class:`LieAlgebra`
        yields the same Lie algebra::

            sage: sc = {('X','Y'): {'Z': 1}}
            sage: C = LieAlgebras(QQ).Nilpotent().FiniteDimensional().WithBasis()
            sage: L1.<X,Y,Z> = LieAlgebra(QQ, sc, category=C)
            sage: L2 = LieAlgebra(QQ, sc, nilpotent=True, names=['X','Y','Z'])
            sage: L1 is L2
            True
        """
        if not names:
            # extract names from structural coefficients
            names = []
            for (X, Y), d in s_coeff.items():
                if X not in names: names.append(X)
                if Y not in names: names.append(Y)
                for k in d:
                    if k not in names: names.append(k)

        from sage.structure.indexed_generators import standardize_names_index_set
        names, index_set = standardize_names_index_set(names, index_set)
        s_coeff = LieAlgebraWithStructureCoefficients._standardize_s_coeff(
            s_coeff, index_set)

        cat = LieAlgebras(R).FiniteDimensional().WithBasis().Nilpotent()
        category = cat.or_subcategory(category)

        return super(NilpotentLieAlgebra_dense, cls).__classcall__(
            cls, R, s_coeff, names, index_set, category=category, **kwds)
Example #5
0
    def __init__(self, R, ngens=None, gram_matrix=None, names=None,
                 index_set=None):
        """
        Initialize self.

        TESTS::

            sage: V = lie_conformal_algebras.FreeFermions(QQ)
            sage: TestSuite(V).run()
        """
        from sage.matrix.matrix_space import MatrixSpace
        from sage.matrix.special import identity_matrix
        if (gram_matrix is not None):
            if ngens is None:
                ngens = gram_matrix.dimensions()[0]
            try:
                assert (gram_matrix in MatrixSpace(R,ngens,ngens))
            except AssertionError:
                raise ValueError("The gram_matrix should be a symmetric " +
                    "{0} x {0} matrix, got {1}".format(ngens,gram_matrix))
            if not gram_matrix.is_symmetric():
                raise ValueError("The gram_matrix should be a symmetric " +
                    "{0} x {0} matrix, got {1}".format(ngens,gram_matrix))
        else:
            if ngens is None:
                ngens = 1;
            gram_matrix = identity_matrix(R,ngens,ngens)

        latex_names=None

        if (names is None) and (index_set is None):
            if ngens==1:
                names = 'psi'
            else:
                names = 'psi_'
            latex_names = tuple(r"\psi_{%d}" % i \
                                      for i in range (ngens)) + ('K',)

        from sage.structure.indexed_generators import \
                                                standardize_names_index_set
        names,index_set = standardize_names_index_set(names=names,
                                                      index_set=index_set,
                                                      ngens=ngens)
        fermiondict = { (i,j): {0: {('K',0): gram_matrix[index_set.rank(i),
                    index_set.rank(j)]}} for i in index_set for j in index_set}

        from sage.rings.rational_field import QQ
        weights = (QQ(1/2),)*ngens
        parity = (1,)*ngens
        GradedLieConformalAlgebra.__init__(self,R,fermiondict,names=names,
                                           latex_names=latex_names,
                                           index_set=index_set,weights=weights,
                                           parity=parity,
                                           central_elements=('K',))

        self._gram_matrix = gram_matrix
    def __classcall_private__(cls, R, names=None, index_set=None):
        """
        Normalize input to ensure a unique representation.

        EXAMPLES::

            sage: from sage.algebras.lie_algebras.free_lie_algebra import FreeLieAlgebra
            sage: L1 = FreeLieAlgebra(QQ, ['x', 'y', 'z'])
            sage: L2.<x,y,z> = LieAlgebra(QQ)
            sage: L1 is L2
            True
        """
        names, index_set = standardize_names_index_set(names, index_set)
        return super(FreeLieAlgebra, cls).__classcall__(cls, R, names, index_set)
Example #7
0
    def __classcall_private__(cls,
                              R,
                              s_coeff,
                              names=None,
                              index_set=None,
                              **kwds):
        """
        Normalize input to ensure a unique representation.

        EXAMPLES::

            sage: L1 = LieAlgebra(QQ, 'x,y', {('x','y'): {'x':1}})
            sage: L2 = LieAlgebra(QQ, 'x,y', {('y','x'): {'x':-1}})
            sage: L1 is L2
            True

        Check that we convert names to the indexing set::

            sage: L = LieAlgebra(QQ, 'x,y,z', {('x','y'): {'z':1}, ('y','z'): {'x':1}, ('z','x'): {'y':1}}, index_set=list(range(3)))
            sage: (x,y,z) = L.gens()
            sage: L[x,y]
            L[2]
        """
        names, index_set = standardize_names_index_set(names, index_set)

        # Make sure the structure coefficients are given by the index set
        if names is not None and names != tuple(index_set):
            d = {x: index_set[i] for i, x in enumerate(names)}
            get_pairs = lambda X: X.items() if isinstance(X, dict) else X
            try:
                s_coeff = {(d[k[0]], d[k[1]]):
                           [(d[x], y) for x, y in get_pairs(s_coeff[k])]
                           for k in s_coeff}
            except KeyError:
                # At this point we assume they are given by the index set
                pass

        s_coeff = LieAlgebraWithStructureCoefficients._standardize_s_coeff(
            s_coeff, index_set)
        if s_coeff.cardinality() == 0:
            from sage.algebras.lie_algebras.abelian import AbelianLieAlgebra
            return AbelianLieAlgebra(R, names, index_set, **kwds)

        if (names is None and len(index_set) <= 1) or len(names) <= 1:
            from sage.algebras.lie_algebras.abelian import AbelianLieAlgebra
            return AbelianLieAlgebra(R, names, index_set, **kwds)

        return super(LieAlgebraWithStructureCoefficients,
                     cls).__classcall__(cls, R, s_coeff, names, index_set,
                                        **kwds)
    def __classcall_private__(cls, R, names=None, index_set=None):
        """
        Normalize input to ensure a unique representation.

        EXAMPLES::

            sage: from sage.algebras.lie_algebras.free_lie_algebra import FreeLieAlgebra
            sage: L1 = FreeLieAlgebra(QQ, ['x', 'y', 'z'])
            sage: L2.<x,y,z> = LieAlgebra(QQ)
            sage: L1 is L2
            True
        """
        names, index_set = standardize_names_index_set(names, index_set)
        return super(FreeLieAlgebra, cls).__classcall__(cls, R, names, index_set)
Example #9
0
    def __init__(self, R, ngens=2, names=None, index_set=None):
        """
        Initialize self.

        TESTS::

            sage: V = lie_conformal_algebras.BosonicGhosts(QQ)
            sage: TestSuite(V).run()
        """
        try:
            assert (ngens > 0 and ngens % 2 == 0)
        except AssertionError:
            raise ValueError("ngens should be an even positive integer, " +
                             "got {}".format(ngens))
        latex_names = None
        if (names is None) and (index_set is None):
            from sage.misc.defaults import variable_names as varnames
            from sage.misc.defaults import latex_variable_names as laxnames
            names = varnames(ngens / 2, 'b') + varnames(ngens / 2, 'c')
            latex_names =  tuple(laxnames(ngens/2,'b') +\
                                          laxnames(ngens/2,'c')) + ('K',)

        from sage.structure.indexed_generators import \
                                                standardize_names_index_set
        names, index_set = standardize_names_index_set(names=names,
                                                       index_set=index_set,
                                                       ngens=ngens)
        from sage.matrix.special import identity_matrix
        A = identity_matrix(R, ngens / 2)
        from sage.matrix.special import block_matrix
        gram_matrix = block_matrix([[R.zero(), A], [A, R.zero()]])
        ghostsdict = {(i, j): {
            0: {
                ('K', 0): gram_matrix[index_set.rank(i),
                                      index_set.rank(j)]
            }
        }
                      for i in index_set for j in index_set}
        weights = (1, ) * (ngens // 2) + (0, ) * (ngens // 2)
        parity = (1, ) * ngens
        super(FermionicGhostsLieConformalAlgebra,
              self).__init__(R,
                             ghostsdict,
                             names=names,
                             latex_names=latex_names,
                             index_set=index_set,
                             weights=weights,
                             parity=parity,
                             central_elements=('K', ))
Example #10
0
    def __classcall_private__(cls, R, names=None, index_set=None, category=None, **kwds):
        """
        Normalize input to ensure a unique representation.

        TESTS::

            sage: L1 = LieAlgebra(QQ, 'x,y', {})
            sage: L2.<x, y> = LieAlgebra(QQ, abelian=True)
            sage: L1 is L2
            True
        """
        names, index_set = standardize_names_index_set(names, index_set)
        if index_set.cardinality() == infinity:
            return InfiniteDimensionalAbelianLieAlgebra(R, index_set, **kwds)
        return super(AbelianLieAlgebra, cls).__classcall__(cls, R, names, index_set, category=category, **kwds)
Example #11
0
    def __init__(self, R, ngens=None, gram_matrix=None, names=None,
                 index_set=None):
        """
        Initialize self.

        TESTS::

            sage: V = lie_conformal_algebras.FreeBosons(QQ)
            sage: TestSuite(V).run()
        """
        from sage.matrix.matrix_space import MatrixSpace
        if (gram_matrix is not None):
            if ngens is None:
                ngens = gram_matrix.dimensions()[0]
            try:
                assert (gram_matrix in MatrixSpace(R,ngens,ngens))
            except AssertionError:
                raise ValueError("the gram_matrix should be a symmetric " +
                    "{0} x {0} matrix, got {1}".format(ngens,gram_matrix))
            if not gram_matrix.is_symmetric():
                raise ValueError("the gram_matrix should be a symmetric " +
                    "{0} x {0} matrix, got {1}".format(ngens,gram_matrix))
        else:
            if ngens is None:
                ngens = 1;
            gram_matrix = identity_matrix(R,ngens,ngens)

        latex_names = None
        if (names is None) and (index_set is None):
            names = 'alpha'
            latex_names = tuple(r'\alpha_{%d}' % i \
                                      for i in range (ngens)) + ('K',)
        names,index_set = standardize_names_index_set(names=names,
                                                      index_set=index_set,
                                                      ngens=ngens)
        bosondict = { (i,j): {1: {('K',0): gram_matrix[index_set.rank(i),
                    index_set.rank(j)]}} for i in index_set for j in index_set}

        GradedLieConformalAlgebra.__init__(self,R,bosondict,names=names,
                                           latex_names=latex_names,
                                           index_set=index_set,
                                           central_elements=('K',))

        self._gram_matrix = gram_matrix
    def __classcall_private__(cls, R, s_coeff, names=None, index_set=None, **kwds):
        """
        Normalize input to ensure a unique representation.

        EXAMPLES::

            sage: L1 = LieAlgebra(QQ, 'x,y', {('x','y'): {'x':1}})
            sage: L2 = LieAlgebra(QQ, 'x,y', {('y','x'): {'x':-1}})
            sage: L1 is L2
            True

        Check that we convert names to the indexing set::

            sage: L = LieAlgebra(QQ, 'x,y,z', {('x','y'): {'z':1}, ('y','z'): {'x':1}, ('z','x'): {'y':1}}, index_set=list(range(3)))
            sage: (x,y,z) = L.gens()
            sage: L[x,y]
            L[2]
        """
        names, index_set = standardize_names_index_set(names, index_set)

        # Make sure the structure coefficients are given by the index set
        if names is not None and names != tuple(index_set):
            d = {x: index_set[i] for i,x in enumerate(names)}
            get_pairs = lambda X: X.items() if isinstance(X, dict) else X
            try:
                s_coeff = {(d[k[0]], d[k[1]]): [(d[x], y) for x,y in get_pairs(s_coeff[k])]
                           for k in s_coeff}
            except KeyError:
                # At this point we assume they are given by the index set
                pass

        s_coeff = LieAlgebraWithStructureCoefficients._standardize_s_coeff(s_coeff, index_set)
        if s_coeff.cardinality() == 0:
            from sage.algebras.lie_algebras.abelian import AbelianLieAlgebra
            return AbelianLieAlgebra(R, names, index_set, **kwds)

        if (names is None and len(index_set) <= 1) or len(names) <= 1:
            from sage.algebras.lie_algebras.abelian import AbelianLieAlgebra
            return AbelianLieAlgebra(R, names, index_set, **kwds)

        return super(LieAlgebraWithStructureCoefficients, cls).__classcall__(
            cls, R, s_coeff, names, index_set, **kwds)
Example #13
0
    def __classcall_private__(cls, A, gens=None, names=None, index_set=None,
                              free_lie_algebra=False):
        """
        Normalize input to ensure a unique representation.

        TESTS::

            sage: G = SymmetricGroup(3)
            sage: S = GroupAlgebra(G, QQ)
            sage: L1 = LieAlgebra(associative=tuple(S.gens()), names=['x','y'])
            sage: L2 = LieAlgebra(associative=[ S(G((1,2,3))), S(G((1,2))) ], names='x,y')
            sage: L1 is L2
            True

            sage: F.<x,y,z> = FreeAlgebra(QQ)
            sage: L1 = LieAlgebra(associative=F.algebra_generators(), names='x,y,z')
            sage: L2.<x,y,z> = LieAlgebra(associative=F.gens())
            sage: L1 is L2
            True
        """
        # If A is not a ring, then we treat it as a set of generators
        if isinstance(A, Parent) and A.category().is_subcategory(Rings()):
            if gens is None and index_set is None:
                # Use the indexing set of the basis
                try:
                    index_set = A.basis().keys()
                except (AttributeError, NotImplementedError):
                    pass
        else:
            gens = A
            A = None

        if index_set is None:
            # See if we can get an index set from the generators
            try:
                index_set = gens.keys()
            except (AttributeError, ValueError):
                pass

        ngens = None
        if isinstance(gens, AbstractFamily):
            if index_set is None and names is None:
                index_set = gens.keys()
            if gens.cardinality() < float('inf'):
                # TODO: This makes the generators of a finitely generated
                #    Lie algebra into an ordered list for uniqueness and then
                #    reconstructs the family. Instead create a key for the
                #    cache this way and then pass the family.
                try:
                    gens = tuple([gens[i] for i in index_set])
                except KeyError:
                    gens = tuple(gens)
                ngens = len(gens)

        elif isinstance(gens, dict):
            if index_set is None and names is None:
                index_set = gens.keys()
            gens = gens.values()
            ngens = len(gens)
        elif gens is not None: # Assume it is list-like
            gens = tuple(gens)
            ngens = len(gens)
            if index_set is None and names is None:
                index_set = list(range(ngens))

        if ngens is not None:
            if A is None:
                A = gens[0].parent()
            # Make sure all the generators have the same parent of A
            gens = tuple([A(g) for g in gens])

        names, index_set = standardize_names_index_set(names, index_set, ngens)

        if isinstance(A, MatrixSpace):
            if gens is not None:
                for g in gens:
                    g.set_immutable()
            return MatrixLieAlgebraFromAssociative(A, gens, names=names,
                                                   index_set=index_set)

        return super(LieAlgebraFromAssociative, cls).__classcall__(cls,
                     A, gens, names=names, index_set=index_set)
Example #14
0
    def __init__(self,
                 R,
                 ngens=None,
                 gram_matrix=None,
                 names=None,
                 index_set=None):
        """
        Initialize self.

        TESTS::

            sage: V = lie_conformal_algebras.Weyl(QQ)
            sage: TestSuite(V).run()
        """
        from sage.matrix.matrix_space import MatrixSpace
        if ngens:
            try:
                from sage.rings.integer_ring import ZZ
                assert ngens in ZZ and ngens % 2 == 0
            except AssertionError:
                raise ValueError("ngens needs to be an even positive " +
                                 "Integer, got {}".format(ngens))
        if (gram_matrix is not None):
            if ngens is None:
                ngens = gram_matrix.dimensions()[0]
            try:
                assert (gram_matrix in MatrixSpace(R, ngens, ngens))
            except AssertionError:
                raise ValueError(
                    "The gram_matrix should be a skew-symmetric " +
                    "{0} x {0} matrix, got {1}".format(ngens, gram_matrix))
            if (not gram_matrix.is_skew_symmetric()) or \
                                                (gram_matrix.is_singular()):
                raise ValueError("The gram_matrix should be a non degenerate " +
                                 "skew-symmetric {0} x {0} matrix, got {1}"\
                                 .format(ngens,gram_matrix))
        elif (gram_matrix is None):
            if ngens is None:
                ngens = 2
            A = identity_matrix(R, ngens // 2)
            from sage.matrix.special import block_matrix
            gram_matrix = block_matrix([[R.zero(), A], [-A, R.zero()]])

        latex_names = None
        if (names is None) and (index_set is None):
            names = 'alpha'
            latex_names = tuple(r'\alpha_{%d}' % i \
                                      for i in range (ngens)) + ('K',)
        names, index_set = standardize_names_index_set(names=names,
                                                       index_set=index_set,
                                                       ngens=ngens)
        weyldict = {(i, j): {
            0: {
                ('K', 0): gram_matrix[index_set.rank(i),
                                      index_set.rank(j)]
            }
        }
                    for i in index_set for j in index_set}

        super(WeylLieConformalAlgebra, self).__init__(R,
                                                      weyldict,
                                                      names=names,
                                                      latex_names=latex_names,
                                                      index_set=index_set,
                                                      central_elements=('K', ))
        self._gram_matrix = gram_matrix
Example #15
0
    def __classcall_private__(cls,
                              R,
                              s_coeff,
                              names=None,
                              index_set=None,
                              category=None,
                              **kwds):
        """
        Normalize input to ensure a unique representation.

        EXAMPLES:

        If the variable order is specified, the order of structural
        coefficients does not matter::

            sage: from sage.algebras.lie_algebras.nilpotent_lie_algebra import NilpotentLieAlgebra_dense
            sage: L1.<x,y,z> = NilpotentLieAlgebra_dense(QQ, {('x','y'): {'z': 1}})
            sage: L2.<x,y,z> = NilpotentLieAlgebra_dense(QQ, {('y','x'): {'z': -1}})
            sage: L1 is L2
            True

        If the variables are implicitly defined by the structural coefficients,
        the ordering may be different and the Lie algebras will be considered
        different::

            sage: from sage.algebras.lie_algebras.nilpotent_lie_algebra import NilpotentLieAlgebra_dense
            sage: L1 = NilpotentLieAlgebra_dense(QQ, {('x','y'): {'z': 1}})
            sage: L2 = NilpotentLieAlgebra_dense(QQ, {('y','x'): {'z': -1}})
            sage: L1
            Nilpotent Lie algebra on 3 generators (x, y, z) over Rational Field
            sage: L2
            Nilpotent Lie algebra on 3 generators (y, x, z) over Rational Field
            sage: L1 is L2
            False

        Constructed using two different methods from :class:`LieAlgebra`
        yields the same Lie algebra::

            sage: sc = {('X','Y'): {'Z': 1}}
            sage: C = LieAlgebras(QQ).Nilpotent().FiniteDimensional().WithBasis()
            sage: L1.<X,Y,Z> = LieAlgebra(QQ, sc, category=C)
            sage: L2 = LieAlgebra(QQ, sc, nilpotent=True, names=['X','Y','Z'])
            sage: L1 is L2
            True
        """
        if not names:
            # extract names from structural coefficients
            names = []
            for (X, Y), d in s_coeff.items():
                if X not in names: names.append(X)
                if Y not in names: names.append(Y)
                for k in d:
                    if k not in names: names.append(k)

        from sage.structure.indexed_generators import standardize_names_index_set
        names, index_set = standardize_names_index_set(names, index_set)
        s_coeff = LieAlgebraWithStructureCoefficients._standardize_s_coeff(
            s_coeff, index_set)

        cat = LieAlgebras(R).FiniteDimensional().WithBasis().Nilpotent()
        category = cat.or_subcategory(category)

        return super(NilpotentLieAlgebra_dense,
                     cls).__classcall__(cls,
                                        R,
                                        s_coeff,
                                        names,
                                        index_set,
                                        category=category,
                                        **kwds)
Example #16
0
    def __init__(self, R, r, s, names, naming, category, **kwds):
        r"""
        Initialize ``self``

        EXAMPLES::

            sage: L = LieAlgebra(ZZ, 2, step=2)
            sage: TestSuite(L).run()

            sage: L = LieAlgebra(QQ, 4, step=3)
            sage: TestSuite(L).run()  # long time
        """
        if r not in ZZ or r <= 0:
            raise ValueError("number of generators %s is not "
                             "a positive integer" % r)
        if s not in ZZ or s <= 0:
            raise ValueError("step %s is not a positive integer" % s)

        # extract an index set from the Lyndon words of the corresponding
        # free Lie algebra, and store the corresponding elements in a dict
        from sage.algebras.lie_algebras.lie_algebra import LieAlgebra

        free_gen_names = ['F%d' % k for k in range(r)]
        free_gen_names_inv = {
            val: i + 1
            for i, val in enumerate(free_gen_names)
        }
        L = LieAlgebra(R, free_gen_names).Lyndon()

        basis_by_deg = {d: [] for d in range(1, s + 1)}
        for d in range(1, s + 1):
            for X in L.graded_basis(d):
                # convert brackets of form [X_1, [X_1, X_2]] to words (1,1,2)
                w = tuple(free_gen_names_inv[s]
                          for s in X.leading_support().to_word())
                basis_by_deg[d].append((w, X))

        index_set = [ind for d in basis_by_deg for ind, val in basis_by_deg[d]]

        if len(names) == 1 and len(index_set) > 1:
            if not naming:
                if r >= 10:
                    naming = 'linear'
                else:
                    naming = 'index'
            if naming == 'linear':
                names = [
                    '%s_%d' % (names[0], k + 1) for k in range(len(index_set))
                ]
            elif naming == 'index':
                if r >= 10:
                    raise ValueError("'index' naming scheme not supported for "
                                     "10 or more generators")
                names = [
                    '%s_%s' % (names[0], "".join(str(s) for s in ind))
                    for ind in index_set
                ]
            else:
                raise ValueError("unknown naming scheme %s" % naming)

        # extract structural coefficients from the free Lie algebra
        s_coeff = {}
        for dx in range(1, s + 1):
            # Brackets are only computed when deg(X) + deg(Y) <= s
            # We also require deg(Y) >= deg(X) by the ordering
            for dy in range(dx, s + 1 - dx):
                if dx == dy:
                    for i, val in enumerate(basis_by_deg[dx]):
                        X_ind, X = val
                        for Y_ind, Y in basis_by_deg[dy][i + 1:]:
                            Z = L[X, Y]
                            if not Z.is_zero():
                                s_coeff[(X_ind, Y_ind)] = {
                                    W_ind: Z[W.leading_support()]
                                    for W_ind, W in basis_by_deg[dx + dy]
                                }
                else:
                    for X_ind, X in basis_by_deg[dx]:
                        for Y_ind, Y in basis_by_deg[dy]:
                            Z = L[X, Y]
                            if not Z.is_zero():
                                s_coeff[(X_ind, Y_ind)] = {
                                    W_ind: Z[W.leading_support()]
                                    for W_ind, W in basis_by_deg[dx + dy]
                                }

        names, index_set = standardize_names_index_set(names, index_set)
        s_coeff = LieAlgebraWithStructureCoefficients._standardize_s_coeff(
            s_coeff, index_set)

        NilpotentLieAlgebra_dense.__init__(self,
                                           R,
                                           s_coeff,
                                           names,
                                           index_set,
                                           s,
                                           category=category,
                                           **kwds)
Example #17
0
    def __init__(self, R, r, s, names, naming, category, **kwds):
        r"""
        Initialize ``self``

        EXAMPLES::

            sage: L = LieAlgebra(ZZ, 2, step=2)
            sage: TestSuite(L).run()

            sage: L = LieAlgebra(QQ, 4, step=3)
            sage: TestSuite(L).run()  # long time
        """
        if r not in ZZ or r <= 0:
            raise ValueError("number of generators %s is not "
                             "a positive integer" % r)
        if s not in ZZ or s <= 0:
            raise ValueError("step %s is not a positive integer" % s)

        # extract an index set from the Lyndon words of the corresponding
        # free Lie algebra, and store the corresponding elements in a dict
        from sage.algebras.lie_algebras.lie_algebra import LieAlgebra

        free_gen_names = ['F%d' % k for k in range(r)]
        free_gen_names_inv = {val: i + 1 for i, val in enumerate(free_gen_names)}
        L = LieAlgebra(R, free_gen_names).Lyndon()

        basis_by_deg = {d: [] for d in range(1, s + 1)}
        for d in range(1, s + 1):
            for X in L.graded_basis(d):
                # convert brackets of form [X_1, [X_1, X_2]] to words (1,1,2)
                w = tuple(free_gen_names_inv[s]
                          for s in X.leading_support().to_word())
                basis_by_deg[d].append((w, X))

        index_set = [ind for d in basis_by_deg for ind, val in basis_by_deg[d]]

        if len(names) == 1 and len(index_set) > 1:
            if not naming:
                if r >= 10:
                    naming = 'linear'
                else:
                    naming = 'index'
            if naming == 'linear':
                names = ['%s_%d' % (names[0], k + 1)
                         for k in range(len(index_set))]
            elif naming == 'index':
                if r >= 10:
                    raise ValueError("'index' naming scheme not supported for "
                                     "10 or more generators")
                names = ['%s_%s' % (names[0], "".join(str(s) for s in w))
                         for w in index_set]
            else:
                raise ValueError("unknown naming scheme %s" % naming)

        # extract structural coefficients from the free Lie algebra
        s_coeff = {}
        for dx in range(1, s + 1):
            # Brackets are only computed when deg(X) + deg(Y) <= s
            # We also require deg(Y) >= deg(X) by the ordering
            for dy in range(dx, s + 1 - dx):
                if dx == dy:
                    for i, val in enumerate(basis_by_deg[dx]):
                        X_ind, X = val
                        for Y_ind, Y in basis_by_deg[dy][i + 1:]:
                            Z = L[X, Y]
                            if not Z.is_zero():
                                s_coeff[(X_ind, Y_ind)] = {W_ind: Z[W.leading_support()]
                                                           for W_ind, W in basis_by_deg[dx + dy]}
                else:
                    for X_ind, X in basis_by_deg[dx]:
                        for Y_ind, Y in basis_by_deg[dy]:
                            Z = L[X, Y]
                            if not Z.is_zero():
                                s_coeff[(X_ind, Y_ind)] = {W_ind: Z[W.leading_support()]
                                                           for W_ind, W in basis_by_deg[dx + dy]}

        names, index_set = standardize_names_index_set(names, index_set)
        s_coeff = LieAlgebraWithStructureCoefficients._standardize_s_coeff(
            s_coeff, index_set)

        NilpotentLieAlgebra_dense.__init__(self, R, s_coeff, names,
                                           index_set, s,
                                           category=category, **kwds)
Example #18
0
    def __classcall_private__(cls,
                              I,
                              ambient=None,
                              names=None,
                              index_set=None,
                              category=None):
        r"""
        Normalize input to ensure a unique representation.

        EXAMPLES:

        Specifying the ambient Lie algebra is not necessary::

            sage: from sage.algebras.lie_algebras.quotient import LieQuotient_finite_dimensional_with_basis
            sage: L.<X,Y> = LieAlgebra(QQ, {('X','Y'): {'X': 1}})
            sage: Q1 = LieQuotient_finite_dimensional_with_basis(X, ambient=L)
            sage: Q2 = LieQuotient_finite_dimensional_with_basis(X)
            sage: Q1 is Q2
            True

        Variable names are extracted from the ambient Lie algebra by default::

            sage: Q3 = L.quotient(X, names=['Y'])
            sage: Q1 is Q3
            True
        """
        if not isinstance(I, LieSubalgebra_finite_dimensional_with_basis):
            # assume I is an element or list of elements of some lie algebra
            if ambient is None:
                if not isinstance(I, (list, tuple)):
                    ambient = I.parent()
                else:
                    ambient = I[0].parent()
            I = ambient.ideal(I)
        if ambient is None:
            ambient = I.ambient()

        if not ambient.base_ring().is_field():
            raise NotImplementedError("quotients over non-fields "
                                      "not implemented")

        # extract an index set from a complementary basis to the ideal
        I_supp = [X.leading_support() for X in I.leading_monomials()]
        inv = ambient.basis().inverse_family()
        sorted_indices = [inv[X] for X in ambient.basis()]
        index_set = [i for i in sorted_indices if i not in I_supp]

        if names is None:
            amb_names = dict(zip(sorted_indices, ambient.variable_names()))
            names = [amb_names[i] for i in index_set]
        elif isinstance(names, str):
            if len(index_set) == 1:
                names = [names]
            else:
                names = [
                    '%s_%d' % (names, k + 1) for k in range(len(index_set))
                ]
        names, index_set = standardize_names_index_set(names, index_set)

        cat = LieAlgebras(ambient.base_ring()).FiniteDimensional().WithBasis()
        if ambient in LieAlgebras(ambient.base_ring()).Nilpotent():
            cat = cat.Nilpotent()
        category = cat.Subquotients().or_subcategory(category)

        sup = super(LieQuotient_finite_dimensional_with_basis, cls)
        return sup.__classcall__(cls,
                                 I,
                                 ambient,
                                 names,
                                 index_set,
                                 category=category)
Example #19
0
    def __classcall_private__(cls,
                              A,
                              gens=None,
                              names=None,
                              index_set=None,
                              free_lie_algebra=False):
        """
        Normalize input to ensure a unique representation.

        TESTS::

            sage: G = SymmetricGroup(3)
            sage: S = GroupAlgebra(G, QQ)
            sage: L1 = LieAlgebra(associative=tuple(S.gens()), names=['x','y'])
            sage: L2 = LieAlgebra(associative=[ S(G((1,2,3))), S(G((1,2))) ], names='x,y')
            sage: L1 is L2
            True

            sage: F.<x,y,z> = FreeAlgebra(QQ)
            sage: L1 = LieAlgebra(associative=F.algebra_generators(), names='x,y,z')
            sage: L2.<x,y,z> = LieAlgebra(associative=F.gens())
            sage: L1 is L2
            True
        """
        # If A is not a ring, then we treat it as a set of generators
        if isinstance(A, Parent) and A.category().is_subcategory(Rings()):
            if gens is None and index_set is None:
                # Use the indexing set of the basis
                try:
                    index_set = A.basis().keys()
                except (AttributeError, NotImplementedError):
                    pass
        else:
            gens = A
            A = None

        if index_set is None:
            # See if we can get an index set from the generators
            try:
                index_set = gens.keys()
            except (AttributeError, ValueError):
                pass

        ngens = None
        if isinstance(gens, AbstractFamily):
            if index_set is None and names is None:
                index_set = gens.keys()
            if gens.cardinality() < float('inf'):
                # TODO: This makes the generators of a finitely generated
                #    Lie algebra into an ordered list for uniqueness and then
                #    reconstructs the family. Instead create a key for the
                #    cache this way and then pass the family.
                try:
                    gens = tuple([gens[i] for i in index_set])
                except KeyError:
                    gens = tuple(gens)
                ngens = len(gens)

        elif isinstance(gens, dict):
            if index_set is None and names is None:
                index_set = gens.keys()
            gens = gens.values()
            ngens = len(gens)
        elif gens is not None:  # Assume it is list-like
            gens = tuple(gens)
            ngens = len(gens)
            if index_set is None and names is None:
                index_set = list(range(ngens))

        if ngens is not None:
            if A is None:
                A = gens[0].parent()
            # Make sure all the generators have the same parent of A
            gens = tuple([A(g) for g in gens])

        names, index_set = standardize_names_index_set(names, index_set, ngens)

        if isinstance(A, MatrixSpace):
            if gens is not None:
                for g in gens:
                    g.set_immutable()
            return MatrixLieAlgebraFromAssociative(A,
                                                   gens,
                                                   names=names,
                                                   index_set=index_set)

        return super(LieAlgebraFromAssociative,
                     cls).__classcall__(cls,
                                        A,
                                        gens,
                                        names=names,
                                        index_set=index_set)
Example #20
0
    def __init__(self,
                 R,
                 s_coeff,
                 index_set=None,
                 central_elements=None,
                 category=None,
                 element_class=None,
                 prefix=None,
                 names=None,
                 latex_names=None,
                 parity=None,
                 **kwds):
        """
        Initialize self.

        TESTS::

            sage: V = lie_conformal_algebras.NeveuSchwarz(QQ)
            sage: TestSuite(V).run()
        """
        names, index_set = standardize_names_index_set(names, index_set)
        if central_elements is None:
            central_elements = tuple()

        if names is not None and names != tuple(index_set):
            names2 = names + tuple(central_elements)
            index_set2 = DisjointUnionEnumeratedSets(
                (index_set, Family(tuple(central_elements))))
            d = {x: index_set2[i] for i, x in enumerate(names2)}
            try:
                #If we are given a dictionary with names as keys,
                #convert to index_set as keys
                s_coeff = {(d[k[0]], d[k[1]]): {
                    a: {(d[x[1]], x[2]): s_coeff[k][a][x]
                        for x in s_coeff[k][a]}
                    for a in s_coeff[k]
                }
                           for k in s_coeff.keys()}

            except KeyError:
                # We assume the dictionary was given with keys in the
                # index_set
                pass

        issuper = kwds.pop('super', False)
        if parity is None:
            parity = (0, ) * index_set.cardinality()
        else:
            issuper = True

        try:
            assert len(parity) == index_set.cardinality()
        except AssertionError:
            raise ValueError("parity should have the same length as the "\
                             "number of generators, got {}".format(parity))

        s_coeff = LieConformalAlgebraWithStructureCoefficients\
                    ._standardize_s_coeff(s_coeff, index_set, central_elements,
                                          parity)

        if names is not None and central_elements is not None:
            names += tuple(central_elements)

        self._index_to_pos = {k: i for i, k in enumerate(index_set)}
        #Add central parameters to index_to_pos so that we can
        #represent names
        if central_elements is not None:
            for i, ce in enumerate(central_elements):
                self._index_to_pos[ce] = len(index_set) + i

        default_category = LieConformalAlgebras(
            R).WithBasis().FinitelyGenerated()
        if issuper:
            category = default_category.Super().or_subcategory(category)
        else:
            category = default_category.or_subcategory(category)

        if element_class is None:
            element_class = LCAStructureCoefficientsElement

        FinitelyFreelyGeneratedLCA.__init__(self,
                                            R,
                                            index_set=index_set,
                                            central_elements=central_elements,
                                            category=category,
                                            element_class=element_class,
                                            prefix=prefix,
                                            names=names,
                                            latex_names=latex_names,
                                            **kwds)

        s_coeff = dict(s_coeff)
        self._s_coeff = Family({
            k: tuple((j, sum(c * self.monomial(i) for i, c in v))
                     for j, v in s_coeff[k])
            for k in s_coeff
        })
        self._parity = dict(
            zip(self.gens(), parity + (0, ) * len(central_elements)))
Example #21
0
    def __classcall_private__(cls, I, ambient=None, names=None,
                              index_set=None, category=None):
        r"""
        Normalize input to ensure a unique representation.

        EXAMPLES:

        Specifying the ambient Lie algebra is not necessary::

            sage: from sage.algebras.lie_algebras.quotient import LieQuotient_finite_dimensional_with_basis
            sage: L.<X,Y> = LieAlgebra(QQ, {('X','Y'): {'X': 1}})
            sage: Q1 = LieQuotient_finite_dimensional_with_basis(X, ambient=L)
            sage: Q2 = LieQuotient_finite_dimensional_with_basis(X)
            sage: Q1 is Q2
            True

        Variable names are extracted from the ambient Lie algebra by default::

            sage: Q3 = L.quotient(X, names=['Y'])
            sage: Q1 is Q3
            True
        """
        if not isinstance(I, LieSubalgebra_finite_dimensional_with_basis):
            # assume I is an element or list of elements of some lie algebra
            if ambient is None:
                if not isinstance(I, (list, tuple)):
                    ambient = I.parent()
                else:
                    ambient = I[0].parent()
            I = ambient.ideal(I)
        if ambient is None:
            ambient = I.ambient()

        if not ambient.base_ring().is_field():
            raise NotImplementedError("quotients over non-fields "
                                      "not implemented")

        # extract an index set from a complementary basis to the ideal
        I_supp = [X.leading_support() for X in I.leading_monomials()]
        inv = ambient.basis().inverse_family()
        sorted_indices = [inv[X] for X in ambient.basis()]
        index_set = [i for i in sorted_indices if i not in I_supp]

        if names is None:
            amb_names = dict(zip(sorted_indices, ambient.variable_names()))
            names = [amb_names[i] for i in index_set]
        elif isinstance(names, str):
            if len(index_set) == 1:
                names = [names]
            else:
                names = ['%s_%d' % (names, k + 1)
                         for k in range(len(index_set))]
        names, index_set = standardize_names_index_set(names, index_set)

        cat = LieAlgebras(ambient.base_ring()).FiniteDimensional().WithBasis()
        if ambient in LieAlgebras(ambient.base_ring()).Nilpotent():
            cat = cat.Nilpotent()
        category = cat.Subquotients().or_subcategory(category)

        sup = super(LieQuotient_finite_dimensional_with_basis, cls)
        return sup.__classcall__(cls, I, ambient, names, index_set,
                                 category=category)