Subalgebras and ideals of Lie algebras#

AUTHORS:

• Eero Hakavuori (2018-08-29): initial version

class sage.algebras.lie_algebras.subalgebra.LieSubalgebra_finite_dimensional_with_basis(ambient, gens, ideal, order=None, category=None)[source]#

A Lie subalgebra of a finite dimensional Lie algebra with basis.

INPUT:

• ambient – the Lie algebra containing the subalgebra

• gens – a list of generators of the subalgebra

• ideal – (default: False) a boolean; if True, then gens is interpreted as the generating set of an ideal instead of a subalgebra

• order – (optional) the key used to sort the indices of ambient

• category – (optional) a subcategory of subobjects of finite dimensional Lie algebras with basis

EXAMPLES:

Subalgebras and ideals are defined by giving a list of generators:

sage: L = lie_algebras.Heisenberg(QQ, 1)
sage: X, Y, Z = L.basis()
sage: S =  L.subalgebra([X, Z]); S
Subalgebra generated by (p1, z) of Heisenberg algebra of rank 1 over Rational Field
sage: I =  L.ideal([X, Z]); I
Ideal (p1, z) of Heisenberg algebra of rank 1 over Rational Field

>>> from sage.all import *
>>> L = lie_algebras.Heisenberg(QQ, Integer(1))
>>> X, Y, Z = L.basis()
>>> S =  L.subalgebra([X, Z]); S
Subalgebra generated by (p1, z) of Heisenberg algebra of rank 1 over Rational Field
>>> I =  L.ideal([X, Z]); I
Ideal (p1, z) of Heisenberg algebra of rank 1 over Rational Field


An ideal is in general larger than the subalgebra with the same generators:

sage: S = L.subalgebra(Y)
sage: S.basis()
Family (q1,)
sage: I = L.ideal(Y)
sage: I.basis()
Family (q1, z)

>>> from sage.all import *
>>> S = L.subalgebra(Y)
>>> S.basis()
Family (q1,)
>>> I = L.ideal(Y)
>>> I.basis()
Family (q1, z)


The zero dimensional subalgebra can be created by giving 0 as a generator or with an empty list of generators:

sage: L.<X,Y,Z> = LieAlgebra(QQ, {('X','Y'): {'Z': 1}})
sage: S1 = L.subalgebra(0)
sage: S2 = L.subalgebra([])
sage: S1 is S2
True
sage: S1.basis()
Family ()

>>> from sage.all import *
>>> L = LieAlgebra(QQ, {('X','Y'): {'Z': Integer(1)}}, names=('X', 'Y', 'Z',)); (X, Y, Z,) = L._first_ngens(3)
>>> S1 = L.subalgebra(Integer(0))
>>> S2 = L.subalgebra([])
>>> S1 is S2
True
>>> S1.basis()
Family ()


Elements of the ambient Lie algebra can be reduced modulo an ideal or subalgebra:

sage: # needs sage.symbolic
sage: L.<X,Y,Z> = LieAlgebra(SR, {('X','Y'): {'Z': 1}})
sage: I = L.ideal(Y)
sage: I.reduce(X + 2*Y + 3*Z)
X
sage: S = L.subalgebra(Y)
sage: S.reduce(X + 2*Y + 3*Z)
X + 3*Z

>>> from sage.all import *
>>> # needs sage.symbolic
>>> L = LieAlgebra(SR, {('X','Y'): {'Z': Integer(1)}}, names=('X', 'Y', 'Z',)); (X, Y, Z,) = L._first_ngens(3)
>>> I = L.ideal(Y)
>>> I.reduce(X + Integer(2)*Y + Integer(3)*Z)
X
>>> S = L.subalgebra(Y)
>>> S.reduce(X + Integer(2)*Y + Integer(3)*Z)
X + 3*Z


The reduction gives elements in a fixed complementary subspace. When the base ring is a field, the complementary subspace is spanned by those basis elements which are not leading supports of the basis:

sage: # needs sage.symbolic
sage: I =  L.ideal(X + Y)
sage: I.basis()
Family (X + Y, Z)
sage: el = var('x')*X + var('y')*Y + var('z')*Z; el
x*X + y*Y + z*Z
sage: I.reduce(el)
(x-y)*X

