]> gitweb.michael.orlitzky.com - sage.d.git/commitdiff
eja: move the element constructor into the parent algebra class.
authorMichael Orlitzky <michael@orlitzky.com>
Fri, 2 Aug 2019 23:18:11 +0000 (19:18 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Fri, 2 Aug 2019 23:18:11 +0000 (19:18 -0400)
Instead of using the element's __init__(), we're now using the
algebra's _element_constructor_() method that only gets called
after the parent tries to coerce the argument and fails. This
is somewhat cleaner because we don't have to handle the "usual"
case.

mjo/eja/eja_algebra.py
mjo/eja/eja_element.py

index c1d66ddaaea7f01f86b4f84065cfa22eb5be1590..d06efb59b14c1c7ecf1fb3fda375168ded981e6e 100644 (file)
@@ -61,6 +61,68 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule):
         self.print_options(bracket='')
 
 
+    def _element_constructor_(self, elt):
+        """
+        Construct an element of this algebra from its natural
+        representation.
+
+        This gets called only after the parent element _call_ method
+        fails to find a coercion for the argument.
+
+        SETUP::
+
+            sage: from mjo.eja.eja_algebra import (JordanSpinEJA,
+            ....:                                  RealCartesianProductEJA,
+            ....:                                  RealSymmetricEJA)
+
+        EXAMPLES:
+
+        The identity in `S^n` is converted to the identity in the EJA::
+
+            sage: J = RealSymmetricEJA(3)
+            sage: I = matrix.identity(QQ,3)
+            sage: J(I) == J.one()
+            True
+
+        This skew-symmetric matrix can't be represented in the EJA::
+
+            sage: J = RealSymmetricEJA(3)
+            sage: A = matrix(QQ,3, lambda i,j: i-j)
+            sage: J(A)
+            Traceback (most recent call last):
+            ...
+            ArithmeticError: vector is not in free module
+
+        TESTS:
+
+        Ensure that we can convert any element of the two non-matrix
+        simple algebras (whose natural representations are their usual
+        vector representations) back and forth faithfully::
+
+            sage: set_random_seed()
+            sage: J = RealCartesianProductEJA(5)
+            sage: x = J.random_element()
+            sage: J(x.to_vector().column()) == x
+            True
+            sage: J = JordanSpinEJA(5)
+            sage: x = J.random_element()
+            sage: J(x.to_vector().column()) == x
+            True
+
+        """
+        natural_basis = self.natural_basis()
+        if elt not in natural_basis[0].matrix_space():
+            raise ValueError("not a naturally-represented algebra element")
+
+        # Thanks for nothing! Matrix spaces aren't vector
+        # spaces in Sage, so we have to figure out its
+        # natural-basis coordinates ourselves.
+        V = VectorSpace(elt.base_ring(), elt.nrows()*elt.ncols())
+        W = V.span_of_basis( _mat2vec(s) for s in natural_basis )
+        coords =  W.coordinate_vector(_mat2vec(elt))
+        return self.from_vector(coords)
+
+
     def _repr_(self):
         """
         Return a string representation of ``self``.
index fb1983859c849c40ae5294f8e45e8d2f14a13b57..5b9142496f434be0a7c4dc014816302262eb33a5 100644 (file)
@@ -25,69 +25,6 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
                       dir(self.__class__) )
 
 
-    def __init__(self, A, elt):
-        """
-
-        SETUP::
-
-            sage: from mjo.eja.eja_algebra import (RealSymmetricEJA,
-            ....:                                  random_eja)
-
-        EXAMPLES:
-
-        The identity in `S^n` is converted to the identity in the EJA::
-
-            sage: J = RealSymmetricEJA(3)
-            sage: I = matrix.identity(QQ,3)
-            sage: J(I) == J.one()
-            True
-
-        This skew-symmetric matrix can't be represented in the EJA::
-
-            sage: J = RealSymmetricEJA(3)
-            sage: A = matrix(QQ,3, lambda i,j: i-j)
-            sage: J(A)
-            Traceback (most recent call last):
-            ...
-            ArithmeticError: vector is not in free module
-
-        TESTS:
-
-        Ensure that we can convert any element of the parent's
-        underlying vector space back into an algebra element whose
-        vector representation is what we started with::
-
-            sage: set_random_seed()
-            sage: J = random_eja()
-            sage: v = J.vector_space().random_element()
-            sage: J(v).to_vector() == v
-            True
-
-        """
-        # Goal: if we're given a matrix, and if it lives in our
-        # parent algebra's "natural ambient space," convert it
-        # into an algebra element.
-        #
-        # The catch is, we make a recursive call after converting
-        # the given matrix into a vector that lives in the algebra.
-        # This we need to try the parent class initializer first,
-        # to avoid recursing forever if we're given something that
-        # already fits into the algebra, but also happens to live
-        # in the parent's "natural ambient space" (this happens with
-        # vectors in R^n).
-        ifme = super(FiniteDimensionalEuclideanJordanAlgebraElement, self)
-        try:
-            ifme.__init__(A, elt)
-        except ValueError:
-            natural_basis = A.natural_basis()
-            if elt in natural_basis[0].matrix_space():
-                # Thanks for nothing! Matrix spaces aren't vector
-                # spaces in Sage, so we have to figure out its
-                # natural-basis coordinates ourselves.
-                V = VectorSpace(elt.base_ring(), elt.nrows()**2)
-                W = V.span( _mat2vec(s) for s in natural_basis )
-                coords =  W.coordinate_vector(_mat2vec(elt))
-                ifme.__init__(A, coords)
 
 
     def __pow__(self, n):