From: Antonio Jimenez Pastor Date: Mon, 1 Oct 2018 14:06:01 +0000 (+0200) Subject: Fixed small error in Log X-Git-Url: http://git.risc.jku.at/gitweb/?a=commitdiff_plain;h=3f769ec81729eb4e00ec23313c37c029d5455e48;p=ajpastor%2Fdiff_defined_functions.git Fixed small error in Log Fixed error in toDiffAlgebraic Added the power with power series. --- diff --git a/ajpastor/dd_functions/ddExamples.py b/ajpastor/dd_functions/ddExamples.py index 611cf38..14b6b86 100644 --- a/ajpastor/dd_functions/ddExamples.py +++ b/ajpastor/dd_functions/ddExamples.py @@ -295,7 +295,7 @@ def Log(input, ddR = None): This function can be converted into symbolic expressions. ''' if(is_DDFunction(input)): - return Log(x+_sage_const_1 )(input); + return Log(x+_sage_const_1 )(input-1); f,dR = __decide_parent(input, ddR); evaluate = lambda p : dR.getSequenceElement(p,_sage_const_0 ); diff --git a/ajpastor/dd_functions/ddFunction.py b/ajpastor/dd_functions/ddFunction.py index 59f1415..340f954 100644 --- a/ajpastor/dd_functions/ddFunction.py +++ b/ajpastor/dd_functions/ddFunction.py @@ -1894,16 +1894,23 @@ class DDFunction (IntegralDomainElement): return super(DDFunction,self).__div__(self.__check_symbolic(other)); def __radd__(self, other): - return super(DDFunction,self).__add__(self.__check_symbolic(other)); + return super(DDFunction,self).__radd__(self.__check_symbolic(other)); def __rsub__(self, other): - return (-self) + self.__check_symbolic(other); + return super(DDFunction,self).__rsub__(self.__check_symbolic(other)); def __rmul__(self, other): - return super(DDFunction,self).__mul__(self.__check_symbolic(other)); + return super(DDFunction,self).__rmul__(self.__check_symbolic(other)); def __rdiv__(self, other): - return self.inverse * self.__check_symbolic(other); + return super(DDFunction,self).__rdiv__(self.__check_symbolic(other)); + + def __rpow__(self, other): + try: + print "__rpow__ was called"; + return self.parent().to_depth(1)(other)**self; + except: + return NotImplemented; def __iadd__(self, other): return super(DDFunction,self).__add__(self.__check_symbolic(other)); @@ -1974,20 +1981,39 @@ class DDFunction (IntegralDomainElement): except Exception: raise ZeroDivisionError("Impossible to compute the inverse"); return inverse.__pow__(-other); - else: ## Trying a power on the basic field - try: - newDDRing = DDRing(self.parent()); - other = self.parent().base_ring()(other); - self.__pows[other] = newDDRing.element([(-other)*f.derivative(),f], [el**other for el in f.getInitialValueList(1 )], check_init=False); + else: ## Trying a generic power + if(is_DDFunction(other) or other in self.parent()): + if(self(x=0) != 1): + raise ValueError("The base of exponentiation must have initial value 1"); + from ajpastor.dd_functions.ddExamples import Log; + lf = Log(self); + + R = sage.categories.pushout.pushout(other.parent(), lf.parent()); + g = R(other); lf = R(lf); + R = R.to_depth(R.depth()+1); + + if((g(x=0) != 0)): + raise ValueError("The exponent must have initial value 0"); newName = None; - if(not(self.__name is None)): - newName = DinamicString("(_1)^%s" %(other), self.__name); - self.__pows[other].__name = newName; - except TypeError: - raise TypeError("Impossible to compute (%s)^(%s) within the basic field %s" %(f.getInitialValue(0 ), other, f.parent().base_ring())); - except ValueError: - raise NotImplementedError("Powering to an element of %s not implemented" %(other.parent())); + if((not is_DDFunction(g)) or (g._DDFunction__name is not None)): + newName = DinamicString("(_1)^(_2)", [self.__name, repr(other)]); + + self.__pows[other] = R.element([-(lf*other).derivative(),1],[1],name=newName); + else: + try: + newDDRing = DDRing(self.parent()); + other = self.parent().base_ring()(other); + self.__pows[other] = newDDRing.element([(-other)*f.derivative(),f], [el**other for el in f.getInitialValueList(1 )], check_init=False); + + newName = None; + if(not(self.__name is None)): + newName = DinamicString("(_1)^%s" %(other), self.__name); + self.__pows[other].__name = newName; + except TypeError: + raise TypeError("Impossible to compute (%s)^(%s) within the basic field %s" %(f.getInitialValue(0 ), other, f.parent().base_ring())); + except ValueError: + raise NotImplementedError("Powering to an element of %s not implemented" %(other.parent())); return self.__pows[other]; diff --git a/ajpastor/dd_functions/toDiffAlgebraic.py b/ajpastor/dd_functions/toDiffAlgebraic.py index 56f42fd..273ab79 100644 --- a/ajpastor/dd_functions/toDiffAlgebraic.py +++ b/ajpastor/dd_functions/toDiffAlgebraic.py @@ -35,13 +35,34 @@ def get_InfinitePolynomialRingVaribale(parent, gen, number): #### TODO: Review this function def infinite_derivative(element, times=1, var=x): - if(times in ZZ and times > 1): + ''' + Method that takes an element and compute its times-th derivative + with respect to the variable given by var. + + If the element is not in a InfinitePolynomialRing then the method + 'derivative' of the object will be called. Otherwise this method + returns the derivative following the rules: + - The coefficients of the polynomial ring are differentiated using + a recursive call to this method (usually this leads to a call of the + method '.derivative' of that coefficient). + - Any variable "#_n" appearing in the InfinitePolynomialRing has + as derivative the variable "#_{n+1}", i.e., the same name but with + one higher index. + ''' + if(not ((times in ZZ) and times >=0)): + raise ValueError("The argument 'times' must be a non-negative integer"); + elif(times > 1): # Recursive call return infinite_derivative(infinite_derivative(element, times-1)) + elif(times == 0): # Empty call + return element; + + ## Call with times = 1 try: parent = element.parent(); except AttributeError: return 0; + ## Simple call: not an InfinitePolynomialRing if(not is_InfinitePolynomialRing(parent)): try: try: @@ -50,27 +71,42 @@ def infinite_derivative(element, times=1, var=x): return element.derivative(); except AttributeError: return parent.zero(); + + ## IPR call + ## Symbolic case? + if(sage.symbolic.ring.is_SymbolicExpressionRing(parent.base())): + raise TypeError("Base ring for the InfinitePolynomialRing not valid (found SymbolicRing)"); + ### Monomial case if(element.is_monomial()): + ## Case of degree 1 (add one to the index of the variable) if(len(element.variables()) == 1 and element.degree() == 1): g,n = get_InfinitePolynomialRingGen(parent, element, True); return get_InfinitePolynomialRingVaribale(parent, g,n+1); + ## Case of higher degree else: - degrees = element.degrees(); + # Computing the variables in the monomial and their degrees (in order) variables = element.variables(); degrees = [element.degree(v) for v in variables]; + variables = [parent(v) for v in variables] ## Computing the common factor - com_factor = prod([variables[i]**(degrees[i]-1) for i in range(len(degrees)) if degrees[i] > 0]); - ## Computing the derivative for each variable - each_sum = [ - degrees[i]*infinite_derivative(parent(variables[i]))*prod( - variables[j] for j in range(len(variables)) if ((i != j) and (degrees[j] > 0))) - for i in range(len(variables)) if degrees[i] > 0]; + com_factor = prod([variables[i]**(degrees[i]-1) for i in range(len(degrees))]); + ## Computing the derivative of each variable + der_variables = [infinite_derivative(parent(v)) for v in variables]; + + ## Computing the particular part for each summand + each_sum = []; + for i in range(len(variables)): + if(degrees[i] > 0): + part_prod = prod([variables[j] for j in range(len(variables)) if j != i]); + each_sum += [degrees[i]*infinite_derivative(parent(variables[i]))*part_prod]; + ## Computing the final result return com_factor*sum(each_sum); + ### Non-monomial case else: coefficients = element.coefficients(); - monomials = element.monomials(); - return sum([infinite_derivative(coefficients[i])*monomials[i] + parent(coefficients[i])*infinite_derivative(parent(monomials[i])) for i in range(len(monomials))]); + monomials = [parent(el) for el in element.monomials()]; + return sum([infinite_derivative(coefficients[i])*monomials[i] + coefficients[i]*infinite_derivative(monomials[i]) for i in range(len(monomials))]); def fromInfinityPolynomial_toFinitePolynomial(poly): if(not is_InfinitePolynomialRing(poly.parent())): diff --git a/releases/diff_defined_functions__0.6.zip b/releases/diff_defined_functions__0.6.zip index 53eb465..c4cca1b 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__18.10.01_16:05:59.zip b/releases/old/diff_defined_functions__0.6__18.10.01_16:05:59.zip new file mode 100644 index 0000000..c4cca1b Binary files /dev/null and b/releases/old/diff_defined_functions__0.6__18.10.01_16:05:59.zip differ