]> gitweb.michael.orlitzky.com - sage.d.git/commitdiff
eja: add random_instance() method for algebras.
authorMichael Orlitzky <michael@orlitzky.com>
Fri, 23 Aug 2019 17:19:27 +0000 (13:19 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Fri, 23 Aug 2019 17:19:27 +0000 (13:19 -0400)
mjo/eja/TODO
mjo/eja/eja_algebra.py
mjo/eja/eja_element.py

index da3e650bf04da611af5d5d54b4fad635b491da9d..f6d7743782613d241c50e05eee665d59278bd4b4 100644 (file)
@@ -15,3 +15,7 @@
 7. If we factor out a "matrix algebra" class, then it would make sense
    to replace the custom embedding/unembedding functions with static
    _real_embedding() and _real_unembedding() methods.
+
+8. Implement random_instance() for the main EJA class.
+
+9. Implement random_instance() for the subalgebra class.
index 1337cc14f8a82862cca9a3eb069a6e33b9c397f2..413128c843647e038e8869471daf29d84f1470f2 100644 (file)
@@ -123,11 +123,11 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule):
         vector representations) back and forth faithfully::
 
             sage: set_random_seed()
-            sage: J = RealCartesianProductEJA(5)
+            sage: J = RealCartesianProductEJA.random_instance()
             sage: x = J.random_element()
             sage: J(x.to_vector().column()) == x
             True
-            sage: J = JordanSpinEJA(5)
+            sage: J = JordanSpinEJA.random_instance()
             sage: x = J.random_element()
             sage: J(x.to_vector().column()) == x
             True
@@ -658,6 +658,28 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule):
             return s.random_element()
 
 
+    @classmethod
+    def random_instance(cls, field=QQ, **kwargs):
+        """
+        Return a random instance of this type of algebra.
+
+        In subclasses for algebras that we know how to construct, this
+        is a shortcut for constructing test cases and examples.
+        """
+        if cls is FiniteDimensionalEuclideanJordanAlgebra:
+            # Red flag! But in theory we could do this I guess. The
+            # only finite-dimensional exceptional EJA is the
+            # octononions. So, we could just create an EJA from an
+            # associative matrix algebra (generated by a subset of
+            # elements) with the symmetric product. Or, we could punt
+            # to random_eja() here, override it in our subclasses, and
+            # not worry about it.
+            raise NotImplementedError
+
+        n = ZZ.random_element(1, cls._max_test_case_size())
+        return cls(n, field, **kwargs)
+
+
     def rank(self):
         """
         Return the rank of this EJA.
@@ -781,8 +803,7 @@ class RealCartesianProductEJA(FiniteDimensionalEuclideanJordanAlgebra):
     Our inner product satisfies the Jordan axiom::
 
         sage: set_random_seed()
-        sage: n = ZZ.random_element(1,5)
-        sage: J = RealCartesianProductEJA(n)
+        sage: J = RealCartesianProductEJA.random_instance()
         sage: x = J.random_element()
         sage: y = J.random_element()
         sage: z = J.random_element()
@@ -812,8 +833,7 @@ class RealCartesianProductEJA(FiniteDimensionalEuclideanJordanAlgebra):
         over `R^n`::
 
             sage: set_random_seed()
-            sage: n = ZZ.random_element(1,5)
-            sage: J = RealCartesianProductEJA(n)
+            sage: J = RealCartesianProductEJA.random_instance()
             sage: x = J.random_element()
             sage: y = J.random_element()
             sage: X = x.natural_representation()
@@ -861,13 +881,12 @@ def random_eja():
         Euclidean Jordan algebra of dimension...
 
     """
-    constructor = choice([RealCartesianProductEJA,
-                          JordanSpinEJA,
-                          RealSymmetricEJA,
-                          ComplexHermitianEJA,
-                          QuaternionHermitianEJA])
-    n = ZZ.random_element(1, constructor._max_test_case_size())
-    return constructor(n, field=QQ)
+    classname = choice([RealCartesianProductEJA,
+                        JordanSpinEJA,
+                        RealSymmetricEJA,
+                        ComplexHermitianEJA,
+                        QuaternionHermitianEJA])
+    return classname.random_instance()
 
 
 
@@ -1047,7 +1066,8 @@ def _embed_complex_matrix(M):
 
     SETUP::
 
