# field can have dimension 4 (quaternions) too.
return 2
- @classmethod
- def _denormalized_basis(cls, n, field):
- raise NotImplementedError
-
- def __init__(self, n, field=QQ, normalize_basis=True, **kwargs):
- S = self._denormalized_basis(n, field)
-
+ def __init__(self, field, basis, rank, normalize_basis=True, **kwargs):
+ """
+ Compared to the superclass constructor, we take a basis instead of
+ a multiplication table because the latter can be computed in terms
+ of the former when the product is known (like it is here).
+ """
# Used in this class's fast _charpoly_coeff() override.
self._basis_normalizers = None
- if n > 1 and normalize_basis:
+ # We're going to loop through this a few times, so now's a good
+ # time to ensure that it isn't a generator expression.
+ basis = tuple(basis)
+
+ if rank > 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.
p = z**2 - 2
if p.is_irreducible():
field = NumberField(p, 'sqrt2', embedding=RLF(2).sqrt())
- S = [ s.change_ring(field) for s in S ]
+ basis = tuple( s.change_ring(field) for s in basis )
self._basis_normalizers = tuple(
- ~(self.natural_inner_product(s,s).sqrt()) for s in S )
- S = tuple( s*c for (s,c) in zip(S,self._basis_normalizers) )
+ ~(self.natural_inner_product(s,s).sqrt()) for s in basis )
+ basis = tuple(s*c for (s,c) in izip(basis,self._basis_normalizers))
- Qs = self.multiplication_table_from_matrix_basis(S)
+ Qs = self.multiplication_table_from_matrix_basis(basis)
fdeja = super(MatrixEuclideanJordanAlgebra, self)
return fdeja.__init__(field,
Qs,
- rank=n,
- natural_basis=S,
+ rank=rank,
+ natural_basis=basis,
**kwargs)
# with had entries in a nice field.
return super(MatrixEuclideanJordanAlgebra, self)._charpoly_coeff(i)
else:
- # If we didn't unembed first, this number would be wrong
- # by a power-of-two factor for complex/quaternion matrices.
- n = self.real_unembed(self.natural_basis_space().zero()).nrows()
- field = self.base_ring().base_ring() # yeeeeaaaahhh
- J = self.__class__(n, field, False)
+ basis = ( (b/n) for (b,n) in izip(self.natural_basis(),
+ self._basis_normalizers) )
+ field = self.base_ring().base_ring() # yeeeaahhhhhhh
+ J = MatrixEuclideanJordanAlgebra(field,
+ basis,
+ self.rank(),
+ normalize_basis=False)
(_,x,_,_) = J._charpoly_matrix_system()
p = J._charpoly_coeff(i)
# p might be missing some vars, have to substitute "optionally"
else:
Sij = Eij + Eij.transpose()
S.append(Sij)
- return tuple(S)
+ return S
@staticmethod
return 4 # Dimension 10
+ def __init__(self, n, field=QQ, **kwargs):
+ basis = self._denormalized_basis(n, field)
+ super(RealSymmetricEJA, self).__init__(field, basis, n, **kwargs)
+
class ComplexMatrixEuclideanJordanAlgebra(MatrixEuclideanJordanAlgebra):
@staticmethod
True
"""
+
@classmethod
def _denormalized_basis(cls, n, field):
"""
# Since we embedded these, we can drop back to the "field" that we
# started with instead of the complex extension "F".
- return tuple( s.change_ring(field) for s in S )
+ return ( s.change_ring(field) for s in S )
+ def __init__(self, n, field=QQ, **kwargs):
+ basis = self._denormalized_basis(n,field)
+ super(ComplexHermitianEJA,self).__init__(field, basis, n, **kwargs)
+
class QuaternionMatrixEuclideanJordanAlgebra(MatrixEuclideanJordanAlgebra):
@staticmethod
S.append(Sij_J)
Sij_K = cls.real_embed(K*Eij - K*Eij.transpose())
S.append(Sij_K)
- return tuple(S)
+ return S
+
+ def __init__(self, n, field=QQ, **kwargs):
+ basis = self._denormalized_basis(n,field)
+ super(QuaternionHermitianEJA,self).__init__(field, basis, n, **kwargs)
class JordanSpinEJA(FiniteDimensionalEuclideanJordanAlgebra):