]> 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.
 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()
         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: 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
             sage: x = J.random_element()
             sage: J(x.to_vector().column()) == x
             True
@@ -658,6 +658,28 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule):
             return s.random_element()
 
 
             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.
     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()
     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()
         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()
         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()
             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...
 
     """
         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::
 
 
     SETUP::
 
-        sage: from mjo.eja.eja_algebra import _embed_complex_matrix
+        sage: from mjo.eja.eja_algebra import (_embed_complex_matrix,
+        ....:                                  ComplexHermitianEJA)
 
     EXAMPLES::
 
 
     EXAMPLES::
 
@@ -1069,7 +1089,8 @@ def _embed_complex_matrix(M):
     Embedding is a homomorphism (isomorphism, in fact)::
 
         sage: set_random_seed()
     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)
         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::
 
 
     SETUP::
 
-        sage: from mjo.eja.eja_algebra import _embed_quaternion_matrix
+        sage: from mjo.eja.eja_algebra import (_embed_quaternion_matrix,
+        ....:                                  QuaternionHermitianEJA)
 
     EXAMPLES::
 
 
     EXAMPLES::
 
@@ -1178,7 +1200,8 @@ def _embed_quaternion_matrix(M):
     Embedding is a homomorphism (isomorphism, in fact)::
 
         sage: set_random_seed()
     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)
         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()
     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
         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()
     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()
         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()
     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()
         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()
     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
 
         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()
     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
 
         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()
     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
         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()
     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()
         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()
     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()
         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()
     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
 
         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()
     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
 
         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()
     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
         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()
     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()
         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()
     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()
         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()
     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
 
         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()
     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
 
         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()
     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()
         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()
         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()
             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()
         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()
             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()
         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
             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
         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: 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():
             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()
         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()
             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()
         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: 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)])
             sage: x0 = x_vec[0]
             sage: x_bar = x_vec[1:]
             sage: A = matrix(QQ, 1, [x_vec.inner_product(x_vec)])