-        sage: from mjo.eja.eja_algebra import _embed_complex_matrix
+        sage: from mjo.eja.eja_algebra import (_embed_complex_matrix,
+        ....:                                  ComplexHermitianEJA)
 
     EXAMPLES::
 
@@ -1069,7 +1089,8 @@ def _embed_complex_matrix(M):
     Embedding is a homomorphism (isomorphism, in fact)::
 
         sage: set_random_seed()
-        sage: n = ZZ.random_element(5)
+        sage: n_max = ComplexHermitianEJA._max_test_case_size()
+        sage: n = ZZ.random_element(n_max)
         sage: F = QuadraticField(-1, 'i')
         sage: X = random_matrix(F, n)
         sage: Y = random_matrix(F, n)
@@ -1161,7 +1182,8 @@ def _embed_quaternion_matrix(M):
 
     SETUP::
 
-        sage: from mjo.eja.eja_algebra import _embed_quaternion_matrix
+        sage: from mjo.eja.eja_algebra import (_embed_quaternion_matrix,
+        ....:                                  QuaternionHermitianEJA)
 
     EXAMPLES::
 
@@ -1178,7 +1200,8 @@ def _embed_quaternion_matrix(M):
     Embedding is a homomorphism (isomorphism, in fact)::
 
         sage: set_random_seed()
-        sage: n = ZZ.random_element(5)
+        sage: n_max = QuaternionHermitianEJA._max_test_case_size()
+        sage: n = ZZ.random_element(n_max)
         sage: Q = QuaternionAlgebra(QQ,-1,-1)
         sage: X = random_matrix(Q, n)
         sage: Y = random_matrix(Q, n)
@@ -1308,7 +1331,8 @@ class RealSymmetricEJA(FiniteDimensionalEuclideanJordanAlgebra):
     The dimension of this algebra is `(n^2 + n) / 2`::
 
         sage: set_random_seed()
-        sage: n = ZZ.random_element(1,5)
+        sage: n_max = RealSymmetricEJA._max_test_case_size()
+        sage: n = ZZ.random_element(1, n_max)
         sage: J = RealSymmetricEJA(n)
         sage: J.dimension() == (n^2 + n)/2
         True
@@ -1316,8 +1340,7 @@ class RealSymmetricEJA(FiniteDimensionalEuclideanJordanAlgebra):
     The Jordan multiplication is what we think it is::
 
         sage: set_random_seed()
-        sage: n = ZZ.random_element(1,5)
-        sage: J = RealSymmetricEJA(n)
+        sage: J = RealSymmetricEJA.random_instance()
         sage: x = J.random_element()
         sage: y = J.random_element()
         sage: actual = (x*y).natural_representation()
@@ -1337,8 +1360,7 @@ class RealSymmetricEJA(FiniteDimensionalEuclideanJordanAlgebra):
     Our inner product satisfies the Jordan axiom::
 
         sage: set_random_seed()
-        sage: n = ZZ.random_element(1,5)
-        sage: J = RealSymmetricEJA(n)
+        sage: J = RealSymmetricEJA.random_instance()
         sage: x = J.random_element()
         sage: y = J.random_element()
         sage: z = J.random_element()
@@ -1349,8 +1371,7 @@ class RealSymmetricEJA(FiniteDimensionalEuclideanJordanAlgebra):
     product unless we specify otherwise::
 
         sage: set_random_seed()
-        sage: n = ZZ.random_element(1,5)
-        sage: J = RealSymmetricEJA(n)
+        sage: J = RealSymmetricEJA.random_instance()
         sage: all( b.norm() == 1 for b in J.gens() )
         True
 
@@ -1361,8 +1382,7 @@ class RealSymmetricEJA(FiniteDimensionalEuclideanJordanAlgebra):
     the operator is self-adjoint by the Jordan axiom::
 
         sage: set_random_seed()
-        sage: n = ZZ.random_element(1,5)
-        sage: x = RealSymmetricEJA(n).random_element()
+        sage: x = RealSymmetricEJA.random_instance().random_element()
         sage: x.operator().matrix().is_symmetric()
         True
 
@@ -1414,7 +1434,8 @@ class ComplexHermitianEJA(FiniteDimensionalEuclideanJordanAlgebra):
     The dimension of this algebra is `n^2`::
 
         sage: set_random_seed()
