+ 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):
+ r"""
+ Return the operator inner product of myself and ``other``.
+
+ The "operator inner product," whose name is not standard, is
+ defined be the usual linear-algebraic trace of the
+ ``(x*y).operator()``.
+
+ Proposition III.1.5 in Faraut and Korányi shows that on any
+ Euclidean Jordan algebra, this is another associative inner
+ product under which the cone of squares is symmetric.
+
+ This works even if the basis hasn't been orthonormalized
+ because the eigenvalues of the corresponding matrix don't
+ change when the basis does (they're preserved by any
+ similarity transformation).
+
+ SETUP::
+
+ sage: from mjo.eja.eja_algebra import (JordanSpinEJA,
+ ....: RealSymmetricEJA,
+ ....: ComplexHermitianEJA,
+ ....: random_eja)
+
+ EXAMPLES:
+
+ Proposition III.4.2 of Faraut and Korányi shows that on a
+ simple algebra of rank `r` and dimension `n`, this inner
+ product is `n/r` times the canonical
+ :meth:`trace_inner_product`::
+
+ sage: J = JordanSpinEJA(4, field=QQ)
+ sage: x,y = J.random_elements(2)
+ sage: n = J.dimension()
+ sage: r = J.rank()
+ sage: actual = x.operator_trace_inner_product(y)
+ sage: expected = (n/r)*x.trace_inner_product(y)
+ sage: actual == expected
+ True
+
+ ::
+
+ sage: J = RealSymmetricEJA(3)
+ sage: x,y = J.random_elements(2)
+ sage: n = J.dimension()
+ sage: r = J.rank()
+ sage: actual = x.operator_trace_inner_product(y)
+ sage: expected = (n/r)*x.trace_inner_product(y)
+ sage: actual == expected
+ True
+
+ ::
+
+ sage: J = ComplexHermitianEJA(3, field=QQ, orthonormalize=False)
+ sage: x,y = J.random_elements(2)
+ sage: n = J.dimension()
+ sage: r = J.rank()
+ sage: actual = x.operator_trace_inner_product(y)
+ sage: expected = (n/r)*x.trace_inner_product(y)
+ sage: actual == expected
+ True
+
+ TESTS: