`(a,b)` into column matrices `(a,b)^{T}` after converting
`a` and `b` themselves.
- - jordan_product -- function of two elements (in matrix form)
- that returns their jordan product in this algebra; this will
- be applied to ``basis`` to compute a multiplication table for
- the algebra.
-
- - inner_product -- function of two elements (in matrix form) that
- returns their inner product. This will be applied to ``basis`` to
- compute an inner-product table (basically a matrix) for this algebra.
-
+ - jordan_product -- function of two ``basis`` elements (in
+ matrix form) that returns their jordan product, also in matrix
+ form; this will be applied to ``basis`` to compute a
+ multiplication table for the algebra.
+
+ - inner_product -- function of two ``basis`` elements (in matrix
+ form) that returns their inner product. This will be applied
+ to ``basis`` to compute an inner-product table (basically a
+ matrix) for this algebra.
"""
Element = FiniteDimensionalEJAElement
def product_on_basis(self, i, j):
+ r"""
+ Returns the Jordan product of the `i` and `j`th basis elements.
+
+ This completely defines the Jordan product on the algebra, and
+ is used direclty by our superclass machinery to implement
+ :meth:`product`.
+
+ SETUP::
+
+ sage: from mjo.eja.eja_algebra import random_eja
+
+ TESTS::
+
+ sage: set_random_seed()
+ sage: J = random_eja()
+ sage: n = J.dimension()
+ sage: ei = J.zero()
+ sage: ej = J.zero()
+ sage: ei_ej = J.zero()*J.zero()
+ sage: if n > 0:
+ ....: i = ZZ.random_element(n)
+ ....: j = ZZ.random_element(n)
+ ....: ei = J.gens()[i]
+ ....: ej = J.gens()[j]
+ ....: ei_ej = J.product_on_basis(i,j)
+ sage: ei*ej == ei_ej
+ True
+
+ """
# We only stored the lower-triangular portion of the
# multiplication table.
if j <= i:
sage: J(x.to_vector().column()) == x
True
+ We cannot coerce elements between algebras just because their
+ matrix representations are compatible::
+
+ sage: J1 = HadamardEJA(3)
+ sage: J2 = JordanSpinEJA(3)
+ sage: J2(J1.one())
+ Traceback (most recent call last):
+ ...
+ ValueError: not an element of this algebra
+ sage: J1(J2.zero())
+ Traceback (most recent call last):
+ ...
+ ValueError: not an element of this algebra
+
"""
msg = "not an element of this algebra"
- if elt == 0:
- # The superclass implementation of random_element()
- # needs to be able to coerce "0" into the algebra.
- return self.zero()
- elif elt in self.base_ring():
+ if elt in self.base_ring():
# Ensure that no base ring -> algebra coercion is performed
# by this method. There's some stupidity in sage that would
# otherwise propagate to this method; for example, sage thinks
raise ValueError(msg)
try:
+ # Try to convert a vector into a column-matrix...
elt = elt.column()
except (AttributeError, TypeError):
- # Try to convert a vector into a column-matrix
+ # and ignore failure, because we weren't really expecting
+ # a vector as an argument anyway.
pass
if elt not in self.matrix_space():
# could be QQ instead of QQbar.
#
# And, we also have to handle Cartesian product bases (when
- # the matric basis consists of tuples) here. The "good news"
+ # the matrix basis consists of tuples) here. The "good news"
# is that we're already converting everything to long vectors,
# and that strategy works for tuples as well.
#
we think of them as matrices (including column vectors of the
appropriate size).
- Generally this will be an `n`-by-`1` column-vector space,
+ "By default" this will be an `n`-by-`1` column-matrix space,
except when the algebra is trivial. There it's `n`-by-`n`
(where `n` is zero), to ensure that two elements of the matrix
- space (empty matrices) can be multiplied.
+ space (empty matrices) can be multiplied. For algebras of
+ matrices, this returns the space in which their
+ real embeddings live.
+
+ SETUP::
+
+ sage: from mjo.eja.eja_algebra import (ComplexHermitianEJA,
+ ....: JordanSpinEJA,
+ ....: QuaternionHermitianEJA,
+ ....: TrivialEJA)
+
+ EXAMPLES:
+
+ By default, the matrix representation is just a column-matrix
+ equivalent to the vector representation::
+
+ sage: J = JordanSpinEJA(3)
+ sage: J.matrix_space()
+ Full MatrixSpace of 3 by 1 dense matrices over Algebraic
+ Real Field
+
+ The matrix representation in the trivial algebra is
+ zero-by-zero instead of the usual `n`-by-one::
+
+ sage: J = TrivialEJA()
+ sage: J.matrix_space()
+ Full MatrixSpace of 0 by 0 dense matrices over Algebraic
+ Real Field
+
+ The matrix space for complex/quaternion Hermitian matrix EJA
+ is the space in which their real-embeddings live, not the
+ original complex/quaternion matrix space::
+
+ sage: J = ComplexHermitianEJA(2,field=QQ,orthonormalize=False)
+ sage: J.matrix_space()
+ Full MatrixSpace of 4 by 4 dense matrices over Rational Field
+ sage: J = QuaternionHermitianEJA(1,field=QQ,orthonormalize=False)
+ sage: J.matrix_space()
+ Full MatrixSpace of 4 by 4 dense matrices over Rational Field
- Matrix algebras override this with something more useful.
"""
if self.is_trivial():
return MatrixSpace(self.base_ring(), 0)