]> gitweb.michael.orlitzky.com - sage.d.git/blobdiff - mjo/eja/eja_subalgebra.py
WIP: switch away from the algebra base class and use CombinatorialFreeModule.
[sage.d.git] / mjo / eja / eja_subalgebra.py
index 5ac0a77c7a9ab27929f4c3e1d73238d93e1ccd1b..a774b985ff54a2ceeb01468b5887849a22ef2d65 100644 (file)
 from sage.matrix.constructor import matrix
-from sage.structure.category_object import normalize_names
 
 from mjo.eja.eja_algebra import FiniteDimensionalEuclideanJordanAlgebra
 from mjo.eja.eja_element import FiniteDimensionalEuclideanJordanAlgebraElement
 
 
-class FiniteDimensionalEuclideanJordanElementSubalgebra(FiniteDimensionalEuclideanJordanAlgebra):
+class FiniteDimensionalEuclideanJordanElementSubalgebraElement(FiniteDimensionalEuclideanJordanAlgebraElement):
     """
-    The subalgebra of an EJA generated by a single element.
-
     SETUP::
 
-        sage: from mjo.eja.eja_algebra import FiniteDimensionalEuclideanJordanAlgebra
+        sage: from mjo.eja.eja_algebra import random_eja
+
+    TESTS::
+
+    The natural representation of an element in the subalgebra is
+    the same as its natural representation in the superalgebra::
+
+        sage: set_random_seed()
+        sage: A = random_eja().random_element().subalgebra_generated_by()
+        sage: y = A.random_element()
+        sage: actual = y.natural_representation()
+        sage: expected = y.superalgebra_element().natural_representation()
+        sage: actual == expected
+        True
+
+    """
+    def __init__(self, A, elt):
+        """
+        SETUP::
+
+            sage: from mjo.eja.eja_algebra import RealSymmetricEJA
+            sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanElementSubalgebra
+
+        EXAMPLES::
+
+            sage: J = RealSymmetricEJA(3)
+            sage: x = sum( i*J.gens()[i] for i in range(6) )
+            sage: K = FiniteDimensionalEuclideanJordanElementSubalgebra(x)
+            sage: [ K.element_class(K,x^k) for k in range(J.rank()) ]
+            [f0, f1, f2]
+
+        ::
+
+        """
+        if elt in A.superalgebra():
+            # Try to convert a parent algebra element into a
+            # subalgebra element...
+            try:
+                coords = A.vector_space().coordinate_vector(elt.to_vector())
+                elt = A.from_vector(coords).monomial_coefficients()
+            except AttributeError:
+                # Catches a missing method in elt.to_vector()
+                pass
+
+        s = super(FiniteDimensionalEuclideanJordanElementSubalgebraElement,
+                  self)
+
+        s.__init__(A, elt)
+
+
+    def superalgebra_element(self):
+        """
+        Return the object in our algebra's superalgebra that corresponds
+        to myself.
+
+        SETUP::
+
+            sage: from mjo.eja.eja_algebra import (RealSymmetricEJA,
+            ....:                                  random_eja)
 
-    TESTS:
+        EXAMPLES::
+
+            sage: J = RealSymmetricEJA(3)
+            sage: x = sum(J.gens())
+            sage: x
+            e0 + e1 + e2 + e3 + e4 + e5
+            sage: A = x.subalgebra_generated_by()
+            sage: A.element_class(A,x)
+            f1
+            sage: A.element_class(A,x).superalgebra_element()
+            e0 + e1 + e2 + e3 + e4 + e5
+
+        TESTS:
+
+        We can convert back and forth faithfully::
+
+            sage: set_random_seed()
+            sage: J = random_eja()
+            sage: x = J.random_element()
+            sage: A = x.subalgebra_generated_by()
+            sage: A.element_class(A,x).superalgebra_element() == x
+            True
+            sage: y = A.random_element()
+            sage: A.element_class(A,y.superalgebra_element()) == y
+            True
+
+        """
+        return self.parent().superalgebra().linear_combination(
+          zip(self.parent()._superalgebra_basis, self.to_vector()) )
 
-    Ensure that non-clashing names are chosen::
 
