]> gitweb.michael.orlitzky.com - sage.d.git/blobdiff - mjo/eja/eja_element.py
eja: use izip() instead of zip() in a few places.
[sage.d.git] / mjo / eja / eja_element.py
index e1f75630bf5b3fc33292e4c84fa657fed715828a..d9b6eb12fe27363721763fc1e6ccb60c7f98aabd 100644 (file)
@@ -1,3 +1,5 @@
+from itertools import izip
+
 from sage.matrix.constructor import matrix
 from sage.modules.free_module import VectorSpace
 from sage.modules.with_basis.indexed_element import IndexedFreeModuleElement
 from sage.matrix.constructor import matrix
 from sage.modules.free_module import VectorSpace
 from sage.modules.with_basis.indexed_element import IndexedFreeModuleElement
@@ -78,7 +80,7 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
         elif n == 1:
             return self
         else:
         elif n == 1:
             return self
         else:
-            return (self.operator()**(n-1))(self)
+            return (self**(n-1))*self
 
 
     def apply_univariate_polynomial(self, p):
 
 
     def apply_univariate_polynomial(self, p):
@@ -243,9 +245,8 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
 
             sage: set_random_seed()
             sage: J = random_eja()
 
             sage: set_random_seed()
             sage: J = random_eja()
-            sage: x = J.random_element()
-            sage: y = J.random_element()
-            sage: x.inner_product(y) in RR
+            sage: x,y = J.random_elements(2)
+            sage: x.inner_product(y) in RLF
             True
 
         """
             True
 
         """
@@ -280,9 +281,7 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
         Test Lemma 1 from Chapter III of Koecher::
 
             sage: set_random_seed()
         Test Lemma 1 from Chapter III of Koecher::
 
             sage: set_random_seed()
-            sage: J = random_eja()
-            sage: u = J.random_element()
-            sage: v = J.random_element()
+            sage: u,v = random_eja().random_elements(2)
             sage: lhs = u.operator_commutes_with(u*v)
             sage: rhs = v.operator_commutes_with(u^2)
             sage: lhs == rhs
             sage: lhs = u.operator_commutes_with(u*v)
             sage: rhs = v.operator_commutes_with(u^2)
             sage: lhs == rhs
@@ -292,9 +291,7 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
         Chapter III, or from Baes (2.3)::
 
             sage: set_random_seed()
         Chapter III, or from Baes (2.3)::
 
             sage: set_random_seed()
-            sage: J = random_eja()
-            sage: x = J.random_element()
-            sage: y = J.random_element()
+            sage: x,y = random_eja().random_elements(2)
             sage: Lx = x.operator()
             sage: Ly = y.operator()
             sage: Lxx = (x*x).operator()
             sage: Lx = x.operator()
             sage: Ly = y.operator()
             sage: Lxx = (x*x).operator()
@@ -306,10 +303,7 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
         Baes (2.4)::
 
             sage: set_random_seed()
         Baes (2.4)::
 
             sage: set_random_seed()
-            sage: J = random_eja()
-            sage: x = J.random_element()
-            sage: y = J.random_element()
-            sage: z = J.random_element()
+            sage: x,y,z = random_eja().random_elements(3)
             sage: Lx = x.operator()
             sage: Ly = y.operator()
             sage: Lz = z.operator()
             sage: Lx = x.operator()
             sage: Ly = y.operator()
             sage: Lz = z.operator()
@@ -323,10 +317,7 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
         Baes (2.5)::
 
             sage: set_random_seed()
         Baes (2.5)::
 
             sage: set_random_seed()
-            sage: J = random_eja()
-            sage: u = J.random_element()
-            sage: y = J.random_element()
-            sage: z = J.random_element()
+            sage: u,y,z = random_eja().random_elements(3)
             sage: Lu = u.operator()
             sage: Ly = y.operator()
             sage: Lz = z.operator()
             sage: Lu = u.operator()
             sage: Ly = y.operator()
             sage: Lz = z.operator()
@@ -388,8 +379,7 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
 
             sage: set_random_seed()
             sage: J = random_eja().random_element().subalgebra_generated_by()
 
             sage: set_random_seed()
             sage: J = random_eja().random_element().subalgebra_generated_by()
-            sage: x = J.random_element()
-            sage: y = J.random_element()
+            sage: x,y = J.random_elements(2)
             sage: (x*y).det() == x.det()*y.det()
             True
 
             sage: (x*y).det() == x.det()*y.det()
             True
 
