From 917a76ab0ae48ddd52e7d24de6f51ca8f91aa3c1 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Mon, 8 Mar 2021 21:21:28 -0500 Subject: [PATCH] hurwitz: add ComplexMatrixAlgebra. --- mjo/hurwitz.py | 117 ++++++++++++++++++++++++++++--------------------- 1 file changed, 66 insertions(+), 51 deletions(-) diff --git a/mjo/hurwitz.py b/mjo/hurwitz.py index ff1792b..75e8568 100644 --- a/mjo/hurwitz.py +++ b/mjo/hurwitz.py @@ -1,11 +1,7 @@ from sage.misc.cachefunc import cached_method -from sage.algebras.quatalg.quaternion_algebra import QuaternionAlgebra from sage.combinat.free_module import CombinatorialFreeModule from sage.modules.with_basis.indexed_element import IndexedFreeModuleElement -from sage.categories.magmatic_algebras import MagmaticAlgebras -from sage.rings.all import AA, ZZ -from sage.matrix.matrix_space import MatrixSpace -from sage.misc.table import table +from sage.rings.all import AA from mjo.matrix_algebra import MatrixAlgebra, MatrixAlgebraElement @@ -34,6 +30,8 @@ class Octonion(IndexedFreeModuleElement): True """ + from sage.rings.all import ZZ + from sage.matrix.matrix_space import MatrixSpace C = MatrixSpace(ZZ,8).diagonal_matrix((1,-1,-1,-1,-1,-1,-1,-1)) return self.parent().from_vector(C*self.to_vector()) @@ -181,50 +179,6 @@ class Octonion(IndexedFreeModuleElement): return self.conjugate()/self._norm_squared() - def cayley_dickson(self, Q=None): - r""" - Return the Cayley-Dickson representation of this element in terms - of the quaternion algebra ``Q``. - - The Cayley-Dickson representation is an identification of - octionions `x` and `y` with pairs of quaternions `(a,b)` and - `(c,d)` respectively such that: - - * `x + y = (a+b, c+d)` - * `xy` = (ac - \bar{d}*b, da + b\bar{c})` - * `\bar{x} = (a,-b)` - - where `\bar{x}` denotes the conjugate of `x`. - - SETUP:: - - sage: from mjo.hurwitz import Octonions - - EXAMPLES:: - - sage: O = Octonions() - sage: x = sum(O.gens()) - sage: x.cayley_dickson() - (1 + i + j + k, 1 + i + j + k) - - """ - if Q is None: - Q = QuaternionAlgebra(self.base_ring(), -1, -1) - - i,j,k = Q.gens() - a = (self.coefficient(0)*Q.one() + - self.coefficient(1)*i + - self.coefficient(2)*j + - self.coefficient(3)*k ) - b = (self.coefficient(4)*Q.one() + - self.coefficient(5)*i + - self.coefficient(6)*j + - self.coefficient(7)*k ) - - from sage.categories.sets_cat import cartesian_product - P = cartesian_product([Q,Q]) - return P((a,b)) - class Octonions(CombinatorialFreeModule): r""" @@ -245,6 +199,7 @@ class Octonions(CombinatorialFreeModule): prefix="e"): # Not associative, not commutative + from sage.categories.magmatic_algebras import MagmaticAlgebras category = MagmaticAlgebras(field).FiniteDimensional() category = category.WithBasis().Unital() @@ -343,6 +298,7 @@ class Octonions(CombinatorialFreeModule): for j in range(n) ] for i in range(n) ] + from sage.misc.table import table return table(M, header_row=True, header_column=True, frame=True) @@ -398,8 +354,8 @@ class HurwitzMatrixAlgebra(MatrixAlgebra): def entry_algebra_gens(self): r""" - Return the generators of (that is, a basis for) the entries of - this matrix algebra. + Return a tuple of 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. @@ -565,5 +521,64 @@ class QuaternionMatrixAlgebra(HurwitzMatrixAlgebra): """ def __init__(self, n, scalars=AA, **kwargs): # The -1,-1 gives us the "usual" definition of quaternion + from sage.algebras.quatalg.quaternion_algebra import QuaternionAlgebra Q = QuaternionAlgebra(scalars,-1,-1) super().__init__(Q, scalars, n, **kwargs) + + +class ComplexMatrixAlgebra(HurwitzMatrixAlgebra): + r""" + The algebra of ``n``-by-``n`` matrices with complex entries over + (a subfield of) the real numbers. + + These differ from the usual complex matrix spaces in SageMath + because the scalar field is real (and not assumed to be the same + as the space from which the entries are drawn). The space of + `1`-by-`1` complex matrices will have dimension two, for example. + + SETUP:: + + sage: from mjo.hurwitz import ComplexMatrixAlgebra + + EXAMPLES:: + + sage: ComplexMatrixAlgebra(3) + Module of 3 by 3 matrices with entries in Algebraic Field + over the scalar ring Algebraic Real Field + sage: ComplexMatrixAlgebra(3,QQ) + Module of 3 by 3 matrices with entries in Algebraic Field + over the scalar ring Rational Field + + :: + + sage: A = ComplexMatrixAlgebra(2) + sage: (I,) = A.entry_algebra().gens() + sage: A([ [1+I, 1], + ....: [-1, -I] ]) + +-------+----+ + | I + 1 | 1 | + +-------+----+ + | -1 | -I | + +-------+----+ + + :: + + sage: A1 = ComplexMatrixAlgebra(1,QQ) + sage: A2 = ComplexMatrixAlgebra(2,QQ) + sage: cartesian_product([A1,A2]) + Module of 1 by 1 matrices with entries in Algebraic Field over + the scalar ring Rational Field (+) Module of 2 by 2 matrices with + entries in Algebraic Field over the scalar ring Rational Field + + TESTS:: + + sage: set_random_seed() + sage: A = ComplexMatrixAlgebra(ZZ.random_element(10)) + sage: x = A.random_element() + sage: x*A.one() == x and A.one()*x == x + True + + """ + def __init__(self, n, scalars=AA, **kwargs): + from sage.rings.all import QQbar + super().__init__(QQbar, scalars, n, **kwargs) -- 2.44.2