-        sage: m1 = matrix.identity(QQ,2)
-        sage: m2 = matrix(QQ, [[0,1],
-        ....:                  [1,0]])
-        sage: J = FiniteDimensionalEuclideanJordanAlgebra(QQ,
-        ....:                                             [m1,m2],
-        ....:                                             2,
-        ....:                                             names='f')
-        sage: J.variable_names()
-        ('f0', 'f1')
-        sage: A = sum(J.gens()).subalgebra_generated_by()
-        sage: A.variable_names()
-        ('g0', 'g1')
 
+
+class FiniteDimensionalEuclideanJordanElementSubalgebra(FiniteDimensionalEuclideanJordanAlgebra):
+    """
+    The subalgebra of an EJA generated by a single element.
     """
-    @staticmethod
-    def __classcall_private__(cls, elt):
+    def __init__(self, elt):
         superalgebra = elt.parent()
 
         # First compute the vector subspace spanned by the powers of
         # the given element.
         V = superalgebra.vector_space()
         superalgebra_basis = [superalgebra.one()]
-        basis_vectors = [superalgebra.one().vector()]
+        basis_vectors = [superalgebra.one().to_vector()]
         W = V.span_of_basis(basis_vectors)
         for exponent in range(1, V.dimension()):
             new_power = elt**exponent
-            basis_vectors.append( new_power.vector() )
+            basis_vectors.append( new_power.to_vector() )
             try:
                 W = V.span_of_basis(basis_vectors)
                 superalgebra_basis.append( new_power )
@@ -58,7 +131,7 @@ class FiniteDimensionalEuclideanJordanElementSubalgebra(FiniteDimensionalEuclide
         # Now figure out the entries of the right-multiplication
         # matrix for the successive basis elements b0, b1,... of
         # that subspace.
-        F = superalgebra.base_ring()
+        field = superalgebra.base_ring()
         mult_table = []
         for b_right in superalgebra_basis:
                 b_right_rows = []
@@ -73,15 +146,18 @@ class FiniteDimensionalEuclideanJordanElementSubalgebra(FiniteDimensionalEuclide
                     # Multiply in the original EJA, but then get the
                     # coordinates from the subalgebra in terms of its
                     # basis.
-                    this_row = W.coordinates((b_left*b_right).vector())
+                    this_row = W.coordinates((b_left*b_right).to_vector())
                     b_right_rows.append(this_row)
-                b_right_matrix = matrix(F, b_right_rows)
+                b_right_matrix = matrix(field, b_right_rows)
                 mult_table.append(b_right_matrix)
 
         for m in mult_table:
             m.set_immutable()
         mult_table = tuple(mult_table)
 
+        # TODO: We'll have to redo this and make it unique again...
+        prefix = 'f'
+
         # The rank is the highest possible degree of a minimal
         # polynomial, and is bounded above by the dimension. We know
         # in this case that there's an element whose minimal
@@ -90,60 +166,23 @@ class FiniteDimensionalEuclideanJordanElementSubalgebra(FiniteDimensionalEuclide
         # its rank too.
         rank = W.dimension()
 
-        # EJAs are power-associative, and this algebra is nothin but
-        # powers.
-        assume_associative=True
-
-        # Figure out a non-conflicting set of names to use.
-        valid_names = ['f','g','h','a','b','c','d']
-        name_idx = 0
-        names = normalize_names(W.dimension(), valid_names[0])
-        # This loops so long as the list of collisions is nonempty.
-        # Just crash if we run out of names without finding a set that
-        # don't conflict with the parent algebra.
-        while [y for y in names if y in superalgebra.variable_names()]:
-            name_idx += 1
-            names = normalize_names(W.dimension(), valid_names[name_idx])
-
-        cat = superalgebra.category().Associative()
+        category = superalgebra.category().Associative()
         natural_basis = tuple( b.natural_representation()
                                for b in superalgebra_basis )
 
-        fdeja = super(FiniteDimensionalEuclideanJordanElementSubalgebra, cls)
-        return fdeja.__classcall__(cls,
-                                   F,
-                                   mult_table,
-                                   rank,
-                                   superalgebra_basis,
-                                   W,
-                                   assume_associative=assume_associative,
-                                   names=names,
-                                   category=cat,
-                                   natural_basis=natural_basis)
-
-    def __init__(self,
-                 field,
-                 mult_table,
-                 rank,
-                 superalgebra_basis,
-                 vector_space,
-                 assume_associative=True,
-                 names='f',
-                 category=None,
-                 natural_basis=None):
-
-        self._superalgebra = superalgebra_basis[0].parent()
-        self._vector_space = vector_space
+        self._superalgebra = superalgebra
+        self._vector_space = W
         self._superalgebra_basis = superalgebra_basis
 
+
         fdeja = super(FiniteDimensionalEuclideanJordanElementSubalgebra, self)
-        fdeja.__init__(field,
-                       mult_table,
-                       rank,
-                       assume_associative=assume_associative,
-                       names=names,
-                       category=category,
-                       natural_basis=natural_basis)
+        return fdeja.__init__(field,
+                              mult_table,
+                              rank,
+                              prefix=prefix,
+                              category=category,
+                              natural_basis=natural_basis)
+
 
 
     def superalgebra(self):
@@ -171,106 +210,15 @@ class FiniteDimensionalEuclideanJordanElementSubalgebra(FiniteDimensionalEuclide
             [ 1  0  0  1  0  1]
             [ 0  1  2  3  4  5]
             [ 5 11 14 26 34 45]
-            sage: (x^0).vector()
+            sage: (x^0).to_vector()
             (1, 0, 0, 1, 0, 1)
-            sage: (x^1).vector()
+            sage: (x^1).to_vector()
             (0, 1, 2, 3, 4, 5)
-            sage: (x^2).vector()
+            sage: (x^2).to_vector()
             (5, 11, 14, 26, 34, 45)
 
         """
         return self._vector_space
 
 
-    class Element(FiniteDimensionalEuclideanJordanAlgebraElement):
-        """
-
-        SETUP::
-
-            sage: from mjo.eja.eja_algebra import random_eja
-
-        TESTS::
-
-        The natural representation of an element in the subalgebra is
-        the same as its natural representation in the superalgebra::
-
-            sage: set_random_seed()
-            sage: A = random_eja().random_element().subalgebra_generated_by()
-            sage: y = A.random_element()
-            sage: actual = y.natural_representation()
-            sage: expected = y.superalgebra_element().natural_representation()
-            sage: actual == expected
-            True
-
-        """
-        def __init__(self, A, elt=None):
-            """
-            SETUP::
-
-                sage: from mjo.eja.eja_algebra import RealSymmetricEJA
-                sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanElementSubalgebra
-
-            EXAMPLES::
-
-                sage: J = RealSymmetricEJA(3)
-                sage: x = sum( i*J.gens()[i] for i in range(6) )
-                sage: K = FiniteDimensionalEuclideanJordanElementSubalgebra(x)
-                sage: [ K(x^k) for k in range(J.rank()) ]
-                [f0, f1, f2]
-
-            ::
-
-            """
-            if elt in A.superalgebra():
-                    # Try to convert a parent algebra element into a
-                    # subalgebra element...
-                try:
-                    coords = A.vector_space().coordinates(elt.vector())
-                    elt = A(coords)
-                except AttributeError:
-                    # Catches a missing method in elt.vector()
-                    pass
-
-            FiniteDimensionalEuclideanJordanAlgebraElement.__init__(self,
-                                                                    A,
-                                                                    elt)
-
-        def superalgebra_element(self):
-            """
-            Return the object in our algebra's superalgebra that corresponds
-            to myself.
-
-            SETUP::
-
-                sage: from mjo.eja.eja_algebra import (RealSymmetricEJA,
-                ....:                                  random_eja)
-
-            EXAMPLES::
-
-                sage: J = RealSymmetricEJA(3)
-                sage: x = sum(J.gens())
-                sage: x
-                e0 + e1 + e2 + e3 + e4 + e5
-                sage: A = x.subalgebra_generated_by()
-                sage: A(x)
-                f1
-                sage: A(x).superalgebra_element()
-                e0 + e1 + e2 + e3 + e4 + e5
-
-            TESTS:
-
-            We can convert back and forth faithfully::
-
-                sage: set_random_seed()
-                sage: J = random_eja()
-                sage: x = J.random_element()
-                sage: A = x.subalgebra_generated_by()
-                sage: A(x).superalgebra_element() == x
-                True
-                sage: y = A.random_element()
-                sage: A(y.superalgebra_element()) == y
-                True
-
-            """
-            return self.parent().superalgebra().linear_combination(
-              zip(self.vector(), self.parent()._superalgebra_basis) )
+    Element = FiniteDimensionalEuclideanJordanElementSubalgebraElement