Clifford Algebras¶
AUTHORS:
Travis Scrimshaw (2013-09-06): Initial version
Trevor K. Karn (2022-07-27): Rewrite basis indexing using FrozenBitset
- class sage.algebras.clifford_algebra.CliffordAlgebra(Q, names, category=None)[source]¶
Bases:
CombinatorialFreeModule
The Clifford algebra of a quadratic form.
Let
denote a quadratic form on a vector space over a field . The Clifford algebra is defined as where is the tensor algebra of and is the two-sided ideal generated by all elements of the form for all .We abuse notation to denote the projection of a pure tensor
onto by . This is motivated by the fact that is the exterior algebra when (one can also think of a Clifford algebra as a quantization of the exterior algebra). SeeExteriorAlgebra
for the concept of an exterior algebra.From the definition, a basis of
is given by monomials of the formwhere
and where is any fixed basis of . HenceNote
The algebra
is a -graded algebra, but not (in general) -graded (in a reasonable way).This construction satisfies the following universal property. Let
denote the natural inclusion (which is an embedding). Then for every associative -algebra and any -linear map satisfyingfor all
, there exists a unique -algebra homomorphism such that . This property determines the Clifford algebra uniquely up to canonical isomorphism. The inclusion is commonly used to identify with a vector subspace of .The Clifford algebra
is a -graded algebra (where ); this grading is determined by placing all elements of in degree . It is also an -filtered algebra, with the filtration too being defined by placing all elements of in degree . Thedegree()
gives the -filtration degree, and to get the super degree use insteadis_even_odd()
.The Clifford algebra also can be considered as a covariant functor from the category of vector spaces equipped with quadratic forms to the category of algebras. In fact, if
and are two vector spaces endowed with quadratic forms, and if is a linear map preserving the quadratic form, then we can define an algebra morphism by requiring that it send every to . Since the quadratic form on is uniquely determined by the quadratic form on (due to the assumption that preserves the quadratic form), this fact can be rewritten as follows: If is a vector space with a quadratic form, and is another vector space, and is any linear map, then we obtain an algebra morphism where (we consider as a matrix) is the quadratic form pulled back to . In fact, the map preserves the quadratic form because ofHence we have
for all .REFERENCES:
INPUT:
Q
– a quadratic formnames
– (default:'e'
) the generator names
EXAMPLES:
To create a Clifford algebra, all one needs to do is specify a quadratic form:
sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6]) sage: Cl = CliffordAlgebra(Q) sage: Cl The Clifford algebra of the Quadratic form in 3 variables over Integer Ring with coefficients: [ 1 2 3 ] [ * 4 5 ] [ * * 6 ]
>>> from sage.all import * >>> Q = QuadraticForm(ZZ, Integer(3), [Integer(1),Integer(2),Integer(3),Integer(4),Integer(5),Integer(6)]) >>> Cl = CliffordAlgebra(Q) >>> Cl The Clifford algebra of the Quadratic form in 3 variables over Integer Ring with coefficients: [ 1 2 3 ] [ * 4 5 ] [ * * 6 ]
We can also explicitly name the generators. In this example, the Clifford algebra we construct is an exterior algebra (since we choose the quadratic form to be zero):
sage: Q = QuadraticForm(ZZ, 4, [0]*10) sage: Cl.<a,b,c,d> = CliffordAlgebra(Q) sage: a*d a*d sage: d*c*b*a + a + 4*b*c a*b*c*d + 4*b*c + a
>>> from sage.all import * >>> Q = QuadraticForm(ZZ, Integer(4), [Integer(0)]*Integer(10)) >>> Cl = CliffordAlgebra(Q, names=('a', 'b', 'c', 'd',)); (a, b, c, d,) = Cl._first_ngens(4) >>> a*d a*d >>> d*c*b*a + a + Integer(4)*b*c a*b*c*d + 4*b*c + a
- algebra_generators()[source]¶
Return the algebra generators of
self
.EXAMPLES:
sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6]) sage: Cl.<x,y,z> = CliffordAlgebra(Q) sage: Cl.algebra_generators() Finite family {'x': x, 'y': y, 'z': z}
>>> from sage.all import * >>> Q = QuadraticForm(ZZ, Integer(3), [Integer(1),Integer(2),Integer(3),Integer(4),Integer(5),Integer(6)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y', 'z',)); (x, y, z,) = Cl._first_ngens(3) >>> Cl.algebra_generators() Finite family {'x': x, 'y': y, 'z': z}
- center_basis()[source]¶
Return a list of elements which correspond to a basis for the center of
self
.This assumes that the ground ring can be used to compute the kernel of a matrix.
See also
supercenter_basis()
, http://math.stackexchange.com/questions/129183/center-of-clifford-algebra-depending-on-the-parity-of-dim-vTodo
Deprecate this in favor of a method called
once subalgebras are properly implemented in Sage.EXAMPLES:
sage: Q = QuadraticForm(QQ, 3, [1,2,3,4,5,6]) sage: Cl.<x,y,z> = CliffordAlgebra(Q) sage: Z = Cl.center_basis(); Z (1, -2/5*x*y*z + x - 3/5*y + 2/5*z) sage: all(z*b - b*z == 0 for z in Z for b in Cl.basis()) True sage: Q = QuadraticForm(QQ, 3, [1,-2,-3, 4, 2, 1]) sage: Cl.<x,y,z> = CliffordAlgebra(Q) sage: Z = Cl.center_basis(); Z (1, -x*y*z + x + 3/2*y - z) sage: all(z*b - b*z == 0 for z in Z for b in Cl.basis()) True sage: Q = QuadraticForm(QQ, 2, [1,-2,-3]) sage: Cl.<x,y> = CliffordAlgebra(Q) sage: Cl.center_basis() (1,) sage: Q = QuadraticForm(QQ, 2, [-1,1,-3]) sage: Cl.<x,y> = CliffordAlgebra(Q) sage: Cl.center_basis() (1,)
>>> from sage.all import * >>> Q = QuadraticForm(QQ, Integer(3), [Integer(1),Integer(2),Integer(3),Integer(4),Integer(5),Integer(6)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y', 'z',)); (x, y, z,) = Cl._first_ngens(3) >>> Z = Cl.center_basis(); Z (1, -2/5*x*y*z + x - 3/5*y + 2/5*z) >>> all(z*b - b*z == Integer(0) for z in Z for b in Cl.basis()) True >>> Q = QuadraticForm(QQ, Integer(3), [Integer(1),-Integer(2),-Integer(3), Integer(4), Integer(2), Integer(1)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y', 'z',)); (x, y, z,) = Cl._first_ngens(3) >>> Z = Cl.center_basis(); Z (1, -x*y*z + x + 3/2*y - z) >>> all(z*b - b*z == Integer(0) for z in Z for b in Cl.basis()) True >>> Q = QuadraticForm(QQ, Integer(2), [Integer(1),-Integer(2),-Integer(3)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y',)); (x, y,) = Cl._first_ngens(2) >>> Cl.center_basis() (1,) >>> Q = QuadraticForm(QQ, Integer(2), [-Integer(1),Integer(1),-Integer(3)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y',)); (x, y,) = Cl._first_ngens(2) >>> Cl.center_basis() (1,)
A degenerate case:
sage: Q = QuadraticForm(QQ, 3, [4,4,-4,1,-2,1]) sage: Cl.<x,y,z> = CliffordAlgebra(Q) sage: Cl.center_basis() (1, x*y*z + x - 2*y - 2*z, x*y + x*z - 2*y*z)
>>> from sage.all import * >>> Q = QuadraticForm(QQ, Integer(3), [Integer(4),Integer(4),-Integer(4),Integer(1),-Integer(2),Integer(1)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y', 'z',)); (x, y, z,) = Cl._first_ngens(3) >>> Cl.center_basis() (1, x*y*z + x - 2*y - 2*z, x*y + x*z - 2*y*z)
The most degenerate case (the exterior algebra):
sage: Q = QuadraticForm(QQ, 3) sage: Cl.<x,y,z> = CliffordAlgebra(Q) sage: Cl.center_basis() (1, x*y, x*z, y*z, x*y*z)
>>> from sage.all import * >>> Q = QuadraticForm(QQ, Integer(3)) >>> Cl = CliffordAlgebra(Q, names=('x', 'y', 'z',)); (x, y, z,) = Cl._first_ngens(3) >>> Cl.center_basis() (1, x*y, x*z, y*z, x*y*z)
- degree_on_basis(m)[source]¶
Return the degree of the monomial indexed by
m
.We are considering the Clifford algebra to be
-filtered, and the degree of the monomialm
is the length ofm
.EXAMPLES:
sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6]) sage: Cl.<x,y,z> = CliffordAlgebra(Q) sage: Cl.degree_on_basis((0,)) 1 sage: Cl.degree_on_basis((0,1)) 2
>>> from sage.all import * >>> Q = QuadraticForm(ZZ, Integer(3), [Integer(1),Integer(2),Integer(3),Integer(4),Integer(5),Integer(6)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y', 'z',)); (x, y, z,) = Cl._first_ngens(3) >>> Cl.degree_on_basis((Integer(0),)) 1 >>> Cl.degree_on_basis((Integer(0),Integer(1))) 2
- dimension()[source]¶
Return the rank of
self
as a free module.Let
be a free -module of rank ; then, is a free -module of rank .EXAMPLES:
sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6]) sage: Cl.<x,y,z> = CliffordAlgebra(Q) sage: Cl.dimension() 8
>>> from sage.all import * >>> Q = QuadraticForm(ZZ, Integer(3), [Integer(1),Integer(2),Integer(3),Integer(4),Integer(5),Integer(6)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y', 'z',)); (x, y, z,) = Cl._first_ngens(3) >>> Cl.dimension() 8
- free_module()[source]¶
Return the underlying free module
ofself
.This is the free module on which the quadratic form that was used to construct
self
is defined.EXAMPLES:
sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6]) sage: Cl.<x,y,z> = CliffordAlgebra(Q) sage: Cl.free_module() Ambient free module of rank 3 over the principal ideal domain Integer Ring
>>> from sage.all import * >>> Q = QuadraticForm(ZZ, Integer(3), [Integer(1),Integer(2),Integer(3),Integer(4),Integer(5),Integer(6)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y', 'z',)); (x, y, z,) = Cl._first_ngens(3) >>> Cl.free_module() Ambient free module of rank 3 over the principal ideal domain Integer Ring
- gen(i)[source]¶
Return the
i
-th standard generator of the algebraself
.This is the
i
-th basis vector of the vector space on which the quadratic form definingself
is defined, regarded as an element ofself
.EXAMPLES:
sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6]) sage: Cl.<x,y,z> = CliffordAlgebra(Q) sage: [Cl.gen(i) for i in range(3)] [x, y, z]
>>> from sage.all import * >>> Q = QuadraticForm(ZZ, Integer(3), [Integer(1),Integer(2),Integer(3),Integer(4),Integer(5),Integer(6)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y', 'z',)); (x, y, z,) = Cl._first_ngens(3) >>> [Cl.gen(i) for i in range(Integer(3))] [x, y, z]
- gens()[source]¶
Return the generators of
self
(as an algebra).EXAMPLES:
sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6]) sage: Cl.<x,y,z> = CliffordAlgebra(Q) sage: Cl.gens() (x, y, z)
>>> from sage.all import * >>> Q = QuadraticForm(ZZ, Integer(3), [Integer(1),Integer(2),Integer(3),Integer(4),Integer(5),Integer(6)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y', 'z',)); (x, y, z,) = Cl._first_ngens(3) >>> Cl.gens() (x, y, z)
- graded_algebra()[source]¶
Return the associated graded algebra of
self
.EXAMPLES:
sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6]) sage: Cl.<x,y,z> = CliffordAlgebra(Q) sage: Cl.graded_algebra() The exterior algebra of rank 3 over Integer Ring
>>> from sage.all import * >>> Q = QuadraticForm(ZZ, Integer(3), [Integer(1),Integer(2),Integer(3),Integer(4),Integer(5),Integer(6)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y', 'z',)); (x, y, z,) = Cl._first_ngens(3) >>> Cl.graded_algebra() The exterior algebra of rank 3 over Integer Ring
- is_commutative()[source]¶
Check if
self
is a commutative algebra.EXAMPLES:
sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6]) sage: Cl.<x,y,z> = CliffordAlgebra(Q) sage: Cl.is_commutative() False
>>> from sage.all import * >>> Q = QuadraticForm(ZZ, Integer(3), [Integer(1),Integer(2),Integer(3),Integer(4),Integer(5),Integer(6)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y', 'z',)); (x, y, z,) = Cl._first_ngens(3) >>> Cl.is_commutative() False
- lift_isometry(m, names=None)[source]¶
Lift an invertible isometry
m
of the quadratic form ofself
to a Clifford algebra morphism.Given an invertible linear map
(here represented by a matrix acting on column vectors), this method returns the algebra morphism from to , where is the Clifford algebraself
and where is the pullback of the quadratic form to along the inverse map . See the documentation ofCliffordAlgebra
for how this pullback and the morphism are defined.INPUT:
m
– an isometry of the quadratic form ofself
names
– (default:'e'
) the names of the generators of the Clifford algebra of the codomain of (the map represented by)m
OUTPUT: the algebra morphism
fromself
toEXAMPLES:
sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6]) sage: Cl.<x,y,z> = CliffordAlgebra(Q) sage: m = matrix([[1,1,2],[0,1,1],[0,0,1]]) sage: phi = Cl.lift_isometry(m, 'abc') sage: phi(x) a sage: phi(y) a + b sage: phi(x*y) a*b + 1 sage: phi(x) * phi(y) a*b + 1 sage: phi(z*y) a*b - a*c - b*c sage: phi(z) * phi(y) a*b - a*c - b*c sage: phi(x + z) * phi(y + z) == phi((x + z) * (y + z)) True
>>> from sage.all import * >>> Q = QuadraticForm(ZZ, Integer(3), [Integer(1),Integer(2),Integer(3),Integer(4),Integer(5),Integer(6)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y', 'z',)); (x, y, z,) = Cl._first_ngens(3) >>> m = matrix([[Integer(1),Integer(1),Integer(2)],[Integer(0),Integer(1),Integer(1)],[Integer(0),Integer(0),Integer(1)]]) >>> phi = Cl.lift_isometry(m, 'abc') >>> phi(x) a >>> phi(y) a + b >>> phi(x*y) a*b + 1 >>> phi(x) * phi(y) a*b + 1 >>> phi(z*y) a*b - a*c - b*c >>> phi(z) * phi(y) a*b - a*c - b*c >>> phi(x + z) * phi(y + z) == phi((x + z) * (y + z)) True
- lift_module_morphism(m, names=None)[source]¶
Lift the matrix
m
to an algebra morphism of Clifford algebras.Given a linear map
(here represented by a matrix acting on column vectors), this method returns the algebra morphism , where is the Clifford algebraself
and where is the pullback of the quadratic form to . See the documentation ofCliffordAlgebra
for how this pullback and the morphism are defined.Note
This is a map into
self
.INPUT:
m
– a matrixnames
– (default:'e'
) the names of the generators of the Clifford algebra of the domain of (the map represented by)m
OUTPUT: the algebra morphism
from toself
EXAMPLES:
sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6]) sage: Cl.<x,y,z> = CliffordAlgebra(Q) sage: m = matrix([[1,-1,-1],[0,1,-1],[1,1,1]]) sage: phi = Cl.lift_module_morphism(m, 'abc') sage: phi Generic morphism: From: The Clifford algebra of the Quadratic form in 3 variables over Integer Ring with coefficients: [ 10 17 3 ] [ * 11 0 ] [ * * 5 ] To: The Clifford algebra of the Quadratic form in 3 variables over Integer Ring with coefficients: [ 1 2 3 ] [ * 4 5 ] [ * * 6 ] sage: a,b,c = phi.domain().gens() sage: phi(a) x + z sage: phi(b) -x + y + z sage: phi(c) -x - y + z sage: phi(a + 3*b) -2*x + 3*y + 4*z sage: phi(a) + 3*phi(b) -2*x + 3*y + 4*z sage: phi(a*b) x*y + 2*x*z - y*z + 7 sage: phi(b*a) -x*y - 2*x*z + y*z + 10 sage: phi(a*b + c) x*y + 2*x*z - y*z - x - y + z + 7 sage: phi(a*b) + phi(c) x*y + 2*x*z - y*z - x - y + z + 7
>>> from sage.all import * >>> Q = QuadraticForm(ZZ, Integer(3), [Integer(1),Integer(2),Integer(3),Integer(4),Integer(5),Integer(6)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y', 'z',)); (x, y, z,) = Cl._first_ngens(3) >>> m = matrix([[Integer(1),-Integer(1),-Integer(1)],[Integer(0),Integer(1),-Integer(1)],[Integer(1),Integer(1),Integer(1)]]) >>> phi = Cl.lift_module_morphism(m, 'abc') >>> phi Generic morphism: From: The Clifford algebra of the Quadratic form in 3 variables over Integer Ring with coefficients: [ 10 17 3 ] [ * 11 0 ] [ * * 5 ] To: The Clifford algebra of the Quadratic form in 3 variables over Integer Ring with coefficients: [ 1 2 3 ] [ * 4 5 ] [ * * 6 ] >>> a,b,c = phi.domain().gens() >>> phi(a) x + z >>> phi(b) -x + y + z >>> phi(c) -x - y + z >>> phi(a + Integer(3)*b) -2*x + 3*y + 4*z >>> phi(a) + Integer(3)*phi(b) -2*x + 3*y + 4*z >>> phi(a*b) x*y + 2*x*z - y*z + 7 >>> phi(b*a) -x*y - 2*x*z + y*z + 10 >>> phi(a*b + c) x*y + 2*x*z - y*z - x - y + z + 7 >>> phi(a*b) + phi(c) x*y + 2*x*z - y*z - x - y + z + 7
We check that the map is an algebra morphism:
sage: phi(a)*phi(b) x*y + 2*x*z - y*z + 7 sage: phi(a*b) x*y + 2*x*z - y*z + 7 sage: phi(a*a) 10 sage: phi(a)*phi(a) 10 sage: phi(b*a) -x*y - 2*x*z + y*z + 10 sage: phi(b) * phi(a) -x*y - 2*x*z + y*z + 10 sage: phi((a + b)*(a + c)) == phi(a + b) * phi(a + c) True
>>> from sage.all import * >>> phi(a)*phi(b) x*y + 2*x*z - y*z + 7 >>> phi(a*b) x*y + 2*x*z - y*z + 7 >>> phi(a*a) 10 >>> phi(a)*phi(a) 10 >>> phi(b*a) -x*y - 2*x*z + y*z + 10 >>> phi(b) * phi(a) -x*y - 2*x*z + y*z + 10 >>> phi((a + b)*(a + c)) == phi(a + b) * phi(a + c) True
We can also lift arbitrary linear maps:
sage: m = matrix([[1,1],[0,1],[1,1]]) sage: phi = Cl.lift_module_morphism(m, 'ab') sage: a,b = phi.domain().gens() sage: phi(a) x + z sage: phi(b) x + y + z sage: phi(a*b) x*y - y*z + 15 sage: phi(a)*phi(b) x*y - y*z + 15 sage: phi(b*a) -x*y + y*z + 12 sage: phi(b)*phi(a) -x*y + y*z + 12 sage: m = matrix([[1,1,1,2], [0,1,1,1], [0,1,1,1]]) sage: phi = Cl.lift_module_morphism(m, 'abcd') sage: a,b,c,d = phi.domain().gens() sage: phi(a) x sage: phi(b) x + y + z sage: phi(c) x + y + z sage: phi(d) 2*x + y + z sage: phi(a*b*c + d*a) -x*y - x*z + 21*x + 7 sage: phi(a*b*c*d) 21*x*y + 21*x*z + 42
>>> from sage.all import * >>> m = matrix([[Integer(1),Integer(1)],[Integer(0),Integer(1)],[Integer(1),Integer(1)]]) >>> phi = Cl.lift_module_morphism(m, 'ab') >>> a,b = phi.domain().gens() >>> phi(a) x + z >>> phi(b) x + y + z >>> phi(a*b) x*y - y*z + 15 >>> phi(a)*phi(b) x*y - y*z + 15 >>> phi(b*a) -x*y + y*z + 12 >>> phi(b)*phi(a) -x*y + y*z + 12 >>> m = matrix([[Integer(1),Integer(1),Integer(1),Integer(2)], [Integer(0),Integer(1),Integer(1),Integer(1)], [Integer(0),Integer(1),Integer(1),Integer(1)]]) >>> phi = Cl.lift_module_morphism(m, 'abcd') >>> a,b,c,d = phi.domain().gens() >>> phi(a) x >>> phi(b) x + y + z >>> phi(c) x + y + z >>> phi(d) 2*x + y + z >>> phi(a*b*c + d*a) -x*y - x*z + 21*x + 7 >>> phi(a*b*c*d) 21*x*y + 21*x*z + 42
- ngens()[source]¶
Return the number of algebra generators of
self
.EXAMPLES:
sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6]) sage: Cl.<x,y,z> = CliffordAlgebra(Q) sage: Cl.ngens() 3
>>> from sage.all import * >>> Q = QuadraticForm(ZZ, Integer(3), [Integer(1),Integer(2),Integer(3),Integer(4),Integer(5),Integer(6)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y', 'z',)); (x, y, z,) = Cl._first_ngens(3) >>> Cl.ngens() 3
- one_basis()[source]¶
Return the basis index of the element
1
. The element1
is indexed by the emptyset, which is represented by thesage.data_structures.bitset.Bitset
0
.EXAMPLES:
sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6]) sage: Cl.<x,y,z> = CliffordAlgebra(Q) sage: Cl.one_basis() 0
>>> from sage.all import * >>> Q = QuadraticForm(ZZ, Integer(3), [Integer(1),Integer(2),Integer(3),Integer(4),Integer(5),Integer(6)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y', 'z',)); (x, y, z,) = Cl._first_ngens(3) >>> Cl.one_basis() 0
- pseudoscalar()[source]¶
Return the unit pseudoscalar of
self
.Given the basis
of the underlying -module, the unit pseudoscalar is defined as .This depends on the choice of basis.
EXAMPLES:
sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6]) sage: Cl.<x,y,z> = CliffordAlgebra(Q) sage: Cl.pseudoscalar() x*y*z sage: Q = QuadraticForm(ZZ, 0, []) sage: Cl = CliffordAlgebra(Q) sage: Cl.pseudoscalar() 1
>>> from sage.all import * >>> Q = QuadraticForm(ZZ, Integer(3), [Integer(1),Integer(2),Integer(3),Integer(4),Integer(5),Integer(6)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y', 'z',)); (x, y, z,) = Cl._first_ngens(3) >>> Cl.pseudoscalar() x*y*z >>> Q = QuadraticForm(ZZ, Integer(0), []) >>> Cl = CliffordAlgebra(Q) >>> Cl.pseudoscalar() 1
REFERENCES:
- quadratic_form()[source]¶
Return the quadratic form of
self
.This is the quadratic form used to define
self
. The quadratic form onself
is yet to be implemented.EXAMPLES:
sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6]) sage: Cl.<x,y,z> = CliffordAlgebra(Q) sage: Cl.quadratic_form() Quadratic form in 3 variables over Integer Ring with coefficients: [ 1 2 3 ] [ * 4 5 ] [ * * 6 ]
>>> from sage.all import * >>> Q = QuadraticForm(ZZ, Integer(3), [Integer(1),Integer(2),Integer(3),Integer(4),Integer(5),Integer(6)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y', 'z',)); (x, y, z,) = Cl._first_ngens(3) >>> Cl.quadratic_form() Quadratic form in 3 variables over Integer Ring with coefficients: [ 1 2 3 ] [ * 4 5 ] [ * * 6 ]
- supercenter_basis()[source]¶
Return a list of elements which correspond to a basis for the supercenter of
self
.This assumes that the ground ring can be used to compute the kernel of a matrix.
See also
center_basis()
, http://math.stackexchange.com/questions/129183/center-of-clifford-algebra-depending-on-the-parity-of-dim-vTodo
Deprecate this in favor of a method called
once subalgebras are properly implemented in Sage.EXAMPLES:
sage: Q = QuadraticForm(QQ, 3, [1,2,3,4,5,6]) sage: Cl.<x,y,z> = CliffordAlgebra(Q) sage: SZ = Cl.supercenter_basis(); SZ (1,) sage: all(z.supercommutator(b) == 0 for z in SZ for b in Cl.basis()) True sage: Q = QuadraticForm(QQ, 3, [1,-2,-3, 4, 2, 1]) sage: Cl.<x,y,z> = CliffordAlgebra(Q) sage: Cl.supercenter_basis() (1,) sage: Q = QuadraticForm(QQ, 2, [1,-2,-3]) sage: Cl.<x,y> = CliffordAlgebra(Q) sage: Cl.supercenter_basis() (1,) sage: Q = QuadraticForm(QQ, 2, [-1,1,-3]) sage: Cl.<x,y> = CliffordAlgebra(Q) sage: Cl.supercenter_basis() (1,)
>>> from sage.all import * >>> Q = QuadraticForm(QQ, Integer(3), [Integer(1),Integer(2),Integer(3),Integer(4),Integer(5),Integer(6)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y', 'z',)); (x, y, z,) = Cl._first_ngens(3) >>> SZ = Cl.supercenter_basis(); SZ (1,) >>> all(z.supercommutator(b) == Integer(0) for z in SZ for b in Cl.basis()) True >>> Q = QuadraticForm(QQ, Integer(3), [Integer(1),-Integer(2),-Integer(3), Integer(4), Integer(2), Integer(1)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y', 'z',)); (x, y, z,) = Cl._first_ngens(3) >>> Cl.supercenter_basis() (1,) >>> Q = QuadraticForm(QQ, Integer(2), [Integer(1),-Integer(2),-Integer(3)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y',)); (x, y,) = Cl._first_ngens(2) >>> Cl.supercenter_basis() (1,) >>> Q = QuadraticForm(QQ, Integer(2), [-Integer(1),Integer(1),-Integer(3)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y',)); (x, y,) = Cl._first_ngens(2) >>> Cl.supercenter_basis() (1,)
Singular vectors of a quadratic form generate in the supercenter:
sage: Q = QuadraticForm(QQ, 3, [1/2,-2,4,256/249,3,-185/8]) sage: Cl.<x,y,z> = CliffordAlgebra(Q) sage: Cl.supercenter_basis() (1, x + 249/322*y + 22/161*z) sage: Q = QuadraticForm(QQ, 3, [4,4,-4,1,-2,1]) sage: Cl.<x,y,z> = CliffordAlgebra(Q) sage: Cl.supercenter_basis() (1, x + 2*z, y + z, x*y + x*z - 2*y*z)
>>> from sage.all import * >>> Q = QuadraticForm(QQ, Integer(3), [Integer(1)/Integer(2),-Integer(2),Integer(4),Integer(256)/Integer(249),Integer(3),-Integer(185)/Integer(8)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y', 'z',)); (x, y, z,) = Cl._first_ngens(3) >>> Cl.supercenter_basis() (1, x + 249/322*y + 22/161*z) >>> Q = QuadraticForm(QQ, Integer(3), [Integer(4),Integer(4),-Integer(4),Integer(1),-Integer(2),Integer(1)]) >>> Cl = CliffordAlgebra(Q, names=('x', 'y', 'z',)); (x, y, z,) = Cl._first_ngens(3) >>> Cl.supercenter_basis() (1, x + 2*z, y + z, x*y + x*z - 2*y*z)
The most degenerate case:
sage: Q = QuadraticForm(QQ, 3) sage: Cl.<x,y,z> = CliffordAlgebra(Q) sage: Cl.supercenter_basis() (1, x, y, z, x*y, x*z, y*z, x*y*z)
>>> from sage.all import * >>> Q = QuadraticForm(QQ, Integer(3)) >>> Cl = CliffordAlgebra(Q, names=('x', 'y', 'z',)); (x, y, z,) = Cl._first_ngens(3) >>> Cl.supercenter_basis() (1, x, y, z, x*y, x*z, y*z, x*y*z)
- class sage.algebras.clifford_algebra.CliffordAlgebraIndices(Qdim, degree=None)[source]¶
Bases:
UniqueRepresentation
,Parent
A facade parent for the indices of Clifford algebra. Users should not create instances of this class directly.
- cardinality()[source]¶
Return the cardinality of
self
.EXAMPLES:
sage: from sage.algebras.clifford_algebra import CliffordAlgebraIndices sage: idx = CliffordAlgebraIndices(7) sage: idx.cardinality() == 2^7 True sage: len(idx) == 2^7 True sage: idx = CliffordAlgebraIndices(7, 3) sage: idx.cardinality() == binomial(7, 3) True sage: len(idx) == binomial(7, 3) True
>>> from sage.all import * >>> from sage.algebras.clifford_algebra import CliffordAlgebraIndices >>> idx = CliffordAlgebraIndices(Integer(7)) >>> idx.cardinality() == Integer(2)**Integer(7) True >>> len(idx) == Integer(2)**Integer(7) True >>> idx = CliffordAlgebraIndices(Integer(7), Integer(3)) >>> idx.cardinality() == binomial(Integer(7), Integer(3)) True >>> len(idx) == binomial(Integer(7), Integer(3)) True
- class sage.algebras.clifford_algebra.ExteriorAlgebra(R, names)[source]¶
Bases:
CliffordAlgebra
An exterior algebra of a free module over a commutative ring.
Let
be a module over a commutative ring . The exterior algebra (or Grassmann algebra) of is defined as the quotient of the tensor algebra of modulo the two-sided ideal generated by all tensors of the form with . The multiplication on is denoted by (so is the projection of onto ) and called the “exterior product” or “wedge product”.If
is a rank- free -module with a basis , then is the -algebra noncommutatively generated by the generators subject to the relations for all , and for all . As an -module, then has a basis with ranging over the subsets of (where is the wedge product of for running through all elements of from smallest to largest), and hence is free of rank .The exterior algebra of an
-module can also be realized as the Clifford algebra of for the quadratic form given by for all vectors . SeeCliffordAlgebra
for the notion of a Clifford algebra.The exterior algebra of an
-module is a connected -graded Hopf superalgebra. It is commutative in the super sense (i.e., the odd elements anticommute and square to ).This class implements the exterior algebra
for a nonnegative integer.INPUT:
R
– the base ring, or the free module whose exterior algebra is to be computednames
– list of strings to name the generators of the exterior algebra; this list can either have one entry only (in which case the generators will be callede + '0'
,e + '1'
, …,e + 'n-1'
, withe
being said entry), or haven
entries (in which case these entries will be used directly as names for the generators)n
– the number of generators, i.e., the rank of the free module whose exterior algebra is to be computed (this doesn’t have to be provided if it can be inferred from the rest of the input)
REFERENCES:
- antipode_on_basis(m)[source]¶
Return the antipode on the basis element indexed by
m
.Given a basis element
, the antipode is defined by .EXAMPLES:
sage: E.<x,y,z> = ExteriorAlgebra(QQ) sage: E.antipode_on_basis(()) 1 sage: E.antipode_on_basis((1,)) -y sage: E.antipode_on_basis((1,2)) y*z
>>> from sage.all import * >>> E = ExteriorAlgebra(QQ, names=('x', 'y', 'z',)); (x, y, z,) = E._first_ngens(3) >>> E.antipode_on_basis(()) 1 >>> E.antipode_on_basis((Integer(1),)) -y >>> E.antipode_on_basis((Integer(1),Integer(2))) y*z
- boundary(s_coeff)[source]¶
Return the boundary operator
defined by the structure coefficientss_coeff
of a Lie algebra.For more on the boundary operator, see
ExteriorAlgebraBoundary
.INPUT:
s_coeff
– dictionary whose keys are in , where is the index set of the underlying vector space , and whose values can be coerced into 1-forms (degree 1 elements) inE
(usually, these values will just be elements of )
EXAMPLES:
sage: E.<x,y,z> = ExteriorAlgebra(QQ) sage: E.boundary({(0,1): z, (1,2): x, (2,0): y}) Boundary endomorphism of The exterior algebra of rank 3 over Rational Field
>>> from sage.all import * >>> E = ExteriorAlgebra(QQ, names=('x', 'y', 'z',)); (x, y, z,) = E._first_ngens(3) >>> E.boundary({(Integer(0),Integer(1)): z, (Integer(1),Integer(2)): x, (Integer(2),Integer(0)): y}) Boundary endomorphism of The exterior algebra of rank 3 over Rational Field
- coboundary(s_coeff)[source]¶
Return the coboundary operator
defined by the structure coefficientss_coeff
of a Lie algebra.For more on the coboundary operator, see
ExteriorAlgebraCoboundary
.INPUT:
s_coeff
– dictionary whose keys are in , where is the index set of the underlying vector space , and whose values can be coerced into 1-forms (degree 1 elements) inE
(usually, these values will just be elements of )
EXAMPLES:
sage: E.<x,y,z> = ExteriorAlgebra(QQ) sage: E.coboundary({(0,1): z, (1,2): x, (2,0): y}) Coboundary endomorphism of The exterior algebra of rank 3 over Rational Field
>>> from sage.all import * >>> E = ExteriorAlgebra(QQ, names=('x', 'y', 'z',)); (x, y, z,) = E._first_ngens(3) >>> E.coboundary({(Integer(0),Integer(1)): z, (Integer(1),Integer(2)): x, (Integer(2),Integer(0)): y}) Coboundary endomorphism of The exterior algebra of rank 3 over Rational Field
- coproduct_on_basis(a)[source]¶
Return the coproduct on the basis element indexed by
a
.The coproduct is defined by
where
denotes the set of all -unshuffles (i.e., permutations in which are increasing on the interval and on the interval ).Warning
This coproduct is a homomorphism of superalgebras, not a homomorphism of algebras!
EXAMPLES:
sage: E.<x,y,z> = ExteriorAlgebra(QQ) sage: E.coproduct_on_basis((0,)) 1 # x + x # 1 sage: E.coproduct_on_basis((0,1)) 1 # x*y + x # y - y # x + x*y # 1 sage: E.coproduct_on_basis((0,1,2)) 1 # x*y*z + x # y*z - y # x*z + x*y # z + z # x*y - x*z # y + y*z # x + x*y*z # 1
>>> from sage.all import * >>> E = ExteriorAlgebra(QQ, names=('x', 'y', 'z',)); (x, y, z,) = E._first_ngens(3) >>> E.coproduct_on_basis((Integer(0),)) 1 # x + x # 1 >>> E.coproduct_on_basis((Integer(0),Integer(1))) 1 # x*y + x # y - y # x + x*y # 1 >>> E.coproduct_on_basis((Integer(0),Integer(1),Integer(2))) 1 # x*y*z + x # y*z - y # x*z + x*y # z + z # x*y - x*z # y + y*z # x + x*y*z # 1
- counit(x)[source]¶
Return the counit of
x
.The counit of an element
of the exterior algebra is its constant coefficient.EXAMPLES:
sage: E.<x,y,z> = ExteriorAlgebra(QQ) sage: elt = x*y - 2*x + 3 sage: E.counit(elt) 3
>>> from sage.all import * >>> E = ExteriorAlgebra(QQ, names=('x', 'y', 'z',)); (x, y, z,) = E._first_ngens(3) >>> elt = x*y - Integer(2)*x + Integer(3) >>> E.counit(elt) 3
- degree_on_basis(m)[source]¶
Return the degree of the monomial indexed by
m
.The degree of
m
in the -grading ofself
is defined to be the length ofm
.EXAMPLES:
sage: E.<x,y,z> = ExteriorAlgebra(QQ) sage: E.degree_on_basis(()) 0 sage: E.degree_on_basis((0,)) 1 sage: E.degree_on_basis((0,1)) 2
>>> from sage.all import * >>> E = ExteriorAlgebra(QQ, names=('x', 'y', 'z',)); (x, y, z,) = E._first_ngens(3) >>> E.degree_on_basis(()) 0 >>> E.degree_on_basis((Integer(0),)) 1 >>> E.degree_on_basis((Integer(0),Integer(1))) 2
- interior_product_on_basis(a, b)[source]¶
Return the interior product
ofa
with respect tob
.See
interior_product()
for more information.In this method,
a
andb
are supposed to be basis elements (seeinterior_product()
for a method that computes interior product of arbitrary elements), and to be input as their keys.This depends on the choice of basis of the vector space whose exterior algebra is
self
.EXAMPLES:
sage: E.<x,y,z> = ExteriorAlgebra(QQ) sage: k = list(E.basis().keys()) sage: E.interior_product_on_basis(k[1], k[1]) 1 sage: E.interior_product_on_basis(k[5], k[1]) z sage: E.interior_product_on_basis(k[2], k[5]) 0 sage: E.interior_product_on_basis(k[5], k[2]) 0 sage: E.interior_product_on_basis(k[7], k[5]) -y
>>> from sage.all import * >>> E = ExteriorAlgebra(QQ, names=('x', 'y', 'z',)); (x, y, z,) = E._first_ngens(3) >>> k = list(E.basis().keys()) >>> E.interior_product_on_basis(k[Integer(1)], k[Integer(1)]) 1 >>> E.interior_product_on_basis(k[Integer(5)], k[Integer(1)]) z >>> E.interior_product_on_basis(k[Integer(2)], k[Integer(5)]) 0 >>> E.interior_product_on_basis(k[Integer(5)], k[Integer(2)]) 0 >>> E.interior_product_on_basis(k[Integer(7)], k[Integer(5)]) -y
Check Issue #34694:
sage: # needs sage.symbolic sage: E = ExteriorAlgebra(SR,'e',3) sage: E.inject_variables() Defining e0, e1, e2 sage: a = (e0*e1).interior_product(e0) sage: a * e0 -e0*e1
>>> from sage.all import * >>> # needs sage.symbolic >>> E = ExteriorAlgebra(SR,'e',Integer(3)) >>> E.inject_variables() Defining e0, e1, e2 >>> a = (e0*e1).interior_product(e0) >>> a * e0 -e0*e1
- lift_morphism(phi, names=None)[source]¶
Lift the matrix
m
to an algebra morphism of exterior algebras.Given a linear map
(here represented by a matrix acting on column vectors over the base ring of ), this method returns the algebra morphism . This morphism is defined on generators by .Note
This is the map going out of
self
as opposed tolift_module_morphism()
for general Clifford algebras.INPUT:
phi
– a linear map from to , encoded as a matrixnames
– (default:'e'
) the names of the generators of the Clifford algebra of the domain of (the map represented by)phi
OUTPUT: the algebra morphism
fromself
toEXAMPLES:
sage: E.<x,y> = ExteriorAlgebra(QQ) sage: phi = matrix([[0,1],[1,1],[1,2]]); phi [0 1] [1 1] [1 2] sage: L = E.lift_morphism(phi, ['a','b','c']); L Generic morphism: From: The exterior algebra of rank 2 over Rational Field To: The exterior algebra of rank 3 over Rational Field sage: L(x) b + c sage: L(y) a + b + 2*c sage: L.on_basis()((1,)) a + b + 2*c sage: p = L(E.one()); p 1 sage: p.parent() The exterior algebra of rank 3 over Rational Field sage: L(x*y) -a*b - a*c + b*c sage: L(x)*L(y) -a*b - a*c + b*c sage: L(x + y) a + 2*b + 3*c sage: L(x) + L(y) a + 2*b + 3*c sage: L(1/2*x + 2) 1/2*b + 1/2*c + 2 sage: L(E(3)) 3 sage: psi = matrix([[1, -3/2]]); psi [ 1 -3/2] sage: Lp = E.lift_morphism(psi, ['a']); Lp Generic morphism: From: The exterior algebra of rank 2 over Rational Field To: The exterior algebra of rank 1 over Rational Field sage: Lp(x) a sage: Lp(y) -3/2*a sage: Lp(x + 2*y + 3) -2*a + 3
>>> from sage.all import * >>> E = ExteriorAlgebra(QQ, names=('x', 'y',)); (x, y,) = E._first_ngens(2) >>> phi = matrix([[Integer(0),Integer(1)],[Integer(1),Integer(1)],[Integer(1),Integer(2)]]); phi [0 1] [1 1] [1 2] >>> L = E.lift_morphism(phi, ['a','b','c']); L Generic morphism: From: The exterior algebra of rank 2 over Rational Field To: The exterior algebra of rank 3 over Rational Field >>> L(x) b + c >>> L(y) a + b + 2*c >>> L.on_basis()((Integer(1),)) a + b + 2*c >>> p = L(E.one()); p 1 >>> p.parent() The exterior algebra of rank 3 over Rational Field >>> L(x*y) -a*b - a*c + b*c >>> L(x)*L(y) -a*b - a*c + b*c >>> L(x + y) a + 2*b + 3*c >>> L(x) + L(y) a + 2*b + 3*c >>> L(Integer(1)/Integer(2)*x + Integer(2)) 1/2*b + 1/2*c + 2 >>> L(E(Integer(3))) 3 >>> psi = matrix([[Integer(1), -Integer(3)/Integer(2)]]); psi [ 1 -3/2] >>> Lp = E.lift_morphism(psi, ['a']); Lp Generic morphism: From: The exterior algebra of rank 2 over Rational Field To: The exterior algebra of rank 1 over Rational Field >>> Lp(x) a >>> Lp(y) -3/2*a >>> Lp(x + Integer(2)*y + Integer(3)) -2*a + 3
- lifted_bilinear_form(M)[source]¶
Return the bilinear form on the exterior algebra
self
which is obtained by lifting the bilinear form on given by the matrixM
.Let
be a module over a commutative ring , and let be a bilinear form on . Then, a bilinear form on can be canonically defined as follows: For every , , , we definewhere
is the -matrix whose -th entry is . This bilinear form is known as the bilinear form on obtained by lifting the bilinear form . Its restriction to the -st homogeneous component of is .The bilinear form
is symmetric if is.INPUT:
M
– a matrix over the same base ring asself
, whose -th entry is , where is the standard basis of the module for whichself
(so that ), and where is the bilinear form which is to be lifted.
OUTPUT:
A bivariate function which takes two elements
and ofself
to .Note
This takes a bilinear form on
as matrix, and returns a bilinear form onself
as a function in two arguments. We do not return the bilinear form as a matrix since this matrix can be huge and one often needs just a particular value.Todo
Implement a class for bilinear forms and rewrite this method to use that class.
EXAMPLES:
sage: E.<x,y,z> = ExteriorAlgebra(QQ) sage: M = Matrix(QQ, [[1, 2, 3], [2, 3, 4], [3, 4, 5]]) sage: Eform = E.lifted_bilinear_form(M) sage: Eform Bilinear Form from The exterior algebra of rank 3 over Rational Field (+) The exterior algebra of rank 3 over Rational Field to Rational Field sage: Eform(x*y, y*z) -1 sage: Eform(x*y, y) 0 sage: Eform(x*(y+z), y*z) -3 sage: Eform(x*(y+z), y*(z+x)) 0 sage: N = Matrix(QQ, [[3, 1, 7], [2, 0, 4], [-1, -3, -1]]) sage: N.determinant() -8 sage: Eform = E.lifted_bilinear_form(N) sage: Eform(x, E.one()) 0 sage: Eform(x, x*z*y) 0 sage: Eform(E.one(), E.one()) 1 sage: Eform(E.zero(), E.one()) 0 sage: Eform(x, y) 1 sage: Eform(z, y) -3 sage: Eform(x*z, y*z) 20 sage: Eform(x+x*y+x*y*z, z+z*y+z*y*x) 11
>>> from sage.all import * >>> E = ExteriorAlgebra(QQ, names=('x', 'y', 'z',)); (x, y, z,) = E._first_ngens(3) >>> M = Matrix(QQ, [[Integer(1), Integer(2), Integer(3)], [Integer(2), Integer(3), Integer(4)], [Integer(3), Integer(4), Integer(5)]]) >>> Eform = E.lifted_bilinear_form(M) >>> Eform Bilinear Form from The exterior algebra of rank 3 over Rational Field (+) The exterior algebra of rank 3 over Rational Field to Rational Field >>> Eform(x*y, y*z) -1 >>> Eform(x*y, y) 0 >>> Eform(x*(y+z), y*z) -3 >>> Eform(x*(y+z), y*(z+x)) 0 >>> N = Matrix(QQ, [[Integer(3), Integer(1), Integer(7)], [Integer(2), Integer(0), Integer(4)], [-Integer(1), -Integer(3), -Integer(1)]]) >>> N.determinant() -8 >>> Eform = E.lifted_bilinear_form(N) >>> Eform(x, E.one()) 0 >>> Eform(x, x*z*y) 0 >>> Eform(E.one(), E.one()) 1 >>> Eform(E.zero(), E.one()) 0 >>> Eform(x, y) 1 >>> Eform(z, y) -3 >>> Eform(x*z, y*z) 20 >>> Eform(x+x*y+x*y*z, z+z*y+z*y*x) 11
Todo
Another way to compute this bilinear form seems to be to map
and to the appropriate Clifford algebra and there compute , then send the result back to the exterior algebra and return its constant coefficient. Or something like this. Once the maps to the Clifford and back are implemented, check if this is faster.
- volume_form()[source]¶
Return the volume form of
self
.Given the basis
of the underlying -module, the volume form is defined as .This depends on the choice of basis.
EXAMPLES:
sage: E.<x,y,z> = ExteriorAlgebra(QQ) sage: E.volume_form() x*y*z
>>> from sage.all import * >>> E = ExteriorAlgebra(QQ, names=('x', 'y', 'z',)); (x, y, z,) = E._first_ngens(3) >>> E.volume_form() x*y*z
- class sage.algebras.clifford_algebra.ExteriorAlgebraBoundary(E, s_coeff)[source]¶
Bases:
ExteriorAlgebraDifferential
The boundary
of an exterior algebra defined by the structure coefficients of .Let
be a Lie algebra. We give the exterior algebra a chain complex structure by considering a differential defined bywhere
denotes a missing index. The corresponding homology is the Lie algebra homology.INPUT:
E
– an exterior algebra of a vector spaces_coeff
– dictionary whose keys are in , where is the index set of the basis of the vector space , and whose values can be coerced into 1-forms (degree 1 elements) inE
; this dictionary will be used to define the Lie algebra structure on (indeed, the -th coordinate of the Lie bracket of the -th and -th basis vectors of for is set to be the value at the key if this key appears ins_coeff
, or otherwise the negated of the value at the key )
Warning
The values of
s_coeff
are supposed to be coercible into 1-forms inE
; but they can also be dictionaries themselves (in which case they are interpreted as giving the coordinates of vectors inL
). In the interest of speed, these dictionaries are not sanitized or checked.Warning
For any two distinct elements
and of , the dictionarys_coeff
must have only one of the pairs and as a key. This is not checked.EXAMPLES:
We consider the differential given by Lie algebra given by the cross product
of :sage: E.<x,y,z> = ExteriorAlgebra(QQ) sage: par = E.boundary({(0,1): z, (1,2): x, (2,0): y}) sage: par(x) 0 sage: par(x*y) z sage: par(x*y*z) 0 sage: par(x+y-y*z+x*y) -x + z sage: par(E.zero()) 0
>>> from sage.all import * >>> E = ExteriorAlgebra(QQ, names=('x', 'y', 'z',)); (x, y, z,) = E._first_ngens(3) >>> par = E.boundary({(Integer(0),Integer(1)): z, (Integer(1),Integer(2)): x, (Integer(2),Integer(0)): y}) >>> par(x) 0 >>> par(x*y) z >>> par(x*y*z) 0 >>> par(x+y-y*z+x*y) -x + z >>> par(E.zero()) 0
We check that
:sage: p2 = par * par sage: all(p2(b) == 0 for b in E.basis()) True
>>> from sage.all import * >>> p2 = par * par >>> all(p2(b) == Integer(0) for b in E.basis()) True
Another example: the Lie algebra
, which has a basis satisfying , , and :sage: E.<e,f,h> = ExteriorAlgebra(QQ) sage: par = E.boundary({(0,1): h, (2,1): -2*f, (2,0): 2*e}) sage: par(E.zero()) 0 sage: par(e) 0 sage: par(e*f) h sage: par(f*h) 2*f sage: par(h*f) -2*f sage: C = par.chain_complex(); C Chain complex with at most 4 nonzero terms over Rational Field sage: ascii_art(C) [ 0 -2 0] [0] [ 0 0 2] [0] [0 0 0] [ 1 0 0] [0] 0 <-- C_0 <-------- C_1 <----------- C_2 <---- C_3 <-- 0 sage: C.homology() {0: Vector space of dimension 1 over Rational Field, 1: Vector space of dimension 0 over Rational Field, 2: Vector space of dimension 0 over Rational Field, 3: Vector space of dimension 1 over Rational Field}
>>> from sage.all import * >>> E = ExteriorAlgebra(QQ, names=('e', 'f', 'h',)); (e, f, h,) = E._first_ngens(3) >>> par = E.boundary({(Integer(0),Integer(1)): h, (Integer(2),Integer(1)): -Integer(2)*f, (Integer(2),Integer(0)): Integer(2)*e}) >>> par(E.zero()) 0 >>> par(e) 0 >>> par(e*f) h >>> par(f*h) 2*f >>> par(h*f) -2*f >>> C = par.chain_complex(); C Chain complex with at most 4 nonzero terms over Rational Field >>> ascii_art(C) [ 0 -2 0] [0] [ 0 0 2] [0] [0 0 0] [ 1 0 0] [0] 0 <-- C_0 <-------- C_1 <----------- C_2 <---- C_3 <-- 0 >>> C.homology() {0: Vector space of dimension 1 over Rational Field, 1: Vector space of dimension 0 over Rational Field, 2: Vector space of dimension 0 over Rational Field, 3: Vector space of dimension 1 over Rational Field}
Over the integers:
sage: C = par.chain_complex(R=ZZ); C Chain complex with at most 4 nonzero terms over Integer Ring sage: ascii_art(C) [ 0 -2 0] [0] [ 0 0 2] [0] [0 0 0] [ 1 0 0] [0] 0 <-- C_0 <-------- C_1 <----------- C_2 <---- C_3 <-- 0 sage: C.homology() {0: Z, 1: C2 x C2, 2: 0, 3: Z}
>>> from sage.all import * >>> C = par.chain_complex(R=ZZ); C Chain complex with at most 4 nonzero terms over Integer Ring >>> ascii_art(C) [ 0 -2 0] [0] [ 0 0 2] [0] [0 0 0] [ 1 0 0] [0] 0 <-- C_0 <-------- C_1 <----------- C_2 <---- C_3 <-- 0 >>> C.homology() {0: Z, 1: C2 x C2, 2: 0, 3: Z}
REFERENCES:
- chain_complex(R=None)[source]¶
Return the chain complex over
R
determined byself
.INPUT:
R
– the base ring; the default is the base ring of the exterior algebra
EXAMPLES:
sage: E.<x,y,z> = ExteriorAlgebra(QQ) sage: par = E.boundary({(0,1): z, (1,2): x, (2,0): y}) sage: C = par.chain_complex(); C Chain complex with at most 4 nonzero terms over Rational Field sage: ascii_art(C) [ 0 0 1] [0] [ 0 -1 0] [0] [0 0 0] [ 1 0 0] [0] 0 <-- C_0 <-------- C_1 <----------- C_2 <---- C_3 <-- 0
>>> from sage.all import * >>> E = ExteriorAlgebra(QQ, names=('x', 'y', 'z',)); (x, y, z,) = E._first_ngens(3) >>> par = E.boundary({(Integer(0),Integer(1)): z, (Integer(1),Integer(2)): x, (Integer(2),Integer(0)): y}) >>> C = par.chain_complex(); C Chain complex with at most 4 nonzero terms over Rational Field >>> ascii_art(C) [ 0 0 1] [0] [ 0 -1 0] [0] [0 0 0] [ 1 0 0] [0] 0 <-- C_0 <-------- C_1 <----------- C_2 <---- C_3 <-- 0
- class sage.algebras.clifford_algebra.ExteriorAlgebraCoboundary(E, s_coeff)[source]¶
Bases:
ExteriorAlgebraDifferential
The coboundary
of an exterior algebra defined by the structure coefficients of a Lie algebra .Let
be a Lie algebra. We endow its exterior algebra with a cochain complex structure by considering a differential defined bywhere
is a basis of , and where is the -coordinate of the Lie bracket .The corresponding cohomology is the Lie algebra cohomology of
.This can also be thought of as the exterior derivative, in which case the resulting cohomology is the de Rham cohomology of a manifold whose exterior algebra of differential forms is
E
.INPUT:
E
– an exterior algebra of a vector spaces_coeff
– dictionary whose keys are in , where is the index set of the basis of the vector space , and whose values can be coerced into 1-forms (degree 1 elements) inE
; this dictionary will be used to define the Lie algebra structure on (indeed, the -th coordinate of the Lie bracket of the -th and -th basis vectors of for is set to be the value at the key if this key appears ins_coeff
, or otherwise the negated of the value at the key )
Warning
For any two distinct elements
and of , the dictionarys_coeff
must have only one of the pairs and as a key. This is not checked.EXAMPLES:
We consider the differential coming from the Lie algebra given by the cross product
of :sage: E.<x,y,z> = ExteriorAlgebra(QQ) sage: d = E.coboundary({(0,1): z, (1,2): x, (0, 2): -y}) sage: d(x) y*z sage: d(y) -x*z sage: d(x+y-y*z) -x*z + y*z sage: d(x*y) 0 sage: d(E.one()) 0 sage: d(E.zero()) 0
>>> from sage.all import * >>> E = ExteriorAlgebra(QQ, names=('x', 'y', 'z',)); (x, y, z,) = E._first_ngens(3) >>> d = E.coboundary({(Integer(0),Integer(1)): z, (Integer(1),Integer(2)): x, (Integer(0), Integer(2)): -y}) >>> d(x) y*z >>> d(y) -x*z >>> d(x+y-y*z) -x*z + y*z >>> d(x*y) 0 >>> d(E.one()) 0 >>> d(E.zero()) 0
We check that
:sage: d2 = d * d sage: all(d2(b) == 0 for b in E.basis()) True
>>> from sage.all import * >>> d2 = d * d >>> all(d2(b) == Integer(0) for b in E.basis()) True
Another example: the Lie algebra
, which has a basis satisfying , , and :sage: E.<e,f,h> = ExteriorAlgebra(QQ) sage: d = E.coboundary({(0,1): h, (2,1): -2*f, (2,0): 2*e}) sage: d(E.zero()) 0 sage: d(e) -2*e*h sage: d(f) 2*f*h sage: d(h) e*f sage: d(e*f) 0 sage: d(f*h) 0 sage: d(e*h) 0 sage: C = d.chain_complex(); C Chain complex with at most 4 nonzero terms over Rational Field sage: ascii_art(C) [ 0 0 1] [0] [-2 0 0] [0] [0 0 0] [ 0 2 0] [0] 0 <-- C_3 <-------- C_2 <----------- C_1 <---- C_0 <-- 0 sage: C.homology() {0: Vector space of dimension 1 over Rational Field, 1: Vector space of dimension 0 over Rational Field, 2: Vector space of dimension 0 over Rational Field, 3: Vector space of dimension 1 over Rational Field}
>>> from sage.all import * >>> E = ExteriorAlgebra(QQ, names=('e', 'f', 'h',)); (e, f, h,) = E._first_ngens(3) >>> d = E.coboundary({(Integer(0),Integer(1)): h, (Integer(2),Integer(1)): -Integer(2)*f, (Integer(2),Integer(0)): Integer(2)*e}) >>> d(E.zero()) 0 >>> d(e) -2*e*h >>> d(f) 2*f*h >>> d(h) e*f >>> d(e*f) 0 >>> d(f*h) 0 >>> d(e*h) 0 >>> C = d.chain_complex(); C Chain complex with at most 4 nonzero terms over Rational Field >>> ascii_art(C) [ 0 0 1] [0] [-2 0 0] [0] [0 0 0] [ 0 2 0] [0] 0 <-- C_3 <-------- C_2 <----------- C_1 <---- C_0 <-- 0 >>> C.homology() {0: Vector space of dimension 1 over Rational Field, 1: Vector space of dimension 0 over Rational Field, 2: Vector space of dimension 0 over Rational Field, 3: Vector space of dimension 1 over Rational Field}
Over the integers:
sage: C = d.chain_complex(R=ZZ); C Chain complex with at most 4 nonzero terms over Integer Ring sage: ascii_art(C) [ 0 0 1] [0] [-2 0 0] [0] [0 0 0] [ 0 2 0] [0] 0 <-- C_3 <-------- C_2 <----------- C_1 <---- C_0 <-- 0 sage: C.homology() {0: Z, 1: 0, 2: C2 x C2, 3: Z}
>>> from sage.all import * >>> C = d.chain_complex(R=ZZ); C Chain complex with at most 4 nonzero terms over Integer Ring >>> ascii_art(C) [ 0 0 1] [0] [-2 0 0] [0] [0 0 0] [ 0 2 0] [0] 0 <-- C_3 <-------- C_2 <----------- C_1 <---- C_0 <-- 0 >>> C.homology() {0: Z, 1: 0, 2: C2 x C2, 3: Z}
REFERENCES:
- chain_complex(R=None)[source]¶
Return the chain complex over
R
determined byself
.INPUT:
R
– the base ring; the default is the base ring of the exterior algebra
EXAMPLES:
sage: E.<x,y,z> = ExteriorAlgebra(QQ) sage: d = E.coboundary({(0,1): z, (1,2): x, (2,0): y}) sage: C = d.chain_complex(); C Chain complex with at most 4 nonzero terms over Rational Field sage: ascii_art(C) [ 0 0 1] [0] [ 0 -1 0] [0] [0 0 0] [ 1 0 0] [0] 0 <-- C_3 <-------- C_2 <----------- C_1 <---- C_0 <-- 0
>>> from sage.all import * >>> E = ExteriorAlgebra(QQ, names=('x', 'y', 'z',)); (x, y, z,) = E._first_ngens(3) >>> d = E.coboundary({(Integer(0),Integer(1)): z, (Integer(1),Integer(2)): x, (Integer(2),Integer(0)): y}) >>> C = d.chain_complex(); C Chain complex with at most 4 nonzero terms over Rational Field >>> ascii_art(C) [ 0 0 1] [0] [ 0 -1 0] [0] [0 0 0] [ 1 0 0] [0] 0 <-- C_3 <-------- C_2 <----------- C_1 <---- C_0 <-- 0
- class sage.algebras.clifford_algebra.ExteriorAlgebraDifferential(E, s_coeff)[source]¶
Bases:
ModuleMorphismByLinearity
,UniqueRepresentation
Internal class to store the data of a boundary or coboundary of an exterior algebra
defined by the structure coefficients of a Lie algebra .See
ExteriorAlgebraBoundary
andExteriorAlgebraCoboundary
for the actual classes, which inherit from this.Warning
This is not a general class for differentials on the exterior algebra.
- homology(deg=None, **kwds)[source]¶
Return the homology determined by
self
.EXAMPLES:
sage: E.<x,y,z> = ExteriorAlgebra(QQ) sage: par = E.boundary({(0,1): z, (1,2): x, (2,0): y}) sage: par.homology() {0: Vector space of dimension 1 over Rational Field, 1: Vector space of dimension 0 over Rational Field, 2: Vector space of dimension 0 over Rational Field, 3: Vector space of dimension 1 over Rational Field} sage: d = E.coboundary({(0,1): z, (1,2): x, (2,0): y}) sage: d.homology() {0: Vector space of dimension 1 over Rational Field, 1: Vector space of dimension 0 over Rational Field, 2: Vector space of dimension 0 over Rational Field, 3: Vector space of dimension 1 over Rational Field}
>>> from sage.all import * >>> E = ExteriorAlgebra(QQ, names=('x', 'y', 'z',)); (x, y, z,) = E._first_ngens(3) >>> par = E.boundary({(Integer(0),Integer(1)): z, (Integer(1),Integer(2)): x, (Integer(2),Integer(0)): y}) >>> par.homology() {0: Vector space of dimension 1 over Rational Field, 1: Vector space of dimension 0 over Rational Field, 2: Vector space of dimension 0 over Rational Field, 3: Vector space of dimension 1 over Rational Field} >>> d = E.coboundary({(Integer(0),Integer(1)): z, (Integer(1),Integer(2)): x, (Integer(2),Integer(0)): y}) >>> d.homology() {0: Vector space of dimension 1 over Rational Field, 1: Vector space of dimension 0 over Rational Field, 2: Vector space of dimension 0 over Rational Field, 3: Vector space of dimension 1 over Rational Field}
- class sage.algebras.clifford_algebra.ExteriorAlgebraIdeal(ring, gens, coerce=True, side='twosided')[source]¶
Bases:
Ideal_nc
An ideal of the exterior algebra.
EXAMPLES:
sage: E.<x,y,z> = ExteriorAlgebra(QQ) sage: I = E.ideal(x*y); I Twosided Ideal (x*y) of The exterior algebra of rank 3 over Rational Field
>>> from sage.all import * >>> E = ExteriorAlgebra(QQ, names=('x', 'y', 'z',)); (x, y, z,) = E._first_ngens(3) >>> I = E.ideal(x*y); I Twosided Ideal (x*y) of The exterior algebra of rank 3 over Rational Field
We can also use it to build a quotient:
sage: Q = E.quotient(I); Q Quotient of The exterior algebra of rank 3 over Rational Field by the ideal (x*y) sage: Q.inject_variables() Defining xbar, ybar, zbar sage: xbar * ybar 0
>>> from sage.all import * >>> Q = E.quotient(I); Q Quotient of The exterior algebra of rank 3 over Rational Field by the ideal (x*y) >>> Q.inject_variables() Defining xbar, ybar, zbar >>> xbar * ybar 0
- groebner_basis(term_order=None, reduced=True)[source]¶
Return the (reduced) Gröbner basis of
self
.INPUT:
term_order
– the term order used to compute the Gröbner basis; must be one of the following:'neglex'
– (default) negative (read right-to-left) lex order'degrevlex'
– degree reverse lex order'deglex'
– degree lex order
reduced
– boolean (default:True
); whether or not to return the reduced Gröbner basis
EXAMPLES:
We compute an example:
sage: E.<a,b,c,d,e> = ExteriorAlgebra(QQ) sage: rels = [c*d*e - b*d*e + b*c*e - b*c*d, ....: c*d*e - a*d*e + a*c*e - a*c*d, ....: b*d*e - a*d*e + a*b*e - a*b*d, ....: b*c*e - a*c*e + a*b*e - a*b*c, ....: b*c*d - a*c*d + a*b*d - a*b*c] sage: I = E.ideal(rels) sage: I.groebner_basis() (-a*b*c + a*b*d - a*c*d + b*c*d, -a*b*c + a*b*e - a*c*e + b*c*e, -a*b*d + a*b*e - a*d*e + b*d*e, -a*c*d + a*c*e - a*d*e + c*d*e)
>>> from sage.all import * >>> E = ExteriorAlgebra(QQ, names=('a', 'b', 'c', 'd', 'e',)); (a, b, c, d, e,) = E._first_ngens(5) >>> rels = [c*d*e - b*d*e + b*c*e - b*c*d, ... c*d*e - a*d*e + a*c*e - a*c*d, ... b*d*e - a*d*e + a*b*e - a*b*d, ... b*c*e - a*c*e + a*b*e - a*b*c, ... b*c*d - a*c*d + a*b*d - a*b*c] >>> I = E.ideal(rels) >>> I.groebner_basis() (-a*b*c + a*b*d - a*c*d + b*c*d, -a*b*c + a*b*e - a*c*e + b*c*e, -a*b*d + a*b*e - a*d*e + b*d*e, -a*c*d + a*c*e - a*d*e + c*d*e)
With different term orders:
sage: I.groebner_basis("degrevlex") (b*c*d - b*c*e + b*d*e - c*d*e, a*c*d - a*c*e + a*d*e - c*d*e, a*b*d - a*b*e + a*d*e - b*d*e, a*b*c - a*b*e + a*c*e - b*c*e) sage: I.groebner_basis("deglex") (-a*b*c + a*b*d - a*c*d + b*c*d, -a*b*c + a*b*e - a*c*e + b*c*e, -a*b*d + a*b*e - a*d*e + b*d*e, -a*c*d + a*c*e - a*d*e + c*d*e)
>>> from sage.all import * >>> I.groebner_basis("degrevlex") (b*c*d - b*c*e + b*d*e - c*d*e, a*c*d - a*c*e + a*d*e - c*d*e, a*b*d - a*b*e + a*d*e - b*d*e, a*b*c - a*b*e + a*c*e - b*c*e) >>> I.groebner_basis("deglex") (-a*b*c + a*b*d - a*c*d + b*c*d, -a*b*c + a*b*e - a*c*e + b*c*e, -a*b*d + a*b*e - a*d*e + b*d*e, -a*c*d + a*c*e - a*d*e + c*d*e)
The example above was computed first using M2, which agrees with the
'degrevlex'
ordering:E = QQ[a..e, SkewCommutative => true] I = ideal( c*d*e - b*d*e + b*c*e - b*c*d, c*d*e - a*d*e + a*c*e - a*c*d, b*d*e - a*d*e + a*b*e - a*b*d, b*c*e - a*c*e + a*b*e - a*b*c, b*c*d - a*c*d + a*b*d - a*b*c) groebnerBasis(I) returns: o3 = | bcd-bce+bde-cde acd-ace+ade-cde abd-abe+ade-bde abc-abe+ace-bce |
By default, the Gröbner basis is reduced, but we can get non-reduced Gröber bases (which are not unique):
sage: E.<x,y,z> = ExteriorAlgebra(QQ) sage: I = E.ideal([x+y*z]) sage: I.groebner_basis(reduced=False) (x*y, x*z, y*z + x, x*y*z) sage: I.groebner_basis(reduced=True) (x*y, x*z, y*z + x)
>>> from sage.all import * >>> E = ExteriorAlgebra(QQ, names=('x', 'y', 'z',)); (x, y, z,) = E._first_ngens(3) >>> I = E.ideal([x+y*z]) >>> I.groebner_basis(reduced=False) (x*y, x*z, y*z + x, x*y*z) >>> I.groebner_basis(reduced=True) (x*y, x*z, y*z + x)
However, if we have already computed a reduced Gröbner basis (with a given term order), then we return that:
sage: I = E.ideal([x+y*z]) # A fresh ideal sage: I.groebner_basis() (x*y, x*z, y*z + x) sage: I.groebner_basis(reduced=False) (x*y, x*z, y*z + x)
>>> from sage.all import * >>> I = E.ideal([x+y*z]) # A fresh ideal >>> I.groebner_basis() (x*y, x*z, y*z + x) >>> I.groebner_basis(reduced=False) (x*y, x*z, y*z + x)
- reduce(f)[source]¶
Reduce
f
moduloself
.EXAMPLES:
sage: E.<x,y,z> = ExteriorAlgebra(QQ) sage: I = E.ideal(x*y); sage: I.reduce(x*y + x*y*z + z) z sage: I.reduce(x*y + x + y) x + y sage: I.reduce(x*y + x*y*z) 0 sage: E.<a,b,c,d> = ExteriorAlgebra(QQ) sage: I = E.ideal([a+b*c]) sage: I.reduce(I.gen(0) * d) 0
>>> from sage.all import * >>> E = ExteriorAlgebra(QQ, names=('x', 'y', 'z',)); (x, y, z,) = E._first_ngens(3) >>> I = E.ideal(x*y); >>> I.reduce(x*y + x*y*z + z) z >>> I.reduce(x*y + x + y) x + y >>> I.reduce(x*y + x*y*z) 0 >>> E = ExteriorAlgebra(QQ, names=('a', 'b', 'c', 'd',)); (a, b, c, d,) = E._first_ngens(4) >>> I = E.ideal([a+b*c]) >>> I.reduce(I.gen(Integer(0)) * d) 0