>>> from sage.all import *
>>> # needs sage.symbolic
>>> I =  L.ideal(X + Y)
>>> I.basis()
Family (X + Y, Z)
>>> el = var('x')*X + var('y')*Y + var('z')*Z; el
x*X + y*Y + z*Z
>>> I.reduce(el)
(x-y)*X


Giving a different order may change the reduction of elements:

sage: I =  L.ideal(X + Y, order=lambda s: ['Z','Y','X'].index(s))               # needs sage.symbolic
sage: I.basis()                                                                 # needs sage.symbolic
Family (Z, X + Y)
sage: I.reduce(el)                                                              # needs sage.symbolic
(-x+y)*Y

>>> from sage.all import *
>>> I =  L.ideal(X + Y, order=lambda s: ['Z','Y','X'].index(s))               # needs sage.symbolic
>>> I.basis()                                                                 # needs sage.symbolic
Family (Z, X + Y)
>>> I.reduce(el)                                                              # needs sage.symbolic
(-x+y)*Y


A subalgebra of a subalgebra is a subalgebra of the original:

sage: sc = {('X','Y'): {'Z': 1}, ('X','Z'): {'W': 1}}
sage: L.<X,Y,Z,W> = LieAlgebra(QQ, sc)
sage: S1 = L.subalgebra([Y, Z, W]); S1
Subalgebra generated by (Y, Z, W) of Lie algebra on 4 generators (X, Y, Z, W) over Rational Field
sage: S2 = S1.subalgebra(S1.gens()[1:]); S2
Subalgebra generated by (Z, W) of Lie algebra on 4 generators (X, Y, Z, W) over Rational Field
sage: S3 = S2.subalgebra(S2.gens()[1:]); S3
Subalgebra generated by (W) of Lie algebra on 4 generators (X, Y, Z, W) over Rational Field

>>> from sage.all import *
>>> sc = {('X','Y'): {'Z': Integer(1)}, ('X','Z'): {'W': Integer(1)}}
>>> L = LieAlgebra(QQ, sc, names=('X', 'Y', 'Z', 'W',)); (X, Y, Z, W,) = L._first_ngens(4)
>>> S1 = L.subalgebra([Y, Z, W]); S1
Subalgebra generated by (Y, Z, W) of Lie algebra on 4 generators (X, Y, Z, W) over Rational Field
>>> S2 = S1.subalgebra(S1.gens()[Integer(1):]); S2
Subalgebra generated by (Z, W) of Lie algebra on 4 generators (X, Y, Z, W) over Rational Field
>>> S3 = S2.subalgebra(S2.gens()[Integer(1):]); S3
Subalgebra generated by (W) of Lie algebra on 4 generators (X, Y, Z, W) over Rational Field


An ideal of an ideal is not necessarily an ideal of the original:

sage: I = L.ideal(Y); I
Ideal (Y) of Lie algebra on 4 generators (X, Y, Z, W) over Rational Field
sage: J = I.ideal(Z); J
Ideal (Z) of Ideal (Y) of Lie algebra on 4 generators (X, Y, Z, W) over Rational Field
sage: J.basis()
Family (Z,)
sage: J.is_ideal(L)
False
sage: K = L.ideal(J.basis().list())
sage: K.basis()
Family (Z, W)

>>> from sage.all import *
>>> I = L.ideal(Y); I
Ideal (Y) of Lie algebra on 4 generators (X, Y, Z, W) over Rational Field
>>> J = I.ideal(Z); J
Ideal (Z) of Ideal (Y) of Lie algebra on 4 generators (X, Y, Z, W) over Rational Field
>>> J.basis()
Family (Z,)
>>> J.is_ideal(L)
False
>>> K = L.ideal(J.basis().list())
>>> K.basis()
Family (Z, W)

class Element[source]#

Return the matrix of the adjoint action of self.

EXAMPLES:

sage: MS = MatrixSpace(QQ, 2)
sage: m = MS([[0, -1], [1, 0]])
sage: L = LieAlgebra(associative=MS)
sage: S = L.subalgebra([m])
sage: x = S.basis()[0]
sage: x.parent() is S
True
[0]

