]> gitweb.michael.orlitzky.com - sage.d.git/blobdiff - mjo/eja/eja_algebra.py
eja: fix one() in the trivial HadamardEJA.
[sage.d.git] / mjo / eja / eja_algebra.py
index c822d14f6d0900a8b90c24d377fb31196003e0e8..c40c8be4c371255f9bc174f99862ef0a7a204555 100644 (file)
@@ -588,6 +588,16 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule):
             sage: actual == expected
             True
 
+        Ensure that the cached unit element (often precomputed by
+        hand) agrees with the computed one::
+
+            sage: set_random_seed()
+            sage: J = random_eja()
+            sage: cached = J.one()
+            sage: J.one.clear_cache()
+            sage: J.one() == cached
+            True
+
         """
         # We can brute-force compute the matrices of the operators
         # that correspond to the basis elements of this algebra.
@@ -1108,7 +1118,8 @@ class MatrixEuclideanJordanAlgebra(FiniteDimensionalEuclideanJordanAlgebra):
         # time to ensure that it isn't a generator expression.
         basis = tuple(basis)
 
-        if len(basis) > 1 and normalize_basis:
+        algebra_dim = len(basis)
+        if algebra_dim > 1 and normalize_basis:
             # We'll need sqrt(2) to normalize the basis, and this
             # winds up in the multiplication table, so the whole
             # algebra needs to be over the field extension.
@@ -1129,6 +1140,14 @@ class MatrixEuclideanJordanAlgebra(FiniteDimensionalEuclideanJordanAlgebra):
                                                            natural_basis=basis,
                                                            **kwargs)
 
+        if algebra_dim == 0:
+            self.one.set_cache(self.zero())
+        else:
+            n = basis[0].nrows()
+            # The identity wrt (A,B) -> (AB + BA)/2 is independent of the
+            # details of this algebra.
+            self.one.set_cache(self(matrix.identity(field,n)))
+
 
     @cached_method
     def _charpoly_coefficients(self):
@@ -2052,6 +2071,11 @@ class HadamardEJA(RationalBasisEuclideanJordanAlgebra):
                                           **kwargs)
         self.rank.set_cache(n)
 
+        if n == 0:
+            self.one.set_cache( self.zero() )
+        else:
+            self.one.set_cache( sum(self.gens()) )
+
     @staticmethod
     def _max_random_instance_size():
         return 5
@@ -2111,6 +2135,20 @@ class BilinearFormEJA(RationalBasisEuclideanJordanAlgebra):
         sage: J0.multiplication_table() == J0.multiplication_table()
         True
 
+    An error is raised if the matrix `B` does not correspond to a
+    positive-definite bilinear form::
+
+        sage: B = matrix.random(QQ,2,3)
+        sage: J = BilinearFormEJA(B)
+        Traceback (most recent call last):
+        ...
+        ValueError: bilinear form is not positive-definite
+        sage: B = matrix.zero(QQ,3)
+        sage: J = BilinearFormEJA(B)
+        Traceback (most recent call last):
+        ...
+        ValueError: bilinear form is not positive-definite
+
     TESTS:
 
     We can create a zero-dimensional algebra::
@@ -2151,7 +2189,7 @@ class BilinearFormEJA(RationalBasisEuclideanJordanAlgebra):
         n = B.nrows()
 
         if not B.is_positive_definite():
-            raise TypeError("matrix B is not positive-definite")
+            raise ValueError("bilinear form is not positive-definite")
 
         V = VectorSpace(field, n)
         mult_table = [[V.zero() for j in range(n)] for i in range(n)]
@@ -2177,10 +2215,39 @@ class BilinearFormEJA(RationalBasisEuclideanJordanAlgebra):
                                               **kwargs)
         self.rank.set_cache(min(n,2))
 
+        if n == 0:
+            self.one.set_cache( self.zero() )
+        else:
+            self.one.set_cache( self.monomial(0) )
+
     @staticmethod
     def _max_random_instance_size():
         return 5
 
+    @classmethod
+    def random_instance(cls, field=AA, **kwargs):
+        """
+        Return a random instance of this algebra.
+        """
+        n = ZZ.random_element(cls._max_random_instance_size() + 1)
+        if n.is_zero():
+            B = matrix.identity(field, n)
+            return cls(B, field, **kwargs)
+
+        B11 = matrix.identity(field,1)
+        M = matrix.random(field, n-1)
+        I = matrix.identity(field, n-1)
+        alpha = field.zero()
+        while alpha.is_zero():
+            alpha = field.random_element().abs()
+        B22 = M.transpose()*M + alpha*I
+
+        from sage.matrix.special import block_matrix
+        B = block_matrix(2,2, [ [B11,   ZZ(0) ],
+                                [ZZ(0), B22 ] ])
+
+        return cls(B, field, **kwargs)
+
     def inner_product(self, x, y):
         r"""
         Half of the trace inner product.
@@ -2200,16 +2267,11 @@ class BilinearFormEJA(RationalBasisEuclideanJordanAlgebra):
         paper::
 
             sage: set_random_seed()
-            sage: n = ZZ.random_element(2,5)
-            sage: M = matrix.random(QQ, max(0,n-1), algorithm='unimodular')
-            sage: B11 = matrix.identity(QQ,1)
-            sage: B22 = M.transpose()*M
-            sage: B = block_matrix(2,2,[ [B11,0  ],
-            ....:                        [0, B22 ] ])
-            sage: J = BilinearFormEJA(B)
+            sage: J = BilinearFormEJA.random_instance()
+            sage: n = J.dimension()
             sage: x = J.random_element()
             sage: y = J.random_element()
-            sage: x.inner_product(y) == (x*y).trace()/2
+            sage: (n == 1) or (x.inner_product(y) == (x*y).trace()/2)
             True
 
         """
@@ -2272,6 +2334,16 @@ class JordanSpinEJA(BilinearFormEJA):
         B = matrix.identity(field, n)
         super(JordanSpinEJA, self).__init__(B, field, **kwargs)
 
+    @classmethod
+    def random_instance(cls, field=AA, **kwargs):
+        """
+        Return a random instance of this type of algebra.
+
+        Needed here to override the implementation for ``BilinearFormEJA``.
+        """
+        n = ZZ.random_element(cls._max_random_instance_size() + 1)
+        return cls(n, field, **kwargs)
+
 
 class TrivialEJA(FiniteDimensionalEuclideanJordanAlgebra):
     """
@@ -2311,6 +2383,7 @@ class TrivialEJA(FiniteDimensionalEuclideanJordanAlgebra):
         # The rank is zero using my definition, namely the dimension of the
         # largest subalgebra generated by any element.
         self.rank.set_cache(0)
+        self.one.set_cache( self.zero() )
 
     @classmethod
     def random_instance(cls, field=AA, **kwargs):