Performance improvements
authorAntonio Jimenez Pastor <antonio@ebook.dk-compmath.jku.at>
Wed, 13 Jun 2018 11:45:01 +0000 (13:45 +0200)
committerAntonio Jimenez Pastor <antonio@ebook.dk-compmath.jku.at>
Wed, 13 Jun 2018 11:45:01 +0000 (13:45 +0200)
1 - The method for computing the root of the indicial polynomial now is cached.
This means that operators with the same indicial polynomial take less time to
compute their roots.
2 - Computing th roots of the indicial polynomial when there are parameters is done
using a modular approximation: we evaluate the parameters and when the polynomial
has the same degree we compute the roots of a univariate polynomial. That is a superset
of the roots we want, so we check and we keep those that were roots for the indicial polynomial.

Minor changes:
   matrix.py now use the method is_Matrix instead of sage.matrix.Matrix (deprecated in
SAGE: https://trac.sagemath.org/ticket/24096

ajpastor/misc/bareiss.py
ajpastor/misc/matrix.py
ajpastor/operator/operator.py
releases/diff_defined_functions__0.5.zip
releases/old/diff_defined_functions__0.5__18.06.13_13:45:01.zip [new file with mode: 0644]

index d6f521f..fb1fb42 100644 (file)
@@ -3,12 +3,12 @@
 from sage.all_cmdline import *   # import sage library
 
 _sage_const_2 = Integer(2); _sage_const_1 = Integer(1); _sage_const_0 = Integer(0)
-from .matrix import swap_rows;
-from .matrix import swap_cols;
+from ajpastor.misc.matrix import swap_rows;
+from ajpastor.misc.matrix import swap_cols;
 
-from .cached_property import derived_property;
+from ajpastor.misc.cached_property import derived_property;
 
-from .verbose import *;
+from ajpastor.misc.verbose import *;
 
 from sage.rings.polynomial.polynomial_ring import is_PolynomialRing as isUniPolynomial;
 from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing as isMPolynomial;
index 2c505d3..3bf18fc 100644 (file)
@@ -4,7 +4,7 @@ from sage.all_cmdline import *   # import sage library
 
 _sage_const_1 = Integer(1); _sage_const_0 = Integer(0)
 
-from sage.matrix.matrix import Matrix as MatrixClass;
+from sage.structure.element import is_Matrix;
 
 ####################################################################################
 ###
@@ -125,7 +125,7 @@ def random_matrix(parent, *args, **kwds):
     
 ### Auxiliary (and private) methods
 def __check_input(X, parent):
-    if(isinstance(X, MatrixClass) and parent.has_coerce_map_from(X.parent().base())):
+    if(is_Matrix(X) and parent.has_coerce_map_from(X.parent().base())):
         return True;
     elif(isinstance(X, list)):
         try:
index 7de0d1a..830eba5 100644 (file)
@@ -45,12 +45,44 @@ from ajpastor.misc.cached_property import derived_property;
 from ajpastor.misc.ring_w_sequence import Ring_w_Sequence;
 from ajpastor.misc.ring_w_sequence import Wrap_w_Sequence_Ring;
 
+from sage.rings.polynomial.polynomial_ring import is_PolynomialRing;
+from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing;
+
+
 ## GENERIC UTILITIES METHODS
 def foo_derivative(p):
     try:
         return p.derivative(x);
     except AttributeError:
         return _sage_const_0 ;
+    
+@cached_function
+def get_integer_roots(element):
+    if(not is_PolynomialRing(element.parent())):
+        raise TypeError("Incompatible element to compute integer roots");
+    base,deep_vars, n_vars = _tower_variables(element.parent().base());
+    gen = str(element.parent().gens()[0]);
+    
+    ring = element.parent().change_ring(base);
+    deg = element.degree();
+    p = ring.one();
+    while(p.degree() < deg):
+        new_ev = {var : base.random_element() for var in deep_vars};
+        p = ring(element(**new_ev));
+    
+    pos_roots = [ZZ(root) for root in p.roots(multiplicities=False) if (root in ZZ)];
+    return [rt for rt in pos_roots if element(**{gen : rt}) == 0];
+    
+@cached_function
+def _tower_variables(parent):
+    result = [];
+    n_vars = _sage_const_0;
+    while(is_PolynomialRing(parent) or is_MPolynomialRing(parent)):
+        result += [str(gen) for gen in parent.gens()];
+        n_vars += parent.ngens();
+        parent = parent.base();
+
+    return (parent,result, n_vars);
 
 ## Operator class
 class Operator(object):
@@ -278,7 +310,7 @@ class Operator(object):
     def jp_value(self):
         ## TODO Be careful with this computation:oinly valid is the base field are the rational
         jp_pol = self.get_recursion_polynomial(self.forward_order);
-        return max([self.getOrder()-self.forward_order] + [ZZ(root[_sage_const_0 ]) for root in jp_pol.roots() if (root[_sage_const_0 ] in ZZ)]);
+        return max([self.getOrder()-self.forward_order] + get_integer_roots(jp_pol));
        
     @derived_property 
     def jp_matrix(self):
index 7805f65..19370ae 100644 (file)
Binary files a/releases/diff_defined_functions__0.5.zip and b/releases/diff_defined_functions__0.5.zip differ
diff --git a/releases/old/diff_defined_functions__0.5__18.06.13_13:45:01.zip b/releases/old/diff_defined_functions__0.5__18.06.13_13:45:01.zip
new file mode 100644 (file)
index 0000000..19370ae
Binary files /dev/null and b/releases/old/diff_defined_functions__0.5__18.06.13_13:45:01.zip differ