Added function to compute the equation for the multiplicative
authorAntonio Jimenez Pastor <antonio@ebook.dk-compmath.jku.at>
Fri, 12 Oct 2018 08:59:18 +0000 (10:59 +0200)
committerAntonio Jimenez Pastor <antonio@ebook.dk-compmath.jku.at>
Fri, 12 Oct 2018 08:59:18 +0000 (10:59 +0200)
inverse of DA-algebraic functions.

ajpastor/dd_functions/ddFunction.py
ajpastor/dd_functions/toDiffAlgebraic.py
releases/diff_defined_functions__0.6.zip
releases/old/diff_defined_functions__0.6__18.10.12_10:59:18.zip [new file with mode: 0644]

index 82468ab..45b6bb5 100644 (file)
@@ -1861,15 +1861,40 @@ class DDFunction (IntegralDomainElement):
     def to_simpler(self):
         try:
             R = self.parent().base();
-            if(is_DDRing(R)):
-                return R(self).to_simpler();
+            if(self.is_constant):
+                return self.parent().base_field(self.getInitialValue(0));
+            elif(is_DDRing(R)):
+                coeffs = [el.to_simpler() for el in self.equation.getCoefficients()];
+                parents = [el.parent() for el in coeffs];
+                final_base = reduce(lambda p,q : pushout(p,q), parents, parents[0]);
+                
+                dR = None;
+                if(is_DDRing(final_base)):
+                    dR = final_base.to_depth(final_base.depth()+1);
+                    
+                elif(not is_DDRing(final_base)):
+                    params = [str(g) for g in final_base.gens()];
+                    var = repr(self.parent().variables()[0]);
+                    
+                    if(var in params):
+                        params.remove(var);
+                    hyper_base = DDRing(PolynomialRing(QQ,[var]));
+                    if(len(params) > 0):
+                        dR = ParametrizedDDRing(hyper_base, params);
+                    else:
+                        dR = hyper_base;
+                else:
+                    raise TypeError("1:No optimization found in the simplifacion");
+                
+                return dR.element([dR.base()(el) for el in coeffs], self.getInitialValueList(self.equation.jp_value+1), name=self.__name).to_simpler();
+                        
             elif(is_PolynomialRing(R)):
                 degs = [self[i].degree() - i for i in range(self.getOrder()+1)];
                 m = max(degs);
                 maxs = [i for i in range(len(degs)) if degs[i] == m];
                 
                 if(len(maxs) <= 1):
-                    raise ValueError("1:Function %s is not a polynomial" %repr(self));
+                    raise ValueError("2:Function %s is not a polynomial" %repr(self));
                 
                 x = R.gens()[0];
                 pol = sum(falling_factorial(x,i)*self[i].lc() for i in maxs);
@@ -1879,9 +1904,9 @@ class DDFunction (IntegralDomainElement):
 
                 if(pol == self):
                     return pol;
-                raise ValueError("2:Function %s is not a polynomial" %repr(self));
+                raise ValueError("3:Function %s is not a polynomial" %repr(self));
         except Exception as e:
-            print e;
+            pass;
         return self;
             
     def quick_equals(self,other): ### TO REVIEW
@@ -2067,7 +2092,7 @@ class DDFunction (IntegralDomainElement):
                     from ajpastor.dd_functions.ddExamples import Log;
                     lf = Log(self);
                     
-                    R = sage.categories.pushout.pushout(other.parent(), lf.parent());
+                    R = pushout(other.parent(), lf.parent());
                     g = R(other); lf = R(lf);
                     R = R.to_depth(R.depth()+1);
                     
index e061b46..9b9f885 100644 (file)
@@ -3,6 +3,7 @@ from sage.all_cmdline import *   # import sage library
 
 from sage.rings.polynomial.polynomial_ring import is_PolynomialRing; 
 from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing;
+from sage.rings.fraction_field import is_FractionField;
 
 from ajpastor.dd_functions.ddFunction import *;
 from sage.rings.polynomial.infinite_polynomial_ring import InfinitePolynomialRing;
@@ -203,6 +204,7 @@ def toDifferentiallyAlgebraic_Below(poly):
             rows += [row for row in matrix_of_dMovement(C, vector(goal_ring, dict_to_vectors[el]), infinite_derivative, S)];
         
     M = Matrix(rows);
+    print M;
     return M.determinant().numerator();
 
 def diff_to_diffalg(func):
@@ -220,9 +222,46 @@ def diff_to_diffalg(func):
     else:
         R = PolynomialRing(PolynomialRing(QQ,x).fraction_field, "y_0");
         return R.gens()[0] - func;
+    
+def inverse_DA(poly, vars=None):
+    '''
+        Method that computes the DA equation for the multiplicative inverse 
+        of the solutions of a DA equation.
+        
+        We assume that the variables given by vars are the variables representing
+        the solution, namely vars[i+1] = vars[i].derivative().
+        If vars is not provided, we take all the variables from the polynomial
+        that is given.
+    '''
+    ## Checking that poly is a polynomial
+    
+    parent = poly.parent();
+    if(is_FractionField(parent)):
+        parent = parent.base();
+    if(is_InfinitePolynomialRing(parent)):
+        poly = fromInfinityPolynomial_toFinitePolynomial(poly);
+        return inverse_DA(poly, vars);
+    if(not (is_PolynomialRing(parent) or is_MPolynomialRing(parent))):
+        raise TypeError("No polynomial is given");
+    poly = parent(poly);
+    
+    ## Getting the list of variables
+    if(vars is None):
+        g = poly.parent().gens();
+    else:
+        if(any(v not in poly.parent().gens())):
+            raise TypeError("The variables given are not in the polynomial ring");
+        g = vars;
+        
+    ## Computing the derivative of the inverse using Faa di Bruno's formula
+    derivatives = [1/g[0]] + [sum((falling_factorial(-1, k)/g[0]**(k+1))*bell_polynomial(n,k)(*g[1:n-k+2]) for k in range(1,n+1)) for n in range(1,len(g
+))];
+    
+    ## Computing the final equation
+    return poly(**{str(g[i]): derivatives[i] for i in range(len(g))}).numerator();
 
 
 ####################################################################################################
 #### PACKAGE ENVIRONMENT VARIABLES
 ####################################################################################################
-__all__ = ["is_InfinitePolynomialRing", "get_InfinitePolynomialRingGen", "get_InfinitePolynomialRingVaribale", "infinite_derivative", "toDifferentiallyAlgebraic_Below", "diff_to_diffalg"];
+__all__ = ["is_InfinitePolynomialRing", "get_InfinitePolynomialRingGen", "get_InfinitePolynomialRingVaribale", "infinite_derivative", "toDifferentiallyAlgebraic_Below", "diff_to_diffalg", "inverse_DA"];
index ac15bb5..5c5445d 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__18.10.12_10:59:18.zip b/releases/old/diff_defined_functions__0.6__18.10.12_10:59:18.zip
new file mode 100644 (file)
index 0000000..5c5445d
Binary files /dev/null and b/releases/old/diff_defined_functions__0.6__18.10.12_10:59:18.zip differ