-        sage: n = ZZ.random_element(1,5)
+        sage: n_max = ComplexHermitianEJA._max_test_case_size()
+        sage: n = ZZ.random_element(1, n_max)
         sage: J = ComplexHermitianEJA(n)
         sage: J.dimension() == n^2
         True
@@ -1422,8 +1443,7 @@ class ComplexHermitianEJA(FiniteDimensionalEuclideanJordanAlgebra):
     The Jordan multiplication is what we think it is::
 
         sage: set_random_seed()
-        sage: n = ZZ.random_element(1,5)
-        sage: J = ComplexHermitianEJA(n)
+        sage: J = ComplexHermitianEJA.random_instance()
         sage: x = J.random_element()
         sage: y = J.random_element()
         sage: actual = (x*y).natural_representation()
@@ -1443,8 +1463,7 @@ class ComplexHermitianEJA(FiniteDimensionalEuclideanJordanAlgebra):
     Our inner product satisfies the Jordan axiom::
 
         sage: set_random_seed()
-        sage: n = ZZ.random_element(1,5)
-        sage: J = ComplexHermitianEJA(n)
+        sage: J = ComplexHermitianEJA.random_instance()
         sage: x = J.random_element()
         sage: y = J.random_element()
         sage: z = J.random_element()
@@ -1455,8 +1474,7 @@ class ComplexHermitianEJA(FiniteDimensionalEuclideanJordanAlgebra):
     product unless we specify otherwise::
 
         sage: set_random_seed()
-        sage: n = ZZ.random_element(1,4)
-        sage: J = ComplexHermitianEJA(n)
+        sage: J = ComplexHermitianEJA.random_instance()
         sage: all( b.norm() == 1 for b in J.gens() )
         True
 
@@ -1467,8 +1485,7 @@ class ComplexHermitianEJA(FiniteDimensionalEuclideanJordanAlgebra):
     the operator is self-adjoint by the Jordan axiom::
 
         sage: set_random_seed()
-        sage: n = ZZ.random_element(1,5)
-        sage: x = ComplexHermitianEJA(n).random_element()
+        sage: x = ComplexHermitianEJA.random_instance().random_element()
         sage: x.operator().matrix().is_symmetric()
         True
 
@@ -1529,7 +1546,8 @@ class QuaternionHermitianEJA(FiniteDimensionalEuclideanJordanAlgebra):
     The dimension of this algebra is `2*n^2 - n`::
 
         sage: set_random_seed()
-        sage: n = ZZ.random_element(1,4)
+        sage: n_max = QuaternionHermitianEJA._max_test_case_size()
+        sage: n = ZZ.random_element(1, n_max)
         sage: J = QuaternionHermitianEJA(n)
         sage: J.dimension() == 2*(n^2) - n
         True
@@ -1537,8 +1555,7 @@ class QuaternionHermitianEJA(FiniteDimensionalEuclideanJordanAlgebra):
     The Jordan multiplication is what we think it is::
 
         sage: set_random_seed()
-        sage: n = ZZ.random_element(1,4)
-        sage: J = QuaternionHermitianEJA(n)
+        sage: J = QuaternionHermitianEJA.random_instance()
         sage: x = J.random_element()
         sage: y = J.random_element()
         sage: actual = (x*y).natural_representation()
@@ -1558,8 +1575,7 @@ class QuaternionHermitianEJA(FiniteDimensionalEuclideanJordanAlgebra):
     Our inner product satisfies the Jordan axiom::
 
         sage: set_random_seed()
-        sage: n = ZZ.random_element(1,4)
-        sage: J = QuaternionHermitianEJA(n)
+        sage: J = QuaternionHermitianEJA.random_instance()
         sage: x = J.random_element()
         sage: y = J.random_element()
         sage: z = J.random_element()
@@ -1570,8 +1586,7 @@ class QuaternionHermitianEJA(FiniteDimensionalEuclideanJordanAlgebra):
     product unless we specify otherwise::
 
         sage: set_random_seed()
-        sage: n = ZZ.random_element(1,4)
-        sage: J = QuaternionHermitianEJA(n)
+        sage: J = QuaternionHermitianEJA.random_instance()
         sage: all( b.norm() == 1 for b in J.gens() )
         True
 
