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 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)
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")
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")