Octonion Algebras#
AUTHORS:
Travis Scrimshaw (2023-05-06): Initial version
- class sage.algebras.octonion_algebra.Octonion#
Bases:
Octonion_generic
An octonion.
This is an element of the octonion algebra with parameters \(a = b = c = -1\), which is a classical octonion number.
- norm()#
Return the norm of
self
.The norm of an octonion \(x\) is \(\lVert x \rVert = \sqrt{x x^*}\), where \(x^*\) is the
conjugate()
of \(x\).See also
This is the square root of
quadratic_form()
.EXAMPLES:
sage: O = OctonionAlgebra(QQ) sage: elt = sum(i * b for i, b in enumerate(O.basis(), start=2)) sage: elt.norm() 2*sqrt(71) sage: elt = sum(O.basis()) sage: elt.norm() 2*sqrt(2)
- quadratic_form()#
Return the quadratic form of
self
.The octonion algebra has a distinguished quadratic form given by \(N(x) = x x^*\), where \(x^*\) is the
conjugate()
of \(x\).EXAMPLES:
sage: O = OctonionAlgebra(QQ) sage: elt = sum(O.basis()); elt 1 + i + j + k + l + li + lj + lk sage: elt.quadratic_form() 8 sage: elt * elt.conjugate() 8
- class sage.algebras.octonion_algebra.OctonionAlgebra(R, a, b, c, names)#
Bases:
UniqueRepresentation
,Parent
The octonion algebra.
Let \(R\) be a commutative ring of characteristic not equal to \(2\). The octonion algebra with parameters \(a, b, c\) is a non-associative non-commutative unital 8-dimensional \(R\)-algebra that is a deformation of the usual octonions, which are when \(a = b = c = -1\). The octonions were originally constructed by Graves and independently discovered by Cayley (due to being published first, these are sometimes called the Cayley numbers) and can also be built from the Cayley-Dickson construction with the
quaternions
.We use the multiplication table from [Scha1996]. The octonion algebra \(\mathbf{O}_{a,b,c}(R)\) is a composition (Hurwitz) algebra, which means it is also an alternative algebra as it satisfies \(x^2 y = (x x) y = x (x y)\) and \(y x^2 = y (x x) = (y x) x\) for all \(x, y \in \mathbf{O}_{a,b,c}\).
EXAMPLES:
We first create the classical octonions and perform some basic computations:
sage: O = OctonionAlgebra(QQ) sage: O Octonion algebra over Rational Field sage: i, j, k, l = O.gens() sage: i * j * k 1 sage: k * j * i -1 sage: (i * k) * l -lj sage: i * (k * l) lj sage: elt = sum(O.basis()) sage: elt^2 -6 + 2*i + 2*j + 2*k + 2*l + 2*li + 2*lj + 2*lk sage: prod(O.basis()) 1 sage: (i + l)^2 -2 sage: (1 + l) * (1 + l).conjugate() 2 sage: S = O.some_elements() sage: B = O.basis() sage: S.extend(x * (i + j/2 - 5*k/3) for x in O.some_elements()) sage: all((x * x) * y == (x * (x * y)) for x in S for y in S) True sage: all(y * (x * x) == (y * x) * x for x in S for y in S) True sage: all((x + x.conjugate()) / 2 == x.real_part() for x in S) True sage: all((x - x.conjugate()) / 2 == x.imag_part() for x in S) True sage: all(sum((b*x)*b for b in B) == -6 * x.conjugate() for x in S) True
We construct the (rescaled) \(E_8\) lattice as the integral octonions, which we verify by constructing \(240\) shortest length elements in the lattice (see also Wikipedia article E8_lattice#Integral_octonions):
sage: m = (i + j + k + l) / 2 sage: basis = [i, j, i*j, i^2, m, i * m, j * m, (i * j) * m] sage: basis [i, j, -k, -1, 1/2*i + 1/2*j + 1/2*k + 1/2*l, -1/2 + 1/2*j - 1/2*k - 1/2*li, -1/2 - 1/2*i + 1/2*k - 1/2*lj, 1/2 - 1/2*i + 1/2*j + 1/2*lk] sage: matrix([vector(b) for b in basis]).rank() 8 sage: [b.norm() for b in basis] [1, 1, 1, 1, 1, 1, 1, 1] sage: roots = set(basis) sage: roots.update(-b for b in basis) sage: new_roots = set(roots) # make a copy sage: while new_roots: ....: prev_roots = new_roots ....: new_roots = set() ....: for a in prev_roots: ....: for b in roots: ....: c = a + b ....: if c.quadratic_form() != 1 or c in roots: ....: continue ....: new_roots.update([c, -c]) ....: roots.update(new_roots) sage: len(roots) 240
A classical construction of the Lie algebra of type \(G_2\) is the Lie algebra of all derivations of \(\mathbf{O}\) (as the automorphism group is the Lie group of type \(G_2\)). We verify that the derivations have the correct dimension:
sage: len(O.derivations_basis()) 14
We can construct the split octonions by taking the parameter \(c = 1\):
sage: SO = OctonionAlgebra(QQ, c=1) sage: SO Octonion algebra over Rational Field with parameters (-1, -1, 1) sage: i, j, k, l = SO.gens() sage: i^2 == j^2 == k^2 == -1 True sage: l^2 1 sage: (i + l)^2 0 sage: (1 + l) * (1 + l).conjugate() 0
REFERENCES:
- Element#
alias of
Octonion_generic
- basis()#
Return the basis of
self
.EXAMPLES:
sage: O = OctonionAlgebra(ZZ) sage: O.basis() Family (1, i, j, k, l, li, lj, lk)
- gens()#
Return the generators of
self
.EXAMPLES:
sage: O = OctonionAlgebra(ZZ) sage: O.gens() (i, j, k, l)
- one_basis()#
Return the index for the basis element of \(1\).
EXAMPLES:
sage: O = OctonionAlgebra(ZZ) sage: O.one_basis() 0
- some_elements()#
Return some elements of
self
.EXAMPLES:
sage: O = OctonionAlgebra(ZZ) sage: O.some_elements() [2, 1, i, j, k, l, li, lj, lk, 2 + 3*i + 4*j + 5*k + 6*l + 7*li + 8*lj + 9*lk, -2*j + 3*k - li - lj, 8 - 7*i + 2*j + 13*k - 18*l + 45*li - 40*lj + 5*lk] sage: O = OctonionAlgebra(Zmod(6)) sage: O.some_elements() [2, 1, i, j, k, l, li, lj, lk, 2 + 3*i + 4*j + 5*k + li + 2*lj + 3*lk, 4*j + 3*k + 5*li + 5*lj, 2 + 5*i + 2*j + k + 3*li + 2*lj + 5*lk]
- class sage.algebras.octonion_algebra.Octonion_generic#
Bases:
AlgebraElement
An octonion with generic parameters.
- abs()#
Return the absolute value of
self
.This is equal to the
norm()
.Warning
If any of the parameters \(a, b, c \not> 0\), then this does not define a metric.
EXAMPLES:
sage: O = OctonionAlgebra(QQ, 1, 3, 7) sage: elt = sum(i * b for i, b in enumerate(O.basis(), start=2)) sage: elt.abs() 2*sqrt(-61) sage: elt = sum(O.basis()) sage: elt.abs() 0
- conjugate()#
Return the conjugate of
self
.EXAMPLES:
sage: O = OctonionAlgebra(QQ) sage: elt = sum(O.basis()); elt 1 + i + j + k + l + li + lj + lk sage: elt.conjugate() 1 - i - j - k - l - li - lj - lk
- dict(copy=False)#
Return
self
as adict
with keys being indices for the basis and the values being the corresponding nonzero coefficients.INPUT:
copy
– ignored
EXAMPLES:
sage: O = OctonionAlgebra(QQ) sage: x = O([2/7, 0, 0, 0, 2/3, 0, -5, 0]) sage: x.monomial_coefficients() {0: 2/7, 4: 2/3, 6: -5}
- imag_part()#
Return the imginary part of
self
.OUTPUT:
The imaginary part of
self
as an element in the octonion algebra.EXAMPLES:
sage: O = OctonionAlgebra(QQ) sage: elt = sum(i * b for i, b in enumerate(O.basis(), start=2)); elt 2 + 3*i + 4*j + 5*k + 6*l + 7*li + 8*lj + 9*lk sage: elt.imag_part() 3*i + 4*j + 5*k + 6*l + 7*li + 8*lj + 9*lk
- is_unit()#
Return if
self
is a unit or not.EXAMPLES:
sage: O = OctonionAlgebra(ZZ) sage: x = O([1, 0, 1, 0, 0, 0, 0, 0]) sage: x.quadratic_form() 2 sage: x.is_unit() False sage: O([1, 0, -1, 0, 0, 0, 0, 0]).is_unit() False sage: x = O([1, 0, 0, 0, 1, 0, 0, 0]) sage: x.quadratic_form() 2 sage: x.is_unit() False sage: x = O([0, 0, 0, 0, 1, 0, 0, 0]) sage: x.quadratic_form() 1 sage: x.is_unit() True sage: O = OctonionAlgebra(ZZ, -1, 1, 2) sage: x = O([1, 0, 1, 0, 0, 0, 0, 0]) sage: x.quadratic_form() 0 sage: x.is_unit() False sage: O([1, 0, -1, 0, 0, 0, 0, 0]).is_unit() False sage: x = O([1, 0, 0, 0, 1, 0, 0, 0]) sage: x.quadratic_form() -1 sage: x.is_unit() True sage: x = O([0, 0, 0, 0, 1, 0, 0, 0]) sage: x.quadratic_form() -2 sage: x.is_unit() False
- monomial_coefficients(copy=False)#
Return
self
as adict
with keys being indices for the basis and the values being the corresponding nonzero coefficients.INPUT:
copy
– ignored
EXAMPLES:
sage: O = OctonionAlgebra(QQ) sage: x = O([2/7, 0, 0, 0, 2/3, 0, -5, 0]) sage: x.monomial_coefficients() {0: 2/7, 4: 2/3, 6: -5}
- norm()#
Return the norm of
self
.The norm of an octonion \(x\) is \(\lVert x \rVert = \sqrt{x x^*}\), where \(x^*\) is the
conjugate()
of \(x\).See also
This is the square root of
quadratic_form()
.Warning
If any of the parameters \(a, b, c \not> 0\), then this is not an actual norm.
EXAMPLES:
sage: O = OctonionAlgebra(QQ, 1, 3, 7) sage: elt = sum(i * b for i, b in enumerate(O.basis(), start=2)) sage: elt.norm() 2*sqrt(-61) sage: elt = sum(O.basis()) sage: elt.norm() 0
- quadratic_form()#
Return the quadratic form of
self
.The octonion algebra has a distinguished quadratic form given by \(N(x) = x x^*\), where \(x^*\) is the
conjugate()
of \(x\).EXAMPLES:
sage: O = OctonionAlgebra(QQ, 1, 3, 7) sage: elt = sum(O.basis()) sage: elt.quadratic_form() 0 sage: elt * elt.conjugate() 0
- real_part()#
Return the real part of
self
.OUTPUT:
The real part of
self
as an element in the base ring.EXAMPLES:
sage: O = OctonionAlgebra(QQ) sage: elt = sum(i * b for i, b in enumerate(O.basis(), start=2)); elt 2 + 3*i + 4*j + 5*k + 6*l + 7*li + 8*lj + 9*lk sage: r = elt.real_part(); r 2 sage: r.parent() is QQ True
- vector(new_base_ring=None)#
Return
self
as a vector in \(R^8\), where \(R\) is the base ring ofself
.EXAMPLES:
sage: O = OctonionAlgebra(QQ) sage: elt = sum(i * b for i, b in enumerate(O.basis(), start=2)) sage: elt.vector() (2, 3, 4, 5, 6, 7, 8, 9)