+ return all( self[i,j] == self[j,i].conjugate()
+ for i in range(self.nrows())
+ for j in range(self.ncols()) )
+
+class OctonionMatrixAlgebra(CombinatorialFreeModule):
+ r"""
+ The algebra of ``n``-by-``n`` matrices with octonion entries over
+ (a subfield of) the real numbers.
+
+ The usual matrix spaces in SageMath don't support octonion entries
+ because they assume that the entries of the matrix come from a
+ commutative and associative ring (i.e. very NOT the octonions).
+ """
+ Element = OctonionMatrix
+
+ def __init__(self, n, scalars=AA, prefix="E", **kwargs):
+ # Not associative, not commutative
+ category = MagmaticAlgebras(scalars).FiniteDimensional()
+ category = category.WithBasis().Unital()
+
+ self._nrows = n
+
+ # Since the scalar ring is real but the entries are not,
+ # sticking a "1" in each position doesn't give us a basis for
+ # the space. We actually need to stick each of e0, e1, ... (a
+ # basis for the entry algebra itself) into each position.
+ from sage.sets.finite_enumerated_set import FiniteEnumeratedSet
+ from sage.categories.sets_cat import cartesian_product
+
+ I = FiniteEnumeratedSet(range(n))
+ J = FiniteEnumeratedSet(range(n))
+ self._entry_algebra = Octonions(field=scalars)
+ entry_basis = self._entry_algebra.gens()