Exemple #1
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)
def in_new_basis(L, basis, names, check=True, category=None):
    r"""
    Return an isomorphic copy of the Lie algebra in a different basis.

    INPUT:

    - ``L`` -- the Lie algebra
    - ``basis`` -- a list of elements of the Lie algebra
    - ``names`` -- a list of strings to use as names for the new basis
    - ``check`` -- (default:``True``) a boolean; if ``True``, verify
      that the list ``basis`` is indeed a basis of the Lie algebra
    - ``category`` -- (default:``None``) a subcategory of
      :class:`FiniteDimensionalLieAlgebrasWithBasis` to apply to the
      new Lie algebra.

    EXAMPLES:

    The method may be used to relabel the elements::

        sage: import sys, pathlib
        sage: sys.path.append(str(pathlib.Path().absolute()))
        sage: from lie_gradings.gradings.utilities import in_new_basis
        sage: L.<X,Y> = LieAlgebra(QQ, {('X','Y'): {'Y': 1}})
        sage: K.<A,B> = in_new_basis(L, [X, Y])
        sage: K[A,B]
        B

    The new Lie algebra inherits nilpotency::

        sage: L = lie_algebras.Heisenberg(QQ, 1)
        sage: X,Y,Z = L.basis()
        sage: L.category()
        Category of finite dimensional nilpotent lie algebras with basis over Rational Field
        sage: K.<A,B,C> = in_new_basis(L, [X + Y, Y - X, Z])
        sage: K[A,B]
        2*C
        sage: K[[A,B],A]
        0
        sage: K.is_nilpotent()
        True
        sage: K.category()
        Category of finite dimensional nilpotent lie algebras with basis over Rational Field

    Some properties such as being stratified may in general be lost when
    changing the basis, and are therefore not preserved::

        sage: L.<X,Y,Z> = LieAlgebra(QQ, 2, step=2)
        sage: L.category()
        Category of finite dimensional stratified lie algebras with basis over Rational Field
        sage: K.<A,B,C> = in_new_basis(L, [Z, X, Y])
        sage: K.category()
        Category of finite dimensional nilpotent lie algebras with basis over Rational Field

    If the property is known to be preserved, an extra category may
    be passed to the method::

        sage: C = L.category()
        sage: K.<A,B,C> = in_new_basis(L, [Z, X, Y], category=C)
        sage: K.category()
        Category of finite dimensional stratified lie algebras with basis over Rational Field
    """
    try:
        m = L.module()
    except AttributeError:
        m = FreeModule(L.base_ring(), L.dimension())
    sm = m.submodule_with_basis([X.to_vector() for X in basis])

    if check:
        # check that new basis is a basis
        A = matrix([X.to_vector() for X in basis])
        if not A.is_invertible():
            raise ValueError("%s is not a basis of the Lie algebra" % basis)

    # form dictionary of structure coefficients in the new basis
    sc = {}
    for (X, nX), (Y, nY) in combinations(zip(basis, names), 2):
        Z = X.bracket(Y)
        zvec = sm.coordinate_vector(Z.to_vector())
        sc[(nX, nY)] = {nW: c for nW, c in zip(names, zvec)}

    C = LieAlgebras(L.base_ring()).FiniteDimensional().WithBasis()
    C = C.or_subcategory(category)
    if L.is_nilpotent():
        C = C.Nilpotent()

    return LieAlgebra(L.base_ring(), sc, names=names, category=C)