]> gitweb.michael.orlitzky.com - sage.d.git/blobdiff - mjo/eja/eja_utils.py
eja: add a deep change_ring() utility function.
[sage.d.git] / mjo / eja / eja_utils.py
index c25b81921e1be4f0d6a77580227cb8692e21605f..81b5634bc921736b0d007f3df04013d0dc6df265 100644 (file)
@@ -2,10 +2,87 @@ from sage.functions.other import sqrt
 from sage.matrix.constructor import matrix
 from sage.modules.free_module_element import vector
 
+def _change_ring(x, R):
+    r"""
+    Change the ring of a vector, matrix, or a cartesian product of
+    those things.
+
+    SETUP::
+
+        sage: from mjo.eja.eja_utils import _change_ring
+
+    EXAMPLES::
+
+        sage: v = vector(QQ, (1,2,3))
+        sage: m = matrix(QQ, [[1,2],[3,4]])
+        sage: _change_ring(v, RDF)
+        (1.0, 2.0, 3.0)
+        sage: _change_ring(m, RDF)
+        [1.0 2.0]
+        [3.0 4.0]
+        sage: _change_ring((v,m), RDF)
+        (
+                         [1.0 2.0]
+        (1.0, 2.0, 3.0), [3.0 4.0]
+        )
+        sage: V1 = cartesian_product([v.parent(), v.parent()])
+        sage: V = cartesian_product([v.parent(), V1])
+        sage: V((v, (v, v)))
+        ((1, 2, 3), ((1, 2, 3), (1, 2, 3)))
+        sage: _change_ring(V((v, (v, v))), RDF)
+        ((1.0, 2.0, 3.0), ((1.0, 2.0, 3.0), (1.0, 2.0, 3.0)))
+
+    """
+    try:
+        return x.change_ring(R)
+    except AttributeError:
+        try:
+            from sage.categories.sets_cat import cartesian_product
+            if hasattr(x, 'element_class'):
+                # x is a parent and we're in a recursive call.
+                return cartesian_product( [_change_ring(x_i, R)
+                                           for x_i in x.cartesian_factors()] )
+            else:
+                # x is an element, and we want to change the ring
+                # of its parent.
+                P = x.parent()
+                Q = cartesian_product( [_change_ring(P_i, R)
+                                        for P_i in P.cartesian_factors()] )
+                return Q(x)
+        except AttributeError:
+            # No parent for x
+            return x.__class__( _change_ring(x_i, R) for x_i in x )
+
 def _scale(x, alpha):
     r"""
     Scale the vector, matrix, or cartesian-product-of-those-things
     ``x`` by ``alpha``.
+
+    This works around the inability to scale certain elements of
+    Cartesian product spaces, as reported in
+
+      https://trac.sagemath.org/ticket/31435
+
+    ..WARNING:
+
+        This will do the wrong thing if you feed it a tuple or list.
+
+    SETUP::
+
+        sage: from mjo.eja.eja_utils import _scale
+
+    EXAMPLES::
+
+        sage: v = vector(QQ, (1,2,3))
+        sage: _scale(v,2)
+        (2, 4, 6)
+        sage: m = matrix(QQ, [[1,2],[3,4]])
+        sage: M = cartesian_product([m.parent(), m.parent()])
+        sage: _scale(M((m,m)), 2)
+        ([2 4]
+        [6 8], [2 4]
+        [6 8])
+
     """
     if hasattr(x, 'cartesian_factors'):
         P = x.parent()
@@ -14,6 +91,7 @@ def _scale(x, alpha):
     else:
         return x*alpha
 
+
 def _all2list(x):
     r"""
     Flatten a vector, matrix, or cartesian product of those things