from sage.modules.free_module import VectorSpace
from sage.modules.with_basis.indexed_element import IndexedFreeModuleElement
-from mjo.eja.eja_operator import FiniteDimensionalEuclideanJordanAlgebraOperator
+from mjo.eja.eja_operator import FiniteDimensionalEJAOperator
from mjo.eja.eja_utils import _mat2vec
-class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
+class FiniteDimensionalEJAElement(IndexedFreeModuleElement):
"""
An element of a Euclidean Jordan algebra.
"""
Ditto for the quaternions::
- sage: J = QuaternionHermitianEJA(3)
+ sage: J = QuaternionHermitianEJA(2)
sage: J.one().inner_product(J.one())
- 3
+ 2
TESTS:
::
sage: set_random_seed()
- sage: J1 = ComplexHermitianEJA(3)
- sage: J2 = ComplexHermitianEJA(3,field=QQ,orthonormalize=False)
- sage: X = matrix.random(GaussianIntegers(),3)
+ sage: J1 = ComplexHermitianEJA(2)
+ sage: J2 = ComplexHermitianEJA(2,field=QQ,orthonormalize=False)
+ sage: X = matrix.random(GaussianIntegers(), 2)
sage: X = X + X.H
sage: expected = AA(X.det())
sage: actual1 = J1(J1.real_embed(X)).det()
ALGORITHM:
- We appeal to the quadratic representation as in Koecher's
- Theorem 12 in Chapter III, Section 5.
+ In general we appeal to the quadratic representation as in
+ Koecher's Theorem 12 in Chapter III, Section 5. But if the
+ parent algebra's "characteristic polynomial of" coefficients
+ happen to be cached, then we use Proposition II.2.4 in Faraut
+ and Korányi which gives a formula for the inverse based on the
+ characteristic polynomial and the Cayley-Hamilton theorem for
+ Euclidean Jordan algebras::
SETUP::
....: x.operator().inverse()(J.one()) == x.inverse() )
True
- Proposition II.2.4 in Faraut and Korányi gives a formula for
- the inverse based on the characteristic polynomial and the
- Cayley-Hamilton theorem for Euclidean Jordan algebras::
+ Check that the fast (cached) and slow algorithms give the same
+ answer::
- sage: set_random_seed()
- sage: J = ComplexHermitianEJA(3)
- sage: x = J.random_element()
- sage: while not x.is_invertible():
- ....: x = J.random_element()
- sage: r = J.rank()
- sage: a = x.characteristic_polynomial().coefficients(sparse=False)
- sage: expected = (-1)^(r+1)/x.det()
- sage: expected *= sum( a[i+1]*x^i for i in range(r) )
- sage: x.inverse() == expected
+ sage: set_random_seed() # long time
+ sage: J = random_eja(field=QQ, orthonormalize=False) # long time
+ sage: x = J.random_element() # long time
+ sage: while not x.is_invertible(): # long time
+ ....: x = J.random_element() # long time
+ sage: slow = x.inverse() # long time
+ sage: _ = J._charpoly_coefficients() # long time
+ sage: fast = x.inverse() # long time
+ sage: slow == fast # long time
True
-
"""
if not self.is_invertible():
raise ValueError("element is not invertible")
sage: (not J.is_trivial()) and J.zero().is_invertible()
False
+ Test that the fast (cached) and slow algorithms give the same
+ answer::
+
+ sage: set_random_seed() # long time
+ sage: J = random_eja(field=QQ, orthonormalize=False) # long time
+ sage: x = J.random_element() # long time
+ sage: slow = x.is_invertible() # long time
+ sage: _ = J._charpoly_coefficients() # long time
+ sage: fast = x.is_invertible() # long time
+ sage: slow == fast # long time
+ True
+
"""
if self.is_zero():
if self.parent().is_trivial():
::
- sage: J = QuaternionHermitianEJA(3)
+ sage: J = QuaternionHermitianEJA(2)
sage: J.one()
- e0 + e5 + e14
+ e0 + e5
sage: J.one().to_matrix()
- [1 0 0 0 0 0 0 0 0 0 0 0]
- [0 1 0 0 0 0 0 0 0 0 0 0]
- [0 0 1 0 0 0 0 0 0 0 0 0]
- [0 0 0 1 0 0 0 0 0 0 0 0]
- [0 0 0 0 1 0 0 0 0 0 0 0]
- [0 0 0 0 0 1 0 0 0 0 0 0]
- [0 0 0 0 0 0 1 0 0 0 0 0]
- [0 0 0 0 0 0 0 1 0 0 0 0]
- [0 0 0 0 0 0 0 0 1 0 0 0]
- [0 0 0 0 0 0 0 0 0 1 0 0]
- [0 0 0 0 0 0 0 0 0 0 1 0]
- [0 0 0 0 0 0 0 0 0 0 0 1]
+ [1 0 0 0 0 0 0 0]
+ [0 1 0 0 0 0 0 0]
+ [0 0 1 0 0 0 0 0]
+ [0 0 0 1 0 0 0 0]
+ [0 0 0 0 1 0 0 0]
+ [0 0 0 0 0 1 0 0]
+ [0 0 0 0 0 0 1 0]
+ [0 0 0 0 0 0 0 1]
+
"""
B = self.parent().matrix_basis()
W = self.parent().matrix_space()
P = self.parent()
left_mult_by_self = lambda y: self*y
L = P.module_morphism(function=left_mult_by_self, codomain=P)
- return FiniteDimensionalEuclideanJordanAlgebraOperator(
- P,
- P,
- L.matrix() )
+ return FiniteDimensionalEJAOperator(P, P, L.matrix() )
def quadratic_representation(self, other=None):
True
"""
- from mjo.eja.eja_element_subalgebra import FiniteDimensionalEuclideanJordanElementSubalgebra
- return FiniteDimensionalEuclideanJordanElementSubalgebra(self, orthonormalize_basis)
+ from mjo.eja.eja_element_subalgebra import FiniteDimensionalEJAElementSubalgebra
+ return FiniteDimensionalEJAElementSubalgebra(self, orthonormalize_basis)
def subalgebra_idempotent(self):