From: Antonio Jimenez Pastor Date: Wed, 6 Feb 2019 13:52:47 +0000 (+0100) Subject: Updated the repository X-Git-Url: http://git.risc.jku.at/gitweb/?a=commitdiff_plain;h=0f1d3ea20eabea027e1195b4ceddcc4b628a2c8f;p=ajpastor%2Fdiff_defined_functions.git Updated the repository --- diff --git a/ajpastor/dd_functions/__init__.py b/ajpastor/dd_functions/__init__.py index 4bb1f3e..66d2738 100644 --- a/ajpastor/dd_functions/__init__.py +++ b/ajpastor/dd_functions/__init__.py @@ -14,6 +14,10 @@ try: from .toDiffAlgebraic import *; except Exception: print "Error loading module dd_functions.toDiffAlgebraic"; +try: + from .lazyDDRing import *; +except Exception: + print "Error loading module dd_functions.lazyDDRing"; from pkgutil import extend_path; __path__ = extend_path(__path__, __name__); diff --git a/ajpastor/dd_functions/lazyDDRing.py b/ajpastor/dd_functions/lazyDDRing.py index 04d2b1b..39d5bee 100644 --- a/ajpastor/dd_functions/lazyDDRing.py +++ b/ajpastor/dd_functions/lazyDDRing.py @@ -2,7 +2,6 @@ # This file was *autogenerated* from the file ./lazyRing.sage from sage.all_cmdline import * # import sage library -_sage_const_2 = Integer(2); _sage_const_1 = Integer(1); _sage_const_0 = Integer(0); _sage_const_20 = Integer(20) from sage.rings.ring import IntegralDomain; from sage.structure.element import IntegralDomainElement; from sage.categories.integral_domains import IntegralDomains; @@ -15,6 +14,7 @@ from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing as is from ajpastor.lazy.conversion import ConversionSystem; from ajpastor.dd_functions.ddFunction import *; +from ajpastor.misc.ring_w_sequence import Ring_w_Sequence; from ajpastor.misc.matrix import differential_movement; #################################################################################################### @@ -36,7 +36,7 @@ class _LazyDDFunction(IntegralDomainElement): self.__poly = parent.poly_ring()(el); except: try: - self.__poly = parent.poly_field()(str(el)); + self.__poly = parent.poly_field()(el); except: self.__raw = parent.base()(el); self.__poly = self.parent().to_poly(self.__raw); @@ -101,13 +101,10 @@ class _LazyDDFunction(IntegralDomainElement): ### Arithmetics methods ################################################################################################ def _add_(self, other): - if(isinstance(other, _LazyDDFunction)): - try: - return _LazyDDFunction(self.parent(), self.poly()+self.parent()(other).poly()); - except NotImplementedError as e: - pass; - - return NotImplemented; + try: + return _LazyDDFunction(self.parent(), self.poly()+self.parent()(other).poly()); + except: + return NotImplemented; def _sub_(self,other): return self.__add__(-other); @@ -116,27 +113,19 @@ class _LazyDDFunction(IntegralDomainElement): try: return _LazyDDFunction(self.parent(), -self.poly()); except NotImplementedError: - pass; + return NotImplemented; - return NotImplemented; - def _mul_(self,other): - if(isinstance(other, _LazyDDFunction)): - try: - return _LazyDDFunction(self.parent(), self.poly()*self.parent()(other).poly()); - except NotImplementedError as e: - pass; - - return NotImplemented; + try: + return _LazyDDFunction(self.parent(), self.poly()*self.parent()(other).poly()); + except: + return NotImplemented; def _div_(self,other): - if(isinstance(other, _LazyDDFunction)): - try: - return _LazyDDFunction(self.parent(), self.parent().poly_field()(self.poly())/self.parent().poly_field()(self.parent()(other).poly())); - except NotImplementedError as e: - pass; - - return NotImplemented; + try: + return _LazyDDFunction(self.parent(), self.poly()/self.parent()(other).poly()); + except: + return NotImplemented; def _pow_(self,i): try: @@ -162,7 +151,7 @@ class _LazyDDFunction(IntegralDomainElement): ''' Method that a common divisor of 'self' and the input ''' - if(len(input) > _sage_const_1): + if(len(input) > 1): return self.gcd(input); return _LazyDDFunction(self.parent(), gcd([self.poly()]+[self.parent()(el).poly() for el in input])); @@ -171,7 +160,7 @@ class _LazyDDFunction(IntegralDomainElement): ''' Method that a common multiple of 'self' and the input ''' - if(len(input) > _sage_const_1 ): + if(len(input) > 1 ): return self.gcd(input); return _LazyDDFunction(self.parent(), lcm([self.poly()]+[self.parent()(el).poly() for el in input])); @@ -205,13 +194,16 @@ class _LazyDDFunction(IntegralDomainElement): except NotImplementedError: factors = pol.factor(proof=False); except: - factors = [(pol,_sage_const_1 )]; + factors = [(pol,1 )]; for factor in factors: - result = (self.parent().to_real(factor[_sage_const_0 ]) == _sage_const_0 ); + result = (self.parent().to_real(factor[0 ]) == 0 ); if(result): - self.parent().add_relations(factor[_sage_const_0 ]); + self.parent().add_relations(factor[0 ]); break; + if(result): + self.__poly = self.parent().poly_ring().zero(); + return result; @cached_method @@ -245,7 +237,7 @@ class LazyDDRing (UniqueRepresentation, ConversionSystem, IntegralDomain): Element = _LazyDDFunction; - def __init__(self, base, constants=QQ, var_name="z" category=None): + def __init__(self, base, constants=QQ, var_name="z", category=None): ''' Implementation of a Covnersion System using InfinitePolynomialRing as a basic structure. @@ -270,6 +262,7 @@ class LazyDDRing (UniqueRepresentation, ConversionSystem, IntegralDomain): self.__constants = constants; self.__poly_ring = InfinitePolynomialRing(constants, names=[var_name]); + self.__poly_field = self.__poly_ring.fraction_field(); self.__gen = self.__poly_ring.gens()[0]; self.__used = 0; @@ -284,7 +277,10 @@ class LazyDDRing (UniqueRepresentation, ConversionSystem, IntegralDomain): self.__map_of_derivatives = {}; # Map for each variable to its derivative (as a polynomial) ## Casting and Coercion system - self.base().register_conversion(LDRSimpleMorphism(self, self.base())); + self.base().register_conversion(LDRSimpleMorphism(self, self.base())); + + ## Adding the 'x' as a basic variable in the ring + self(DFinite.element([0,0,1],[0,1],name="x")); ################################################################################################ ### Implementing methods of ConversionSystem @@ -315,23 +311,23 @@ class LazyDDRing (UniqueRepresentation, ConversionSystem, IntegralDomain): try: built = element.built(); if(not (built is None)): - if(built[_sage_const_0 ] == "derivative"): - if(not(element in built[_sage_const_1 ])): - integral = self(built[_sage_const_1 ][_sage_const_0 ]); - if(not (integral.poly().is_monomial() and integral.poly().degree() == _sage_const_1 )): - return self(built[_sage_const_1 ][_sage_const_0 ]).derivative().poly(); - elif(built[_sage_const_0 ] == "polynomial"): + if(built[0 ] == "derivative"): + if(not(element in built[1 ])): + integral = self(built[1 ][0 ]); + if(not (integral.poly().is_monomial() and integral.poly().degree() == 1 )): + return self(built[1 ][0 ]).derivative().poly(); + elif(built[0 ] == "polynomial"): ## We check we do not have infinite recursion - if(not element in built[_sage_const_1 ][_sage_const_1 ].values()): + if(not element in built[1 ][1 ].values()): ## We have some building information - polys = {key : self.to_poly(built[_sage_const_1 ][_sage_const_1 ][key]) for key in built[_sage_const_1 ][_sage_const_1 ]}; - return built[_sage_const_1 ][_sage_const_0 ](**polys); + polys = {key : self.to_poly(built[1 ][1 ][key]) for key in built[1 ][1 ]}; + return built[1 ][0 ](**polys); except AttributeError: pass; ## Otherwise we look for a linear relation between the element and the variables ## Breath-search for a linear relation - roots = [el for el in self.__r_graph.vertices() if self.__r_graph.in_degree() == 0];# Getting roots + roots = [el for el in self.__r_graph if self.__r_graph.in_degree(el) == 0];# Getting roots from collections import deque; to_search = deque(roots); # Initializing the queue while(len(to_search) > 0): @@ -341,7 +337,7 @@ class LazyDDRing (UniqueRepresentation, ConversionSystem, IntegralDomain): to_search.append(edge[1]); # Visiting the current node - relation = self.__find_relation(element, current); + relation = self.__find_relation(element, current, self.__trans[current][1].nrows()); if(not (relation is None)): ## If it is not just the function, create a new node for future relations if(relation[0] != 0): @@ -350,14 +346,14 @@ class LazyDDRing (UniqueRepresentation, ConversionSystem, IntegralDomain): ## Creating the vector in the current level v = [0 for i in range(self.__trans[current][1].nrows())]; - v[relation[0]] = relation[1]; - v = vector(self, v); + v[relation[0]] = relation[1][0]; + v = vector(self.poly_field(), v); ## Going to a root with the vector - v,const,dest = self.__pullup_vector(v, self.__poly_ring().zero(), current); + v,const,dest = self.__pullup_vector(v, relation[1][1], current); ## Returning the appropriate polynomial using the final vector - return self.__vector_to_poly(v, dest); + return self.__vector_to_poly(v, dest)+const; ## At this point, no direct relation was found. We look for relation between element and the roots for root in roots: @@ -367,6 +363,10 @@ class LazyDDRing (UniqueRepresentation, ConversionSystem, IntegralDomain): self.__add_function(element, gen=True); self.__r_graph.add_edge((element, root, relation)); + # Adding the relation for future simplifications + rel = self.__gen[root] - relation[1][1]*self.__gen[self.__map_to_vars[element]+relation[0]] - relation[1][1]; + self.add_relations(rel); + # Removing root as a generator index = self.__gens.index(self.__gen[self.__map_to_vars[root]]); for i in range(self.__trans[root][1].nrows()): @@ -421,6 +421,12 @@ class LazyDDRing (UniqueRepresentation, ConversionSystem, IntegralDomain): def element(self, X): return self(X); + def gens(self): + return self.__gens; + + def ngens(self): + return len(self.__gens); + ################################################################################################ ### Other Ring methods ################################################################################################ @@ -441,8 +447,10 @@ class LazyDDRing (UniqueRepresentation, ConversionSystem, IntegralDomain): ################################################################################################ def _coerce_map_from_(self, S): coer = None; - if(isinstance(S, LazyRing)): + if(isinstance(S, LazyDDRing)): coer = self.base()._coerce_map_from_(S.base()); + elif(S == self.poly_ring() or S == self.poly_field()): + coer = True; elif(S == self.base()): coer = True; else: @@ -457,15 +465,14 @@ class LazyDDRing (UniqueRepresentation, ConversionSystem, IntegralDomain): return (not(coer is False) and not(coer is None)); def _element_constructor_(self, *args, **kwds): - if(len(args) < _sage_const_1 ): - print args + if(len(args) < 1 ): raise ValueError("Impossible to build an element without arguments"); - i = _sage_const_0 ; - if(len(args) >= _sage_const_2 ): - if(not (args[_sage_const_0 ] is self)): + i = 0 ; + if(len(args) >= 2 ): + if(not (args[0 ] is self)): raise ValueError("RIOKO: What the .... are you sending to this method?"); - i = _sage_const_1 ; + i = 1 ; X = args[i]; try: @@ -552,10 +559,10 @@ class LazyDDRing (UniqueRepresentation, ConversionSystem, IntegralDomain): order = f.getOrder(); relation = None; - for i in range(f.getOrder(),0,-1): - n_relation = self.__find_relation(derivatives[i], derivatives[:i-1], _debug); + for i in range(f.getOrder()-1,0,-1): + n_relation = self.__find_relation(derivatives[i], derivatives[:i]); if(not (n_relation is None)): - order = i-1; + order = i; relation = n_relation; else: break; @@ -568,11 +575,11 @@ class LazyDDRing (UniqueRepresentation, ConversionSystem, IntegralDomain): new_row = [companion[i][j] for j in range(order)]; if(i == relation[0]): new_row[-1] = relation[1][0]; - C += [[companion[i][j] for j in range(k-1)] + []]; + C += [new_row]; C = Matrix(self,C); - self.__trans[f] = (relation[1],C); + self.__trans[f] = (relation[1][1],C); else: - self.__trans[f] = (self.zero(),Matrix(self, f.equation.companion())); + self.__trans[f] = (self.poly_ring().zero(),Matrix(self, f.equation.companion())); ## Adding f as a vertex (edges must be added outside this function) self.__r_graph.add_vertex(f); @@ -589,57 +596,65 @@ class LazyDDRing (UniqueRepresentation, ConversionSystem, IntegralDomain): return; - def __find_relation(self, g,f): - ''' - Method that get the relation between g and a f. If possible, it computes the derivatives up to - some order of f and check relations with them. - - It returns a tuple (k,res) where: - - k: the first index which we found a relation - - res: the relation (see __find_linear_relation to see how such relation is expressed). - - Then the following statement is always True: - g == f[k]*res[0] + res[1] - ''' - if(is_DDFunction(f)): - f = [f.derivative(times=i) for i in range(f.getOrder())]; - - for k in range(d): - res = __find_linear_relation(g,f[k]); - if(not (res is None)): - return (k,res); - - return None; - -def __find_linear_relation(f,g): - ''' - This method receives two DDFunctions and return two constants (c,d) such that f = cg+d. - None is return if those constants do not exist. - ''' - if(not (is_DDFunction(f) and is_DDFunction(g))): - raise TypeError("find_linear_relation: The functions are not DDFunctions"); - - ## Simplest case: some of the functions are constants is a constant - if(f.is_constant): - return (f.parent().zero(), f(0)); - elif(g.is_constant): + def __find_relation(self, g,f,d=None): + ''' + Method that get the relation between g and a f. If possible, it computes + the derivatives up to some order of f and check relations with them. + + It returns a tuple (k,res) where + - k: the first index which we found a relation + - res: the relation (see __find_linear_relation to see how such + relation is expressed). + + Then the following statement is always True + g == f[k]*res[0] + res[1] + + INPUT: + - g: Function we want to see the relation + - f: Function or list of functions where we look for relations + - d: Optional parameter to limit + ''' + if(is_DDFunction(f)): # If f is a function, computing the derivatives + f = [f.derivative(times=i) for i in range(f.getOrder())]; + if(not(d is None)): + f = f[:d]; # Limiting the list with the optional parameter d + + for k in range(len(f)): + res = self.__find_linear_relation(g,f[k]); + if(not (res is None)): + return (k,res); + return None; - try: - of = 1; og = 1; - while(f.getSequenceElement(of) == 0): of += 1; - while(g.getSequenceElement(og) == 0): og += 1; - - if(of == og): - c = f.getSequenceElement(of)/g.getSequenceElement(og); - d = f(0) - c*g(0); + def __find_linear_relation(self, f,g): + ''' + This method receives two DDFunctions and return two constants (c,d) + such that f = cg+d. None is return if those constants do not exist. + ''' + if(not (is_DDFunction(f) and is_DDFunction(g))): + raise TypeError("find_linear_relation: The functions are not DDFunctions"); + + ## Simplest case: some of the functions are constants is a constant + if(f.is_constant): + return (f.parent().zero(), f(0)); + elif(g.is_constant): + return None; + + try: + of = 1; og = 1; + while(f.getSequenceElement(of) == 0): of += 1; + while(g.getSequenceElement(og) == 0): og += 1; - if(f == c*g + d): - return (c,d); - except Exception: - pass; - - return None; + if(of == og): + c = f.getSequenceElement(of)/g.getSequenceElement(og); + d = f(0) - c*g(0); + + if(f == c*g + d): + return (c,d); + except Exception: + pass; + + return None; #################################################################################################### #################################################################################################### @@ -649,7 +664,7 @@ def __find_linear_relation(f,g): class LazyDDRingFunctor (ConstructionFunctor): def __init__(self): ID = IntegralDomains(); - self.rank = _sage_const_20 ; + self.rank = 20 ; super(LazyDDRingFunctor, self).__init__(ID,ID); ### Methods to implement diff --git a/ajpastor/lazy/conversion.py b/ajpastor/lazy/conversion.py index 4cc1ada..4949906 100644 --- a/ajpastor/lazy/conversion.py +++ b/ajpastor/lazy/conversion.py @@ -5,6 +5,8 @@ from sage.all_cmdline import * # import sage library _sage_const_1 = Integer(1); _sage_const_0 = Integer(0) from sage.rings.polynomial.polynomial_ring import is_PolynomialRing as isUniPolynomial; from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing as isMPolynomial; +from sage.rings.polynomial.infinite_polynomial_ring import InfinitePolynomialRing_dense as isDenseIPolynomial; +from sage.rings.polynomial.infinite_polynomial_ring import InfinitePolynomialRing_sparse as isSparseIPolynomial; class ConversionSystem(object): ## Main bulder @@ -34,7 +36,10 @@ class ConversionSystem(object): ''' Returns a Boolean value that show if there are variables in this conversion system. ''' - return (isUniPolynomial(self.poly_ring()) or isMPolynomial(self.poly_ring())); + return (isUniPolynomial(self.poly_ring()) or + isMPolynomial(self.poly_ring()) or + isinstance(self.poly_ring(),isDenseIPolynomial) or + isinstance(self.poly_ring(),isSparseIPolynomial)); def poly_ring(self): ''' @@ -132,7 +137,12 @@ class ConversionSystem(object): if(poly in self.poly_ring()): if(not self.is_polynomial()): return self.base()(poly); - return self._to_real_element(self.poly_ring()(poly)); + try: + n = self._to_real_element(self.poly_ring()(poly.numerator())); + d = self._to_real_element(self.poly_ring()(poly.denominator())); + return n/d; + except AttributeError: + return self._to_real_element(self.poly_ring()(poly)); elif(poly in self.poly_field()): n = self.to_real(poly.numerator()); d = self.to_real(poly.denominator()); @@ -170,10 +180,16 @@ class ConversionSystem(object): from sage.structure.element import is_Vector; if(element in self.poly_ring()): - try: - return self.poly_ring()(element).reduce(self._relations()); + element = self.poly_ring()(element); + try: # Weird case: fraction field fall in polynomial field + n = self.poly_ring()(element.numerator()).reduce(self._relations()); + d = self.poly_ring()(element.denominator()).reduce(self._relations()); + return n/d; except AttributeError: - return self.poly_ring()(element); + try: + return self.poly_ring()(element).reduce(self._relations()); + except AttributeError: + return self.poly_ring()(element); elif(element in self.poly_field()): element = self.poly_field()(element); n = self.simplify(element.numerator()); @@ -250,7 +266,7 @@ class ConversionSystem(object): This method can be overwritten if needed. ''' - variables = polynomial.parent().gens(); + variables = polynomial.variables(); multi = (len(variables) > _sage_const_1 ); res = self.base().zero(); for (k,v) in polynomial.dict().items(): diff --git a/releases/diff_defined_functions__0.6.zip b/releases/diff_defined_functions__0.6.zip index c492eb6..3361f62 100644 Binary files a/releases/diff_defined_functions__0.6.zip and b/releases/diff_defined_functions__0.6.zip differ diff --git a/releases/old/diff_defined_functions__0.6__19.02.06_14:52:45.zip b/releases/old/diff_defined_functions__0.6__19.02.06_14:52:45.zip new file mode 100644 index 0000000..3361f62 Binary files /dev/null and b/releases/old/diff_defined_functions__0.6__19.02.06_14:52:45.zip differ