@@ -1582,8 +1597,7 @@ class QuaternionHermitianEJA(FiniteDimensionalEuclideanJordanAlgebra):
     the operator is self-adjoint by the Jordan axiom::
 
         sage: set_random_seed()
-        sage: n = ZZ.random_element(1,5)
-        sage: x = QuaternionHermitianEJA(n).random_element()
+        sage: x = QuaternionHermitianEJA.random_instance().random_element()
         sage: x.operator().matrix().is_symmetric()
         True
 
@@ -1670,8 +1684,7 @@ class JordanSpinEJA(FiniteDimensionalEuclideanJordanAlgebra):
     Our inner product satisfies the Jordan axiom::
 
         sage: set_random_seed()
-        sage: n = ZZ.random_element(1,5)
-        sage: J = JordanSpinEJA(n)
+        sage: J = JordanSpinEJA.random_instance()
         sage: x = J.random_element()
         sage: y = J.random_element()
         sage: z = J.random_element()
@@ -1716,8 +1729,7 @@ class JordanSpinEJA(FiniteDimensionalEuclideanJordanAlgebra):
         over `R^n`::
 
             sage: set_random_seed()
-            sage: n = ZZ.random_element(1,5)
-            sage: J = JordanSpinEJA(n)
+            sage: J = JordanSpinEJA.random_instance()
             sage: x = J.random_element()
             sage: y = J.random_element()
             sage: X = x.natural_representation()
index d787c5fc1366411fe6f6a3b549d8dbd285037d8b..f26766df80f65de8c31fe12ef3eab5d5bd727c7a 100644 (file)
@@ -424,8 +424,7 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
         Example 11.11::
 
             sage: set_random_seed()
-            sage: n = ZZ.random_element(1,10)
-            sage: J = JordanSpinEJA(n)
+            sage: J = JordanSpinEJA.random_instance()
             sage: x = J.random_element()
             sage: while not x.is_invertible():
             ....:     x = J.random_element()
@@ -651,8 +650,7 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
         aren't multiples of the identity are regular::
 
             sage: set_random_seed()
-            sage: n = ZZ.random_element(1,10)
-            sage: J = JordanSpinEJA(n)
+            sage: J = JordanSpinEJA.random_instance()
             sage: x = J.random_element()
             sage: x == x.coefficient(0)*J.one() or x.degree() == 2
             True
@@ -735,10 +733,12 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
         The minimal polynomial and the characteristic polynomial coincide
         and are known (see Alizadeh, Example 11.11) for all elements of
         the spin factor algebra that aren't scalar multiples of the
-        identity::
+        identity. We require the dimension of the algebra to be at least
+        two here so that said elements actually exist::
 
             sage: set_random_seed()
-            sage: n = ZZ.random_element(2,10)
+            sage: n_max = max(2, JordanSpinEJA._max_test_case_size())
+            sage: n = ZZ.random_element(2, n_max)
             sage: J = JordanSpinEJA(n)
             sage: y = J.random_element()
             sage: while y == y.coefficient(0)*J.one():
@@ -763,8 +763,9 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
         and in particular, a re-scaling of the basis::
 
             sage: set_random_seed()
-            sage: n = ZZ.random_element(1,5)
-            sage: J1 = RealSymmetricEJA(n)
+            sage: n_max = RealSymmetricEJA._max_test_case_size()
+            sage: n = ZZ.random_element(1, n_max)
+            sage: J1 = RealSymmetricEJA(n,QQ)
             sage: J2 = RealSymmetricEJA(n,QQ,False)
             sage: X = random_matrix(QQ,n)
             sage: X = X*X.transpose()
@@ -916,10 +917,9 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
         Alizadeh's Example 11.12::
 
             sage: set_random_seed()
-            sage: n = ZZ.random_element(1,10)
-            sage: J = JordanSpinEJA(n)
-            sage: x = J.random_element()
+            sage: x = JordanSpinEJA.random_instance().random_element()
             sage: x_vec = x.to_vector()
+            sage: n = x_vec.degree()
             sage: x0 = x_vec[0]
             sage: x_bar = x_vec[1:]
             sage: A = matrix(QQ, 1, [x_vec.inner_product(x_vec)])