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)
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)
def __init__(self, R, names, index_set, category, **kwds): """ Initialize ``self``. EXAMPLES:: sage: L = LieAlgebra(QQ, 3, 'x', abelian=True) sage: TestSuite(L).run() """ cat = LieAlgebras(R).FiniteDimensional().WithBasis().Nilpotent() category = cat.or_subcategory(category) LieAlgebraWithStructureCoefficients.__init__(self, R, Family({}), names, index_set, category, **kwds)
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)
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)