]> gitweb.michael.orlitzky.com - sage.d.git/blobdiff - mjo/eja/eja_algebra.py
eja: pass check=False for known-good constructions.
[sage.d.git] / mjo / eja / eja_algebra.py
index 562797318646cb1dd837691f846fd114b44ec131..b681296b698287bdb506ee0519fcf098711b380b 100644 (file)
@@ -61,7 +61,10 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule):
         """
         SETUP::
 
-            sage: from mjo.eja.eja_algebra import (JordanSpinEJA, random_eja)
+            sage: from mjo.eja.eja_algebra import (
+            ....:   FiniteDimensionalEuclideanJordanAlgebra,
+            ....:   JordanSpinEJA,
+            ....:   random_eja)
 
         EXAMPLES:
 
@@ -75,13 +78,20 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule):
 
         TESTS:
 
-        The ``field`` we're given must be real::
+        The ``field`` we're given must be real with ``check=True``::
 
             sage: JordanSpinEJA(2,QQbar)
             Traceback (most recent call last):
             ...
             ValueError: field is not real
 
+        The multiplication table must be square with ``check=True``::
+
+            sage: FiniteDimensionalEuclideanJordanAlgebra(QQ,((),()))
+            Traceback (most recent call last):
+            ...
+            ValueError: multiplication table is not square
+
         """
         if check:
             if not field.is_subring(RR):
@@ -98,6 +108,9 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule):
 
         # The multiplication table had better be square
         n = len(mult_table)
