From: Michael Orlitzky Date: Fri, 23 Aug 2019 17:19:27 +0000 (-0400) Subject: eja: add random_instance() method for algebras. X-Git-Url: http://gitweb.michael.orlitzky.com/?p=sage.d.git;a=commitdiff_plain;h=16825a1ceedeb8363b025cda56dc9f65f639f726 eja: add random_instance() method for algebras. --- diff --git a/mjo/eja/TODO b/mjo/eja/TODO index da3e650..f6d7743 100644 --- a/mjo/eja/TODO +++ b/mjo/eja/TODO @@ -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. diff --git a/mjo/eja/eja_algebra.py b/mjo/eja/eja_algebra.py index 1337cc1..413128c 100644 --- a/mjo/eja/eja_algebra.py +++ b/mjo/eja/eja_algebra.py @@ -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() diff --git a/mjo/eja/eja_element.py b/mjo/eja/eja_element.py index d787c5f..f26766d 100644 --- a/mjo/eja/eja_element.py +++ b/mjo/eja/eja_element.py @@ -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)])