]> gitweb.michael.orlitzky.com - sage.d.git/blobdiff - mjo/eja/eja_element.py
eja: add random_instance() method for algebras.
[sage.d.git] / mjo / eja / eja_element.py
index c47156d31e2c6989e1fe863091794520f395523c..f26766df80f65de8c31fe12ef3eab5d5bd727c7a 100644 (file)
@@ -165,6 +165,21 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
             sage: x.apply_univariate_polynomial(p)
             0
 
             sage: x.apply_univariate_polynomial(p)
             0
 
+        The characteristic polynomials of the zero and unit elements
+        should be what we think they are in a subalgebra, too::
+
+            sage: J = RealCartesianProductEJA(3)
+            sage: p1 = J.one().characteristic_polynomial()
+            sage: q1 = J.zero().characteristic_polynomial()
+            sage: e0,e1,e2 = J.gens()
+            sage: A = (e0 + 2*e1 + 3*e2).subalgebra_generated_by() # dim 3
+            sage: p2 = A.one().characteristic_polynomial()
+            sage: q2 = A.zero().characteristic_polynomial()
+            sage: p1 == p2
+            True
+            sage: q1 == q2
+            True
+
         """
         p = self.parent().characteristic_polynomial()
         return p(*self.to_vector())
         """
         p = self.parent().characteristic_polynomial()
         return p(*self.to_vector())
@@ -368,6 +383,16 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
             sage: x.is_invertible() == (x.det() != 0)
             True
 
             sage: x.is_invertible() == (x.det() != 0)
             True
 
+        Ensure that the determinant is multiplicative on an associative
+        subalgebra as in Faraut and Koranyi's Proposition II.2.2::
+
+            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).det() == x.det()*y.det()
+            True
+
         """
         P = self.parent()
         r = P.rank()
         """
         P = self.parent()
         r = P.rank()
@@ -399,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()
@@ -626,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
@@ -684,6 +707,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:
@@ -709,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():
@@ -733,6 +759,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,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
@@ -800,10 +841,37 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
 
         """
         B = self.parent().natural_basis()
 
         """
         B = self.parent().natural_basis()
-        W = B[0].matrix_space()
+        W = self.parent().natural_basis_space()
         return W.linear_combination(zip(B,self.to_vector()))
 
 
         return W.linear_combination(zip(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):
         """
         Return the left-multiplication-by-this-element
     def operator(self):
         """
         Return the left-multiplication-by-this-element
@@ -849,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)])
@@ -887,7 +954,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
 
@@ -992,7 +1059,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
 
@@ -1109,22 +1176,19 @@ 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.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: x = J.random_element();
             sage: y = J.random_element()
             sage: z = J.random_element()
             sage: y = J.random_element()
             sage: z = J.random_element()
-            sage: a = QQ.random_element();
+            sage: # commutative
+            sage: x.trace_inner_product(y) == y.trace_inner_product(x)
+            True
+            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) )
@@ -1135,15 +1199,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
 
@@ -1152,3 +1208,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()