+ 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:
+
+ The operator inner product is commutative, bilinear, and
+ associative::
+
+ sage: J = random_eja()
+ sage: x,y,z = J.random_elements(3)
+ sage: # commutative
+ sage: actual = x.operator_trace_inner_product(y)
+ sage: expected = y.operator_trace_inner_product(x)
+ sage: actual == expected
+ True
+ sage: # bilinear
+ sage: a = J.base_ring().random_element()
+ sage: actual = (a*(x+z)).operator_trace_inner_product(y)
+ sage: expected = ( a*x.operator_trace_inner_product(y) +
+ ....: a*z.operator_trace_inner_product(y) )
+ sage: actual == expected
+ True
+ sage: actual = x.operator_trace_inner_product(a*(y+z))
+ sage: expected = ( a*x.operator_trace_inner_product(y) +
+ ....: a*x.operator_trace_inner_product(z) )
+ sage: actual == expected
+ True
+ sage: # associative
+ sage: actual = (x*y).operator_trace_inner_product(z)
+ sage: expected = y.operator_trace_inner_product(x*z)
+ sage: actual == expected
+ True
+
+ Despite the fact that the implementation uses a matrix representation,
+ the answer is independent of the basis used::
+
+ sage: J = RealSymmetricEJA(3, field=QQ, orthonormalize=False)
+ sage: V = RealSymmetricEJA(3)
+ sage: x,y = J.random_elements(2)
+ sage: w = V(x.to_matrix())
+ sage: z = V(y.to_matrix())
+ sage: expected = x.operator_trace_inner_product(y)
+ sage: actual = w.operator_trace_inner_product(z)
+ sage: actual == expected
+ True
+
+ """
+ if not other in self.parent():
+ raise TypeError("'other' must live in the same algebra")
+
+ return (self*other).operator().matrix().trace()
+
+
+ def operator_trace_norm(self):
+ """
+ The norm of this element with respect to
+ :meth:`operator_trace_inner_product`.
+
+ SETUP::
+
+ sage: from mjo.eja.eja_algebra import (JordanSpinEJA,
+ ....: HadamardEJA)
+
+ EXAMPLES:
+
+ On a simple algebra, this will differ from :meth:`trace_norm`
+ by the scalar factor ``(n/r).sqrt()``, where `n` is the
+ dimension of the algebra and `r` its rank. This follows from
+ the corresponding result (Proposition III.4.2 of Faraut and
+ Korányi) for the trace inner product::
+
+ sage: J = HadamardEJA(2)