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.
# 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.
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):
**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
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::
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)]
**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
Return a random instance of this algebra.
"""
n = ZZ.random_element(cls._max_random_instance_size() + 1)
- if n == 0:
- # Special case needed since we use (n-1) below.
- B = matrix.identity(field, 0)
+ if n.is_zero():
+ B = matrix.identity(field, n)
return cls(B, field, **kwargs)
B11 = matrix.identity(field,1)
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):
"""
# 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):