INPUT:
- - basis -- a tuple of basis elements in "matrix form," which
- must be the same form as the arguments to ``jordan_product``
- and ``inner_product``. In reality, "matrix form" can be either
- vectors, matrices, or a Cartesian product (ordered tuple)
- of vectors or matrices. All of these would ideally be vector
- spaces in sage with no special-casing needed; but in reality
- we turn vectors into column-matrices and Cartesian products
- `(a,b)` into column matrices `(a,b)^{T}` after converting
- `a` and `b` themselves.
-
- - 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.
+ - ``basis`` -- a tuple; a tuple of basis elements in "matrix
+ form," which must be the same form as the arguments to
+ ``jordan_product`` and ``inner_product``. In reality, "matrix
+ form" can be either vectors, matrices, or a Cartesian product
+ (ordered tuple) of vectors or matrices. All of these would
+ ideally be vector spaces in sage with no special-casing
+ needed; but in reality we turn vectors into column-matrices
+ and Cartesian products `(a,b)` into column matrices
+ `(a,b)^{T}` after converting `a` and `b` themselves.
+
+ - ``jordan_product`` -- a function; afunction 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`` -- a function; a 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.
+
+ - ``field`` -- a subfield of the reals (default: ``AA``); the scalar
+ field for the algebra.
+
+ - ``orthonormalize`` -- boolean (default: ``True``); whether or
+ not to orthonormalize the basis. Doing so is expensive and
+ generally rules out using the rationals as your ``field``, but
+ is required for spectral decompositions.
+
"""
Element = FiniteDimensionalEJAElement
category = MagmaticAlgebras(field).FiniteDimensional()
- category = category.WithBasis().Unital()
+ category = category.WithBasis().Unital().Commutative()
+
if associative:
# Element subalgebras can take advantage of this.
category = category.Associative()
"""
return "Associative" in self.category().axioms()
+ def _is_commutative(self):
+ r"""
+ Whether or not this algebra's multiplication table is commutative.
+
+ This method should of course always return ``True``, unless
+ this algebra was constructed with ``check_axioms=False`` and
+ passed an invalid multiplication table.
+ """
+ return all( self.product_on_basis(i,j) == self.product_on_basis(i,j)
+ for i in range(self.dimension())
+ for j in range(self.dimension()) )
+
def _is_jordanian(self):
r"""
Whether or not this algebra's multiplication table respects the
We only check one arrangement of `x` and `y`, so for a
``True`` result to be truly true, you should also check
- :meth:`is_commutative`. This method should of course always
+ :meth:`_is_commutative`. This method should of course always
return ``True``, unless this algebra was constructed with
``check_axioms=False`` and passed an invalid multiplication table.
"""
for i in range(self.dimension())
for j in range(self.dimension()) )
+ def _jordan_product_is_associative(self):
+ r"""
+ Return whether or not this algebra's Jordan product is
+ associative; that is, whether or not `x*(y*z) = (x*y)*z`
+ for all `x,y,x`.
+
+ This method should agree with :meth:`is_associative` unless
+ you lied about the value of the ``associative`` parameter
+ when you constructed the algebra.
+
+ SETUP::
+
+ sage: from mjo.eja.eja_algebra import (RealSymmetricEJA,
+ ....: ComplexHermitianEJA,
+ ....: QuaternionHermitianEJA)
+
+ EXAMPLES::
+
+ sage: J = RealSymmetricEJA(4, orthonormalize=False)
+ sage: J._jordan_product_is_associative()
+ False
+ sage: x = sum(J.gens())
+ sage: A = x.subalgebra_generated_by()
+ sage: A._jordan_product_is_associative()
+ True
+
+ ::
+
+ sage: J = ComplexHermitianEJA(2,field=QQ,orthonormalize=False)
+ sage: J._jordan_product_is_associative()
+ False
+ sage: x = sum(J.gens())
+ sage: A = x.subalgebra_generated_by(orthonormalize=False)
+ sage: A._jordan_product_is_associative()
+ True
+
+ ::
+
+ sage: J = QuaternionHermitianEJA(2)
+ sage: J._jordan_product_is_associative()
+ False
+ sage: x = sum(J.gens())
+ sage: A = x.subalgebra_generated_by()
+ sage: A._jordan_product_is_associative()
+ True
+
+ """
+ R = self.base_ring()
+
+ # Used to check whether or not something is zero.
+ epsilon = R.zero()
+ if not R.is_exact():
+ # I don't know of any examples that make this magnitude
+ # necessary because I don't know how to make an
+ # associative algebra when the element subalgebra
+ # construction is unreliable (as it is over RDF; we can't
+ # find the degree of an element because we can't compute
+ # the rank of a matrix). But even multiplication of floats
+ # is non-associative, so *some* epsilon is needed... let's
+ # just take the one from _inner_product_is_associative?
+ epsilon = 1e-15
+
+ for i in range(self.dimension()):
+ for j in range(self.dimension()):
+ for k in range(self.dimension()):
+ x = self.gens()[i]
+ y = self.gens()[j]
+ z = self.gens()[k]
+ diff = (x*y)*z - x*(y*z)
+
+ if diff.norm() > epsilon:
+ return False
+
+ return True
+
def _inner_product_is_associative(self):
r"""
Return whether or not this algebra's inner product `B` is
this algebra was constructed with ``check_axioms=False`` and
passed an invalid Jordan or inner-product.
"""
+ R = self.base_ring()
- # Used to check whether or not something is zero in an inexact
- # ring. This number is sufficient to allow the construction of
- # QuaternionHermitianEJA(2, field=RDF) with check_axioms=True.
- epsilon = 1e-16
+ # Used to check whether or not something is zero.
+ epsilon = R.zero()
+ if not R.is_exact():
+ # This choice is sufficient to allow the construction of
+ # QuaternionHermitianEJA(2, field=RDF) with check_axioms=True.
+ epsilon = 1e-15
for i in range(self.dimension()):
for j in range(self.dimension()):
z = self.gens()[k]
diff = (x*y).inner_product(z) - x.inner_product(y*z)
- if self.base_ring().is_exact():
- if diff != 0:
- return False
- else:
- if diff.abs() > epsilon:
- return False
+ if diff.abs() > epsilon:
+ return False
return True
SETUP::
- sage: from mjo.eja.eja_algebra import (JordanSpinEJA,
+ sage: from mjo.eja.eja_algebra import (random_eja,
+ ....: JordanSpinEJA,
....: HadamardEJA,
....: RealSymmetricEJA)
TESTS:
- Ensure that we can convert any element of the two non-matrix
- simple algebras (whose matrix representations are columns)
- back and forth faithfully::
+ Ensure that we can convert any element back and forth
+ faithfully between its matrix and algebra representations::
sage: set_random_seed()
- sage: J = HadamardEJA.random_instance()
- sage: x = J.random_element()
- sage: J(x.to_vector().column()) == x
- True
- sage: J = JordanSpinEJA.random_instance()
+ sage: J = random_eja()
sage: x = J.random_element()
- sage: J(x.to_vector().column()) == x
+ sage: J(x.to_matrix()) == x
True
We cannot coerce elements between algebras just because their
Traceback (most recent call last):
...
ValueError: not an element of this algebra
-
"""
msg = "not an element of this algebra"
if elt in self.base_ring():
In theory, our "field" can be any subfield of the reals::
- sage: RealSymmetricEJA(2, field=RDF)
+ sage: RealSymmetricEJA(2, field=RDF, check_axioms=True)
Euclidean Jordan algebra of dimension 3 over Real Double Field
- sage: RealSymmetricEJA(2, field=RR)
+ sage: RealSymmetricEJA(2, field=RR, check_axioms=True)
Euclidean Jordan algebra of dimension 3 over Real Field with
53 bits of precision
In theory, our "field" can be any subfield of the reals::
- sage: ComplexHermitianEJA(2, field=RDF)
+ sage: ComplexHermitianEJA(2, field=RDF, check_axioms=True)
Euclidean Jordan algebra of dimension 4 over Real Double Field
- sage: ComplexHermitianEJA(2, field=RR)
+ sage: ComplexHermitianEJA(2, field=RR, check_axioms=True)
Euclidean Jordan algebra of dimension 4 over Real Field with
53 bits of precision
In theory, our "field" can be any subfield of the reals::
- sage: QuaternionHermitianEJA(2, field=RDF)
+ sage: QuaternionHermitianEJA(2, field=RDF, check_axioms=True)
Euclidean Jordan algebra of dimension 6 over Real Double Field
- sage: QuaternionHermitianEJA(2, field=RR)
+ sage: QuaternionHermitianEJA(2, field=RR, check_axioms=True)
Euclidean Jordan algebra of dimension 6 over Real Field with
53 bits of precision