@@ -424,8 +414,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 +640,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
@@ -709,6 +697,7 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
         SETUP::
 
             sage: from mjo.eja.eja_algebra import (JordanSpinEJA,
         SETUP::
 
             sage: from mjo.eja.eja_algebra import (JordanSpinEJA,
+            ....:                                  RealSymmetricEJA,
             ....:                                  random_eja)
 
         TESTS:
             ....:                                  random_eja)
 
         TESTS:
@@ -734,10 +723,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():
@@ -758,6 +749,21 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
             sage: x.apply_univariate_polynomial(p)
             0
 
             sage: x.apply_univariate_polynomial(p)
             0
 
+        The minimal polynomial is invariant under a change of basis,
+        and in particular, a re-scaling of the basis::
+
+            sage: set_random_seed()
+            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,normalize_basis=False)
+            sage: X = random_matrix(QQ,n)
+            sage: X = X*X.transpose()
+            sage: x1 = J1(X)
+            sage: x2 = J2(X)
+            sage: x1.minimal_polynomial() == x2.minimal_polynomial()
+            True
+
         """
         if self.is_zero():
             # We would generate a zero-dimensional subalgebra
         """
         if self.is_zero():
             # We would generate a zero-dimensional subalgebra
@@ -825,8 +831,35 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
 
         """
         B = self.parent().natural_basis()
 
         """
         B = self.parent().natural_basis()
-        W = B[0].matrix_space()
-        return W.linear_combination(zip(B,self.to_vector()))
+        W = self.parent().natural_basis_space()
+        return W.linear_combination(izip(B,self.to_vector()))
+
+
+    def norm(self):
+        """
+        The norm of this element with respect to :meth:`inner_product`.
+
+        SETUP::
+
+            sage: from mjo.eja.eja_algebra import (JordanSpinEJA,
+            ....:                                  RealCartesianProductEJA)
+
+        EXAMPLES::
+
+            sage: J = RealCartesianProductEJA(2)
+            sage: x = sum(J.gens())
+            sage: x.norm()
+            sqrt(2)
+
+        ::
+
+            sage: J = JordanSpinEJA(4)
+            sage: x = sum(J.gens())
+            sage: x.norm()
+            2
+
+        """
+        return self.inner_product(self).sqrt()
 
 
     def operator(self):
 
 
     def operator(self):
@@ -842,8 +875,7 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
 
             sage: set_random_seed()
             sage: J = random_eja()
 
             sage: set_random_seed()
             sage: J = random_eja()
-            sage: x = J.random_element()
-            sage: y = J.random_element()
+            sage: x,y = J.random_elements(2)
             sage: x.operator()(y) == x*y
             True
             sage: y.operator()(x) == x*y
             sage: x.operator()(y) == x*y
             True
             sage: y.operator()(x) == x*y
@@ -874,10 +906,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)])
@@ -894,8 +925,7 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
 
             sage: set_random_seed()
             sage: J = random_eja()
 
             sage: set_random_seed()
             sage: J = random_eja()
-            sage: x = J.random_element()
-            sage: y = J.random_element()
+            sage: x,y = J.random_elements(2)
             sage: Lx = x.operator()
             sage: Lxx = (x*x).operator()
             sage: Qx = x.quadratic_representation()
             sage: Lx = x.operator()
             sage: Lxx = (x*x).operator()
             sage: Qx = x.quadratic_representation()
@@ -912,7 +942,7 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
 
         Property 2 (multiply on the right for :trac:`28272`):
 
 
         Property 2 (multiply on the right for :trac:`28272`):
 
-            sage: alpha = QQ.random_element()
+            sage: alpha = J.base_ring().random_element()
             sage: (alpha*x).quadratic_representation() == Qx*(alpha^2)
             True
 
             sage: (alpha*x).quadratic_representation() == Qx*(alpha^2)
             True
 
@@ -940,10 +970,10 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
             sage: not x.is_invertible() or (
             ....:   x.quadratic_representation(x.inverse())*Qx
             ....:   ==
             sage: not x.is_invertible() or (
             ....:   x.quadratic_representation(x.inverse())*Qx
             ....:   ==
-            ....:   2*x.operator()*Qex - Qx )
+            ....:   2*Lx*Qex - Qx )
             True
 
             True
 
-            sage: 2*x.operator()*Qex - Qx == Lxx
+            sage: 2*Lx*Qex - Qx == Lxx
             True
 
         Property 5:
             True
 
         Property 5:
@@ -997,9 +1027,7 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
             sage: set_random_seed()
             sage: x0 = random_eja().random_element()
             sage: A = x0.subalgebra_generated_by()
             sage: set_random_seed()
             sage: x0 = random_eja().random_element()
             sage: A = x0.subalgebra_generated_by()
-            sage: x = A.random_element()
-            sage: y = A.random_element()
-            sage: z = A.random_element()
+            sage: x,y,z = A.random_elements(3)
             sage: (x*y)*z == x*(y*z)
             True
 
             sage: (x*y)*z == x*(y*z)
             True
 
@@ -1017,7 +1045,7 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
             sage: set_random_seed()
             sage: A = random_eja().zero().subalgebra_generated_by()
             sage: A
             sage: set_random_seed()
             sage: A = random_eja().zero().subalgebra_generated_by()
             sage: A
-            Euclidean Jordan algebra of dimension 0 over Rational Field
+            Euclidean Jordan algebra of dimension 0 over...
             sage: A.one()
             0
 
             sage: A.one()
             0
 
@@ -1110,7 +1138,7 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
 
             sage: set_random_seed()
             sage: J = random_eja()
 
             sage: set_random_seed()
             sage: J = random_eja()
-            sage: J.random_element().trace() in J.base_ring()
+            sage: J.random_element().trace() in RLF
             True
 
         """
             True
 
         """
@@ -1134,22 +1162,17 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
 
         TESTS:
 
 
         TESTS:
 
-        The trace inner product is commutative::
+        The trace inner product is commutative, bilinear, and satisfies
+        the Jordan axiom:
 
             sage: set_random_seed()
             sage: J = random_eja()
 
             sage: set_random_seed()
             sage: J = random_eja()
-            sage: x = J.random_element(); y = J.random_element()
+            sage: x,y,z = J.random_elements(3)
+            sage: # commutative
             sage: x.trace_inner_product(y) == y.trace_inner_product(x)
             True
             sage: x.trace_inner_product(y) == y.trace_inner_product(x)
             True
-
-        The trace inner product is bilinear::
-
-            sage: set_random_seed()
-            sage: J = random_eja()
-            sage: x = J.random_element()
-            sage: y = J.random_element()
-            sage: z = J.random_element()
-            sage: a = QQ.random_element();
+            sage: # bilinear
+            sage: a = J.base_ring().random_element();
             sage: actual = (a*(x+z)).trace_inner_product(y)
             sage: expected = ( a*x.trace_inner_product(y) +
             ....:              a*z.trace_inner_product(y) )
             sage: actual = (a*(x+z)).trace_inner_product(y)
             sage: expected = ( a*x.trace_inner_product(y) +
             ....:              a*z.trace_inner_product(y) )
@@ -1160,15 +1183,7 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
             ....:              a*x.trace_inner_product(z) )
             sage: actual == expected
             True
             ....:              a*x.trace_inner_product(z) )
             sage: actual == expected
             True
-
-        The trace inner product satisfies the compatibility
-        condition in the definition of a Euclidean Jordan algebra::
-
-            sage: set_random_seed()
-            sage: J = random_eja()
-            sage: x = J.random_element()
-            sage: y = J.random_element()
-            sage: z = J.random_element()
+            sage: # jordan axiom
             sage: (x*y).trace_inner_product(z) == y.trace_inner_product(x*z)
             True
 
             sage: (x*y).trace_inner_product(z) == y.trace_inner_product(x*z)
             True
 
@@ -1177,3 +1192,30 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
             raise TypeError("'other' must live in the same algebra")
 
         return (self*other).trace()
             raise TypeError("'other' must live in the same algebra")
 
         return (self*other).trace()
+
+
+    def trace_norm(self):
+        """
+        The norm of this element with respect to :meth:`trace_inner_product`.
+
+        SETUP::
+
+            sage: from mjo.eja.eja_algebra import (JordanSpinEJA,
+            ....:                                  RealCartesianProductEJA)
+
+        EXAMPLES::
+
+            sage: J = RealCartesianProductEJA(2)
+            sage: x = sum(J.gens())
+            sage: x.trace_norm()
+            sqrt(2)
+
+        ::
+
+            sage: J = JordanSpinEJA(4)
+            sage: x = sum(J.gens())
+            sage: x.trace_norm()
+            2*sqrt(2)
+
+        """
+        return self.trace_inner_product(self).sqrt()