from sage.matrix.constructor import matrix
+from sage.misc.cachefunc import cached_method
+from sage.rings.all import QQ
from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanSubalgebra
P = matrix(field, power_vectors)
if orthonormalize_basis == False:
+ # Echelonize the matrix ourselves, because otherwise the
+ # call to P.pivot_rows() below can choose a non-optimal
+ # row-reduction algorithm. In particular, scaling can
+ # help over AA because it avoids the RecursionError that
+ # gets thrown when we have to look too hard for a root.
+ #
+ # Beware: QQ supports an entirely different set of "algorithm"
+ # keywords than do AA and RR.
+ algo = None
+ if field is not QQ:
+ algo = "scaled_partial_pivoting"
+ P.echelonize(algorithm=algo)
+
# In this case, we just need to figure out which elements
# of the "powers" list are redundant... First compute the
# vector subspace spanned by the powers of the given
# Pick those out of the list of all powers.
superalgebra_basis = tuple(map(powers.__getitem__, ind_rows))
-
- # If our superalgebra is a subalgebra of something else, then
- # these vectors won't have the right coordinates for
- # V.span_of_basis() unless we use V.from_vector() on them.
- basis_vectors = map(power_vectors.__getitem__, ind_rows)
else:
# If we're going to orthonormalize the basis anyway, we
# might as well just do Gram-Schmidt on the whole list of
superalgebra_basis = [ self._superalgebra.from_vector(b)
for b in basis_vectors ]
- W = V.span_of_basis( V.from_vector(v) for v in basis_vectors )
+ fdeja = super(FiniteDimensionalEuclideanJordanElementSubalgebra, self)
+ fdeja.__init__(self._superalgebra,
+ superalgebra_basis,
+ category=category,
+ check_axioms=False)
# The rank is the highest possible degree of a minimal
# polynomial, and is bounded above by the dimension. We know
# polynomial has the same degree as the space's dimension
# (remember how we constructed the space?), so that must be
# its rank too.
- rank = W.dimension()
-
- fdeja = super(FiniteDimensionalEuclideanJordanElementSubalgebra, self)
- return fdeja.__init__(self._superalgebra,
- superalgebra_basis,
- rank=rank,
- category=category)
-
-
- def _a_regular_element(self):
- """
- Override the superalgebra method to return the one
- regular element that is sure to exist in this
- subalgebra, namely the element that generated it.
-
- SETUP::
-
- sage: from mjo.eja.eja_algebra import random_eja
-
- TESTS::
-
- sage: set_random_seed()
- sage: J = random_eja().random_element().subalgebra_generated_by()
- sage: J._a_regular_element().is_regular()
- True
-
- """
- if self.dimension() == 0:
- return self.zero()
- else:
- return self.monomial(1)
+ self.rank.set_cache(self.dimension())
+ @cached_method
def one(self):
"""
Return the multiplicative identity element of this algebra.
The superclass method computes the identity element, which is
beyond overkill in this case: the superalgebra identity
restricted to this algebra is its identity. Note that we can't
- count on the first basis element being the identity -- it migth
+ count on the first basis element being the identity -- it might
have been scaled if we orthonormalized the basis.
SETUP::
- sage: from mjo.eja.eja_algebra import (RealCartesianProductEJA,
+ sage: from mjo.eja.eja_algebra import (HadamardEJA,
....: random_eja)
EXAMPLES::
- sage: J = RealCartesianProductEJA(5)
+ sage: J = HadamardEJA(5)
sage: J.one()
e0 + e1 + e2 + e3 + e4
sage: x = sum(J.gens())
The identity element acts like the identity over the rationals::
sage: set_random_seed()
- sage: x = random_eja().random_element()
+ sage: x = random_eja(field=QQ).random_element()
sage: A = x.subalgebra_generated_by()
sage: x = A.random_element()
sage: A.one()*x == x and x*A.one() == x
reals with an orthonormal basis::
sage: set_random_seed()
- sage: x = random_eja(AA).random_element()
+ sage: x = random_eja().random_element()
sage: A = x.subalgebra_generated_by(orthonormalize_basis=True)
sage: x = A.random_element()
sage: A.one()*x == x and x*A.one() == x
the rationals::
sage: set_random_seed()
- sage: x = random_eja().random_element()
+ sage: x = random_eja(field=QQ).random_element()
sage: A = x.subalgebra_generated_by()
sage: actual = A.one().operator().matrix()
sage: expected = matrix.identity(A.base_ring(), A.dimension())
the algebraic reals with an orthonormal basis::
sage: set_random_seed()
- sage: x = random_eja(AA).random_element()
+ sage: x = random_eja().random_element()
sage: A = x.subalgebra_generated_by(orthonormalize_basis=True)
sage: actual = A.one().operator().matrix()
sage: expected = matrix.identity(A.base_ring(), A.dimension())
"""
if self.dimension() == 0:
return self.zero()
- else:
- sa_one = self.superalgebra().one().to_vector()
- sa_coords = self.vector_space().coordinate_vector(sa_one)
- return self.from_vector(sa_coords)
+
+ return self(self.superalgebra().one())
+