]> gitweb.michael.orlitzky.com - sage.d.git/blobdiff - mjo/eja/euclidean_jordan_algebra.py
eja: finally get scalar-morphism multiplication working with the new homsets.
[sage.d.git] / mjo / eja / euclidean_jordan_algebra.py
index 2b00302dc73461f089390a715bb1f12dc7aef6c1..cc356dc0ff7e6a94186d4d809ae937c01f0a3e6c 100644 (file)
@@ -5,13 +5,80 @@ are used in optimization, and have some additional nice methods beyond
 what can be supported in a general Jordan Algebra.
 """
 
-from sage.categories.magmatic_algebras import MagmaticAlgebras
+from sage.categories.finite_dimensional_algebras_with_basis import FiniteDimensionalAlgebrasWithBasis
+from sage.categories.morphism import SetMorphism
 from sage.structure.element import is_Matrix
 from sage.structure.category_object import normalize_names
 
 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
+from sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra_morphism import FiniteDimensionalAlgebraMorphism, FiniteDimensionalAlgebraHomset
+
+
+class FiniteDimensionalEuclideanJordanAlgebraHomset(FiniteDimensionalAlgebraHomset):
+
+    def has_coerce_map_from(self, S):
+        """
+        EXAMPLES::
+
+            sage: J = RealSymmetricEJA(2)
+            sage: H = J.Hom(J)
+            sage: H.has_coerce_map_from(QQ)
+            True
+
+        """
+        try:
+            # The Homset classes override has_coerce_map_from() with
+            # something that crashes when it's given e.g. QQ.
+            if S.is_subring(self.codomain().base_ring()):
+                return True
+        except:
+            pclass = super(FiniteDimensionalEuclideanJordanAlgebraHomset, self)
+            return pclass.has_coerce_map_from(S)
+
+
+    def _coerce_map_from_(self, S):
+        """
+        EXAMPLES::
+
+            sage: J = RealSymmetricEJA(2)
+            sage: H = J.Hom(J)
+            sage: H.coerce(2)
+            Morphism from Euclidean Jordan algebra of degree 3 over Rational
+            Field to Euclidean Jordan algebra of degree 3 over Rational Field
+            given by matrix
+            [2 0 0]
+            [0 2 0]
+            [0 0 2]
+
+        """
+        C = self.codomain()
+        R = C.base_ring()
+        if S.is_subring(R):
+            h = S.hom(self.codomain())
+            return SetMorphism(Hom(S,C), lambda x: h(x).operator())
+
+
+    def __call__(self, x):
+        """
+        EXAMPLES::
+
+            sage: J = RealSymmetricEJA(2)
+            sage: H = J.Hom(J)
+            sage: H(2)
+            Morphism from Euclidean Jordan algebra of degree 3 over Rational
+            Field to Euclidean Jordan algebra of degree 3 over Rational Field
+            given by matrix
+            [2 0 0]
+            [0 2 0]
+            [0 0 2]
+
+        """
+        if x in self.base_ring():
+            cols = self.domain().dimension()
+            rows = self.codomain().dimension()
+            x = x*identity_matrix(self.codomain().base_ring(), rows, cols)
+        return FiniteDimensionalEuclideanJordanAlgebraMorphism(self, x)
 
 
 class FiniteDimensionalEuclideanJordanAlgebraMorphism(FiniteDimensionalAlgebraMorphism):
@@ -38,8 +105,7 @@ class FiniteDimensionalEuclideanJordanAlgebraMorphism(FiniteDimensionalAlgebraMo
     algebra morphism, but they don't seem to be callable on elements of
     our EJA, and you can't add/multiply/etc. them.
     """
