From cda12a746b75b33381325e31afab44c6e9b85950 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sun, 22 Nov 2020 09:32:32 -0500 Subject: [PATCH] eja: alter BilinearFormEJA to take only a matrix argument. 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 | 55 +++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/mjo/eja/eja_algebra.py b/mjo/eja/eja_algebra.py index 222b12c..c822d14 100644 --- a/mjo/eja/eja_algebra.py +++ b/mjo/eja/eja_algebra.py @@ -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 + , 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``. + (,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): -- 2.44.2