+        if check:
+            if not all( len(l) == n for l in mult_table ):
+                raise ValueError("multiplication table is not square")
 
         fda = super(FiniteDimensionalEuclideanJordanAlgebra, self)
         fda.__init__(field,
@@ -283,14 +296,26 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule):
         this algebra was constructed with ``check=False`` and passed
         an invalid multiplication table.
         """
+
+        # Used to check whether or not something is zero in an inexact
+        # ring. This number is sufficient to allow the construction of
+        # QuaternionHermitianEJA(2, RDF) with check=True.
+        epsilon = 1e-16
+
         for i in range(self.dimension()):
             for j in range(self.dimension()):
                 for k in range(self.dimension()):
                     x = self.monomial(i)
                     y = self.monomial(j)
                     z = self.monomial(k)
-                    if (x*y).inner_product(z) != x.inner_product(y*z):
-                        return False
+                    diff = (x*y).inner_product(z) - x.inner_product(y*z)
+
+                    if self.base_ring().is_exact():
+                        if diff != 0:
+                            return False
+                    else:
+                        if diff.abs() > epsilon:
+                            return False
 
         return True
 
@@ -1024,8 +1049,10 @@ class HadamardEJA(FiniteDimensionalEuclideanJordanAlgebra):
         mult_table = [ [ V.gen(i)*(i == j) for j in range(n) ]
                        for i in range(n) ]
 
-        fdeja = super(HadamardEJA, self)
-        fdeja.__init__(field, mult_table, **kwargs)
+        super(HadamardEJA, self).__init__(field,
+                                          mult_table,
+                                          check=False,
+                                          **kwargs)
         self.rank.set_cache(n)
 
     def inner_product(self, x, y):
@@ -1114,9 +1141,10 @@ class MatrixEuclideanJordanAlgebra(FiniteDimensionalEuclideanJordanAlgebra):
 
         Qs = self.multiplication_table_from_matrix_basis(basis)
 
-        fdeja = super(MatrixEuclideanJordanAlgebra, self)
-        fdeja.__init__(field, Qs, natural_basis=basis, **kwargs)
-        return
+        super(MatrixEuclideanJordanAlgebra, self).__init__(field,
+                                                           Qs,
+                                                           natural_basis=basis,
+                                                           **kwargs)
 
 
     @cached_method
@@ -1135,10 +1163,13 @@ class MatrixEuclideanJordanAlgebra(FiniteDimensionalEuclideanJordanAlgebra):
 
             # Do this over the rationals and convert back at the end.
             # Only works because we know the entries of the basis are
-            # integers.
+            # integers. The argument ``check=False`` is required
+            # because the trace inner-product method for this
+            # class is a stub and can't actually be checked.
             J = MatrixEuclideanJordanAlgebra(QQ,
                                              basis,
-                                             normalize_basis=False)
+                                             normalize_basis=False,
+                                             check=False)
             a = J._charpoly_coefficients()
 
             # Unfortunately, changing the basis does change the
@@ -1381,7 +1412,10 @@ class RealSymmetricEJA(RealMatrixEuclideanJordanAlgebra):
 
     def __init__(self, n, field=AA, **kwargs):
         basis = self._denormalized_basis(n, field)
-        super(RealSymmetricEJA, self).__init__(field, basis, **kwargs)
+        super(RealSymmetricEJA, self).__init__(field,
+                                               basis,
+                                               check=False,
+                                               **kwargs)
         self.rank.set_cache(n)
 
 
@@ -1677,7 +1711,10 @@ class ComplexHermitianEJA(ComplexMatrixEuclideanJordanAlgebra):
 
     def __init__(self, n, field=AA, **kwargs):
         basis = self._denormalized_basis(n,field)
-        super(ComplexHermitianEJA,self).__init__(field, basis, **kwargs)
+        super(ComplexHermitianEJA,self).__init__(field,
+                                                 basis,
+                                                 check=False,
+                                                 **kwargs)
         self.rank.set_cache(n)
 
 
@@ -1978,7 +2015,10 @@ class QuaternionHermitianEJA(QuaternionMatrixEuclideanJordanAlgebra):
 
     def __init__(self, n, field=AA, **kwargs):
         basis = self._denormalized_basis(n,field)
-        super(QuaternionHermitianEJA,self).__init__(field, basis, **kwargs)
+        super(QuaternionHermitianEJA,self).__init__(field,
+                                                    basis,
+                                                    check=False,
+                                                    **kwargs)
         self.rank.set_cache(n)
 
 
@@ -2061,8 +2101,10 @@ class BilinearFormEJA(FiniteDimensionalEuclideanJordanAlgebra):
         # The rank of this algebra is two, unless we're in a
         # one-dimensional ambient space (because the rank is bounded
         # by the ambient dimension).
-        fdeja = super(BilinearFormEJA, self)
-        fdeja.__init__(field, mult_table, **kwargs)
+        super(BilinearFormEJA, self).__init__(field,
+                                              mult_table,
+                                              check=False,
+                                              **kwargs)
         self.rank.set_cache(min(n,2))
 
     def inner_product(self, x, y):
@@ -2154,7 +2196,7 @@ class JordanSpinEJA(BilinearFormEJA):
     def __init__(self, n, field=AA, **kwargs):
         # This is a special case of the BilinearFormEJA with the identity
         # matrix as its bilinear form.
-        return super(JordanSpinEJA, self).__init__(n, field, **kwargs)
+        super(JordanSpinEJA, self).__init__(n, field, **kwargs)
 
 
 class TrivialEJA(FiniteDimensionalEuclideanJordanAlgebra):
@@ -2188,10 +2230,12 @@ class TrivialEJA(FiniteDimensionalEuclideanJordanAlgebra):
     """
     def __init__(self, field=AA, **kwargs):
         mult_table = []
-        fdeja = super(TrivialEJA, self)
+        super(TrivialEJA, self).__init__(field,
+                                         mult_table,
+                                         check=False,
+                                         **kwargs)
         # The rank is zero using my definition, namely the dimension of the
         # largest subalgebra generated by any element.
-        fdeja.__init__(field, mult_table, **kwargs)
         self.rank.set_cache(0)
 
 
@@ -2237,6 +2281,8 @@ class DirectSumEJA(FiniteDimensionalEuclideanJordanAlgebra):
                 p = (J2.monomial(i)*J2.monomial(j)).to_vector()
                 mult_table[n1+i][n1+j] = V([field.zero()]*n1 + p.list())
 
-        fdeja = super(DirectSumEJA, self)
-        fdeja.__init__(field, mult_table, **kwargs)
+        super(DirectSumEJA, self).__init__(field,
+                                           mult_table,
+                                           check=False,
+                                           **kwargs)
         self.rank.set_cache(J1.rank() + J2.rank())