X-Git-Url: http://gitweb.michael.orlitzky.com/?p=sage.d.git;a=blobdiff_plain;f=mjo%2Fhurwitz.py;fp=mjo%2Foctonions.py;h=ff1792bd9f3dc26d8b337fe3a6ff1549ab1f68e2;hp=78365e298ec7a46fcaff0603039f6410aa768c96;hb=e28bd3518185e3a87866c61d973876f84fdeea66;hpb=2d94a6ffbaacfc4d63ec47580d0caa1ae6c02e07 diff --git a/mjo/octonions.py b/mjo/hurwitz.py similarity index 78% rename from mjo/octonions.py rename to mjo/hurwitz.py index 78365e2..ff1792b 100644 --- a/mjo/octonions.py +++ b/mjo/hurwitz.py @@ -7,14 +7,14 @@ from sage.rings.all import AA, ZZ from sage.matrix.matrix_space import MatrixSpace from sage.misc.table import table -from mjo.matrix_algebra import HurwitzMatrixAlgebra +from mjo.matrix_algebra import MatrixAlgebra, MatrixAlgebraElement class Octonion(IndexedFreeModuleElement): def conjugate(self): r""" SETUP:: - sage: from mjo.octonions import Octonions + sage: from mjo.hurwitz import Octonions EXAMPLES:: @@ -47,7 +47,7 @@ class Octonion(IndexedFreeModuleElement): SETUP:: - sage: from mjo.octonions import Octonions + sage: from mjo.hurwitz import Octonions EXAMPLES:: @@ -80,7 +80,7 @@ class Octonion(IndexedFreeModuleElement): SETUP:: - sage: from mjo.octonions import Octonions + sage: from mjo.hurwitz import Octonions EXAMPLES:: @@ -111,7 +111,7 @@ class Octonion(IndexedFreeModuleElement): SETUP:: - sage: from mjo.octonions import Octonions + sage: from mjo.hurwitz import Octonions EXAMPLES:: @@ -152,7 +152,7 @@ class Octonion(IndexedFreeModuleElement): SETUP:: - sage: from mjo.octonions import Octonions + sage: from mjo.hurwitz import Octonions EXAMPLES:: @@ -198,7 +198,7 @@ class Octonion(IndexedFreeModuleElement): SETUP:: - sage: from mjo.octonions import Octonions + sage: from mjo.hurwitz import Octonions EXAMPLES:: @@ -230,7 +230,7 @@ class Octonions(CombinatorialFreeModule): r""" SETUP:: - sage: from mjo.octonions import Octonions + sage: from mjo.hurwitz import Octonions EXAMPLES:: @@ -280,7 +280,7 @@ class Octonions(CombinatorialFreeModule): SETUP:: - sage: from mjo.octonions import Octonions + sage: from mjo.hurwitz import Octonions TESTS: @@ -305,7 +305,7 @@ class Octonions(CombinatorialFreeModule): SETUP:: - sage: from mjo.octonions import Octonions + sage: from mjo.hurwitz import Octonions EXAMPLES: @@ -347,6 +347,106 @@ class Octonions(CombinatorialFreeModule): + + +class HurwitzMatrixAlgebraElement(MatrixAlgebraElement): + def is_hermitian(self): + r""" + + SETUP:: + + sage: from mjo.hurwitz import HurwitzMatrixAlgebra + + EXAMPLES:: + + sage: A = HurwitzMatrixAlgebra(QQbar, ZZ, 2) + sage: M = A([ [ 0,I], + ....: [-I,0] ]) + sage: M.is_hermitian() + True + + """ + return all( self[i,j] == self[j,i].conjugate() + for i in range(self.nrows()) + for j in range(self.ncols()) ) + + +class HurwitzMatrixAlgebra(MatrixAlgebra): + r""" + A class of matrix algebras whose entries come from a Hurwitz + algebra. + + For our purposes, we consider "a Hurwitz" algebra to be the real + or complex numbers, the quaternions, or the octonions. These are + typically also referred to as the Euclidean Hurwitz algebras, or + the normed division algebras. + + By the Cayley-Dickson construction, each Hurwitz algebra is an + algebra over the real numbers, so we restrict the scalar field in + this case to be real. This also allows us to more accurately + produce the generators of the matrix algebra. + """ + Element = HurwitzMatrixAlgebraElement + + def __init__(self, entry_algebra, scalars, n, **kwargs): + from sage.rings.all import RR + if not scalars.is_subring(RR): + # Not perfect, but it's what we're using. + raise ValueError("scalar field is not real") + + super().__init__(entry_algebra, scalars, n, **kwargs) + + def entry_algebra_gens(self): + r""" + Return the generators of (that is, a basis for) the entries of + this matrix algebra. + + This works around the inconsistency in the ``gens()`` methods + of the real/complex numbers, quaternions, and octonions. + + SETUP:: + + sage: from mjo.hurwitz import Octonions, HurwitzMatrixAlgebra + + EXAMPLES: + + The inclusion of the unit element is inconsistent across + (subalgebras of) Hurwitz algebras:: + + sage: AA.gens() + (1,) + sage: QQbar.gens() + (I,) + sage: QuaternionAlgebra(AA,1,-1).gens() + [i, j, k] + sage: Octonions().gens() + (e0, e1, e2, e3, e4, e5, e6, e7) + + The unit element is always returned by this method, so the + sets of generators have cartinality 1,2,4, and 8 as you'd + expect:: + + sage: HurwitzMatrixAlgebra(AA, AA, 2).entry_algebra_gens() + (1,) + sage: HurwitzMatrixAlgebra(QQbar, AA, 2).entry_algebra_gens() + (1, I) + sage: Q = QuaternionAlgebra(AA,-1,-1) + sage: HurwitzMatrixAlgebra(Q, AA, 2).entry_algebra_gens() + (1, i, j, k) + sage: O = Octonions() + sage: HurwitzMatrixAlgebra(O, AA, 2).entry_algebra_gens() + (e0, e1, e2, e3, e4, e5, e6, e7) + + """ + gs = self.entry_algebra().gens() + one = self.entry_algebra().one() + if one in gs: + return gs + else: + return (one,) + tuple(gs) + + + class OctonionMatrixAlgebra(HurwitzMatrixAlgebra): r""" The algebra of ``n``-by-``n`` matrices with octonion entries over @@ -358,7 +458,7 @@ class OctonionMatrixAlgebra(HurwitzMatrixAlgebra): SETUP:: - sage: from mjo.octonions import OctonionMatrixAlgebra + sage: from mjo.hurwitz import OctonionMatrixAlgebra EXAMPLES:: @@ -418,7 +518,7 @@ class QuaternionMatrixAlgebra(HurwitzMatrixAlgebra): SETUP:: - sage: from mjo.octonions import QuaternionMatrixAlgebra + sage: from mjo.hurwitz import QuaternionMatrixAlgebra EXAMPLES::