]> gitweb.michael.orlitzky.com - sage.d.git/commitdiff
eja: normalize the real symmetric matrix basis.
authorMichael Orlitzky <michael@orlitzky.com>
Tue, 20 Aug 2019 20:46:16 +0000 (16:46 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Tue, 20 Aug 2019 20:46:16 +0000 (16:46 -0400)
This is necessary to ensure that the default basis representation is
an isometry. When it is not, the left-multiplication operator is
self-adjoint (by the Jordan axiom), but its matrix with respect to
that basis is not. The other two matrix algebras need similar fixing.

mjo/eja/eja_algebra.py
mjo/eja/eja_element.py
mjo/eja/eja_operator.py
mjo/eja/eja_subalgebra.py

index 47d247be636c01d59a06a4f48da4d56b63b0f508..992174e45b763e95677588beee2787859c0e64b1 100644 (file)
@@ -502,8 +502,8 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule):
             Finite family {0: e0, 1: e1, 2: e2}
             sage: J.natural_basis()
             (
-            [1 0]  [0 1]  [0 0]
-            [0 0], [1 0], [0 1]
+            [1 0]  [        0 1/2*sqrt2]  [0 0]
+            [0 0], [1/2*sqrt2         0], [0 1]
             )
 
         ::
@@ -678,7 +678,7 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule):
 
             sage: J = RealSymmetricEJA(2)
             sage: J.vector_space()
-            Vector space of dimension 3 over Rational Field
+            Vector space of dimension 3 over...
 
         """
         return self.zero().to_vector().parent().ambient_vector_space()
@@ -827,8 +827,9 @@ def _real_symmetric_basis(n, field):
             if i == j:
                 Sij = Eij
             else:
-                # Beware, orthogonal but not normalized!
                 Sij = Eij + Eij.transpose()
+            # Now normalize it.
+            Sij = Sij / _real_symmetric_matrix_ip(Sij,Sij).sqrt()
             S.append(Sij)
     return tuple(S)
 
@@ -1190,6 +1191,9 @@ def _matrix_ip(X,Y):
     Y_mat = Y.natural_representation()
     return (X_mat*Y_mat).trace()
 
+def _real_symmetric_matrix_ip(X,Y):
+    return (X*Y).trace()
+
 
 class RealSymmetricEJA(FiniteDimensionalEuclideanJordanAlgebra):
     """
@@ -1208,7 +1212,7 @@ class RealSymmetricEJA(FiniteDimensionalEuclideanJordanAlgebra):
         sage: e0*e0
         e0
         sage: e1*e1
-        e0 + e2
+        1/2*e0 + 1/2*e2
         sage: e2*e2
         e2
 
@@ -1254,8 +1258,31 @@ class RealSymmetricEJA(FiniteDimensionalEuclideanJordanAlgebra):
         sage: (x*y).inner_product(z) == y.inner_product(x*z)
         True
 
