]> gitweb.michael.orlitzky.com - sage.d.git/commitdiff
eja: alter BilinearFormEJA to take only a matrix argument.
authorMichael Orlitzky <michael@orlitzky.com>
Sun, 22 Nov 2020 14:32:32 +0000 (09:32 -0500)
committerMichael Orlitzky <michael@orlitzky.com>
Sun, 22 Nov 2020 14:32:32 +0000 (09:32 -0500)
The BilinearFormEJA constructor originally took both the size "n" and
a bilinear form matrix "B" that acted on the x-bar component of an
algebra element. This was a bit silly: except when n=0, we can
determine the size of the algebra from the bilinear form matrix.

Now, we insist that the entire matrix "B" be passed in, including the
upper-left "1" block. This allows us to pass in a matrix of size zero
to get the trivial algebra, and in all other cases, to infer that the
dimension of the algebra is the size of the matrix.

mjo/eja/eja_algebra.py

index 222b12c9ea0074792c807471eb546d1c45282e71..c822d14f6d0900a8b90c24d377fb31196003e0e8 100644 (file)
@@ -2085,10 +2085,15 @@ class BilinearFormEJA(RationalBasisEuclideanJordanAlgebra):
     r"""
     The rank-2 simple EJA consisting of real vectors ``x=(x0, x_bar)``
     with the half-trace inner product and jordan product ``x*y =
-    (x0*y0 + <B*x_bar,y_bar>, x0*y_bar + y0*x_bar)`` where ``B`` is a
-    symmetric positive-definite "bilinear form" matrix. It has
-    dimension `n` over the reals, and reduces to the ``JordanSpinEJA``
-    when ``B`` is the identity matrix of order ``n-1``.
+    (<Bx,y>,y_bar>, x0*y_bar + y0*x_bar)`` where `B = 1 \times B22` is
+    a symmetric positive-definite "bilinear form" matrix. Its
+    dimension is the size of `B`, and it has rank two in dimensions
+    larger than two. It reduces to the ``JordanSpinEJA`` when `B` is
+    the identity matrix of order ``n``.
+
+    We insist that the one-by-one upper-left identity block of `B` be
+    passed in as well so that we can be passed a matrix of size zero
+    to construct a trivial algebra.
 
     SETUP::
 
@@ -2100,7 +2105,8 @@ class BilinearFormEJA(RationalBasisEuclideanJordanAlgebra):
     When no bilinear form is specified, the identity matrix is used,
     and the resulting algebra is the Jordan spin algebra::
 
-        sage: J0 = BilinearFormEJA(3)
+        sage: B = matrix.identity(AA,3)
+        sage: J0 = BilinearFormEJA(B)
         sage: J1 = JordanSpinEJA(3)
         sage: J0.multiplication_table() == J0.multiplication_table()
         True
@@ -2109,7 +2115,8 @@ class BilinearFormEJA(RationalBasisEuclideanJordanAlgebra):
 
     We can create a zero-dimensional algebra::
 
-        sage: J = BilinearFormEJA(0)
+        sage: B = matrix.identity(AA,0)
+        sage: J = BilinearFormEJA(B)
         sage: J.basis()
         Finite family {}
 
@@ -2121,8 +2128,11 @@ class BilinearFormEJA(RationalBasisEuclideanJordanAlgebra):
         sage: set_random_seed()
         sage: n = ZZ.random_element(5)
         sage: M = matrix.random(QQ, max(0,n-1), algorithm='unimodular')
-        sage: B = M.transpose()*M
-        sage: J = BilinearFormEJA(n, B=B)
+        sage: B11 = matrix.identity(QQ,1)
+        sage: B22 = M.transpose()*M
+        sage: B = block_matrix(2,2,[ [B11,0  ],
+        ....:                        [0, B22 ] ])
+        sage: J = BilinearFormEJA(B)
         sage: eis = VectorSpace(M.base_ring(), M.ncols()).basis()
         sage: V = J.vector_space()
         sage: sis = [ J.from_vector(V([0] + (M.inverse()*ei).list()))
@@ -2136,11 +2146,12 @@ class BilinearFormEJA(RationalBasisEuclideanJordanAlgebra):
         sage: actual == expected
         True
     """
-    def __init__(self, n, field=AA, B=None, **kwargs):
-        if B is None:
-            self._B = matrix.identity(field, max(0,n-1))
-        else:
-            self._B = B
+    def __init__(self, B, field=AA, **kwargs):
+        self._B = B
+        n = B.nrows()
+
+        if not B.is_positive_definite():
+            raise TypeError("matrix B is not positive-definite")
 
         V = VectorSpace(field, n)
         mult_table = [[V.zero() for j in range(n)] for i in range(n)]
@@ -2152,7 +2163,7 @@ class BilinearFormEJA(RationalBasisEuclideanJordanAlgebra):
                 xbar = x[1:]
                 y0 = y[0]
                 ybar = y[1:]
-                z0 = x0*y0 + (self._B*xbar).inner_product(ybar)
+                z0 = (B*x).inner_product(y)
                 zbar = y0*xbar + x0*ybar
                 z = V([z0] + zbar.list())
                 mult_table[i][j] = z
@@ -2191,19 +2202,18 @@ class BilinearFormEJA(RationalBasisEuclideanJordanAlgebra):
             sage: set_random_seed()
             sage: n = ZZ.random_element(2,5)
             sage: M = matrix.random(QQ, max(0,n-1), algorithm='unimodular')
-            sage: B = M.transpose()*M
-            sage: J = BilinearFormEJA(n, B=B)
+            sage: B11 = matrix.identity(QQ,1)
+            sage: B22 = M.transpose()*M
+            sage: B = block_matrix(2,2,[ [B11,0  ],
+            ....:                        [0, B22 ] ])
+            sage: J = BilinearFormEJA(B)
             sage: x = J.random_element()
             sage: y = J.random_element()
             sage: x.inner_product(y) == (x*y).trace()/2
             True
 
         """
-        xvec = x.to_vector()
-        xbar = xvec[1:]
-        yvec = y.to_vector()
-        ybar = yvec[1:]
-        return x[0]*y[0] + (self._B*xbar).inner_product(ybar)
+        return (self._B*x.to_vector()).inner_product(y.to_vector())
 
 
 class JordanSpinEJA(BilinearFormEJA):
@@ -2259,7 +2269,8 @@ class JordanSpinEJA(BilinearFormEJA):
     def __init__(self, n, field=AA, **kwargs):
         # This is a special case of the BilinearFormEJA with the identity
         # matrix as its bilinear form.
-        super(JordanSpinEJA, self).__init__(n, field, **kwargs)
+        B = matrix.identity(field, n)
+        super(JordanSpinEJA, self).__init__(B, field, **kwargs)
 
 
 class TrivialEJA(FiniteDimensionalEuclideanJordanAlgebra):