sage: m1 = MS([[0, 1], [0, 0]])
sage: m2 = MS([[0, 0], [1, 0]])
sage: S = L.subalgebra([m1, m2])
sage: e,f = S.lie_algebra_generators()
sage: ascii_art([b.value.value for b in S.basis()])
[ [0 1]  [0 0]  [-1  0] ]
[ [0 0], [1 0], [ 0  1] ]
[ 0  0  2]
[ 0  0  0]
[ 0 -1  0]
[ 0  0  0]
[ 0  0 -2]
[ 1  0  0]
sage: h = e.bracket(f)
sage: E * F - F * E == h.adjoint_matrix()
True

>>> from sage.all import *
>>> MS = MatrixSpace(QQ, Integer(2))
>>> m = MS([[Integer(0), -Integer(1)], [Integer(1), Integer(0)]])
>>> L = LieAlgebra(associative=MS)
>>> S = L.subalgebra([m])
>>> x = S.basis()[Integer(0)]
>>> x.parent() is S
True
[0]

>>> m1 = MS([[Integer(0), Integer(1)], [Integer(0), Integer(0)]])
>>> m2 = MS([[Integer(0), Integer(0)], [Integer(1), Integer(0)]])
>>> S = L.subalgebra([m1, m2])
>>> e,f = S.lie_algebra_generators()
>>> ascii_art([b.value.value for b in S.basis()])
[ [0 1]  [0 0]  [-1  0] ]
[ [0 0], [1 0], [ 0  1] ]
[ 0  0  2]
[ 0  0  0]
[ 0 -1  0]
[ 0  0  0]
[ 0  0 -2]
[ 1  0  0]
>>> h = e.bracket(f)
>>> E * F - F * E == h.adjoint_matrix()
True

ambient()[source]#

Return the ambient Lie algebra of self.

EXAMPLES:

sage: L.<x,y> = LieAlgebra(QQ, abelian=True)
sage: S = L.subalgebra(x)
sage: S.ambient() is L
True

>>> from sage.all import *
>>> L = LieAlgebra(QQ, abelian=True, names=('x', 'y',)); (x, y,) = L._first_ngens(2)
>>> S = L.subalgebra(x)
>>> S.ambient() is L
True

basis()[source]#

Return a basis of self.

EXAMPLES:

A basis of a subalgebra:

sage: sc = {('a','b'): {'c': 1}, ('a','c'): {'d': 1}}
sage: L.<a,b,c,d> = LieAlgebra(QQ, sc)
sage: L.subalgebra([a + b, c + d]).basis()
Family (a + b, c, d)

>>> from sage.all import *
>>> sc = {('a','b'): {'c': Integer(1)}, ('a','c'): {'d': Integer(1)}}
>>> L = LieAlgebra(QQ, sc, names=('a', 'b', 'c', 'd',)); (a, b, c, d,) = L._first_ngens(4)
>>> L.subalgebra([a + b, c + d]).basis()
Family (a + b, c, d)


A basis of an ideal:

sage: sc = {('x','y'): {'z': 1}, ('x','z'): {'w': 1}}
sage: L.<x,y,z,w> = LieAlgebra(QQ, sc)
sage: L.ideal([x + y + z + w]).basis()
Family (x + y, z, w)

>>> from sage.all import *
>>> sc = {('x','y'): {'z': Integer(1)}, ('x','z'): {'w': Integer(1)}}
>>> L = LieAlgebra(QQ, sc, names=('x', 'y', 'z', 'w',)); (x, y, z, w,) = L._first_ngens(4)
>>> L.ideal([x + y + z + w]).basis()
Family (x + y, z, w)


This also works for Lie algebras whose natural basis elements are not comparable (but have a well-defined basis ordering):

sage: sl3 = LieAlgebra(QQ, cartan_type=['A',2])
sage: D = sl3.derived_subalgebra()
sage: len(D.basis())
8
sage: e = list(sl3.e())
sage: sl3.ideal(e).dimension()
8
sage: sl3.subalgebra(e).dimension()
3

