+
+ def trace_inner_product(self, other):
+ """
+ Return the trace inner product of myself and ``other``.
+
+ SETUP::
+
+ sage: from mjo.eja.eja_algebra import random_eja
+
+ TESTS:
+
+ The trace inner product is commutative, bilinear, and associative::
+
+ sage: J = random_eja()
+ sage: x,y,z = J.random_elements(3)
+ 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 == expected
+ True
+ sage: actual = x.trace_inner_product(a*(y+z))
+ sage: expected = ( a*x.trace_inner_product(y) +
+ ....: a*x.trace_inner_product(z) )
+ sage: actual == expected
+ True
+ sage: # associative
+ sage: (x*y).trace_inner_product(z) == y.trace_inner_product(x*z)
+ True
+
+ """
+ if not other in self.parent():
+ 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,
+ ....: HadamardEJA)
+
+ EXAMPLES::
+
+ sage: J = HadamardEJA(2)
+ sage: x = sum(J.gens())
+ sage: x.trace_norm()
+ 1.414213562373095?
+
+ ::
+
+ sage: J = JordanSpinEJA(4)
+ sage: x = sum(J.gens())
+ sage: x.trace_norm()
+ 2.828427124746190?
+
+ """
+ return self.trace_inner_product(self).sqrt()
+
+
+ def operator_trace_inner_product(self, other):