# -*- coding: utf-8 -*-
-from itertools import izip
-
from sage.matrix.constructor import matrix
from sage.modules.free_module import VectorSpace
from sage.modules.with_basis.indexed_element import IndexedFreeModuleElement
# TODO: make this unnecessary somehow.
from sage.misc.lazy_import import lazy_import
lazy_import('mjo.eja.eja_algebra', 'FiniteDimensionalEuclideanJordanAlgebra')
-lazy_import('mjo.eja.eja_subalgebra',
+lazy_import('mjo.eja.eja_element_subalgebra',
'FiniteDimensionalEuclideanJordanElementSubalgebra')
from mjo.eja.eja_operator import FiniteDimensionalEuclideanJordanAlgebraOperator
from mjo.eja.eja_utils import _mat2vec
SETUP::
- sage: from mjo.eja.eja_algebra import (RealCartesianProductEJA,
+ sage: from mjo.eja.eja_algebra import (HadamardEJA,
....: random_eja)
EXAMPLES::
sage: R = PolynomialRing(QQ, 't')
sage: t = R.gen(0)
sage: p = t^4 - t^3 + 5*t - 2
- sage: J = RealCartesianProductEJA(5)
+ sage: J = HadamardEJA(5)
sage: J.one().apply_univariate_polynomial(p) == 3*J.one()
True
SETUP::
- sage: from mjo.eja.eja_algebra import RealCartesianProductEJA
+ sage: from mjo.eja.eja_algebra import HadamardEJA
EXAMPLES:
the identity element is `(t-1)` from which it follows that
the characteristic polynomial should be `(t-1)^3`::
- sage: J = RealCartesianProductEJA(3)
+ sage: J = HadamardEJA(3)
sage: J.one().characteristic_polynomial()
t^3 - 3*t^2 + 3*t - 1
Likewise, the characteristic of the zero element in the
rank-three algebra `R^{n}` should be `t^{3}`::
- sage: J = RealCartesianProductEJA(3)
+ sage: J = HadamardEJA(3)
sage: J.zero().characteristic_polynomial()
t^3
to zero on that element::
sage: set_random_seed()
- sage: x = RealCartesianProductEJA(3).random_element()
+ sage: x = HadamardEJA(3).random_element()
sage: p = x.characteristic_polynomial()
sage: x.apply_univariate_polynomial(p)
0
The characteristic polynomials of the zero and unit elements
should be what we think they are in a subalgebra, too::
- sage: J = RealCartesianProductEJA(3)
+ sage: J = HadamardEJA(3)
sage: p1 = J.one().characteristic_polynomial()
sage: q1 = J.zero().characteristic_polynomial()
sage: e0,e1,e2 = J.gens()
return not (p(zero) == zero)
+ def is_primitive_idempotent(self):
+ """
+ Return whether or not this element is a primitive (or minimal)
+ idempotent.
+
+ A primitive idempotent is a non-zero idempotent that is not
+ the sum of two other non-zero idempotents. Remark 2.7.15 in
+ Baes shows that this is what he refers to as a "minimal
+ idempotent."
+
+ An element of a Euclidean Jordan algebra is a minimal idempotent
+ if it :meth:`is_idempotent` and if its Peirce subalgebra
+ corresponding to the eigenvalue ``1`` has dimension ``1`` (Baes,
+ Proposition 2.7.17).
+
+ SETUP::
+
+ sage: from mjo.eja.eja_algebra import (JordanSpinEJA,
+ ....: RealSymmetricEJA,
+ ....: TrivialEJA,
+ ....: random_eja)
+
+ WARNING::
+
+ This method is sloooooow.
+
+ EXAMPLES:
+
+ The spectral decomposition of a non-regular element should always
+ contain at least one non-minimal idempotent::
+
+ sage: J = RealSymmetricEJA(3, AA)
+ sage: x = sum(J.gens())
+ sage: x.is_regular()
+ False
+ sage: [ c.is_primitive_idempotent()
+ ....: for (l,c) in x.spectral_decomposition() ]
+ [False, True]
+
+ On the other hand, the spectral decomposition of a regular
+ element should always be in terms of minimal idempotents::
+
+ sage: J = JordanSpinEJA(4, AA)
+ sage: x = sum( i*J.gens()[i] for i in range(len(J.gens())) )
+ sage: x.is_regular()
+ True
+ sage: [ c.is_primitive_idempotent()
+ ....: for (l,c) in x.spectral_decomposition() ]
+ [True, True]
+
+ TESTS:
+
+ The identity element is minimal only in an EJA of rank one::
+
+ sage: set_random_seed()
+ sage: J = random_eja()
+ sage: J.rank() == 1 or not J.one().is_primitive_idempotent()
+ True
+
+ A non-idempotent cannot be a minimal idempotent::
+
+ sage: set_random_seed()
+ sage: J = JordanSpinEJA(4)
+ sage: x = J.random_element()
+ sage: (not x.is_idempotent()) and x.is_primitive_idempotent()
+ False
+
+ Proposition 2.7.19 in Baes says that an element is a minimal
+ idempotent if and only if it's idempotent with trace equal to
+ unity::
+
+ sage: set_random_seed()
+ sage: J = JordanSpinEJA(4)
+ sage: x = J.random_element()
+ sage: expected = (x.is_idempotent() and x.trace() == 1)
+ sage: actual = x.is_primitive_idempotent()
+ sage: actual == expected
+ True
+
+ Primitive idempotents must be non-zero::
+
+ sage: set_random_seed()
+ sage: J = random_eja()
+ sage: J.zero().is_idempotent()
+ True
+ sage: J.zero().is_primitive_idempotent()
+ False
+
+ As a consequence of the fact that primitive idempotents must
+ be non-zero, there are no primitive idempotents in a trivial
+ Euclidean Jordan algebra::
+
+ sage: J = TrivialEJA()
+ sage: J.one().is_idempotent()
+ True
+ sage: J.one().is_primitive_idempotent()
+ False
+
+ """
+ if not self.is_idempotent():
+ return False
+
+ if self.is_zero():
+ return False
+
+ (_,_,J1) = self.parent().peirce_decomposition(self)
+ return (J1.dimension() == 1)
+
+
def is_nilpotent(self):
"""
Return whether or not some power of this element is zero.
"""
B = self.parent().natural_basis()
W = self.parent().natural_basis_space()
- return W.linear_combination(izip(B,self.to_vector()))
+ return W.linear_combination(zip(B,self.to_vector()))
def norm(self):
SETUP::
sage: from mjo.eja.eja_algebra import (JordanSpinEJA,
- ....: RealCartesianProductEJA)
+ ....: HadamardEJA)
EXAMPLES::
- sage: J = RealCartesianProductEJA(2)
+ sage: J = HadamardEJA(2)
sage: x = sum(J.gens())
sage: x.norm()
sqrt(2)
sage: from mjo.eja.eja_algebra import random_eja
- TESTS::
+ TESTS:
+
+ Ensure that we can find an idempotent in a non-trivial algebra
+ where there are non-nilpotent elements::
sage: set_random_seed()
- sage: J = random_eja()
+ sage: J = random_eja(nontrivial=True)
sage: x = J.random_element()
sage: while x.is_nilpotent():
....: x = J.random_element()
True
"""
+ if self.parent().is_trivial():
+ return self
+
if self.is_nilpotent():
raise ValueError("this only works with non-nilpotent elements!")
# will be minimal for some natural number s...
s = 0
minimal_dim = J.dimension()
- for i in xrange(1, minimal_dim):
+ for i in range(1, minimal_dim):
this_dim = (u**i).operator().matrix().image().dimension()
if this_dim < minimal_dim:
minimal_dim = this_dim
SETUP::
sage: from mjo.eja.eja_algebra import (JordanSpinEJA,
- ....: RealCartesianProductEJA,
+ ....: HadamardEJA,
....: TrivialEJA,
....: random_eja)
::
- sage: J = RealCartesianProductEJA(5)
+ sage: J = HadamardEJA(5)
sage: J.one().trace()
5
SETUP::
sage: from mjo.eja.eja_algebra import (JordanSpinEJA,
- ....: RealCartesianProductEJA)
+ ....: HadamardEJA)
EXAMPLES::
- sage: J = RealCartesianProductEJA(2)
+ sage: J = HadamardEJA(2)
sage: x = sum(J.gens())
sage: x.trace_norm()
sqrt(2)