>>> from sage.all import *
>>> sl3 = LieAlgebra(QQ, cartan_type=['A',Integer(2)])
>>> D = sl3.derived_subalgebra()
>>> len(D.basis())
8
>>> e = list(sl3.e())
>>> sl3.ideal(e).dimension()
8
>>> sl3.subalgebra(e).dimension()
3

basis_matrix()[source]#

Return the basis matrix of self as a submodule of the ambient Lie algebra.

EXAMPLES:

sage: L.<X,Y,Z> = LieAlgebra(ZZ, {('X','Y'): {'Z': 3}})
sage: S1 = L.subalgebra([4*X + Y, Y])
sage: S1.basis_matrix()
[ 4  0  0]
[ 0  1  0]
[ 0  0 12]
sage: K.<X,Y,Z> = LieAlgebra(QQ, {('X','Y'): {'Z': 3}})
sage: S2 = K.subalgebra([4*X + Y, Y])
sage: S2.basis_matrix()
[1 0 0]
[0 1 0]
[0 0 1]

>>> from sage.all import *
>>> L = LieAlgebra(ZZ, {('X','Y'): {'Z': Integer(3)}}, names=('X', 'Y', 'Z',)); (X, Y, Z,) = L._first_ngens(3)
>>> S1 = L.subalgebra([Integer(4)*X + Y, Y])
>>> S1.basis_matrix()
[ 4  0  0]
[ 0  1  0]
[ 0  0 12]
>>> K = LieAlgebra(QQ, {('X','Y'): {'Z': Integer(3)}}, names=('X', 'Y', 'Z',)); (X, Y, Z,) = K._first_ngens(3)
>>> S2 = K.subalgebra([Integer(4)*X + Y, Y])
>>> S2.basis_matrix()
[1 0 0]
[0 1 0]
[0 0 1]

from_vector(v, order=None, coerce=False)[source]#

Return the element of self corresponding to the vector v

INPUT:

• v – a vector in self.module() or self.ambient().module()

EXAMPLES:

An element from a vector of the intrinsic module:

sage: L.<X,Y,Z> = LieAlgebra(ZZ, abelian=True)
sage: L.dimension()
3
sage: S = L.subalgebra([X, Y])
sage: S.dimension()
2
sage: el = S.from_vector([1, 2]); el
X + 2*Y
sage: el.parent() == S
True

>>> from sage.all import *
>>> L = LieAlgebra(ZZ, abelian=True, names=('X', 'Y', 'Z',)); (X, Y, Z,) = L._first_ngens(3)
>>> L.dimension()
3
>>> S = L.subalgebra([X, Y])
>>> S.dimension()
2
>>> el = S.from_vector([Integer(1), Integer(2)]); el
X + 2*Y
>>> el.parent() == S
True


An element from a vector of the ambient module

sage: el = S.from_vector([1, 2, 0]); el X + 2*Y sage: el.parent() == S True

gens()[source]#

Return the generating set of self.

EXAMPLES:

sage: L.<x,y,z> = LieAlgebra(QQ, {('x','y'): {'z': 1}})
sage: S = L.subalgebra(x)
sage: S.gens()
(x,)

>>> from sage.all import *
>>> L = LieAlgebra(QQ, {('x','y'): {'z': Integer(1)}}, names=('x', 'y', 'z',)); (x, y, z,) = L._first_ngens(3)
>>> S = L.subalgebra(x)
>>> S.gens()
(x,)

indices()[source]#

Return the set of indices for the basis of self.

EXAMPLES:

sage: L.<x,y,z> = LieAlgebra(QQ, abelian=True)
sage: S = L.subalgebra([x, y])
sage: S.indices()
{0, 1}
sage: [S.basis()[k] for k in S.indices()]
[x, y]

>>> from sage.all import *
>>> L = LieAlgebra(QQ, abelian=True, names=('x', 'y', 'z',)); (x, y, z,) = L._first_ngens(3)
>>> S = L.subalgebra([x, y])
>>> S.indices()
{0, 1}
>>> [S.basis()[k] for k in S.indices()]
[x, y]

is_ideal(A)[source]#

Return if self is an ideal of A.

