from sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra import FiniteDimensionalAlgebra
from sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra_element import FiniteDimensionalAlgebraElement
+from sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra_morphism import FiniteDimensionalAlgebraMorphism
+
+
+class FiniteDimensionalEuclideanJordanAlgebraMorphism(FiniteDimensionalAlgebraMorphism):
+ """
+ A very thin wrapper around FiniteDimensionalAlgebraMorphism that
+ does only two things:
+
+ 1. Avoids the ``unitary`` and ``check`` arguments to the constructor
+ that will always be ``False``. This is necessary because these
+ are homomorphisms with respect to ADDITION, but the SageMath
+ machinery wants to check that they're homomorphisms with respect
+ to (Jordan) MULTIPLICATION. That obviously doesn't work.
+
+ 2. Inputs and outputs the underlying matrix with respect to COLUMN
+ vectors, unlike the parent class.
+
+ If this seems a bit heavyweight, it is. I would have been happy to
+ use a the ring morphism that underlies the finite-dimensional
+ algebra morphism, but they don't seem to be callable on elements of
+ our EJA.
+ """
+ def __init__(self, parent, f):
+ FiniteDimensionalAlgebraMorphism.__init__(self,
+ parent,
+ f.transpose(),
+ unitary=False,
+ check=False)
+
+
+ def _repr_(self):
+ """
+ We override only the representation that is shown to the user,
+ because we want the matrix to be with respect to COLUMN vectors.
+
+ TESTS:
+
+ Ensure that we see the transpose of the underlying matrix object:
+
+ sage: J = RealSymmetricEJA(3)
+ sage: x = J.linear_combination(zip(range(len(J.gens())), J.gens()))
+ sage: L = x.operator()
+ sage: L
+ Morphism from Euclidean Jordan algebra of degree 6 over Rational
+ Field to Euclidean Jordan algebra of degree 6 over Rational Field
+ given by matrix
+ [ 0 1 2 0 0 0]
+ [1/2 3/2 2 1/2 1 0]
+ [ 1 2 5/2 0 1/2 1]
+ [ 0 1 0 3 4 0]
+ [ 0 1 1/2 2 4 2]
+ [ 0 0 2 0 4 5]
+ sage: L._matrix
+ [ 0 1/2 1 0 0 0]
+ [ 1 3/2 2 1 1 0]
+ [ 2 2 5/2 0 1/2 2]
+ [ 0 1/2 0 3 2 0]
+ [ 0 1 1/2 4 4 4]
+ [ 0 0 1 0 2 5]
+
+ """
+ return "Morphism from {} to {} given by matrix\n{}".format(
+ self.domain(), self.codomain(), self.matrix())
+
+ def matrix(self):
+ """
+ Return the matrix of this morphism with respect to a left-action
+ on column vectors.
+ """
+ return FiniteDimensionalAlgebraMorphism.matrix(self).transpose()
+
class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra):
@staticmethod
An element of a Euclidean Jordan algebra.
"""
+ def __dir__(self):
+ """
+ Oh man, I should not be doing this. This hides the "disabled"
+ methods ``left_matrix`` and ``matrix`` from introspection;
+ in particular it removes them from tab-completion.
+ """
+ return filter(lambda s: s not in ['left_matrix', 'matrix'],
+ dir(self.__class__) )
+
+
def __init__(self, A, elt=None):
"""
EXAMPLES:
return self.span_of_powers().dimension()
+ def left_matrix(self):
+ """
+ Our parent class defines ``left_matrix`` and ``matrix``
+ methods whose names are misleading. We don't want them.
+ """
+ raise NotImplementedError("use operator_matrix() instead")
+
+ matrix = left_matrix
+
+
def minimal_polynomial(self):
"""
Return the minimal polynomial of this element,
Return the matrix that represents left- (or right-)
multiplication by this element in the parent algebra.
- We have to override this because the superclass method
- returns a matrix that acts on row vectors (that is, on
- the right).
+ We implement this ourselves to work around the fact that
+ our parent class represents everything with row vectors.
EXAMPLES: