]> gitweb.michael.orlitzky.com - sage.d.git/commitdiff
eja: speed up det() for Cartesian product elements.
authorMichael Orlitzky <michael@orlitzky.com>
Sun, 14 Mar 2021 01:46:54 +0000 (20:46 -0500)
committerMichael Orlitzky <michael@orlitzky.com>
Sun, 14 Mar 2021 01:46:54 +0000 (20:46 -0500)
mjo/eja/TODO
mjo/eja/eja_algebra.py
mjo/eja/eja_element.py

index 82c49d53d883d40712b66897c115ed1e58fa430f..9cee421b4f5cacee4e623a6b4d1099c191eeaf72 100644 (file)
@@ -7,9 +7,5 @@
    the nontrivial factor. On the other hand, it's nice that we can
    test out some alternate code paths...
 
    the nontrivial factor. On the other hand, it's nice that we can
    test out some alternate code paths...
 
-4. Conjecture: if x = (x1,x2), then det(x) = det(x1)det(x2). This
-   should be used to fix the fact that det(x) is monstrously slow in
-   Cartesian product algebras, and thus randomly in the doctests.
-
-5. Add dimension bounds on any tests over AA that compute element
+4. Add dimension bounds on any tests over AA that compute element
    subalgebras.
    subalgebras.
index 907f40d72135df42d211cdd9bb8923df6bf462e6..2bad32c2f500193e4126b7c5e209c0acb3116ede 100644 (file)
@@ -166,7 +166,8 @@ from sage.modules.free_module import FreeModule, VectorSpace
 from sage.rings.all import (ZZ, QQ, AA, QQbar, RR, RLF, CLF,
                             PolynomialRing,
                             QuadraticField)
 from sage.rings.all import (ZZ, QQ, AA, QQbar, RR, RLF, CLF,
                             PolynomialRing,
                             QuadraticField)
-from mjo.eja.eja_element import FiniteDimensionalEJAElement
+from mjo.eja.eja_element import (CartesianProductEJAElement,
+                                 FiniteDimensionalEJAElement)
 from mjo.eja.eja_operator import FiniteDimensionalEJAOperator
 from mjo.eja.eja_utils import _all2list
 
 from mjo.eja.eja_operator import FiniteDimensionalEJAOperator
 from mjo.eja.eja_utils import _all2list
 
@@ -3089,6 +3090,7 @@ class CartesianProductEJA(FiniteDimensionalEJA):
         sage: actual == expected             # long time
         True
     """
         sage: actual == expected             # long time
         True
     """
+    Element = CartesianProductEJAElement
     def __init__(self, factors, **kwargs):
         m = len(factors)
         if m == 0:
     def __init__(self, factors, **kwargs):
         m = len(factors)
         if m == 0:
index 693e8e2d03c0e2aadeb5cf52034fa112a2208f4b..47f6ff080c1d48a1a32b4903991aa0ec5bd0a502 100644 (file)
@@ -6,6 +6,7 @@ from sage.modules.with_basis.indexed_element import IndexedFreeModuleElement
 from mjo.eja.eja_operator import FiniteDimensionalEJAOperator
 from mjo.eja.eja_utils import _scale
 
 from mjo.eja.eja_operator import FiniteDimensionalEJAOperator
 from mjo.eja.eja_utils import _scale
 
+
 class FiniteDimensionalEJAElement(IndexedFreeModuleElement):
     """
     An element of a Euclidean Jordan algebra.
 class FiniteDimensionalEJAElement(IndexedFreeModuleElement):
     """
     An element of a Euclidean Jordan algebra.
@@ -1121,18 +1122,10 @@ class FiniteDimensionalEJAElement(IndexedFreeModuleElement):
         B = self.parent().matrix_basis()
         W = self.parent().matrix_space()
 
         B = self.parent().matrix_basis()
         W = self.parent().matrix_space()
 
-        if hasattr(W, 'cartesian_factors'):
-            # Aaaaand linear combinations don't work in Cartesian
-            # product spaces, even though they provide a method with
-            # that name. This is hidden behind an "if" because the
-            # _scale() function is slow.
-            pairs = zip(B, self.to_vector())
-            return W.sum( _scale(b, alpha) for (b,alpha) in pairs )
-        else:
-            # This is just a manual "from_vector()", but of course
-            # matrix spaces aren't vector spaces in sage, so they
-            # don't have a from_vector() method.
-            return W.linear_combination( zip(B, self.to_vector()) )
+        # This is just a manual "from_vector()", but of course
+        # matrix spaces aren't vector spaces in sage, so they
+        # don't have a from_vector() method.
+        return W.linear_combination( zip(B, self.to_vector()) )
 
 
 
 
 
 
@@ -1650,3 +1643,29 @@ class FiniteDimensionalEJAElement(IndexedFreeModuleElement):
 
         """
         return self.trace_inner_product(self).sqrt()
 
         """
         return self.trace_inner_product(self).sqrt()
+
+
+class CartesianProductEJAElement(FiniteDimensionalEJAElement):
+    def det(self):
+        r"""
+        Compute the determinant of this product-element using the
+        determianants of its factors.
+
+        This result Follows from the spectral decomposition of (say)
+        the pair `(x,y)` in terms of the Jordan frame `\left\{ (c_1,
+        0),(c_2, 0),...,(0,d_1),(0,d_2),... \right\}.
+        """
+        from sage.misc.misc_c import prod
+        return prod( f.det() for f in self.cartesian_factors() )
+
+    def to_matrix(self):
+        # An override is necessary to call our custom _scale().
+        B = self.parent().matrix_basis()
+        W = self.parent().matrix_space()
+
+        # Aaaaand linear combinations don't work in Cartesian
+        # product spaces, even though they provide a method with
+        # that name. This is hidden behind an "if" because the
+        # _scale() function is slow.
+        pairs = zip(B, self.to_vector())
+        return W.sum( _scale(b, alpha) for (b,alpha) in pairs )