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

Commit

Permalink
Added free nilpotent Lie algebras to LieAlgebra constructor
Browse files Browse the repository at this point in the history
  • Loading branch information
ehaka committed Aug 21, 2018
1 parent 4d4bdf6 commit 31fa53a
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 38 deletions.
18 changes: 18 additions & 0 deletions src/sage/algebras/lie_algebras/lie_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,17 @@ class LieAlgebra(Parent, UniqueRepresentation): # IndexedGenerators):
sage: E[X, [X, [X, Y + Z]]]
0
Free nilpotent Lie algebras are the truncated versions of the free Lie
algebras. That is, the only relations other than anticommutativity and the
Jacobi identity among the Lie brackets are that brackets of length higher
than the nilpotency step vanish. They can be created by using the
``step`` keyword::
sage: L = LieAlgebra(ZZ, 2, step=3); L
Free Nilpotent Lie algebra on 5 generators (X_1, X_2, X_12, X_112, X_122) over Integer Ring
sage: L.step()
3
REFERENCES:
- [deG2000]_ Willem A. de Graaf. *Lie Algebras: Theory and Algorithms*.
Expand Down Expand Up @@ -412,6 +423,13 @@ def __classcall_private__(cls, R=None, arg0=None, arg1=None, names=None,
# Otherwise it must be either a free or abelian Lie algebra

if arg1 in ZZ:
step = kwds.get("step", None)
if step:
# Parse input as a free nilpotent Lie algebra
from sage.algebras.lie_algebras.nilpotent_lie_algebra import FreeNilpotentLieAlgebra
del kwds["step"]
return FreeNilpotentLieAlgebra(R, arg1, step, names=names, **kwds)

if isinstance(arg0, str):
names = arg0
if names is None:
Expand Down
94 changes: 56 additions & 38 deletions src/sage/algebras/lie_algebras/nilpotent_lie_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,23 +158,26 @@ class FreeNilpotentLieAlgebra(NilpotentLieAlgebra_dense):
- ``R`` -- the base ring
- ``r`` -- an integer; the number of generators
- ``s`` -- an integer; the nilpotency step of the algebra
- ``naming`` -- a string (default: ``None``); the naming scheme to use for
the basis. Valid values are:
'index' : The basis elements are `X_w`, where `w` are Lyndon words.
- ``names`` -- (optional) a string or a list of strings used to name the
basis elements; If ``names`` is a string, then names for the basis will be
autogenerated as determined by the ``naming`` parameter.
- ``naming`` -- (optional) a string; the naming scheme to use for the basis.
Valid values are:
'index' : The basis elements are ``names_w``, where `w` are Lyndon
words indexing the basis.
This naming scheme is not supported if `r > 10`, since it
leads to ambiguous names. When `r \leq 10`, this is the
default naming scheme.
'linear' : the basis is indexed `X_1`,...,`X_n` in the ordering of the
Lyndon basis. When `r > 10`, this is the
'linear' : the basis is indexed ``names_1``,...,``names_n`` in the
ordering of the Lyndon basis. When `r > 10`, this is the
default naming scheme.
EXAMPLES:
We compute the free step 4 Lie algebra on 2 generators and verify the only
non-trivial relation [[1,[1,2]],2] = [1,[[1,2],2]]::
sage: from sage.algebras.lie_algebras.nilpotent_lie_algebra import FreeNilpotentLieAlgebra
sage: L = FreeNilpotentLieAlgebra(QQ, 2, 4)
sage: L = LieAlgebra(QQ, 2, step=4)
sage: L.basis().list()
[X_1, X_2, X_12, X_112, X_122, X_1112, X_1122, X_1222]
sage: X_1, X_2 = L.basis().list()[:2]
Expand All @@ -185,21 +188,21 @@ class FreeNilpotentLieAlgebra(NilpotentLieAlgebra_dense):
The linear naming scheme on the same Lie algebra::
sage: K = FreeNilpotentLieAlgebra(QQ, 2, 4, naming='linear')
sage: K = LieAlgebra(QQ, 2, step=4, names='Y', naming='linear')
sage: K.basis().list()
[X_1, X_2, X_3, X_4, X_5, X_6, X_7, X_8]
[Y_1, Y_2, Y_3, Y_4, Y_5, Y_6, Y_7, Y_8]
sage: K.inject_variables()
Defining X_1, X_2, X_3, X_4, X_5, X_6, X_7, X_8
sage: X_2.bracket(X_3)
-X_5
sage: X_5.bracket(X_1)
-X_7
sage: X_3.bracket(X_4)
Defining Y_1, Y_2, Y_3, Y_4, Y_5, Y_6, Y_7, Y_8
sage: Y_2.bracket(Y_3)
-Y_5
sage: Y_5.bracket(Y_1)
-Y_7
sage: Y_3.bracket(Y_4)
0
A custom naming scheme on the Heisenberg algebra::
A fully custom naming scheme on the Heisenberg algebra::
sage: L = FreeNilpotentLieAlgebra(ZZ, 2, 2, names = ('X', 'Y', 'Z'))
sage: L = LieAlgebra(ZZ, 2, step=2, names = ('X', 'Y', 'Z'))
sage: a, b, c = L.basis()
sage: L.basis().list()
[X, Y, Z]
Expand All @@ -209,23 +212,23 @@ class FreeNilpotentLieAlgebra(NilpotentLieAlgebra_dense):
An equivalent way to define custom names for the basis elements and
bind them as local variables simultaneously::
sage: L.<X,Y,Z> = FreeNilpotentLieAlgebra(ZZ, 2, 2)
sage: L.<X,Y,Z> = LieAlgebra(ZZ, 2, step=2)
sage: L.basis().list()
[X, Y, Z]
sage: X.bracket(Y)
Z
A free nilpotent Lie algebra is a stratified nilpotent Lie algebra::
sage: L = FreeNilpotentLieAlgebra(QQ, 3, 3)
sage: L = LieAlgebra(QQ, 3, step=3)
sage: L.category()
Category of stratified finite dimensional lie algebras with basis over Rational Field
Category of finite dimensional stratified nilpotent graded lie algebras with basis over Rational Field
sage: L in LieAlgebras(QQ).Nilpotent()
True
Being graded means that each basis element has a degree::
sage: L in LieAlgebras.FiniteDimensional.WithBasis.Graded
sage: L in LieAlgebras(QQ).Graded()
True
sage: L.homogeneous_component_basis(1).list()
[X_1, X_2, X_3]
Expand All @@ -236,10 +239,10 @@ class FreeNilpotentLieAlgebra(NilpotentLieAlgebra_dense):
TESTS:
Verify all bracket relations in the free nilpotent Lie algebra step 5
Verify all bracket relations in the free nilpotent Lie algebra of step 5
with 2 generators::
sage: L = FreeNilpotentLieAlgebra(QQ, 2, 5)
sage: L = LieAlgebra(QQ, 2, step=5)
sage: L.inject_variables()
Defining 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
Expand Down Expand Up @@ -277,28 +280,27 @@ class FreeNilpotentLieAlgebra(NilpotentLieAlgebra_dense):
The dimensions of the smallest free nilpotent Lie algebras on 2 or 3
generators::
sage: l = [FreeNilpotentLieAlgebra(QQ, 2, k) for k in range(1, 7)]
sage: l = [LieAlgebra(QQ, 2, step=k) for k in range(1, 7)]
sage: [L.dimension() for L in l]
[2, 3, 5, 8, 14, 23]
sage: l = [FreeNilpotentLieAlgebra(QQ, 3, k) for k in range(1, 4)]
sage: l = [LieAlgebra(QQ, 3, step=k) for k in range(1, 4)]
sage: [L.dimension() for L in l]
[3, 6, 14]
Test suite for a free nilpotent Lie algebra::
sage: L = FreeNilpotentLieAlgebra(QQ, 4, 3)
sage: L = LieAlgebra(QQ, 4, step=3)
sage: TestSuite(L).run()
"""

def __init__(self, R, r, s, naming=None, names=None, category=None, **kwds):
def __init__(self, R, r, s, names=None, naming=None, category=None, **kwds):
r"""
Initialize ``self``
EXAMPLES::
sage: from sage.algebras.lie_algebras.nilpotent_lie_algebra import FreeNilpotentLieAlgebra
sage: FreeNilpotentLieAlgebra(ZZ, 2, 2, naming='linear')
Nilpotent Lie algebra on 3 generators (X_1, X_2, X_3) over Integer Ring
sage: LieAlgebra(ZZ, 2, step=2)
Free Nilpotent Lie algebra on 3 generators (X_1, X_2, X_12) over Integer Ring
"""
from sage.rings.integer_ring import ZZ

Expand All @@ -324,19 +326,24 @@ def __init__(self, R, r, s, naming=None, names=None, category=None, **kwds):
basis_dict[w] = X

# define names for basis elements
if names == None:
if not names:
names = 'X'
if isinstance(names, str):
names = tuple(names)
if len(names) == 1 and len(basis_dict)>1:
if not naming:
if r > 10:
naming = 'linear'
else:
naming = 'index'
if naming == 'linear':
names = ['X_%d' % (k + 1) for k in range(len(basis_dict))]
names = ['%s_%d' % (names[0], k + 1)
for k in range(len(basis_dict))]
elif naming == 'index':
if r > 10:
raise ValueError("'index' naming scheme not supported for "
"over 10 generators")
names = ['X_%s' % "".join(str(s) for s in w)
names = ['%s_%s' % (names[0], "".join(str(s) for s in w))
for w in basis_dict]
else:
raise ValueError("unknown naming scheme %s" % naming)
Expand Down Expand Up @@ -364,7 +371,7 @@ def __init__(self, R, r, s, naming=None, names=None, category=None, **kwds):
s_coeff, index_set)

category = LieAlgebras(R).FiniteDimensional().WithBasis() \
.Stratified().or_subcategory(category)
.Graded().Stratified().or_subcategory(category)
NilpotentLieAlgebra_dense.__init__(self, R, s_coeff, names,
index_set, s,
category, **kwds)
Expand All @@ -376,16 +383,27 @@ def _repr_generator(self, w):
EXAMPLES::
sage: from sage.algebras.lie_algebras.nilpotent_lie_algebra import FreeNilpotentLieAlgebra
sage: L = FreeNilpotentLieAlgebra(QQ, 2, 4)
sage: L = LieAlgebra(QQ, 2, step=4)
sage: L._repr_generator((1, 1, 2, 2))
'X_1122'
sage: L = FreeNilpotentLieAlgebra(QQ, 2, 4, naming='linear')
sage: L = LieAlgebra(QQ, 2, step=4, naming='linear')
sage: L._repr_generator((1, 1, 2, 2))
'X_7'
sage: L.<X,Y,Z> = FreeNilpotentLieAlgebra(QQ, 2, 2)
sage: L.<X,Y,Z> = LieAlgebra(QQ, 2, step=2)
sage: L._repr_generator((1, 2))
'Z'
"""
i = self.indices().index(w)
return self.variable_names()[i]

def _repr_(self):
"""
Return a string representation of ``self``.
EXAMPLES::
sage: L = LieAlgebra(QQ, 2, step=3)
sage: L
Free Nilpotent Lie algebra on 5 generators (X_1, X_2, X_12, X_112, X_122) over Rational Field
"""
return "Free %s" % (super(FreeNilpotentLieAlgebra, self)._repr_())

0 comments on commit 31fa53a

Please sign in to comment.