sage: x.apply_univariate_polynomial(p)
0
+ The characteristic polynomials of the zero and unit elements
+ should be what we think they are in a subalgebra, too::
+
+ sage: J = RealCartesianProductEJA(3)
+ sage: p1 = J.one().characteristic_polynomial()
+ sage: q1 = J.zero().characteristic_polynomial()
+ sage: e0,e1,e2 = J.gens()
+ sage: A = (e0 + 2*e1 + 3*e2).subalgebra_generated_by() # dim 3
+ sage: p2 = A.one().characteristic_polynomial()
+ sage: q2 = A.zero().characteristic_polynomial()
+ sage: p1 == p2
+ True
+ sage: q1 == q2
+ True
+
"""
p = self.parent().characteristic_polynomial()
return p(*self.to_vector())
sage: x.is_invertible() == (x.det() != 0)
True
+ Ensure that the determinant is multiplicative on an associative
+ subalgebra as in Faraut and Koranyi's Proposition II.2.2::
+
+ sage: set_random_seed()
+ sage: J = random_eja().random_element().subalgebra_generated_by()
+ sage: x = J.random_element()
+ sage: y = J.random_element()
+ sage: (x*y).det() == x.det()*y.det()
+ True
+
"""
P = self.parent()
r = P.rank()
sage: J.one().is_invertible()
True
- The zero element is never invertible::
+ The zero element is never invertible in a non-trivial algebra::
sage: set_random_seed()
sage: J = random_eja()
- sage: J.zero().is_invertible()
+ sage: (not J.is_trivial()) and J.zero().is_invertible()
False
"""
+ if self.is_zero():
+ if self.parent().is_trivial():
+ return True
+ else:
+ return False
+
# In fact, we only need to know if the constant term is non-zero,
# so we can pass in the field's zero element instead.
zero = self.base_ring().zero()
True
"""
+ if self.is_zero() and not self.parent().is_trivial():
+ # The minimal polynomial of zero in a nontrivial algebra
+ # is "t"; in a trivial algebra it's "1" by convention
+ # (it's an empty product).
+ return 1
return self.subalgebra_generated_by().dimension()
SETUP::
sage: from mjo.eja.eja_algebra import (JordanSpinEJA,
+ ....: RealSymmetricEJA,
....: random_eja)
TESTS:
sage: x.apply_univariate_polynomial(p)
0
+ The minimal polynomial is invariant under a change of basis,
+ and in particular, a re-scaling of the basis::
+
+ sage: set_random_seed()
+ sage: n = ZZ.random_element(1,5).abs()
+ sage: J1 = RealSymmetricEJA(n)
+ sage: J2 = RealSymmetricEJA(n,QQ,False)
+ sage: X = random_matrix(QQ,n)
+ sage: X = X*X.transpose()
+ sage: x1 = J1(X)
+ sage: x2 = J2(X)
+ sage: x1.minimal_polynomial() == x2.minimal_polynomial()
+ True
+
"""
+ if self.is_zero():
+ # We would generate a zero-dimensional subalgebra
+ # where the minimal polynomial would be constant.
+ # That might be correct, but only if *this* algebra
+ # is trivial too.
+ if not self.parent().is_trivial():
+ # Pretty sure we know what the minimal polynomial of
+ # the zero operator is going to be. This ensures
+ # consistency of e.g. the polynomial variable returned
+ # in the "normal" case without us having to think about it.
+ return self.operator().minimal_polynomial()
+
A = self.subalgebra_generated_by()
return A(self).operator().minimal_polynomial()
"""
B = self.parent().natural_basis()
- W = B[0].matrix_space()
+ W = self.parent().natural_basis_space()
return W.linear_combination(zip(B,self.to_vector()))
+ def norm(self):
+ """
+ The norm of this element with respect to :meth:`inner_product`.
+
+ SETUP::
+
+ sage: from mjo.eja.eja_algebra import (JordanSpinEJA,
+ ....: RealCartesianProductEJA)
+
+ EXAMPLES::
+
+ sage: J = RealCartesianProductEJA(2)
+ sage: x = sum(J.gens())
+ sage: x.norm()
+ sqrt(2)
+
+ ::
+
+ sage: J = JordanSpinEJA(4)
+ sage: x = sum(J.gens())
+ sage: x.norm()
+ 2
+
+ """
+ return self.inner_product(self).sqrt()
+
+
def operator(self):
"""
Return the left-multiplication-by-this-element
Property 2 (multiply on the right for :trac:`28272`):
- sage: alpha = QQ.random_element()
+ sage: alpha = J.base_ring().random_element()
sage: (alpha*x).quadratic_representation() == Qx*(alpha^2)
True
sage: A(x^2) == A(x)*A(x)
True
+ The subalgebra generated by the zero element is trivial::
+
+ sage: set_random_seed()
+ sage: A = random_eja().zero().subalgebra_generated_by()
+ sage: A
+ Euclidean Jordan algebra of dimension 0 over...
+ sage: A.one()
+ 0
+
"""
return FiniteDimensionalEuclideanJordanElementSubalgebra(self)
sage: x = J.random_element()
sage: y = J.random_element()
sage: z = J.random_element()
- sage: a = QQ.random_element();
+ 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) )
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,
+ ....: RealCartesianProductEJA)
+
+ EXAMPLES::
+
+ sage: J = RealCartesianProductEJA(2)
+ sage: x = sum(J.gens())
+ sage: x.trace_norm()
+ sqrt(2)
+
+ ::
+
+ sage: J = JordanSpinEJA(4)
+ sage: x = sum(J.gens())
+ sage: x.trace_norm()
+ 2*sqrt(2)
+
+ """
+ return self.trace_inner_product(self).sqrt()