-
-    def __add__(self, other):
+    def _add_(self, other):
         """
         Add two EJA morphisms in the obvious way.
 
@@ -124,25 +190,48 @@ class FiniteDimensionalEuclideanJordanAlgebraMorphism(FiniteDimensionalAlgebraMo
         return FiniteDimensionalEuclideanJordanAlgebraMorphism(self.parent(),
                                                                 A.inverse())
 
-    def __mul__(self, other):
+    def _lmul_(self, right):
         """
         Compose two EJA morphisms using multiplicative notation.
 
         EXAMPLES::
 
-            sage: J = RealSymmetricEJA(3)
+            sage: J = RealSymmetricEJA(2)
             sage: x = J.zero()
             sage: y = J.one()
             sage: x.operator() * y.operator()
-            Morphism from Euclidean Jordan algebra of degree 6 over Rational
-            Field to Euclidean Jordan algebra of degree 6 over Rational Field
+            Morphism from Euclidean Jordan algebra of degree 3 over Rational
+            Field to Euclidean Jordan algebra of degree 3 over Rational Field
             given by matrix
-            [0 0 0 0 0 0]
-            [0 0 0 0 0 0]
-            [0 0 0 0 0 0]
-            [0 0 0 0 0 0]
-            [0 0 0 0 0 0]
-            [0 0 0 0 0 0]
+            [0 0 0]
+            [0 0 0]
+            [0 0 0]
+
+        ::
+
+            sage: J = RealSymmetricEJA(2)
+            sage: x = J.linear_combination(zip(range(len(J.gens())), J.gens()))
+            sage: x.operator()
+            Morphism from Euclidean Jordan algebra of degree 3 over Rational
+            Field to Euclidean Jordan algebra of degree 3 over Rational Field
+            given by matrix
+            [  0   1   0]
+            [1/2   1 1/2]
+            [  0   1   2]
+            sage: 2*x.operator()
+            Morphism from Euclidean Jordan algebra of degree 3 over Rational
+            Field to Euclidean Jordan algebra of degree 3 over Rational Field
+            given by matrix
+            [0 2 0]
+            [1 2 1]
+            [0 2 4]
+            sage: x.operator()*2
+            Morphism from Euclidean Jordan algebra of degree 3 over Rational
+            Field to Euclidean Jordan algebra of degree 3 over Rational Field
+            given by matrix
+            [0 2 0]
+            [1 2 1]
+            [0 2 4]
 
         TESTS::
 
@@ -154,15 +243,24 @@ class FiniteDimensionalEuclideanJordanAlgebraMorphism(FiniteDimensionalAlgebraMo
             True
 
         """
-        if not other.codomain() is self.domain():
+        try:
+            # I think the morphism classes break the coercion framework
+            # somewhere along the way, so we have to do this ourselves.
+            right = self.parent().coerce(right)
+        except:
+            pass
+
+        if not right.codomain() is self.domain():
             raise ValueError("(co)domains must agree for composition")
 
         return FiniteDimensionalEuclideanJordanAlgebraMorphism(
-                  self.parent(),
-                  self.matrix()*other.matrix() )
+                 self.parent(),
+                 self.matrix()*right.matrix() )
 
+    __mul__ = _lmul_
 
-    def __neg__(self):
+
+    def _neg_(self):
         """
         Negate this morphism.
 
@@ -282,7 +380,7 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra):
                 raise ValueError("input is not a multiplication table")
         mult_table = tuple(mult_table)
 
-        cat = MagmaticAlgebras(field).FiniteDimensional().WithBasis()
+        cat = FiniteDimensionalAlgebrasWithBasis(field)
         cat.or_subcategory(category)
         if assume_associative:
             cat = cat.Associative()
@@ -300,6 +398,15 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra):
                                  natural_basis=natural_basis)
 
 
+    def _Hom_(self, B, cat):
+        """
+        Construct a homset of ``self`` and ``B``.
+        """
+        return FiniteDimensionalEuclideanJordanAlgebraHomset(self,
+                                                             B,
+                                                             category=cat)
+
+
     def __init__(self,
                  field,
                  mult_table,