Beispiel #1
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)
Beispiel #2
0
def abelian(R, names=None, index_set=None):
    """
    Return the abelian Lie algebra generated by ``names``.

    EXAMPLES::

        sage: lie_algebras.abelian(QQ, 'x, y, z')
        Abelian Lie algebra on 3 generators (x, y, z) over Rational Field
    """
    if isinstance(names, str):
        names = names.split(',')
    elif isinstance(names, (list, tuple)):
        names = tuple(names)
    elif names is not None:
        if index_set is not None:
            raise ValueError("invalid generator names")
        index_set = names
        names = None
    from sage.rings.infinity import infinity
    if (index_set is not None
            and not isinstance(index_set, (list, tuple))
            and index_set.cardinality() == infinity):
        from sage.algebras.lie_algebras.abelian import InfiniteDimensionalAbelianLieAlgebra
        return InfiniteDimensionalAbelianLieAlgebra(R, index_set=index_set)
    from sage.algebras.lie_algebras.abelian import AbelianLieAlgebra
    return AbelianLieAlgebra(R, names=names, index_set=index_set)
Beispiel #3
0
def three_dimensional_by_rank(R, n, a=None, names=['X', 'Y', 'Z']):
    r"""
    Return a 3-dimensional Lie algebra of rank ``n``, where `0 \leq n \leq 3`.

    Here, the *rank* of a Lie algebra `L` is defined as the dimension
    of its derived subalgebra `[L, L]`. (We are assuming that `R` is
    a field of characteristic `0`; otherwise the Lie algebras
    constructed by this function are still well-defined but no longer
    might have the correct ranks.) This is not to be confused with
    the other standard definition of a rank (namely, as the
    dimension of a Cartan subalgebra, when `L` is semisimple).

    INPUT:

    - ``R`` -- the base ring
    - ``n`` -- the rank
    - ``a`` -- the deformation parameter (used for `n = 2`); this should
      be a nonzero element of `R` in order for the resulting Lie
      algebra to actually have the right rank(?)
    - ``names`` -- (optional) the generator names

    EXAMPLES::

        sage: lie_algebras.three_dimensional_by_rank(QQ, 0)
        Abelian Lie algebra on 3 generators (X, Y, Z) over Rational Field
        sage: L = lie_algebras.three_dimensional_by_rank(QQ, 1)
        sage: L.structure_coefficients()
        Finite family {('Y', 'Z'): X}
        sage: L = lie_algebras.three_dimensional_by_rank(QQ, 2, 4)
        sage: L.structure_coefficients()
        Finite family {('X', 'Y'): Y, ('X', 'Z'): Y + Z}
        sage: L = lie_algebras.three_dimensional_by_rank(QQ, 2, 0)
        sage: L.structure_coefficients()
        Finite family {('X', 'Y'): Y}
        sage: lie_algebras.three_dimensional_by_rank(QQ, 3)
        sl2 over Rational Field
    """
    if isinstance(names, str):
        names = names.split(',')
    names = tuple(names)

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

    if n == 1:
        L = three_dimensional(R, 0, 1, 0, 0, names=names) # Strictly upper triangular matrices
        L.rename("Lie algebra of 3x3 strictly upper triangular matrices over {}".format(R))
        return L

    if n == 2:
        if a is None:
            raise ValueError("The parameter 'a' must be specified")
        X = names[0]
        Y = names[1]
        Z = names[2]
        from sage.algebras.lie_algebras.structure_coefficients import LieAlgebraWithStructureCoefficients
        if a == 0:
            s_coeff = {(X,Y): {Y:R.one()}, (X,Z): {Y:R(a)}}
            # Why use R(a) here if R == 0 ? Also this has rank 1.
            L = LieAlgebraWithStructureCoefficients(R, s_coeff, tuple(names))
            L.rename("Degenerate Lie algebra of dimension 3 and rank 2 over {}".format(R))
        else:
            s_coeff = {(X,Y): {Y:R.one()}, (X,Z): {Y:R.one(), Z:R.one()}}
            # a doesn't appear here :/
            L = LieAlgebraWithStructureCoefficients(R, s_coeff, tuple(names))
            L.rename("Lie algebra of dimension 3 and rank 2 with parameter {} over {}".format(a, R))
        return L

    if n == 3:
        #return sl(R, 2)
        from sage.algebras.lie_algebras.structure_coefficients import LieAlgebraWithStructureCoefficients
        E = names[0]
        F = names[1]
        H = names[2]
        s_coeff = { (E,F): {H:R.one()}, (H,E): {E:R(2)}, (H,F): {F:R(-2)} }
        L = LieAlgebraWithStructureCoefficients(R, s_coeff, tuple(names))
        L.rename("sl2 over {}".format(R))
        return L

    raise ValueError("Invalid rank")
Beispiel #4
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")