]> gitweb.michael.orlitzky.com - sage.d.git/commitdiff
eja: move the "field" argument to (usually passed through) kwargs.
authorMichael Orlitzky <michael@orlitzky.com>
Thu, 3 Dec 2020 04:37:01 +0000 (23:37 -0500)
committerMichael Orlitzky <michael@orlitzky.com>
Thu, 3 Dec 2020 04:37:01 +0000 (23:37 -0500)
mjo/eja/TODO
mjo/eja/eja_algebra.py
mjo/eja/eja_subalgebra.py

index c9c264c436b198e02c39f7792307572c5efead7d..08b8e81b22e8b5fde0a368e11840267edab4d250 100644 (file)
@@ -24,9 +24,5 @@ sage: a0 = (1/4)*X[4]**2*X[6]**2 - (1/2)*X[2]*X[5]*X[6]**2 - (1/2)*X[3]*X[4]*X[6
 7. Figure out if CombinatorialFreeModule's use of IndexedGenerators
    can be used to replace the matrix_basis().
 
-8. Move the "field" argument to a keyword after basis, jp, and ip.
-
 9. Add back the check_field=False and check_axioms=False parameters
-   for the EJAs we've constructed ourselves. We can probably pass
-   the value of "check_axioms" to <whatever>.span_of_basis() to skip
-   the linear-independence check.
+   for the EJAs we've constructed ourselves.
index 56d91bdef13bd76dc7e48f8f1237b02c18ef59a3..e32bc24cbb2741fca9de2285de703b7adf1497af 100644 (file)
@@ -119,11 +119,11 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule):
 
         The ``field`` we're given must be real with ``check_field=True``::
 
-            sage: JordanSpinEJA(2, QQbar)
+            sage: JordanSpinEJA(2, field=QQbar)
             Traceback (most recent call last):
             ...
             ValueError: scalar field is not real
-            sage: JordanSpinEJA(2, QQbar, check_field=False)
+            sage: JordanSpinEJA(2, field=QQbar, check_field=False)
             Euclidean Jordan algebra of dimension 2 over Algebraic Field
 
         The multiplication table must be square with ``check_axioms=True``::
@@ -293,6 +293,7 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule):
             sage: x = J.random_element()
             sage: J(x.to_vector().column()) == x
             True