EXAMPLES:

Some subalgebras are ideals:

sage: L.<x,y,z> = LieAlgebra(QQ, {('x','y'): {'z': 1}})
sage: S1 = L.subalgebra([x])
sage: S1.is_ideal(L)
False
sage: S2 = L.subalgebra([x, y])
sage: S2.is_ideal(L)
True
sage: S3 = L.subalgebra([y, z])
sage: S3.is_ideal(L)
True

>>> from sage.all import *
>>> L = LieAlgebra(QQ, {('x','y'): {'z': Integer(1)}}, names=('x', 'y', 'z',)); (x, y, z,) = L._first_ngens(3)
>>> S1 = L.subalgebra([x])
>>> S1.is_ideal(L)
False
>>> S2 = L.subalgebra([x, y])
>>> S2.is_ideal(L)
True
>>> S3 = L.subalgebra([y, z])
>>> S3.is_ideal(L)
True


All ideals are ideals:

sage: L.<x,y> = LieAlgebra(QQ, {('x','y'): {'x': 1}})
sage: I = L.ideal(x)
sage: I.is_ideal(L)
True
sage: I.is_ideal(I)
True

>>> from sage.all import *
>>> L = LieAlgebra(QQ, {('x','y'): {'x': Integer(1)}}, names=('x', 'y',)); (x, y,) = L._first_ngens(2)
>>> I = L.ideal(x)
>>> I.is_ideal(L)
True
>>> I.is_ideal(I)
True


Return the set of leading monomials of the basis of self.

EXAMPLES:

A basis of an ideal and the corresponding leading monomials:

sage: sc = {('a','b'): {'c': 2}, ('a','c'): {'d': 4}}
sage: L.<a,b,c,d> = LieAlgebra(ZZ, sc)
sage: I = L.ideal(a + b)
sage: I.basis()
Family (a + b, 2*c, 4*d)
Family (b, c, d)

>>> from sage.all import *
>>> sc = {('a','b'): {'c': Integer(2)}, ('a','c'): {'d': Integer(4)}}
>>> L = LieAlgebra(ZZ, sc, names=('a', 'b', 'c', 'd',)); (a, b, c, d,) = L._first_ngens(4)
>>> I = L.ideal(a + b)
>>> I.basis()
Family (a + b, 2*c, 4*d)
Family (b, c, d)


A different ordering can give different leading monomials:

sage: key = lambda s: ['d','c','b','a'].index(s)
sage: I = L.ideal(a + b, order=key)
sage: I.basis()
Family (4*d, 2*c, a + b)
Family (d, c, a)

>>> from sage.all import *
>>> key = lambda s: ['d','c','b','a'].index(s)
>>> I = L.ideal(a + b, order=key)
>>> I.basis()
Family (4*d, 2*c, a + b)
Family (d, c, a)

lie_algebra_generators()[source]#

Return the generating set of self as a Lie algebra.

EXAMPLES:

The Lie algebra generators of a subalgebra are the original generators:

sage: L.<x,y,z> = LieAlgebra(QQ, {('x','y'): {'z': 1}})
sage: S = L.subalgebra(x)
sage: S.lie_algebra_generators()
(x,)

>>> from sage.all import *
>>> L = LieAlgebra(QQ, {('x','y'): {'z': Integer(1)}}, names=('x', 'y', 'z',)); (x, y, z,) = L._first_ngens(3)
>>> S = L.subalgebra(x)
>>> S.lie_algebra_generators()
(x,)


The Lie algebra generators of an ideal is usually a larger set:

sage: I = L.ideal(x)
sage: I.lie_algebra_generators()
Family (x, z)

>>> from sage.all import *
>>> I = L.ideal(x)
>>> I.lie_algebra_generators()
Family (x, z)

lift(X)[source]#

Coerce an element X of self into the ambient Lie algebra.

INPUT:

• X – an element of self

EXAMPLES:

sage: L.<x,y> = LieAlgebra(QQ, abelian=True)
sage: S = L.subalgebra(x)
sage: sx = S(x); sx
x
sage: sx.parent()
Subalgebra generated by (x) of Abelian Lie algebra on 2 generators (x, y) over Rational Field
sage: a = S.lift(sx); a
x
sage: a.parent()
Abelian Lie algebra on 2 generators (x, y) over Rational Field