+    Our basis is normalized with respect to the natural inner product::
+
+        sage: set_random_seed()
+        sage: n = ZZ.random_element(1,5)
+        sage: J = RealSymmetricEJA(n)
+        sage: all( b.norm() == 1 for b in J.gens() )
+        True
+
+    Left-multiplication operators are symmetric because they satisfy
+    the Jordan axiom::
+
+        sage: set_random_seed()
+        sage: n = ZZ.random_element(1,5)
+        sage: x = RealSymmetricEJA(n).random_element()
+        sage: x.operator().matrix().is_symmetric()
+        True
+
     """
     def __init__(self, n, field=QQ, **kwargs):
+        if n > 1 and field is QQ:
+            # We'll need sqrt(2) to normalize the basis, and this
+            # winds up in the multiplication table, so the whole
+            # algebra needs to be over the field extension.
+            field = QuadraticField(2, 'sqrt2')
+
         S = _real_symmetric_basis(n, field)
         Qs = _multiplication_table_from_matrix_basis(S)
 
@@ -1267,7 +1294,9 @@ class RealSymmetricEJA(FiniteDimensionalEuclideanJordanAlgebra):
                               **kwargs)
 
     def inner_product(self, x, y):
-        return _matrix_ip(x,y)
+        X = x.natural_representation()
+        Y = y.natural_representation()
+        return _real_symmetric_matrix_ip(X,Y)
 
 
 class ComplexHermitianEJA(FiniteDimensionalEuclideanJordanAlgebra):
index a681ae29652f913246033affb3db74d85b52c9c0..90c236af8ef4dd46784007cb4927d00ba6b4e33e 100644 (file)
@@ -939,7 +939,7 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
 
         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
 
@@ -1044,7 +1044,7 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
             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
 
@@ -1176,7 +1176,7 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement):
             sage: x = J.random_element()
             sage: y = J.random_element()
             sage: z = J.random_element()
-            sage: a = QQ.random_element();
+            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) )
index 7c3b2a6a4721848caaaf4d30cecbb08d0eab587f..4b72e5783210b51cd6d8d658f0f5d4e8c40a7f57 100644 (file)
@@ -81,10 +81,8 @@ class FiniteDimensionalEuclideanJordanAlgebraOperator(Map):
             [2 0 0]
             [0 2 0]
             [0 0 2]
-            Domain: Euclidean Jordan algebra of dimension 3 over
-            Rational Field
-            Codomain: Euclidean Jordan algebra of dimension 3 over
-            Rational Field
+            Domain: Euclidean Jordan algebra of dimension 3 over...
+            Codomain: Euclidean Jordan algebra of dimension 3 over...
 
         If you try to add two identical vector space operators but on
         different EJAs, that should blow up::
@@ -179,10 +177,8 @@ class FiniteDimensionalEuclideanJordanAlgebraOperator(Map):
             [1 0 0]
             [0 1 0]
             [0 0 1]
-            Domain: Euclidean Jordan algebra of dimension 3 over
-            Rational Field
-            Codomain: Euclidean Jordan algebra of dimension 3 over
-            Rational Field
+            Domain: Euclidean Jordan algebra of dimension 3 over...
+            Codomain: Euclidean Jordan algebra of dimension 3 over...
 
         """
         return FiniteDimensionalEuclideanJordanAlgebraOperator(
@@ -215,30 +211,31 @@ class FiniteDimensionalEuclideanJordanAlgebraOperator(Map):
             sage: x.operator()
             Linear operator between finite-dimensional Euclidean Jordan algebras
             represented by the matrix:
-            [ 2  4  0]
+            [ 2  2  0]
             [ 2  9  2]
-            [ 0  4 16]
-            Domain: Euclidean Jordan algebra of dimension 3 over
-            Rational Field
-            Codomain: Euclidean Jordan algebra of dimension 3 over
-            Rational Field
+            [ 0  2 16]
+            Domain: Euclidean Jordan algebra of dimension 3 over...
+            Codomain: Euclidean Jordan algebra of dimension 3 over...
             sage: x.operator()*(1/2)
             Linear operator between finite-dimensional Euclidean Jordan algebras
             represented by the matrix:
-            [  1   2   0]
+            [  1   1   0]
             [  1 9/2   1]
-            [  0   2   8]
-            Domain: Euclidean Jordan algebra of dimension 3 over
-            Rational Field
-            Codomain: Euclidean Jordan algebra of dimension 3 over
-            Rational Field
+            [  0   1   8]
+            Domain: Euclidean Jordan algebra of dimension 3 over...
+            Codomain: Euclidean Jordan algebra of dimension 3 over...
 
         """
-        if other in self.codomain().base_ring():
-            return FiniteDimensionalEuclideanJordanAlgebraOperator(
-                self.domain(),
-                self.codomain(),
-                self.matrix()*other)
+        try:
+            if other in self.codomain().base_ring():
+                return FiniteDimensionalEuclideanJordanAlgebraOperator(
+                    self.domain(),
+                    self.codomain(),
+                    self.matrix()*other)
+        except NotImplementedError:
+            # This can happen with certain arguments if the base_ring()
+            # is weird and doesn't know how to test membership.
+            pass
 
         # This should eventually delegate to _composition_ after performing
         # some sanity checks for us.
@@ -266,10 +263,8 @@ class FiniteDimensionalEuclideanJordanAlgebraOperator(Map):
             [-1  0  0]
             [ 0 -1  0]
             [ 0  0 -1]
-            Domain: Euclidean Jordan algebra of dimension 3 over
-            Rational Field
-            Codomain: Euclidean Jordan algebra of dimension 3 over
-            Rational Field
+            Domain: Euclidean Jordan algebra of dimension 3 over...
+            Codomain: Euclidean Jordan algebra of dimension 3 over...
 
         """
         return FiniteDimensionalEuclideanJordanAlgebraOperator(
@@ -301,10 +296,8 @@ class FiniteDimensionalEuclideanJordanAlgebraOperator(Map):
             [3 0 0]
             [0 3 0]
             [0 0 3]
-            Domain: Euclidean Jordan algebra of dimension 3 over
-            Rational Field
-            Codomain: Euclidean Jordan algebra of dimension 3 over
-            Rational Field
+            Domain: Euclidean Jordan algebra of dimension 3 over...
+            Codomain: Euclidean Jordan algebra of dimension 3 over...
 
         """
         if (n == 1):
@@ -380,10 +373,8 @@ class FiniteDimensionalEuclideanJordanAlgebraOperator(Map):
             [-1  0  0]
             [ 0 -1  0]
             [ 0  0 -1]
-            Domain: Euclidean Jordan algebra of dimension 3 over
-            Rational Field
-            Codomain: Euclidean Jordan algebra of dimension 3 over
-            Rational Field
+            Domain: Euclidean Jordan algebra of dimension 3 over...
+            Codomain: Euclidean Jordan algebra of dimension 3 over...
 
         """
         return (self + (-other))
index 2318d12bfd0ebbfc765ca74766af9ab0e73ce02c..646da2fb8b649c11baa226833085c26564d75d46 100644 (file)
@@ -342,20 +342,20 @@ class FiniteDimensionalEuclideanJordanElementSubalgebra(FiniteDimensionalEuclide
         EXAMPLES::
 
             sage: J = RealSymmetricEJA(3)
-            sage: x = sum( i*J.gens()[i] for i in range(6) )
+            sage: x = J.monomial(0) + 2*J.monomial(2) + 5*J.monomial(5)
             sage: K = FiniteDimensionalEuclideanJordanElementSubalgebra(x)
             sage: K.vector_space()
-            Vector space of degree 6 and dimension 3 over Rational Field
+            Vector space of degree 6 and dimension 3 over...
             User basis matrix:
             [ 1  0  1  0  0  1]
-            [ 0  1  2  3  4  5]
-            [10 14 21 19 31 50]
+            [ 1  0  2  0  0  5]
+            [ 1  0  4  0  0 25]
             sage: (x^0).to_vector()
             (1, 0, 1, 0, 0, 1)
             sage: (x^1).to_vector()
-            (0, 1, 2, 3, 4, 5)
+            (1, 0, 2, 0, 0, 5)
             sage: (x^2).to_vector()
-            (10, 14, 21, 19, 31, 50)
+            (1, 0, 4, 0, 0, 25)
 
         """
         return self._vector_space