]> gitweb.michael.orlitzky.com - sage.d.git/blobdiff - mjo/eja/eja_algebra.py
eja: ensure that Sage doesn't think EJAs are associative.
[sage.d.git] / mjo / eja / eja_algebra.py
index 28e86c25e3a3d315cf8fefb325fc05ef4b03b427..8c66de69ee4a451ce59b0319d1680b8474e7439d 100644 (file)
@@ -6,11 +6,12 @@ what can be supported in a general Jordan Algebra.
 """
 
 from sage.algebras.quatalg.quaternion_algebra import QuaternionAlgebra
-from sage.categories.finite_dimensional_algebras_with_basis import FiniteDimensionalAlgebrasWithBasis
+from sage.categories.magmatic_algebras import MagmaticAlgebras
 from sage.combinat.free_module import CombinatorialFreeModule
 from sage.matrix.constructor import matrix
 from sage.misc.cachefunc import cached_method
 from sage.misc.prandom import choice
+from sage.misc.table import table
 from sage.modules.free_module import VectorSpace
 from sage.rings.integer_ring import ZZ
 from sage.rings.number_field.number_field import QuadraticField
@@ -22,6 +23,14 @@ from mjo.eja.eja_element import FiniteDimensionalEuclideanJordanAlgebraElement
 from mjo.eja.eja_utils import _mat2vec
 
 class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule):
+    # This is an ugly hack needed to prevent the category framework
+    # from implementing a coercion from our base ring (e.g. the
+    # rationals) into the algebra. First of all -- such a coercion is
+    # nonsense to begin with. But more importantly, it tries to do so
+    # in the category of rings, and since our algebras aren't
+    # associative they generally won't be rings.
+    _no_generic_basering_coercion = True
+
     def __init__(self,
                  field,
                  mult_table,
@@ -50,7 +59,9 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule):
         self._natural_basis = natural_basis
 
         if category is None:
-            category = FiniteDimensionalAlgebrasWithBasis(field).Unital()
+            category = MagmaticAlgebras(field).FiniteDimensional()
+            category = category.WithBasis().Unital()
+
         fda = super(FiniteDimensionalEuclideanJordanAlgebra, self)
         fda.__init__(field,
                      range(len(mult_table)),
@@ -117,6 +128,11 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule):
             True
 
         """
+        if elt == 0:
+            # The superclass implementation of random_element()
+            # needs to be able to coerce "0" into the algebra.
+            return self.zero()
+
         natural_basis = self.natural_basis()
         if elt not in natural_basis[0].matrix_space():
             raise ValueError("not a naturally-represented algebra element")
@@ -381,37 +397,36 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule):
 
     def multiplication_table(self):
         """
-        Return a readable matrix representation of this algebra's
-        multiplication table. The (i,j)th entry in the matrix contains
-        the product of the ith basis element with the jth.
-
-        This is not extraordinarily useful, but it overrides a superclass
-        method that would otherwise just crash and complain about the
-        algebra being infinite.
+        Return a visual representation of this algebra's multiplication
+        table (on basis elements).
 
         SETUP::
 
-            sage: from mjo.eja.eja_algebra import (JordanSpinEJA,
-            ....:                                  RealCartesianProductEJA)
+            sage: from mjo.eja.eja_algebra import JordanSpinEJA
 
         EXAMPLES::
 
-            sage: J = RealCartesianProductEJA(3)
-            sage: J.multiplication_table()
-            [e0  0  0]
-            [ 0 e1  0]
-            [ 0  0 e2]
-
-        ::
-
-            sage: J = JordanSpinEJA(3)
+            sage: J = JordanSpinEJA(4)
             sage: J.multiplication_table()
-            [e0 e1 e2]
-            [e1 e0  0]
-            [e2  0 e0]
+            +----++----+----+----+----+
+            | *  || e0 | e1 | e2 | e3 |
+            +====++====+====+====+====+
+            | e0 || e0 | e1 | e2 | e3 |
+            +----++----+----+----+----+
+            | e1 || e1 | e0 | 0  | 0  |
+            +----++----+----+----+----+
+            | e2 || e2 | 0  | e0 | 0  |
+            +----++----+----+----+----+
+            | e3 || e3 | 0  | 0  | e0 |
+            +----++----+----+----+----+
 
         """
-        return matrix(self._multiplication_table)
+        M = list(self._multiplication_table) # copy
+        for i in range(len(M)):
+            # M had better be "square"
+            M[i] = [self.monomial(i)] + M[i]
+        M = [["*"] + list(self.gens())] + M
+        return table(M, header_row=True, header_column=True, frame=True)
 
 
     def natural_basis(self):