from sage.modules.free_module import VectorSpace
from sage.modules.with_basis.indexed_element import IndexedFreeModuleElement
-from mjo.eja.eja_operator import FiniteDimensionalEJAOperator
+from mjo.eja.eja_operator import EJAOperator
from mjo.eja.eja_utils import _scale
-class FiniteDimensionalEJAElement(IndexedFreeModuleElement):
+class EJAElement(IndexedFreeModuleElement):
"""
An element of a Euclidean Jordan algebra.
"""
SETUP::
- sage: from mjo.eja.eja_algebra import (JordanSpinEJA,
+ sage: from mjo.eja.eja_algebra import (AlbertEJA,
+ ....: JordanSpinEJA,
....: TrivialEJA,
....: RealSymmetricEJA,
....: ComplexHermitianEJA,
sage: actual2 == expected
True
+ There's a formula for the determinant of the Albert algebra
+ (Yokota, Section 2.1)::
+
+ sage: def albert_det(x):
+ ....: X = x.to_matrix()
+ ....: res = X[0,0]*X[1,1]*X[2,2]
+ ....: res += 2*(X[1,2]*X[2,0]*X[0,1]).real()
+ ....: res -= X[0,0]*X[1,2]*X[2,1]
+ ....: res -= X[1,1]*X[2,0]*X[0,2]
+ ....: res -= X[2,2]*X[0,1]*X[1,0]
+ ....: return res.leading_coefficient()
+ sage: J = AlbertEJA(field=QQ, orthonormalize=False)
+ sage: xs = J.random_elements(10)
+ sage: all( albert_det(x) == x.det() for x in xs )
+ True
+
"""
P = self.parent()
r = P.rank()
P = self.parent()
left_mult_by_self = lambda y: self*y
L = P.module_morphism(function=left_mult_by_self, codomain=P)
- return FiniteDimensionalEJAOperator(P, P, L.matrix() )
+ return EJAOperator(P, P, L.matrix() )
def quadratic_representation(self, other=None):
return self.trace_inner_product(self).sqrt()
-class CartesianProductEJAElement(FiniteDimensionalEJAElement):
- def det(self):
- r"""
- Compute the determinant of this product-element using the
- determianants of its factors.
-
- This result Follows from the spectral decomposition of (say)
- the pair `(x,y)` in terms of the Jordan frame `\left\{ (c_1,
- 0),(c_2, 0),...,(0,d_1),(0,d_2),... \right\}.
- """
- from sage.misc.misc_c import prod
- return prod( f.det() for f in self.cartesian_factors() )
+class CartesianProductParentEJAElement(EJAElement):
+ r"""
+ An intermediate class for elements that have a Cartesian
+ product as their parent algebra.
+ This is needed because the ``to_matrix`` method (which gives you a
+ representation from the superalgebra) needs to do special stuff
+ for Cartesian products. Specifically, an EJA subalgebra of a
+ Cartesian product EJA will not itself be a Cartesian product (it
+ has its own basis) -- but we want ``to_matrix()`` to be able to
+ give us a Cartesian product representation.
+ """
def to_matrix(self):
# An override is necessary to call our custom _scale().
B = self.parent().matrix_basis()
# Aaaaand linear combinations don't work in Cartesian
# product spaces, even though they provide a method with
- # that name. This is hidden behind an "if" because the
+ # that name. This is hidden in a subclass because the
# _scale() function is slow.
pairs = zip(B, self.to_vector())
return W.sum( _scale(b, alpha) for (b,alpha) in pairs )
+
+class CartesianProductEJAElement(CartesianProductParentEJAElement):
+ def det(self):
+ r"""
+ Compute the determinant of this product-element using the
+ determianants of its factors.
+
+ This result Follows from the spectral decomposition of (say)
+ the pair `(x,y)` in terms of the Jordan frame `\left\{ (c_1,
+ 0),(c_2, 0),...,(0,d_1),(0,d_2),... \right\}.
+ """
+ from sage.misc.misc_c import prod
+ return prod( f.det() for f in self.cartesian_factors() )