+ def __init__(self, n, entry_algebra=None, scalars=AA, **kwargs):
+ if entry_algebra is None:
+ # The -1,-1 gives us the "usual" definition of quaternion
+ from sage.algebras.quatalg.quaternion_algebra import (
+ QuaternionAlgebra
+ )
+ entry_algebra = QuaternionAlgebra(scalars,-1,-1)
+ super().__init__(n, entry_algebra, scalars, **kwargs)
+
+ def _entry_algebra_element_to_vector(self, entry):
+ r"""
+
+ SETUP::
+
+ sage: from mjo.hurwitz import QuaternionMatrixAlgebra
+
+ EXAMPLES::
+
+ sage: A = QuaternionMatrixAlgebra(2)
+ sage: u = A.entry_algebra().one()
+ sage: A._entry_algebra_element_to_vector(u)
+ (1, 0, 0, 0)
+ sage: i,j,k = A.entry_algebra().gens()
+ sage: A._entry_algebra_element_to_vector(i)
+ (0, 1, 0, 0)
+ sage: A._entry_algebra_element_to_vector(j)
+ (0, 0, 1, 0)
+ sage: A._entry_algebra_element_to_vector(k)
+ (0, 0, 0, 1)
+
+ """
+ from sage.modules.free_module import FreeModule
+ d = len(self.entry_algebra_gens())
+ V = FreeModule(self.entry_algebra().base_ring(), d)
+ return V(entry.coefficient_tuple())
+
+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,scalars=QQ)
+ Module of 3 by 3 matrices with entries in Algebraic Field
+ over the scalar ring Rational Field
+
+ ::
+
+ sage: A = ComplexMatrixAlgebra(1,CC)
+ sage: A
+ Module of 1 by 1 matrices with entries in Complex Field with
+ 53 bits of precision over the scalar ring Algebraic Real Field
+ sage: A.one()
+ +------------------+
+ | 1.00000000000000 |
+ +------------------+
+ sage: A.gens()
+ (+------------------+
+ | 1.00000000000000 |
+ +------------------+,
+ +--------------------+
+ | 1.00000000000000*I |
+ +--------------------+)
+
+ ::
+
+ sage: A = ComplexMatrixAlgebra(2)
+ sage: (I,) = A.entry_algebra().gens()
+ sage: A([ [1+I, 1],
+ ....: [-1, -I] ])
+ +---------+------+
+ | 1 + 1*I | 1 |
+ +---------+------+
+ | -1 | -1*I |
+ +---------+------+
+
+ ::
+
+ sage: A1 = ComplexMatrixAlgebra(1,scalars=QQ)
+ sage: A2 = ComplexMatrixAlgebra(2,scalars=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: 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, entry_algebra=None, scalars=AA, **kwargs):
+ if entry_algebra is None:
+ from sage.rings.all import QQbar
+ entry_algebra = QQbar
+ super().__init__(n, entry_algebra, scalars, **kwargs)
+
+ def _entry_algebra_element_to_vector(self, entry):
+ r"""
+
+ SETUP::
+
+ sage: from mjo.hurwitz import ComplexMatrixAlgebra
+
+ EXAMPLES::
+
+ sage: A = ComplexMatrixAlgebra(2, QQbar, QQ)
+ sage: A._entry_algebra_element_to_vector(QQbar(1))
+ (1, 0)
+ sage: A._entry_algebra_element_to_vector(QQbar(I))
+ (0, 1)
+
+ """
+ from sage.modules.free_module import FreeModule
+ d = len(self.entry_algebra_gens())
+ V = FreeModule(self.entry_algebra().base_ring(), d)
+ return V((entry.real(), entry.imag()))