>>> from sage.all import *
>>> L = LieAlgebra(QQ, abelian=True, names=('x', 'y',)); (x, y,) = L._first_ngens(2)
>>> S = L.subalgebra(x)
>>> sx = S(x); sx
x
>>> sx.parent()
Subalgebra generated by (x) of Abelian Lie algebra on 2 generators (x, y) over Rational Field
>>> a = S.lift(sx); a
x
>>> a.parent()
Abelian Lie algebra on 2 generators (x, y) over Rational Field

module(sparse=False)[source]#

Return the submodule of the ambient Lie algebra corresponding to self.

EXAMPLES:

sage: L.<X,Y,Z> = LieAlgebra(ZZ, {('X','Y'): {'Z': 3}})
sage: S = L.subalgebra([X, Y])
sage: S.module()
Free module of degree 3 and rank 3 over Integer Ring
User basis matrix:
[1 0 0]
[0 1 0]
[0 0 3]

>>> from sage.all import *
>>> L = LieAlgebra(ZZ, {('X','Y'): {'Z': Integer(3)}}, names=('X', 'Y', 'Z',)); (X, Y, Z,) = L._first_ngens(3)
>>> S = L.subalgebra([X, Y])
>>> S.module()
Free module of degree 3 and rank 3 over Integer Ring
User basis matrix:
[1 0 0]
[0 1 0]
[0 0 3]

retract(X)[source]#

Retract X to self.

INPUT:

• X – an element of the ambient Lie algebra

EXAMPLES:

Retraction to a subalgebra of a free nilpotent Lie algebra:

sage: L = LieAlgebra(QQ, 3, step=2)
sage: L.inject_variables()
Defining X_1, X_2, X_3, X_12, X_13, X_23
sage: S = L.subalgebra([X_1, X_2])
sage: el = S.retract(2*X_1 + 3*X_2 + 5*X_12); el
2*X_1 + 3*X_2 + 5*X_12
sage: el.parent()
Subalgebra generated by (X_1, X_2) of Free Nilpotent Lie algebra on
6 generators (X_1, X_2, X_3, X_12, X_13, X_23) over Rational Field

>>> from sage.all import *
>>> L = LieAlgebra(QQ, Integer(3), step=Integer(2))
>>> L.inject_variables()
Defining X_1, X_2, X_3, X_12, X_13, X_23
>>> S = L.subalgebra([X_1, X_2])
>>> el = S.retract(Integer(2)*X_1 + Integer(3)*X_2 + Integer(5)*X_12); el
2*X_1 + 3*X_2 + 5*X_12
>>> el.parent()
Subalgebra generated by (X_1, X_2) of Free Nilpotent Lie algebra on
6 generators (X_1, X_2, X_3, X_12, X_13, X_23) over Rational Field


Retraction raises an error if the element is not contained in the subalgebra:

sage: S.retract(X_3)
Traceback (most recent call last):
...
ValueError: the element X_3 is not in Subalgebra generated
by (X_1, X_2) of Free Nilpotent Lie algebra on 6 generators
(X_1, X_2, X_3, X_12, X_13, X_23) over Rational Field

>>> from sage.all import *
>>> S.retract(X_3)
Traceback (most recent call last):
...
ValueError: the element X_3 is not in Subalgebra generated
by (X_1, X_2) of Free Nilpotent Lie algebra on 6 generators
(X_1, X_2, X_3, X_12, X_13, X_23) over Rational Field

zero()[source]#

Return the element $$0$$.

EXAMPLES:

sage: L.<x,y> = LieAlgebra(QQ, abelian=True)
sage: S = L.subalgebra(x)
sage: S.zero()
0
sage: S.zero() == S(L.zero())
True

>>> from sage.all import *
>>> L = LieAlgebra(QQ, abelian=True, names=('x', 'y',)); (x, y,) = L._first_ngens(2)
>>> S = L.subalgebra(x)
>>> S.zero()
0
>>> S.zero() == S(L.zero())
True