Updated the repository
authorAntonio Jimenez Pastor <ajpastor@risc.uni-linz.ac.at>
Wed, 6 Feb 2019 13:52:47 +0000 (14:52 +0100)
committerAntonio Jimenez Pastor <ajpastor@risc.uni-linz.ac.at>
Wed, 6 Feb 2019 13:52:47 +0000 (14:52 +0100)
ajpastor/dd_functions/__init__.py
ajpastor/dd_functions/lazyDDRing.py
ajpastor/lazy/conversion.py
releases/diff_defined_functions__0.6.zip
releases/old/diff_defined_functions__0.6__19.02.06_14:52:45.zip [new file with mode: 0644]

index 4bb1f3e..66d2738 100644 (file)
@@ -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__);
index 04d2b1b..39d5bee 100644 (file)
@@ -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
index 4cc1ada..4949906 100644 (file)
@@ -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():
index c492eb6..3361f62 100644 (file)
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 (file)
index 0000000..3361f62
Binary files /dev/null and b/releases/old/diff_defined_functions__0.6__19.02.06_14:52:45.zip differ