Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
Merge remote-tracking branch 'trac/public/lie_algebras/base_class_nil…
Browse files Browse the repository at this point in the history
…ponent-26074' into free_nilpotent_lie_algebras
  • Loading branch information
ehaka committed Aug 21, 2018
2 parents cb8a103 + f1a0b1e commit 4d4bdf6
Show file tree
Hide file tree
Showing 12 changed files with 505 additions and 469 deletions.
4 changes: 4 additions & 0 deletions src/doc/en/reference/categories/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ Individual Categories
sage/categories/finite_dimensional_algebras_with_basis
sage/categories/finite_dimensional_bialgebras_with_basis
sage/categories/finite_dimensional_coalgebras_with_basis
sage/categories/finite_dimensional_graded_lie_algebras_with_basis
sage/categories/finite_dimensional_hopf_algebras_with_basis
sage/categories/finite_dimensional_lie_algebras_with_basis
sage/categories/finite_dimensional_modules_with_basis
Expand Down Expand Up @@ -107,6 +108,8 @@ Individual Categories
sage/categories/graded_coalgebras_with_basis
sage/categories/graded_hopf_algebras
sage/categories/graded_hopf_algebras_with_basis
sage/categories/graded_lie_algebras
sage/categories/graded_lie_algebras_with_basis
sage/categories/graded_modules
sage/categories/graded_modules_with_basis
sage/categories/graphs
Expand Down Expand Up @@ -228,6 +231,7 @@ Examples of parents using categories
sage/categories/examples/finite_dimensional_algebras_with_basis
sage/categories/examples/finite_enumerated_sets
sage/categories/examples/finite_dimensional_lie_algebras_with_basis
sage/categories/examples/finite_dimensional_nilpotent_lie_algebras_with_basis
sage/categories/examples/finite_monoids
sage/categories/examples/finite_semigroups
sage/categories/examples/finite_weyl_groups
Expand Down
35 changes: 31 additions & 4 deletions src/sage/algebras/lie_algebras/heisenberg.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,22 @@ def _latex_term(self, m):
return m
return "%s_{%s}"%(m[0], m[1:]) # else it is of length at least 2

def step(self):
r"""
Return the nilpotency step of ``self``.
EXAMPLES::
sage: h = lie_algebras.Heisenberg(ZZ, 10)
sage: h.step()
2
sage: h = lie_algebras.Heisenberg(ZZ, oo)
sage: h.step()
2
"""
return Integer(2)

class Element(LieAlgebraElement):
pass

Expand Down Expand Up @@ -353,7 +369,7 @@ def __init__(self, R, n):
+ ['q%s'%i for i in range(1,n+1)]
+ ['z'])
LieAlgebraWithGenerators.__init__(self, R, names=names, index_set=names,
category=LieAlgebras(R).FiniteDimensional().WithBasis())
category=LieAlgebras(R).Nilpotent().FiniteDimensional().WithBasis())
HeisenbergAlgebra_abstract.__init__(self, names)

def _repr_(self):
Expand Down Expand Up @@ -389,7 +405,7 @@ def __init__(self, R):
True
"""
S = cartesian_product([PositiveIntegers(), ['p','q']])
cat = LieAlgebras(R).WithBasis()
cat = LieAlgebras(R).Nilpotent().WithBasis()
LieAlgebraWithGenerators.__init__(self, R, index_set=S, category=cat)
HeisenbergAlgebra_abstract.__init__(self, S)

Expand Down Expand Up @@ -427,7 +443,6 @@ def lie_algebra_generators(self):
sage: L.lie_algebra_generators()
Lazy family (generator map(i))_{i in The Cartesian product of
(Positive integers, {'p', 'q'})}
"""
return Family(self._indices, lambda x: self.monomial(x[1] + str(x[0])),
name='generator map')
Expand Down Expand Up @@ -652,7 +667,7 @@ def __init__(self, R, n):
z = (MS({(0,n+1): one}),)
names = tuple('p%s'%i for i in range(1,n+1))
names = names + tuple('q%s'%i for i in range(1,n+1)) + ('z',)
cat = LieAlgebras(R).FiniteDimensional().WithBasis()
cat = LieAlgebras(R).Nilpotent().FiniteDimensional().WithBasis()
LieAlgebraFromAssociative.__init__(self, MS, p + q + z, names=names,
index_set=names, category=cat)

Expand Down Expand Up @@ -711,6 +726,18 @@ def z(self):
"""
return self._gens['z']

def step(self):
r"""
Return the nilpotency step of ``self``.
EXAMPLES::
sage: h = lie_algebras.Heisenberg(ZZ, 2, representation="matrix")
sage: h.step()
2
"""
return Integer(2)

class Element(LieAlgebraMatrixWrapper, LieAlgebraFromAssociative.Element):
def monomial_coefficients(self, copy=True):
"""
Expand Down
38 changes: 34 additions & 4 deletions src/sage/algebras/lie_algebras/lie_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,31 @@ class LieAlgebra(Parent, UniqueRepresentation): # IndexedGenerators):
sage: P.bracket(a, b) + P.bracket(a - c, b + 3*c)
2*a*b + 3*a*c - 2*b*a + b*c - 3*c*a - c*b
**6.** Nilpotent Lie algebras are Lie algebras such that there exists an
integer `s` such that all iterated brackets of length longer than `s`
are zero. They can be constructed from structural coefficients using the
``nilpotent`` keyword::
sage: L.<X,Y,Z> = LieAlgebra(QQ, {('X','Y'): {'Z': 1}}, nilpotent=True)
sage: L
Nilpotent Lie algebra on 3 generators (X, Y, Z) over Rational Field
sage: L.category()
Category of finite dimensional nilpotent lie algebras with basis over Rational Field
A second example defining the Engel Lie algebra::
sage: sc = {('X','Y'): {'Z': 1}, ('X','Z'): {'W': 1}}
sage: E.<X,Y,Z,W> = LieAlgebra(QQ, sc, nilpotent=True); E
Nilpotent Lie algebra on 4 generators (X, Y, Z, W) over Rational Field
sage: E.step()
3
sage: E[X, Y + Z]
Z + W
sage: E[X, [X, Y + Z]]
W
sage: E[X, [X, [X, Y + Z]]]
0
REFERENCES:
- [deG2000]_ Willem A. de Graaf. *Lie Algebras: Theory and Algorithms*.
Expand All @@ -297,7 +322,8 @@ class LieAlgebra(Parent, UniqueRepresentation): # IndexedGenerators):
# __classcall_private__ will only be called when calling LieAlgebra
@staticmethod
def __classcall_private__(cls, R=None, arg0=None, arg1=None, names=None,
index_set=None, abelian=False, **kwds):
index_set=None, abelian=False,
nilpotent=False, **kwds):
"""
Select the correct parent based upon input.
Expand Down Expand Up @@ -376,6 +402,10 @@ def __classcall_private__(cls, R=None, arg0=None, arg1=None, names=None,

if isinstance(arg1, dict):
# Assume it is some structure coefficients
if nilpotent:
from sage.algebras.lie_algebras.nilpotent_lie_algebra import NilpotentLieAlgebra_dense
return NilpotentLieAlgebra_dense(R, arg1, names, index_set, **kwds)

from sage.algebras.lie_algebras.structure_coefficients import LieAlgebraWithStructureCoefficients
return LieAlgebraWithStructureCoefficients(R, arg1, names, index_set, **kwds)

Expand Down Expand Up @@ -434,7 +464,7 @@ def __init__(self, R, names=None, category=None):
sage: L.<x,y> = LieAlgebra(QQ, abelian=True)
sage: L.category()
Category of finite dimensional lie algebras with basis over Rational Field
Category of finite dimensional nilpotent lie algebras with basis over Rational Field
"""
category = LieAlgebras(R).or_subcategory(category)
Parent.__init__(self, base=R, names=names, category=category)
Expand Down Expand Up @@ -671,7 +701,7 @@ def __init__(self, R, names=None, index_set=None, category=None, prefix='L', **k
sage: L.<x,y> = LieAlgebra(QQ, abelian=True)
sage: L.category()
Category of finite dimensional lie algebras with basis over Rational Field
Category of finite dimensional nilpotent lie algebras with basis over Rational Field
"""
self._indices = index_set
LieAlgebra.__init__(self, R, names, category)
Expand Down Expand Up @@ -755,7 +785,7 @@ def __init__(self, R, names=None, index_set=None, category=None):
sage: L.<x,y> = LieAlgebra(QQ, abelian=True)
sage: L.category()
Category of finite dimensional lie algebras with basis over Rational Field
Category of finite dimensional nilpotent lie algebras with basis over Rational Field
"""
LieAlgebraWithGenerators.__init__(self, R, names, index_set, category)
self.__ngens = len(self._indices)
Expand Down
153 changes: 31 additions & 122 deletions src/sage/algebras/lie_algebras/nilpotent_lie_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,22 @@ class NilpotentLieAlgebra_dense(LieAlgebraWithStructureCoefficients):
- ``R`` -- the base ring
- ``s_coeff`` -- a dictionary of structural coefficients
- ``names`` -- (default:``None``) list of strings to use as names of basis
elements. If ``None``, the names will be inferred from the structural
coefficients.
elements; if ``None``, the names will be inferred from the structural
coefficients
- ``index_set`` -- (default:``None``) list of hashable and comparable
elements to use for indexing.
- ``step`` -- (default:``None``) an integer; the nilpotency step of the
Lie algebra. If ``None``, the nilpotency step is undefined and will need
to be computed later.
- ``category`` -- (default:``None``) a subcategory of
:class:`~sage.categories.lie_algebras.LieAlgebras.FiniteDimensional.WithBasis.Nilpotent`
elements to use for indexing
- ``step`` -- (optional) an integer; the nilpotency step of the
Lie algebra if known; otherwise it will be computed when needed
- ``category`` -- (optional) a subcategory of finite dimensional
nilpotent Lie algebras with basis
EXAMPLES:
The input to a :class:`NilpotentLieAlgebra_dense` should be of the same form
as to a :class:`~sage.algebras.lie_algebras.structure_coefficients.LieAlgebraWithStructureCoefficients`::
The input to a :class:`NilpotentLieAlgebra_dense` should be of the
same form as to a
:class:`~sage.algebras.lie_algebras.structure_coefficients.LieAlgebraWithStructureCoefficients`::
sage: from sage.algebras.lie_algebras.nilpotent_lie_algebra import NilpotentLieAlgebra_dense
sage: L.<X,Y,Z,W> = NilpotentLieAlgebra_dense(QQ, {('X','Y'): {'Z': 1}})
sage: L.<X,Y,Z,W> = LieAlgebra(QQ, {('X','Y'): {'Z': 1}}, nilpotent=True)
sage: L
Nilpotent Lie algebra on 4 generators (X, Y, Z, W) over Rational Field
sage: L[X, Y]
Expand All @@ -56,27 +55,25 @@ class NilpotentLieAlgebra_dense(LieAlgebraWithStructureCoefficients):
If the parameter ``names`` is omitted, then the terms appearing in the
structural coefficients are used as names::
sage: L = NilpotentLieAlgebra_dense(QQ, {('X','Y'): {'Z': 1}}); L
sage: L = LieAlgebra(QQ, {('X','Y'): {'Z': 1}}, nilpotent=True); L
Nilpotent Lie algebra on 3 generators (X, Y, Z) over Rational Field
TESTS::
sage: L = NilpotentLieAlgebra_dense(QQ, {('X','Y'): {'Z': 1},
....: ('X','Z'): {'W': 1},
....: ('Y','Z'): {'T': 1}})
sage: L = LieAlgebra(QQ, {('X','Y'): {'Z': 1},
....: ('X','Z'): {'W': 1},
....: ('Y','Z'): {'T': 1}}, nilpotent=True)
sage: TestSuite(L).run()
"""

@staticmethod
def __classcall_private__(cls, R, s_coeff, names=None, index_set=None, **kwds):
"""
Normalize input to ensure a unique representation.
EXAMPLES:
If the variable order is specified, the order of structural coefficients
does not matter::
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}})
Expand Down Expand Up @@ -118,34 +115,33 @@ def __classcall_private__(cls, R, s_coeff, names=None, index_set=None, **kwds):
def __init__(self, R, s_coeff, names, index_set, step=None,
category=None, **kwds):
r"""
Initialize ``self``
"""
Initialize ``self``.
EXAMPLES::
sage: L.<X,Y,Z,W> = LieAlgebra(QQ, {('X','Y'): {'Z': 1}}, nilpotent=True)
sage: TestSuite(L).run()
"""
if step:
self._step = step

category = LieAlgebras(R).FiniteDimensional().WithBasis() \
.Nilpotent().or_subcategory(category)
cat = LieAlgebras(R).FiniteDimensional().WithBasis().Nilpotent()
cat = cat.or_subcategory(category)
LieAlgebraWithStructureCoefficients.__init__(self, R, s_coeff,
names, index_set,
category=category, **kwds)
category=cat, **kwds)

def _repr_(self):
return "Nilpotent %s" % (super(NilpotentLieAlgebra_dense, self)._repr_())

def is_nilpotent(self):
"""
Returns ``True``, since ``self`` is nilpotent.
Return a string representation of ``self``.
EXAMPLES::
sage: from sage.algebras.lie_algebras.nilpotent_lie_algebra import NilpotentLieAlgebra
sage: L = NilpotentLieAlgebra(QQ, {('x','y'): {'z': 1}})
sage: L.is_nilpotent()
True
sage: L.<X,Y,Z,W> = LieAlgebra(QQ, {('X','Y'): {'Z': 1}}, nilpotent=True)
sage: L
Nilpotent Lie algebra on 4 generators (X, Y, Z, W) over Rational Field
"""
return True

return "Nilpotent %s" % (super(NilpotentLieAlgebra_dense, self)._repr_())

class FreeNilpotentLieAlgebra(NilpotentLieAlgebra_dense):
r"""
Expand Down Expand Up @@ -393,90 +389,3 @@ def _repr_generator(self, w):
"""
i = self.indices().index(w)
return self.variable_names()[i]

def NilpotentLieAlgebra(R, arg, step=None, names=None, category=None, **kwds):
r"""
Constructs a nilpotent Lie algebra.
INPUT:
- ``R`` -- the base ring
- ``arg`` -- a dictionary of structural coefficients, or an integer.
An integer is interpreted as the number of generators of a free nilpotent
Lie algebra.
- ``step`` -- (default:``None``) an integer; the nilpotency step of the
Lie algebra. If ``None``, the nilpotency step is undefined and will be
computed later. The ``step`` must be specified if ``arg`` is an integer.
- ``names`` -- (default:``None``) a list of strings to use as names of basis
elements. If ``None``, the names will be autogenerated from the structural
coefficients or the basis of the free nilpotent Lie algebra.
- ``category`` -- (default:``None``) a subcategory of
:class:`~sage.categories.lie_algebras.LieAlgebras.FiniteDimensional.WithBasis.Nilpotent`
EXAMPLES:
The Heisenberg algebra from its structural coefficients::
sage: from sage.algebras.lie_algebras.nilpotent_lie_algebra import NilpotentLieAlgebra
sage: L = NilpotentLieAlgebra(QQ, {('X','Y'): {'Z': 1}}); L
Nilpotent Lie algebra on 3 generators (X, Y, Z) over Rational Field
sage: L.category()
Category of finite dimensional nilpotent lie algebras with basis over Rational Field
Defining the Engel Lie algebra and binding its basis::
sage: sc = {('X','Y'): {'Z': 1}, ('X','Z'): {'W': 1}}
sage: E.<X,Y,Z,W> = NilpotentLieAlgebra(QQ, sc); E
Nilpotent Lie algebra on 4 generators (X, Y, Z, W) over Rational Field
sage: E[X, Y + Z]
Z + W
sage: E[X, [X, Y + Z]]
W
sage: E[X, [X, [X, Y + Z]]]
0
Free nilpotent Lie algebras are created by passing an integer instead
of the structural coefficients. In this case the nilpotency step must
be specified::
sage: NilpotentLieAlgebra(QQ, 2)
Traceback (most recent call last):
...
ValueError: step None is not a positive integer
For example the Heisenberg algebra is also the free nilpotent Lie
algebra of step 2 on 2 generators::
sage: L = NilpotentLieAlgebra(QQ, 2, 2); L
Nilpotent Lie algebra on 3 generators (X_1, X_2, X_12) over Rational Field
When the names of elements are unspecified, the default naming scheme is
to label the variables `X_w`, where `w` is the Lyndon word related to
the construction. Passing the parameter ``naming='linear'`` changes
the default naming scheme::
sage: L = NilpotentLieAlgebra(QQ, 2, 2, naming='linear'); L
Nilpotent Lie algebra on 3 generators (X_1, X_2, X_3) over Rational Field
A completely custom naming is also possible::
sage: L.<X,Y,Z> = NilpotentLieAlgebra(QQ, 2, 2); L
Nilpotent Lie algebra on 3 generators (X, Y, Z) over Rational Field
A higher dimensional example over a different base ring: the free
nilpotent Lie algebra of step 5 on 2 generators over a polynomial ring::
sage: NilpotentLieAlgebra(QQ['x'], 2, 5)
Nilpotent Lie algebra on 14 generators (X_1, X_2, X_12, X_112,
X_122, X_1112, X_1122, X_1222, X_11112, X_11122, X_11212, X_11222,
X_12122, X_12222) over Univariate Polynomial Ring in x over Rational Field
..SEEALSO: :class:`FreeNilpotentLieAlgebra`
"""
from sage.rings.integer_ring import ZZ
if arg in ZZ:
return FreeNilpotentLieAlgebra(R, arg, step, names=names,
category=category, **kwds)

return NilpotentLieAlgebra_dense(R, arg, names, step=step,
category=category, **kwds)
2 changes: 1 addition & 1 deletion src/sage/categories/category_with_axiom.py
Original file line number Diff line number Diff line change
Expand Up @@ -1686,7 +1686,7 @@ class ``Sets.Finite``), or in a separate file (typically in a class
"Distributive",
"Endset",
"Pointed",
"Nilpotent"
"Stratified", "Nilpotent"
)

def uncamelcase(s,separator=" "):
Expand Down
Loading

0 comments on commit 4d4bdf6

Please sign in to comment.