X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=mjo%2Feja%2Feja_algebra.py;h=7089c50ab81c222b5be8ddca3c6667da9699cf98;hb=89868b0bee2843c64160f4cd67aa333be0a2e5d1;hp=3f91ee3ae72c6281c9238804f146944d2c431f1e;hpb=fd6618bf82173916b9a35bb3f114d31b4604f456;p=sage.d.git diff --git a/mjo/eja/eja_algebra.py b/mjo/eja/eja_algebra.py index 3f91ee3..7089c50 100644 --- a/mjo/eja/eja_algebra.py +++ b/mjo/eja/eja_algebra.py @@ -217,7 +217,7 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule): return self.from_vector(coords) @staticmethod - def _max_test_case_size(): + def _max_random_instance_size(): """ Return an integer "size" that is an upper bound on the size of this algebra when it is used in a random test @@ -233,7 +233,7 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule): interpreted to be far less than the dimension) should override with a smaller number. """ - return 5 + raise NotImplementedError def _repr_(self): """ @@ -839,12 +839,7 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule): Beware, this will crash for "most instances" because the constructor below looks wrong. """ - if cls is TrivialEJA: - # The TrivialEJA class doesn't take an "n" argument because - # there's only one. - return cls(field) - - n = ZZ.random_element(cls._max_test_case_size() + 1) + n = ZZ.random_element(cls._max_random_instance_size() + 1) return cls(n, field, **kwargs) @cached_method @@ -1094,7 +1089,7 @@ class RationalBasisEuclideanJordanAlgebra(FiniteDimensionalEuclideanJordanAlgebr class MatrixEuclideanJordanAlgebra(FiniteDimensionalEuclideanJordanAlgebra): @staticmethod - def _max_test_case_size(): + def _max_random_instance_size(): # Play it safe, since this will be squared and the underlying # field can have dimension 4 (quaternions) too. return 2 @@ -1306,7 +1301,7 @@ class RealSymmetricEJA(RealMatrixEuclideanJordanAlgebra): The dimension of this algebra is `(n^2 + n) / 2`:: sage: set_random_seed() - sage: n_max = RealSymmetricEJA._max_test_case_size() + sage: n_max = RealSymmetricEJA._max_random_instance_size() sage: n = ZZ.random_element(1, n_max) sage: J = RealSymmetricEJA(n) sage: J.dimension() == (n^2 + n)/2 @@ -1389,7 +1384,7 @@ class RealSymmetricEJA(RealMatrixEuclideanJordanAlgebra): @staticmethod - def _max_test_case_size(): + def _max_random_instance_size(): return 4 # Dimension 10 @@ -1435,7 +1430,7 @@ class ComplexMatrixEuclideanJordanAlgebra(MatrixEuclideanJordanAlgebra): Embedding is a homomorphism (isomorphism, in fact):: sage: set_random_seed() - sage: n_max = ComplexMatrixEuclideanJordanAlgebra._max_test_case_size() + sage: n_max = ComplexMatrixEuclideanJordanAlgebra._max_random_instance_size() sage: n = ZZ.random_element(n_max) sage: F = QuadraticField(-1, 'I') sage: X = random_matrix(F, n) @@ -1587,7 +1582,7 @@ class ComplexHermitianEJA(ComplexMatrixEuclideanJordanAlgebra): The dimension of this algebra is `n^2`:: sage: set_random_seed() - sage: n_max = ComplexHermitianEJA._max_test_case_size() + sage: n_max = ComplexHermitianEJA._max_random_instance_size() sage: n = ZZ.random_element(1, n_max) sage: J = ComplexHermitianEJA(n) sage: J.dimension() == n^2 @@ -1731,7 +1726,7 @@ class QuaternionMatrixEuclideanJordanAlgebra(MatrixEuclideanJordanAlgebra): Embedding is a homomorphism (isomorphism, in fact):: sage: set_random_seed() - sage: n_max = QuaternionMatrixEuclideanJordanAlgebra._max_test_case_size() + sage: n_max = QuaternionMatrixEuclideanJordanAlgebra._max_random_instance_size() sage: n = ZZ.random_element(n_max) sage: Q = QuaternionAlgebra(QQ,-1,-1) sage: X = random_matrix(Q, n) @@ -1890,7 +1885,7 @@ class QuaternionHermitianEJA(QuaternionMatrixEuclideanJordanAlgebra): The dimension of this algebra is `2*n^2 - n`:: sage: set_random_seed() - sage: n_max = QuaternionHermitianEJA._max_test_case_size() + sage: n_max = QuaternionHermitianEJA._max_random_instance_size() sage: n = ZZ.random_element(1, n_max) sage: J = QuaternionHermitianEJA(n) sage: J.dimension() == 2*(n^2) - n @@ -2056,6 +2051,10 @@ class HadamardEJA(RationalBasisEuclideanJordanAlgebra): **kwargs) self.rank.set_cache(n) + @staticmethod + def _max_random_instance_size(): + return 5 + def inner_product(self, x, y): """ Faster to reimplement than to use natural representations. @@ -2166,6 +2165,10 @@ class BilinearFormEJA(RationalBasisEuclideanJordanAlgebra): **kwargs) self.rank.set_cache(min(n,2)) + @staticmethod + def _max_random_instance_size(): + return 5 + def inner_product(self, x, y): r""" Half of the trace inner product. @@ -2297,6 +2300,11 @@ class TrivialEJA(FiniteDimensionalEuclideanJordanAlgebra): # largest subalgebra generated by any element. self.rank.set_cache(0) + @classmethod + def random_instance(cls, field=AA, **kwargs): + # We don't take a "size" argument so the superclass method is + # inappropriate for us. + return cls(field, **kwargs) class DirectSumEJA(FiniteDimensionalEuclideanJordanAlgebra): r""" @@ -2399,3 +2407,83 @@ class DirectSumEJA(FiniteDimensionalEuclideanJordanAlgebra): pi_left = lambda x: J1.from_vector(x.to_vector()[:n]) pi_right = lambda x: J2.from_vector(x.to_vector()[n:]) return (pi_left, pi_right) + + def inclusions(self): + r""" + Return the pair of inclusion maps from our factors into us. + + SETUP:: + + sage: from mjo.eja.eja_algebra import (JordanSpinEJA, + ....: RealSymmetricEJA, + ....: DirectSumEJA) + + EXAMPLES:: + + sage: J1 = JordanSpinEJA(3) + sage: J2 = RealSymmetricEJA(2) + sage: J = DirectSumEJA(J1,J2) + sage: (iota_left, iota_right) = J.inclusions() + sage: iota_left(J1.zero()) == J.zero() + True + sage: iota_right(J2.zero()) == J.zero() + True + sage: J1.one().to_vector() + (1, 0, 0) + sage: iota_left(J1.one()).to_vector() + (1, 0, 0, 0, 0, 0) + sage: J2.one().to_vector() + (1, 0, 1) + sage: iota_right(J2.one()).to_vector() + (0, 0, 0, 1, 0, 1) + sage: J.one().to_vector() + (1, 0, 0, 1, 0, 1) + + """ + (J1,J2) = self.factors() + n = J1.dimension() + V_basis = self.vector_space().basis() + I1 = matrix.column(self.base_ring(), V_basis[:n]) + I2 = matrix.column(self.base_ring(), V_basis[n:]) + iota_left = lambda x: self.from_vector(I1*x.to_vector()) + iota_right = lambda x: self.from_vector(I2*+x.to_vector()) + return (iota_left, iota_right) + + def inner_product(self, x, y): + r""" + The standard Cartesian inner-product. + + We project ``x`` and ``y`` onto our factors, and add up the + inner-products from the subalgebras. + + SETUP:: + + + sage: from mjo.eja.eja_algebra import (HadamardEJA, + ....: QuaternionHermitianEJA, + ....: DirectSumEJA) + + EXAMPLE:: + + sage: J1 = HadamardEJA(3) + sage: J2 = QuaternionHermitianEJA(2,QQ,normalize_basis=False) + sage: J = DirectSumEJA(J1,J2) + sage: x1 = J1.one() + sage: x2 = x1 + sage: y1 = J2.one() + sage: y2 = y1 + sage: x1.inner_product(x2) + 3 + sage: y1.inner_product(y2) + 2 + sage: J.one().inner_product(J.one()) + 5 + + """ + (pi_left, pi_right) = self.projections() + x1 = pi_left(x) + x2 = pi_right(x) + y1 = pi_left(y) + y2 = pi_right(y) + + return (x1.inner_product(y1) + x2.inner_product(y2))