X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=mjo%2Feja%2Feja_algebra.py;h=f687e46215a1f1aefb5a5955acffd4fc4c6be301;hb=a167bfc4ffb18296eb75d505112a6c1dd4c7f9ae;hp=88ceef48a370e21ea10b7afca34057c048579f2d;hpb=b0915886d2503c46bce66d92e79f49687c5c4466;p=sage.d.git diff --git a/mjo/eja/eja_algebra.py b/mjo/eja/eja_algebra.py index 88ceef4..f687e46 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 @@ -155,6 +155,26 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule): return self.from_vector(coords) + @staticmethod + def _max_test_case_size(): + """ + Return an integer "size" that is an upper bound on the size of + this algebra when it is used in a random test + case. Unfortunately, the term "size" is quite vague -- when + dealing with `R^n` under either the Hadamard or Jordan spin + product, the "size" refers to the dimension `n`. When dealing + with a matrix algebra (real symmetric or complex/quaternion + Hermitian), it refers to the size of the matrix, which is + far less than the dimension of the underlying vector space. + + We default to five in this class, which is safe in `R^n`. The + matrix algebra subclasses (or any class where the "size" is + interpreted to be far less than the dimension) should override + with a smaller number. + """ + return 5 + + def _repr_(self): """ Return a string representation of ``self``. @@ -638,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. @@ -761,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() @@ -792,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() @@ -841,18 +881,12 @@ def random_eja(): Euclidean Jordan algebra of dimension... """ - - # The max_n component lets us choose different upper bounds on the - # value "n" that gets passed to the constructor. This is needed - # because e.g. R^{10} is reasonable to test, while the Hermitian - # 10-by-10 quaternion matrices are not. - (constructor, max_n) = choice([(RealCartesianProductEJA, 6), - (JordanSpinEJA, 6), - (RealSymmetricEJA, 5), - (ComplexHermitianEJA, 4), - (QuaternionHermitianEJA, 3)]) - n = ZZ.random_element(1, max_n) - return constructor(n, field=QQ) + classname = choice([RealCartesianProductEJA, + JordanSpinEJA, + RealSymmetricEJA, + ComplexHermitianEJA, + QuaternionHermitianEJA]) + return classname.random_instance() @@ -1032,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:: @@ -1054,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) @@ -1146,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:: @@ -1163,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) @@ -1258,14 +1296,6 @@ def _unembed_quaternion_matrix(M): return matrix(Q, n/4, elements) -# The inner product used for the real symmetric simple EJA. -# We keep it as a separate function because e.g. the complex -# algebra uses the same inner product, except divided by 2. -def _matrix_ip(X,Y): - X_mat = X.natural_representation() - Y_mat = Y.natural_representation() - return (X_mat*Y_mat).trace() - class RealSymmetricEJA(FiniteDimensionalEuclideanJordanAlgebra): """ @@ -1293,7 +1323,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 @@ -1301,8 +1332,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() @@ -1322,8 +1352,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() @@ -1334,8 +1363,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 @@ -1346,8 +1374,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 @@ -1378,6 +1405,9 @@ class RealSymmetricEJA(FiniteDimensionalEuclideanJordanAlgebra): natural_basis=S, **kwargs) + @staticmethod + def _max_test_case_size(): + return 5 class ComplexHermitianEJA(FiniteDimensionalEuclideanJordanAlgebra): @@ -1396,7 +1426,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 @@ -1404,8 +1435,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() @@ -1425,8 +1455,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() @@ -1437,8 +1466,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 @@ -1449,8 +1477,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 @@ -1482,6 +1509,10 @@ class ComplexHermitianEJA(FiniteDimensionalEuclideanJordanAlgebra): **kwargs) + @staticmethod + def _max_test_case_size(): + return 4 + @staticmethod def natural_inner_product(X,Y): Xu = _unembed_complex_matrix(X) @@ -1507,7 +1538,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 @@ -1515,8 +1547,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() @@ -1536,8 +1567,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() @@ -1548,8 +1578,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 @@ -1560,8 +1589,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 @@ -1592,6 +1620,10 @@ class QuaternionHermitianEJA(FiniteDimensionalEuclideanJordanAlgebra): natural_basis=S, **kwargs) + @staticmethod + def _max_test_case_size(): + return 3 + @staticmethod def natural_inner_product(X,Y): Xu = _unembed_quaternion_matrix(X) @@ -1644,8 +1676,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() @@ -1690,8 +1721,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()