2. Inputs and outputs the underlying matrix with respect to COLUMN
vectors, unlike the parent class.
- 3. Allows us to add, multiply (compose), and invert morphisms in
- the obvious way.
+ 3. Allows us to add, subtract, negate, multiply (compose), and
+ invert morphisms in the obvious way.
If this seems a bit heavyweight, it is. I would have been happy to
use a the ring morphism that underlies the finite-dimensional
algebra morphism, but they don't seem to be callable on elements of
- our EJA, and you can't add/multiply/invert them.
+ our EJA, and you can't add/multiply/etc. them.
"""
def __add__(self, other):
self.matrix()*other.matrix() )
+ def __neg__(self):
+ """
+ Negate this morphism.
+
+ EXAMPLES::
+
+ sage: J = RealSymmetricEJA(2)
+ sage: x = J.one()
+ sage: -x.operator()
+ Morphism from Euclidean Jordan algebra of degree 3 over Rational
+ Field to Euclidean Jordan algebra of degree 3 over Rational Field
+ given by matrix
+ [-1 0 0]
+ [ 0 -1 0]
+ [ 0 0 -1]
+
+ TESTS::
+
+ sage: set_random_seed()
+ sage: J = random_eja()
+ sage: x = J.random_element()
+ sage: -x.operator() in J.Hom(J)
+ True
+
+ """
+ return FiniteDimensionalEuclideanJordanAlgebraMorphism(
+ self.parent(),
+ -self.matrix() )
+
+
def _repr_(self):
"""
We override only the representation that is shown to the user,
return "Morphism from {} to {} given by matrix\n{}".format(
self.domain(), self.codomain(), self.matrix())
+
+ def __sub__(self, other):
+ """
+ Subtract one morphism from another using addition and negation.
+
+ EXAMPLES::
+
+ sage: J = RealSymmetricEJA(2)
+ sage: L1 = J.one().operator()
+ sage: L1 - L1
+ Morphism from Euclidean Jordan algebra of degree 3 over Rational
+ Field to Euclidean Jordan algebra of degree 3 over Rational
+ Field given by matrix
+ [0 0 0]
+ [0 0 0]
+ [0 0 0]
+
+ TESTS::
+
+ sage: set_random_seed()
+ sage: J = random_eja()
+ sage: x = J.random_element()
+ sage: y = J.random_element()
+ sage: x.operator() - y.operator() in J.Hom(J)
+ True
+
+ """
+ return self + (-other)
+
+
def matrix(self):
"""
Return the matrix of this morphism with respect to a left-action
sage: D = (x0^2 - x_bar.inner_product(x_bar))*D
sage: D = D + 2*x_bar.tensor_product(x_bar)
sage: Q = block_matrix(2,2,[A,B,C,D])
- sage: Q == x.quadratic_representation()
+ sage: Q == x.quadratic_representation().operator_matrix()
True
Test all of the properties from Theorem 11.2 in Alizadeh::
sage: J = random_eja()
sage: x = J.random_element()
sage: y = J.random_element()
- sage: Lx = x.operator_matrix()
- sage: Lxx = (x*x).operator_matrix()
+ sage: Lx = x.operator()
+ sage: Lxx = (x*x).operator()
sage: Qx = x.quadratic_representation()
sage: Qy = y.quadratic_representation()
sage: Qxy = x.quadratic_representation(y)
Property 3:
- sage: not x.is_invertible() or (
- ....: Qx*x.inverse().vector() == x.vector() )
+ sage: not x.is_invertible() or ( Qx(x.inverse()) == x )
True
sage: not x.is_invertible() or (
- ....: Qx.inverse()
+ ....: ~Qx
....: ==
....: x.inverse().quadratic_representation() )
True
- sage: Qxy*(J.one().vector()) == (x*y).vector()
+ sage: Qxy(J.one()) == x*y
True
Property 4:
sage: not x.is_invertible() or (
....: x.quadratic_representation(x.inverse())*Qx
....: ==
- ....: 2*x.operator_matrix()*Qex - Qx )
+ ....: 2*x.operator()*Qex - Qx )
True
- sage: 2*x.operator_matrix()*Qex - Qx == Lxx
+ sage: 2*x.operator()*Qex - Qx == Lxx
True
Property 5:
- sage: J(Qy*x.vector()).quadratic_representation() == Qy*Qx*Qy
+ sage: Qy(x).quadratic_representation() == Qy*Qx*Qy
True
Property 6:
Property 7:
sage: not x.is_invertible() or (
- ....: Qx*x.inverse().operator_matrix() == Lx )
+ ....: Qx*x.inverse().operator() == Lx )
True
Property 8:
sage: not x.operator_commutes_with(y) or (
- ....: J(Qx*y.vector())^n == J(Qxn*(y^n).vector()) )
+ ....: Qx(y)^n == Qxn(y^n) )
True
"""
elif not other in self.parent():
raise TypeError("'other' must live in the same algebra")
- L = self.operator_matrix()
- M = other.operator_matrix()
- return ( L*M + M*L - (self*other).operator_matrix() )
+ L = self.operator()
+ M = other.operator()
+ return ( L*M + M*L - (self*other).operator() )
def span_of_powers(self):