+
         """
         msg = "not an element of this algebra"
         if elt == 0:
@@ -399,7 +400,7 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule):
 
         # Used to check whether or not something is zero in an inexact
         # ring. This number is sufficient to allow the construction of
-        # QuaternionHermitianEJA(2, RDF) with check_axioms=True.
+        # QuaternionHermitianEJA(2, field=RDF) with check_axioms=True.
         epsilon = 1e-16
 
         for i in range(self.dimension()):
@@ -496,7 +497,7 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule):
             sage: J = HadamardEJA(2)
             sage: J.coordinate_polynomial_ring()
             Multivariate Polynomial Ring in X1, X2...
-            sage: J = RealSymmetricEJA(3,QQ,orthonormalize=False)
+            sage: J = RealSymmetricEJA(3,field=QQ,orthonormalize=False)
             sage: J.coordinate_polynomial_ring()
             Multivariate Polynomial Ring in X1, X2, X3, X4, X5, X6...
 
@@ -1161,10 +1162,10 @@ class RationalBasisEuclideanJordanAlgebra(FiniteDimensionalEuclideanJordanAlgebr
 
     """
     def __init__(self,
-                 field,
                  basis,
                  jordan_product,
                  inner_product,
+                 field=AA,
                  orthonormalize=True,
                  prefix='e',
                  category=None,
@@ -1177,6 +1178,10 @@ class RationalBasisEuclideanJordanAlgebra(FiniteDimensionalEuclideanJordanAlgebr
             if not all( all(b_i in QQ for b_i in b.list()) for b in basis ):
                 raise TypeError("basis not rational")
 
+        # Temporary(?) hack to ensure that the matrix and vector bases
+        # are over the same ring.
+        basis = tuple( b.change_ring(field) for b in basis )
+
         n = len(basis)
         vector_basis = basis
 
@@ -1215,10 +1220,10 @@ class RationalBasisEuclideanJordanAlgebra(FiniteDimensionalEuclideanJordanAlgebr
                 # because they are necessarily defined with respect to
                 # ambient coordinates and not any particular basis.
                 self._rational_algebra = RationalBasisEuclideanJordanAlgebra(
-                                          QQ,
                                           basis,
                                           jordan_product,
                                           inner_product,
+                                          field=QQ,
                                           orthonormalize=False,
                                           prefix=prefix,
                                           category=category,
@@ -1539,9 +1544,9 @@ class RealSymmetricEJA(ConcreteEuclideanJordanAlgebra,
 
     In theory, our "field" can be any subfield of the reals::
 
-        sage: RealSymmetricEJA(2, RDF)
+        sage: RealSymmetricEJA(2, field=RDF)
         Euclidean Jordan algebra of dimension 3 over Real Double Field
-        sage: RealSymmetricEJA(2, RR)
+        sage: RealSymmetricEJA(2, field=RR)
         Euclidean Jordan algebra of dimension 3 over Real Field with
         53 bits of precision
 
@@ -1582,7 +1587,7 @@ class RealSymmetricEJA(ConcreteEuclideanJordanAlgebra,
 
     """
     @classmethod
-    def _denormalized_basis(cls, n, field):
+    def _denormalized_basis(cls, n):
         """
         Return a basis for the space of real symmetric n-by-n matrices.
 
@@ -1594,7 +1599,7 @@ class RealSymmetricEJA(ConcreteEuclideanJordanAlgebra,
 
             sage: set_random_seed()
             sage: n = ZZ.random_element(1,5)
-            sage: B = RealSymmetricEJA._denormalized_basis(n,QQ)
+            sage: B = RealSymmetricEJA._denormalized_basis(n)
             sage: all( M.is_symmetric() for M in  B)
             True
 
@@ -1604,7 +1609,7 @@ class RealSymmetricEJA(ConcreteEuclideanJordanAlgebra,
         S = []
         for i in range(n):
             for j in range(i+1):
-                Eij = matrix(field, n, lambda k,l: k==i and l==j)
+                Eij = matrix(ZZ, n, lambda k,l: k==i and l==j)
                 if i == j:
                     Sij = Eij
                 else:
@@ -1618,22 +1623,20 @@ class RealSymmetricEJA(ConcreteEuclideanJordanAlgebra,
         return 4 # Dimension 10
 
     @classmethod
-    def random_instance(cls, field=AA, **kwargs):
+    def random_instance(cls, **kwargs):
         """
         Return a random instance of this type of algebra.
         """
         n = ZZ.random_element(cls._max_random_instance_size() + 1)
-        return cls(n, field, **kwargs)
+        return cls(n, **kwargs)
 
-    def __init__(self, n, field=AA, **kwargs):
-        basis = self._denormalized_basis(n, field)
-        super(RealSymmetricEJA, self).__init__(field,
-                                               basis,
+    def __init__(self, n, **kwargs):
+        super(RealSymmetricEJA, self).__init__(self._denormalized_basis(n),
                                                self.jordan_product,
                                                self.trace_inner_product,
                                                **kwargs)
         self.rank.set_cache(n)
-        self.one.set_cache(self(matrix.identity(field,n)))
+        self.one.set_cache(self(matrix.identity(ZZ,n)))
 
 
 class ComplexMatrixEuclideanJordanAlgebra(MatrixEuclideanJordanAlgebra):
@@ -1810,9 +1813,9 @@ class ComplexHermitianEJA(ConcreteEuclideanJordanAlgebra,
 
     In theory, our "field" can be any subfield of the reals::
 
-        sage: ComplexHermitianEJA(2, RDF)
+        sage: ComplexHermitianEJA(2, field=RDF)
         Euclidean Jordan algebra of dimension 4 over Real Double Field
-        sage: ComplexHermitianEJA(2, RR)
+        sage: ComplexHermitianEJA(2, field=RR)
         Euclidean Jordan algebra of dimension 4 over Real Field with
         53 bits of precision
 
@@ -1854,7 +1857,7 @@ class ComplexHermitianEJA(ConcreteEuclideanJordanAlgebra,
     """
 
     @classmethod
-    def _denormalized_basis(cls, n, field):
+    def _denormalized_basis(cls, n):
         """
         Returns a basis for the space of complex Hermitian n-by-n matrices.
 
@@ -1873,15 +1876,16 @@ class ComplexHermitianEJA(ConcreteEuclideanJordanAlgebra,
             sage: set_random_seed()
             sage: n = ZZ.random_element(1,5)
             sage: field = QuadraticField(2, 'sqrt2')
-            sage: B = ComplexHermitianEJA._denormalized_basis(n, field)
+            sage: B = ComplexHermitianEJA._denormalized_basis(n)
             sage: all( M.is_symmetric() for M in  B)
             True
 
         """
+        field = ZZ
         R = PolynomialRing(field, 'z')
         z = R.gen()
         F = field.extension(z**2 + 1, 'I')
-        I = F.gen()
+        I = F.gen(1)
 
         # This is like the symmetric case, but we need to be careful:
         #
@@ -1907,13 +1911,11 @@ class ComplexHermitianEJA(ConcreteEuclideanJordanAlgebra,
         return tuple( s.change_ring(field) for s in S )
 
 
-    def __init__(self, n, field=AA, **kwargs):
-        basis = self._denormalized_basis(n,field)
-        super(ComplexHermitianEJA, self).__init__(field,
-                                               basis,
-                                               self.jordan_product,
-                                               self.trace_inner_product,
-                                               **kwargs)
+    def __init__(self, n, **kwargs):
+        super(ComplexHermitianEJA, self).__init__(self._denormalized_basis(n),
+                                                  self.jordan_product,
+                                                  self.trace_inner_product,
+                                                  **kwargs)
         self.rank.set_cache(n)
         # TODO: pre-cache the identity!
 
@@ -1922,12 +1924,12 @@ class ComplexHermitianEJA(ConcreteEuclideanJordanAlgebra,
         return 3 # Dimension 9
 
     @classmethod
-    def random_instance(cls, field=AA, **kwargs):
+    def random_instance(cls, **kwargs):
         """
         Return a random instance of this type of algebra.
         """
         n = ZZ.random_element(cls._max_random_instance_size() + 1)
-        return cls(n, field, **kwargs)
+        return cls(n, **kwargs)
 
 class QuaternionMatrixEuclideanJordanAlgebra(MatrixEuclideanJordanAlgebra):
     @staticmethod
@@ -2107,9 +2109,9 @@ class QuaternionHermitianEJA(ConcreteEuclideanJordanAlgebra,
 
     In theory, our "field" can be any subfield of the reals::
 
-        sage: QuaternionHermitianEJA(2, RDF)
+        sage: QuaternionHermitianEJA(2, field=RDF)
         Euclidean Jordan algebra of dimension 6 over Real Double Field
-        sage: QuaternionHermitianEJA(2, RR)
+        sage: QuaternionHermitianEJA(2, field=RR)
         Euclidean Jordan algebra of dimension 6 over Real Field with
         53 bits of precision
 
@@ -2150,7 +2152,7 @@ class QuaternionHermitianEJA(ConcreteEuclideanJordanAlgebra,
 
     """
     @classmethod
-    def _denormalized_basis(cls, n, field):
+    def _denormalized_basis(cls, n):
         """
         Returns a basis for the space of quaternion Hermitian n-by-n matrices.
 
@@ -2168,11 +2170,12 @@ class QuaternionHermitianEJA(ConcreteEuclideanJordanAlgebra,
 
             sage: set_random_seed()
             sage: n = ZZ.random_element(1,5)
-            sage: B = QuaternionHermitianEJA._denormalized_basis(n,QQ)
+            sage: B = QuaternionHermitianEJA._denormalized_basis(n)
             sage: all( M.is_symmetric() for M in B )
             True
 
         """
+        field = ZZ
         Q = QuaternionAlgebra(QQ,-1,-1)
         I,J,K = Q.gens()
 
@@ -2205,10 +2208,8 @@ class QuaternionHermitianEJA(ConcreteEuclideanJordanAlgebra,
         return tuple( s.change_ring(field) for s in S )
 
 
-    def __init__(self, n, field=AA, **kwargs):
-        basis = self._denormalized_basis(n,field)
-        super(QuaternionHermitianEJA, self).__init__(field,
-                                                     basis,
+    def __init__(self, n, **kwargs):
+        super(QuaternionHermitianEJA, self).__init__(self._denormalized_basis(n),
                                                      self.jordan_product,
                                                      self.trace_inner_product,
                                                      **kwargs)
@@ -2223,12 +2224,12 @@ class QuaternionHermitianEJA(ConcreteEuclideanJordanAlgebra,
         return 2 # Dimension 6
 
     @classmethod
-    def random_instance(cls, field=AA, **kwargs):
+    def random_instance(cls, **kwargs):
         """
         Return a random instance of this type of algebra.
         """
         n = ZZ.random_element(cls._max_random_instance_size() + 1)
-        return cls(n, field, **kwargs)
+        return cls(n, **kwargs)
 
 
 class HadamardEJA(ConcreteEuclideanJordanAlgebra):
@@ -2271,24 +2272,24 @@ class HadamardEJA(ConcreteEuclideanJordanAlgebra):
         (r0, r1, r2)
 
     """
-    def __init__(self, n, field=AA, **kwargs):
-        V = VectorSpace(field, n)
-        basis = V.basis()
-
+    def __init__(self, n, **kwargs):
         def jordan_product(x,y):
-            return V([ xi*yi for (xi,yi) in zip(x,y) ])
+            P = x.parent()
+            return P(tuple( xi*yi for (xi,yi) in zip(x,y) ))
         def inner_product(x,y):
             return x.inner_product(y)
 
         # Don't orthonormalize because our basis is already
-        # orthonormal with respect to our inner-product. But also
-        # don't pass check_field=False here, because the user can pass
-        # in a field!
-        super(HadamardEJA, self).__init__(field,
-                                          basis,
+        # orthonormal with respect to our inner-product.
+        if not 'orthonormalize' in kwargs:
+            kwargs['orthonormalize'] = False
+
+        # But also don't pass check_field=False here, because the user
+        # can pass in a field!
+        standard_basis = FreeModule(ZZ, n).basis()
+        super(HadamardEJA, self).__init__(standard_basis,
                                           jordan_product,
                                           inner_product,
-                                          orthonormalize=False,
                                           check_axioms=False,
                                           **kwargs)
         self.rank.set_cache(n)
@@ -2306,12 +2307,12 @@ class HadamardEJA(ConcreteEuclideanJordanAlgebra):
         return 5
 
     @classmethod
-    def random_instance(cls, field=AA, **kwargs):
+    def random_instance(cls, **kwargs):
         """
         Return a random instance of this type of algebra.
         """
         n = ZZ.random_element(cls._max_random_instance_size() + 1)
-        return cls(n, field, **kwargs)
+        return cls(n, **kwargs)
 
 
 class BilinearFormEJA(ConcreteEuclideanJordanAlgebra):
@@ -2395,27 +2396,26 @@ class BilinearFormEJA(ConcreteEuclideanJordanAlgebra):
         sage: actual == expected
         True
     """
-    def __init__(self, B, field=AA, **kwargs):
+    def __init__(self, B, **kwargs):
         if not B.is_positive_definite():
             raise ValueError("bilinear form is not positive-definite")
 
-        n = B.nrows()
-        V = VectorSpace(field, n)
-
         def inner_product(x,y):
             return (B*x).inner_product(y)
 
         def jordan_product(x,y):
+            P = x.parent()
             x0 = x[0]
             xbar = x[1:]
             y0 = y[0]
             ybar = y[1:]
             z0 = inner_product(x,y)
             zbar = y0*xbar + x0*ybar
-            return V([z0] + zbar.list())
+            return P((z0,) + tuple(zbar))
 
-        super(BilinearFormEJA, self).__init__(field,
-                                              V.basis(),
+        n = B.nrows()
+        standard_basis = FreeModule(ZZ, n).basis()
+        super(BilinearFormEJA, self).__init__(standard_basis,
                                               jordan_product,
                                               inner_product,
                                               **kwargs)
@@ -2438,28 +2438,28 @@ class BilinearFormEJA(ConcreteEuclideanJordanAlgebra):
         return 5
 
     @classmethod
-    def random_instance(cls, field=AA, **kwargs):
+    def random_instance(cls, **kwargs):
         """
         Return a random instance of this algebra.
         """
         n = ZZ.random_element(cls._max_random_instance_size() + 1)
         if n.is_zero():
-            B = matrix.identity(field, n)
-            return cls(B, field, **kwargs)
+            B = matrix.identity(ZZ, n)
+            return cls(B, **kwargs)
 
-        B11 = matrix.identity(field,1)
-        M = matrix.random(field, n-1)
-        I = matrix.identity(field, n-1)
-        alpha = field.zero()
+        B11 = matrix.identity(ZZ, 1)
+        M = matrix.random(ZZ, n-1)
+        I = matrix.identity(ZZ, n-1)
+        alpha = ZZ.zero()
         while alpha.is_zero():
-            alpha = field.random_element().abs()
+            alpha = ZZ.random_element().abs()
         B22 = M.transpose()*M + alpha*I
 
         from sage.matrix.special import block_matrix
         B = block_matrix(2,2, [ [B11,   ZZ(0) ],
                                 [ZZ(0), B22 ] ])
 
-        return cls(B, field, **kwargs)
+        return cls(B, **kwargs)
 
 
 class JordanSpinEJA(BilinearFormEJA):
@@ -2512,18 +2512,19 @@ class JordanSpinEJA(BilinearFormEJA):
             True
 
     """
-    def __init__(self, n, field=AA, **kwargs):
+    def __init__(self, n, **kwargs):
         # This is a special case of the BilinearFormEJA with the
         # identity matrix as its bilinear form.
-        B = matrix.identity(field, n)
+        B = matrix.identity(ZZ, n)
 
         # Don't orthonormalize because our basis is already
-        # orthonormal with respect to our inner-product. But
-        # also don't pass check_field=False here, because the
-        # user can pass in a field!
+        # orthonormal with respect to our inner-product.
+        if not 'orthonormalize' in kwargs:
+            kwargs['orthonormalize'] = False
+
+        # But also don't pass check_field=False here, because the user
+        # can pass in a field!
         super(JordanSpinEJA, self).__init__(B,
-                                            field,
-                                            orthonormalize=False,
                                             check_axioms=False,
                                             **kwargs)
 
@@ -2535,14 +2536,14 @@ class JordanSpinEJA(BilinearFormEJA):
         return 5
 
     @classmethod
-    def random_instance(cls, field=AA, **kwargs):
+    def random_instance(cls, **kwargs):
         """
         Return a random instance of this type of algebra.
 
         Needed here to override the implementation for ``BilinearFormEJA``.
         """
         n = ZZ.random_element(cls._max_random_instance_size() + 1)
-        return cls(n, field, **kwargs)
+        return cls(n, **kwargs)
 
 
 class TrivialEJA(ConcreteEuclideanJordanAlgebra):
@@ -2574,12 +2575,11 @@ class TrivialEJA(ConcreteEuclideanJordanAlgebra):
         0
 
     """
-    def __init__(self, field=AA, **kwargs):
+    def __init__(self, **kwargs):
         jordan_product = lambda x,y: x
-        inner_product = lambda x,y: field(0)
+        inner_product = lambda x,y: 0
         basis = ()
-        super(TrivialEJA, self).__init__(field,
-                                         basis,
+        super(TrivialEJA, self).__init__(basis,
                                          jordan_product,
                                          inner_product,
                                          **kwargs)
@@ -2589,10 +2589,10 @@ class TrivialEJA(ConcreteEuclideanJordanAlgebra):
         self.one.set_cache( self.zero() )
 
     @classmethod
-    def random_instance(cls, field=AA, **kwargs):
+    def random_instance(cls, **kwargs):
         # We don't take a "size" argument so the superclass method is
         # inappropriate for us.
-        return cls(field, **kwargs)
+        return cls(**kwargs)
 
 class DirectSumEJA(FiniteDimensionalEuclideanJordanAlgebra):
     r"""
@@ -2625,8 +2625,8 @@ class DirectSumEJA(FiniteDimensionalEuclideanJordanAlgebra):
     have the same base ring; an error is raised otherwise::
 
         sage: set_random_seed()
-        sage: J1 = random_eja(AA)
-        sage: J2 = random_eja(QQ,orthonormalize=False)
+        sage: J1 = random_eja(field=AA)
+        sage: J2 = random_eja(field=QQ,orthonormalize=False)
         sage: J = DirectSumEJA(J1,J2)
         Traceback (most recent call last):
         ...
@@ -2679,8 +2679,8 @@ class DirectSumEJA(FiniteDimensionalEuclideanJordanAlgebra):
 
         EXAMPLES::
 
-            sage: J1 = HadamardEJA(2,QQ)
-            sage: J2 = JordanSpinEJA(3,QQ)
+            sage: J1 = HadamardEJA(2, field=QQ)
+            sage: J2 = JordanSpinEJA(3, field=QQ)
             sage: J = DirectSumEJA(J1,J2)
             sage: J.factors()
             (Euclidean Jordan algebra of dimension 2 over Rational Field,
@@ -2809,8 +2809,8 @@ class DirectSumEJA(FiniteDimensionalEuclideanJordanAlgebra):
 
         EXAMPLE::
 
-            sage: J1 = HadamardEJA(3,QQ)
-            sage: J2 = QuaternionHermitianEJA(2,QQ,orthonormalize=False)
+            sage: J1 = HadamardEJA(3,field=QQ)
+            sage: J2 = QuaternionHermitianEJA(2,field=QQ,orthonormalize=False)
             sage: J = DirectSumEJA(J1,J2)
             sage: x1 = J1.one()
             sage: x2 = x1
index 8c0f9092f040e659b5e550cfa90d4f27f4487ad4..e7308ea34b9a36aef09a84069a1289e072487ec7 100644 (file)
@@ -27,7 +27,7 @@ class FiniteDimensionalEuclideanJordanSubalgebraElement(FiniteDimensionalEuclide
     our basis::
 
         sage: set_random_seed()
-        sage: x = random_eja(AA).random_element()
+        sage: x = random_eja(field=AA).random_element()
         sage: A = x.subalgebra_generated_by(orthonormalize_basis=True)
         sage: y = A.random_element()
         sage: y.operator()(A.one()) == y