From: Antonio Jimenez Pastor Date: Wed, 13 Jun 2018 11:45:01 +0000 (+0200) Subject: Performance improvements X-Git-Url: http://git.risc.jku.at/gitweb/?a=commitdiff_plain;h=4598b6852a8e25f8e5a8daa886e726854bb3c71a;p=ajpastor%2Fdiff_defined_functions.git Performance improvements 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 --- diff --git a/ajpastor/misc/bareiss.py b/ajpastor/misc/bareiss.py index d6f521f..fb1fb42 100644 --- a/ajpastor/misc/bareiss.py +++ b/ajpastor/misc/bareiss.py @@ -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; diff --git a/ajpastor/misc/matrix.py b/ajpastor/misc/matrix.py index 2c505d3..3bf18fc 100644 --- a/ajpastor/misc/matrix.py +++ b/ajpastor/misc/matrix.py @@ -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: diff --git a/ajpastor/operator/operator.py b/ajpastor/operator/operator.py index 7de0d1a..830eba5 100644 --- a/ajpastor/operator/operator.py +++ b/ajpastor/operator/operator.py @@ -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): diff --git a/releases/diff_defined_functions__0.5.zip b/releases/diff_defined_functions__0.5.zip index 7805f65..19370ae 100644 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 index 0000000..19370ae Binary files /dev/null and b/releases/old/diff_defined_functions__0.5__18.06.13_13:45:01.zip differ