+ def __init__(self, n, field=AA, **kwargs):
+ V = VectorSpace(field, n)
+ mult_table = [ [ V.gen(i)*(i == j) for j in range(n) ]
+ for i in range(n) ]
+
+ super(HadamardEJA, self).__init__(field,
+ mult_table,
+ check_axioms=False,
+ **kwargs)
+ self.rank.set_cache(n)
+
+ def inner_product(self, x, y):
+ """
+ Faster to reimplement than to use natural representations.
+
+ SETUP::
+
+ sage: from mjo.eja.eja_algebra import HadamardEJA
+
+ TESTS:
+
+ Ensure that this is the usual inner product for the algebras
+ over `R^n`::
+
+ sage: set_random_seed()
+ sage: J = HadamardEJA.random_instance()
+ sage: x,y = J.random_elements(2)
+ sage: X = x.natural_representation()
+ sage: Y = y.natural_representation()
+ sage: x.inner_product(y) == J.natural_inner_product(X,Y)
+ True
+
+ """
+ return x.to_vector().inner_product(y.to_vector())
+
+
+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``.
+
+ SETUP::
+
+ sage: from mjo.eja.eja_algebra import (BilinearFormEJA,
+ ....: JordanSpinEJA)
+
+ EXAMPLES:
+
+ 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: J1 = JordanSpinEJA(3)
+ sage: J0.multiplication_table() == J0.multiplication_table()
+ True
+
+ TESTS:
+
+ We can create a zero-dimensional algebra::
+
+ sage: J = BilinearFormEJA(0)
+ sage: J.basis()
+ Finite family {}
+
+ We can check the multiplication condition given in the Jordan, von
+ Neumann, and Wigner paper (and also discussed on my "On the
+ symmetry..." paper). Note that this relies heavily on the standard
+ choice of basis, as does anything utilizing the bilinear form matrix::
+
+ 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: eis = VectorSpace(M.base_ring(), M.ncols()).basis()
+ sage: V = J.vector_space()
+ sage: sis = [ J.from_vector(V([0] + (M.inverse()*ei).list()))
+ ....: for ei in eis ]
+ sage: actual = [ sis[i]*sis[j]
+ ....: for i in range(n-1)
+ ....: for j in range(n-1) ]
+ sage: expected = [ J.one() if i == j else J.zero()
+ ....: for i in range(n-1)
+ ....: for j in range(n-1) ]
+ 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
+