]> gitweb.michael.orlitzky.com - sage.d.git/blobdiff - mjo/eja/eja_algebra.py
eja: add is_associative() method and corresponding cartesian product magic.
[sage.d.git] / mjo / eja / eja_algebra.py
index a4208519268cf204cfe43b80dddf882f9638fcd1..99cf0d0d078851ec49391c9c2f290716e6e42e22 100644 (file)
@@ -305,11 +305,33 @@ class FiniteDimensionalEJA(CombinatorialFreeModule):
             sage: y = J.random_element()
             sage: (n == 1) or (x.inner_product(y) == (x*y).trace()/2)
             True
+
         """
         B = self._inner_product_matrix
         return (B*x.to_vector()).inner_product(y.to_vector())
 
 
+    def is_associative(self):
+        r"""
+        Return whether or not this algebra's Jordan product is associative.
+
+        SETUP::
+
+            sage: from mjo.eja.eja_algebra import ComplexHermitianEJA
+
+        EXAMPLES::
+
+            sage: J = ComplexHermitianEJA(3, field=QQ, orthonormalize=False)
+            sage: J.is_associative()
+            False
+            sage: x = sum(J.gens())
+            sage: A = x.subalgebra_generated_by(orthonormalize=False)
+            sage: A.is_associative()
+            True
+
+        """
+        return "Associative" in self.category().axioms()
+
     def _is_commutative(self):
         r"""
         Whether or not this algebra's multiplication table is commutative.
@@ -2384,7 +2406,11 @@ class HadamardEJA(ConcreteEJA):
         if "check_axioms" not in kwargs: kwargs["check_axioms"] = False
 
         column_basis = tuple( b.column() for b in FreeModule(ZZ, n).basis() )
-        super().__init__(column_basis, jordan_product, inner_product, **kwargs)
+        super().__init__(column_basis,
+                         jordan_product,
+                         inner_product,
+                         associative=True,
+                         **kwargs)
         self.rank.set_cache(n)
 
         if n == 0:
@@ -2779,6 +2805,25 @@ class CartesianProductEJA(CombinatorialFreeModule_CartesianProduct,
         sage: J.rank() == J1.rank() + J2.rank()
         True
 
+    The product algebra will be associative if and only if all of its
+    components are associative::
+
+        sage: J1 = HadamardEJA(2)
+        sage: J1.is_associative()
+        True
+        sage: J2 = HadamardEJA(3)
+        sage: J2.is_associative()
+        True
+        sage: J3 = RealSymmetricEJA(3)
+        sage: J3.is_associative()
+        False
+        sage: CP1 = cartesian_product([J1,J2])
+        sage: CP1.is_associative()
+        True
+        sage: CP2 = cartesian_product([J1,J3])
+        sage: CP2.is_associative()
+        False
+
     TESTS:
 
     All factors must share the same base field::
@@ -2816,14 +2861,16 @@ class CartesianProductEJA(CombinatorialFreeModule_CartesianProduct,
         True
 
     """
-    def __init__(self, modules, **kwargs):
+    def __init__(self, algebras, **kwargs):
         CombinatorialFreeModule_CartesianProduct.__init__(self,
-                                                          modules,
+                                                          algebras,
                                                           **kwargs)
-        field = modules[0].base_ring()
-        if not all( J.base_ring() == field for J in modules ):
+        field = algebras[0].base_ring()
+        if not all( J.base_ring() == field for J in algebras ):
             raise ValueError("all factors must share the same base field")
 
+        associative = all( m.is_associative() for m in algebras )
+
         # The definition of matrix_space() and self.basis() relies
         # only on the stuff in the CFM_CartesianProduct class, which
         # we've already initialized.
@@ -2859,13 +2906,14 @@ class CartesianProductEJA(CombinatorialFreeModule_CartesianProduct,
                                       inner_product,
                                       field=field,
                                       orthonormalize=False,
+                                      associative=associative,
                                       cartesian_product=True,
                                       check_field=False,
                                       check_axioms=False)
 
-        ones = tuple(J.one() for J in modules)
+        ones = tuple(J.one() for J in algebras)
         self.one.set_cache(self._cartesian_product_of_elements(ones))
-        self.rank.set_cache(sum(J.rank() for J in modules))
+        self.rank.set_cache(sum(J.rank() for J in algebras))
 
     def matrix_space(self):
         r"""