Ticket #7377: trac_7377-assumptions-p3.patch

File trac_7377-assumptions-p3.patch, 25.8 KB (added by jpflori, 8 years ago)

More fixes

• sage/calculus/calculus.py

# HG changeset patch
# User Karl-Dieter Crisman <kcrisman@gmail.com>
# Date 1299792266 18000
# Node ID c86e54a6bef8e0625f47bac2ec1128c30d0f235a
# Parent  8e1dc3ae4ccc1b0ab2a5da96e0f484e56265138f
Trac 7377 - provisional patch fixing error messages for assumptions

Also fixes various other things, including extra documentation in a number of places and additional examples of assumptions in summation, integration, and limits.

diff -r 8e1dc3ae4ccc -r c86e54a6bef8 sage/calculus/calculus.py
 a sage: symbolic_sum(a*q^k, k, 0, n) (a*q^(n + 1) - a)/(q - 1) The geometric series:: For the geometric series, we will have to assume the right values for the sum to converge:: sage: assume(abs(q) < 1) sage: symbolic_sum(a*q^k, k, 0, oo) Traceback (most recent call last): ... ValueError: Sum is divergent. sage: forget() sage: assumptions() # check the assumptions were really forgotten [] This summation only Mathematica can perform:: raise ValueError, "summation limits must not depend on the summation variable" if algorithm == 'maxima': try: return maxima.sr_sum(expression,v,a,b) except TypeError, error: s = str(error) if "divergent" in s or 'Pole encountered' in s: raise ValueError, "Sum is divergent." else: raise return maxima.sr_sum(expression,v,a,b) elif algorithm == 'mathematica': try: sage: CDF(f.limit(x = I)) 2.06287223508 + 0.74500706218*I Notice that Maxima may ask for more information:: sage: var('a') a sage: limit(x^a,x=0) Traceback (most recent call last): ... ValueError: Computation failed since Maxima requested additional constraints; using the 'assume' command before limit evaluation *may* help (see assume? for more details) Is  a  positive, negative, or zero? With this example, Maxima is looking for a LOT of information:: sage: assume(a>0) sage: limit(x^a,x=0) Traceback (most recent call last): ... ValueError: Computation failed since Maxima requested additional constraints; using the 'assume' command before limit evaluation *may* help (see assume? for more details) Is a an integer? sage: assume(a,'integer') sage: limit(x^a,x=0) Traceback (most recent call last): ... ValueError: Computation failed since Maxima requested additional constraints; using the 'assume' command before limit evaluation *may* help (see assume? for more details) Is a an even number? sage: assume(a,'even') sage: limit(x^a,x=0) 0 sage: forget() More examples:: sage: limit(x*log(x), x = 0, dir='+')
• sage/calculus/functional.py

diff -r 8e1dc3ae4ccc -r c86e54a6bef8 sage/calculus/functional.py
 a sage: integral(abs(x)*x, x, 0, a) Traceback (most recent call last): ... TypeError: Computation failed since Maxima requested additional constraints (try the command 'assume(a>0)' before integral or limit evaluation, for example): ValueError: Computation failed since Maxima requested additional constraints; using the 'assume' command before integral evaluation *may* help (example of legal syntax is 'assume(a>0)', see assume? for more details) Is  a  positive, negative, or zero? sage: assume(a>0) sage: integral(abs(x)*x, x, 0, a)
• sage/interfaces/maxima.py

diff -r 8e1dc3ae4ccc -r c86e54a6bef8 sage/interfaces/maxima.py
 a def _expect_expr(self, expr=None, timeout=None): """ EXAMPLES: sage: a,b=var('a,b') sage: integrate(1/(x^3 *(a+b*x)^(1/3)),x) Wait for a given expression expr (which could be a regular expression or list of regular expressions) to appear in the output for at most timeout seconds. See sage.interfaces.expect.Expect._expect_expr for full details on its use and functionality. TESTS: These tests indirectly show that the interface is working and catching certain errors:: sage: maxima('2+2') 4 sage: maxima('integrate(1/(x^3*(a+b*x)^(1/3)),x)') Traceback (most recent call last): ... TypeError: Computation failed since Maxima requested additional constraints (try the command 'assume(a>0)' before integral or limit evaluation, for example): TypeError: Computation failed since Maxima requested additional constraints (try the command "maxima.assume('a>0')" before integral or limit evaluation, for example): Is  a  positive or negative? sage: assume(a>0) sage: integrate(1/(x^3 *(a+b*x)^(1/3)),x) 2/9*sqrt(3)*b^2*arctan(1/3*(2*(b*x + a)^(1/3) + a^(1/3))*sqrt(3)/a^(1/3))/a^(7/3) + 2/9*b^2*log((b*x + a)^(1/3) - a^(1/3))/a^(7/3) - 1/9*b^2*log((b*x + a)^(2/3) + (b*x + a)^(1/3)*a^(1/3) + a^(2/3))/a^(7/3) + 1/6*(4*(b*x + a)^(5/3)*b^2 - 7*(b*x + a)^(2/3)*a*b^2)/((b*x + a)^2*a^2 - 2*(b*x + a)*a^3 + a^4) sage: var('x, n') (x, n) sage: integral(x^n,x) sage: maxima.assume('a>0') [a>0] sage: maxima('integrate(1/(x^3*(a+b*x)^(1/3)),x)') -b^2*log((b*x+a)^(2/3)+a^(1/3)*(b*x+a)^(1/3)+a^(2/3))/(9*a^(7/3))+2*b^2*atan((2*(b*x+a)^(1/3)+a^(1/3))/(sqrt(3)*a^(1/3)))/(3^(3/2)*a^(7/3))+2*b^2*log((b*x+a)^(1/3)-a^(1/3))/(9*a^(7/3))+(4*b^2*(b*x+a)^(5/3)-7*a*b^2*(b*x+a)^(2/3))/(6*a^2*(b*x+a)^2-12*a^3*(b*x+a)+6*a^4) sage: maxima('integrate(x^n,x)') Traceback (most recent call last): ... TypeError: Computation failed since Maxima requested additional constraints (try the command 'assume(n+1>0)' before integral or limit evaluation, for example): TypeError: Computation failed since Maxima requested additional constraints (try the command "maxima.assume('n+1>0')" before integral or limit evaluation, for example): Is  n+1  zero or nonzero? sage: assume(n+1>0) sage: integral(x^n,x) x^(n + 1)/(n + 1) sage: forget() sage: maxima.assume('n+1>0') [n>-1] sage: maxima('integrate(x^n,x)') x^(n+1)/(n+1) sage: maxima.forget([fact for fact in maxima.facts()]) [[a>0,n>-1]] sage: maxima.facts() [] sage: var('a') a sage: maxima('limit(x^a,x,0)') Traceback (most recent call last): ... TypeError: Computation failed since Maxima requested additional constraints (try the command "maxima.assume('a>0')" before integral or limit evaluation, for example): Is  a  positive, negative, or zero? """ if expr is None: expr = self._prompt_wait j = v.find('Is ') v = v[j:] k = v.find(' ',4) msg = "Computation failed since Maxima requested additional constraints (try the command 'assume(" + v[4:k] +">0)' before integral or limit evaluation, for example):\n" + v + self._ask[i-1] msg = """Computation failed since Maxima requested additional constraints (try the command "maxima.assume('""" + v[4:k] +""">0')" before integral or limit evaluation, for example):\n""" + v + self._ask[i-1] self._sendline(";") self._expect_expr() raise ValueError, msg """ return MaximaElementFunction ##some helper functions to wrap tha calculus use of the maxima interface. ##some old helper functions to wrap the calculus use of the maxima interface. ##these routines expect arguments living in the symbolic ring and return something ##that is hopefully coercible into the symbolic ring again. def sr_integral(self,*args): return args._maxima_().integrate(*args[1:]) def sr_sum(self,expression,v,a,b): sum  = "'sum(%s, %s, %s, %s)" % tuple([repr(expr._maxima_()) for expr in (expression, v, a, b)]) result = self.simplify_sum(sum) result = result.ratsimp() return expression.parent()(result) def sr_limit(self,ex,*args): return ex._maxima_().limit(*args) def sr_tlimit(self,ex,*args): return ex._maxima_().tlimit(*args) ## ##    def sr_integral(self,*args): ##        return args._maxima_().integrate(*args[1:]) ## ##    def sr_sum(self,expression,v,a,b): ##        sum  = "'sum(%s, %s, %s, %s)" % tuple([repr(expr._maxima_()) for expr in (expression, v, a, b)]) ##        result = self.simplify_sum(sum) ##        result = result.ratsimp() ##        return expression.parent()(result) ## ##    def sr_limit(self,ex,*args): ##        return ex._maxima_().limit(*args) ## ##    def sr_tlimit(self,ex,*args): ##        return ex._maxima_().tlimit(*args) ## def is_MaximaElement(x): """
• sage/interfaces/maxima_lib.py

diff -r 8e1dc3ae4ccc -r c86e54a6bef8 sage/interfaces/maxima_lib.py
 a ##that is hopefully coercible into the symbolic ring again. def sr_integral(self,*args): """ Helper function to wrap calculus use of Maxima's integration. TESTS:: sage: a,b=var('a,b') sage: integrate(1/(x^3 *(a+b*x)^(1/3)),x) Traceback (most recent call last): ... ValueError: Computation failed since Maxima requested additional constraints; using the 'assume' command before integral evaluation *may* help (example of legal syntax is 'assume(a>0)', see assume? for more details) Is  a  positive or negative? sage: assume(a>0) sage: integrate(1/(x^3 *(a+b*x)^(1/3)),x) 2/9*sqrt(3)*b^2*arctan(1/3*(2*(b*x + a)^(1/3) + a^(1/3))*sqrt(3)/a^(1/3))/a^(7/3) + 2/9*b^2*log((b*x + a)^(1/3) - a^(1/3))/a^(7/3) - 1/9*b^2*log((b*x + a)^(2/3) + (b*x + a)^(1/3)*a^(1/3) + a^(2/3))/a^(7/3) + 1/6*(4*(b*x + a)^(5/3)*b^2 - 7*(b*x + a)^(2/3)*a*b^2)/((b*x + a)^2*a^2 - 2*(b*x + a)*a^3 + a^4) sage: var('x, n') (x, n) sage: integral(x^n,x) Traceback (most recent call last): ... ValueError: Computation failed since Maxima requested additional constraints; using the 'assume' command before integral evaluation *may* help (example of legal syntax is 'assume(n+1>0)', see assume? for more details) Is  n+1  zero or nonzero? sage: assume(n+1>0) sage: integral(x^n,x) x^(n + 1)/(n + 1) sage: forget() sage: assumptions()  # Check the assumptions really were forgotten [] """ try: return max_to_sr(maxima_eval(([max_integrate],[sr_to_max(SR(a)) for a in args]))) except RuntimeError, error: s = str(error) if "Divergent" in s or "divergent" in s: # in pexpect interface, one looks for this - e.g. integrate(1/x^3,x,-1,3) gives a principal value #            if "divergent" in s or 'Principal Value' in s: raise ValueError, "Integral is divergent." elif "Is" in s: # Maxima asked for a condition j = s.find('Is ') s = s[j:] k = s.find(' ',4) raise ValueError, "Computation failed since Maxima requested additional constraints; using the 'assume' command before integral evaluation *may* help (example of legal syntax is 'assume(" + s[4:k] +">0)', see assume? for more details)\n" + s else: raise error def sr_sum(self,*args): """ Helper function to wrap calculus use of Maxima's summation. TESTS:: sage: x, y, k, n = var('x, y, k, n') sage: sum(binomial(n,k) * x^k * y^(n-k), k, 0, n) (x + y)^n sage: q, a = var('q, a') sage: sum(a*q^k, k, 0, oo) Traceback (most recent call last): ... ValueError: Computation failed since Maxima requested additional constraints; using the 'assume' command before summation *may* help (example of legal syntax is 'assume(abs(q)-1>0)', see assume? for more details) Is  abs(q)-1  positive, negative, or zero? sage: assume(q > 1) sage: sum(a*q^k, k, 0, oo) Traceback (most recent call last): ... ValueError: Sum is divergent. sage: forget() sage: assume(abs(q) < 1) sage: sum(a*q^k, k, 0, oo) -a/(q - 1) sage: forget() sage: assumptions() # check the assumptions were really forgotten [] """ try: return max_to_sr(maxima_eval([[max_ratsimp],[[max_simplify_sum],([max_sum],[sr_to_max(SR(a)) for a in args])]])); except RuntimeError, error: s = str(error) if "divergent" in s: # in pexpect interface, one looks for this - could not find an example where 'Pole encountered' occurred, though #            if "divergent" in s or 'Pole encountered' in s: raise ValueError, "Sum is divergent." elif "Is" in s: # Maxima asked for a condition j = s.find('Is ') s = s[j:] k = s.find(' ',4) raise ValueError, "Computation failed since Maxima requested additional constraints; using the 'assume' command before summation *may* help (example of legal syntax is 'assume(" + s[4:k] +">0)', see assume? for more details)\n" + s else: raise error def sr_limit(self,expr,v,a,dir=None): L=[sr_to_max(SR(a)) for a in [expr,v,a]] if dir == "plus": L.append(max_plus) elif dir == "minus": L.append(max_minus) return max_to_sr(maxima_eval(([max_limit],L))) """ Helper function to wrap calculus use of Maxima's limits. TESTS:: sage: f = (1+1/x)^x sage: limit(f,x = oo) e sage: limit(f,x = 5) 7776/3125 sage: limit(f,x = 1.2) 2.06961575467... sage: var('a') a sage: limit(x^a,x=0) Traceback (most recent call last): ... ValueError: Computation failed since Maxima requested additional constraints; using the 'assume' command before limit evaluation *may* help (see assume? for more details) Is  a  positive, negative, or zero? sage: assume(a>0) sage: limit(x^a,x=0) Traceback (most recent call last): ... ValueError: Computation failed since Maxima requested additional constraints; using the 'assume' command before limit evaluation *may* help (see assume? for more details) Is a an integer? sage: assume(a,'integer') sage: assume(a,'even')  # Yes, Maxima will ask this too sage: limit(x^a,x=0) 0 sage: forget() sage: assumptions() # check the assumptions were really forgotten [] """ try: L=[sr_to_max(SR(a)) for a in [expr,v,a]] if dir == "plus": L.append(max_plus) elif dir == "minus": L.append(max_minus) return max_to_sr(maxima_eval(([max_limit],L))) except RuntimeError, error: s = str(error) if "Is" in s: # Maxima asked for a condition j = s.find('Is ') s = s[j:] raise ValueError, "Computation failed since Maxima requested additional constraints; using the 'assume' command before limit evaluation *may* help (see assume? for more details)\n" + s else: raise error def sr_tlimit(self,expr,v,a,dir=None): """ Helper function to wrap calculus use of Maxima's Taylor series limits. TESTS:: sage: f = (1+1/x)^x sage: limit(f, x = I, taylor=True) (-I + 1)^I """ L=[sr_to_max(SR(a)) for a in [expr,v,a]] if dir == "plus": L.append(max_plus)
• sage/symbolic/assumptions.py

diff -r 8e1dc3ae4ccc -r c86e54a6bef8 sage/symbolic/assumptions.py
 a """ from sage.calculus.calculus import maxima if self._context is None: # We get the list here because features may be added with time. # We get the list here because features may be added with time. valid_features = list(maxima("features")) if self._assumption not in [repr(x).strip() for x in list(valid_features)]: raise ValueError, "%s not a valid assumption, must be one of %s" % (self._assumption, valid_features) self._context = maxima.newcontext('context' + maxima._next_var_name()) try: maxima.eval("declare(%s, %s)" % (repr(self._var), self._assumption)) except TypeError, mess: #            except TypeError, mess: #                if 'inconsistent' in str(mess): # note Maxima doesn't tell you if declarations are redundant #                    raise ValueError, "Assumption is inconsistent" except RuntimeError, mess: if 'inconsistent' in str(mess): # note Maxima doesn't tell you if declarations are redundant raise ValueError, "Assumption is inconsistent" else: else: # trying to forget a declaration explicitly rather than implicitly for x in _assumptions: if repr(self) == repr(x): # so by implication x is also a GenericDeclaration x.forget() x.forget() break return def contradicts(self, soln): """ Returns True if this assumption is violated by the given variable assignment(s). Returns True if this assumption is violated by the given variable assignment(s). INPUT: -  *args - assumptions EXAMPLES:: EXAMPLES: Assumptions are typically used to ensure certain relations are evaluated as true that are not true in general. Here, we verify that for x>0, \sqrt(x^2)=x:: sage: assume(x > 0) sage: bool(sqrt(x^2) == x) True This will be assumed in the current Sage session until forgotten:: sage: forget() sage: bool(sqrt(x^2) == x) False Another major use case is in taking certain integrals and limits where the answers may depend on some sign condition:: sage: var('x, n') (x, n) sage: assume(n+1>0) sage: integral(x^n,x) x^(n + 1)/(n + 1) sage: forget() :: sage: var('q, a, k') (q, a, k) sage: assume(q > 1) sage: sum(a*q^k, k, 0, oo) Traceback (most recent call last): ... ValueError: Sum is divergent. sage: forget() sage: assume(abs(q) < 1) sage: sum(a*q^k, k, 0, oo) -a/(q - 1) sage: forget() An integer constraint:: sage: var('n, P, r, r2') sage: solve(c==d,r2) [r2 == e^r - 1] :: Simplifying certain well-known identities works as well:: sage: sin(n*pi) sin(pi*n)
• sage/symbolic/integration/external.py

diff -r 8e1dc3ae4ccc -r c86e54a6bef8 sage/symbolic/integration/external.py
 a if a is None: result = maxima.sr_integral(expression,v) else: try: result = maxima.sr_integral(expression, v, a, b) except TypeError, error: s = str(error) if "divergent" in s or 'Principal Value' in s: raise ValueError, "Integral is divergent." else: raise result = maxima.sr_integral(expression, v, a, b) return result._sage_() def sympy_integrator(expression, v, a=None, b=None):
• sage/symbolic/integration/integral.py

diff -r 8e1dc3ae4ccc -r c86e54a6bef8 sage/symbolic/integration/integral.py
 a """ # The automatic evaluation routine will try these integrators # in the given order. This is an attribute of the class instead of # a global variable in this module to enable customization by # a global variable in this module to enable customization by # creating a subclasses which define a different set of integrators self.integrators = [external.maxima_integrator] """ # The automatic evaluation routine will try these integrators # in the given order. This is an attribute of the class instead of # a global variable in this module to enable customization by # a global variable in this module to enable customization by # creating a subclasses which define a different set of integrators self.integrators = [external.maxima_integrator] sage: integral(x^n,x) Traceback (most recent call last): ... TypeError: Computation failed since Maxima requested additional constraints (try the command 'assume(n+1>0)' before integral or limit evaluation, for example): ValueError: Computation failed since Maxima requested additional constraints; using the 'assume' command before integral evaluation *may* help (example of legal syntax is 'assume(n+1>0)', see assume? for more details) Is  n+1  zero or nonzero? sage: assume(n > 0) sage: integral(x^n,x) Note that an exception is raised when a definite integral is divergent:: sage: forget() sage: forget() # always remember to forget assumptions you no longer need sage: integrate(1/x^3,(x,0,1)) Traceback (most recent call last): ... ValueError: Integral is divergent. sage: integrate(1/x^3,x,-1,3) sage: integrate(1/x^3,x,-1,3) Traceback (most recent call last): ... ValueError: Integral is divergent. But Sage can calculate the convergent improper integral of this function:: sage: integrate(1/x^3,x,1,infinity) sage: integrate(1/x^3,x,1,infinity) 1/2 The examples in the Maxima documentation:: -y*z + x^y/log(x) sage: (x^y-z).integrate(y,algorithm="sympy") -y*z + x^y/log(x) We integrate the above function in maple now:: :: sage: integral(e^(-x^2),(x, 0, 0.1)) sage: integral(e^(-x^2),(x, 0, 0.1)) 0.0562314580091*sqrt(pi) ALIASES: integral() and integrate() are the same. EXAMPLES: Here is example where we have to use assume:: EXAMPLES: Here is an example where we have to use assume:: sage: a,b = var('a,b') sage: integrate(1/(x^3 *(a+b*x)^(1/3)), x) Traceback (most recent call last): ... TypeError: Computation failed since Maxima requested additional constraints (try the command 'assume(a>0)' before integral or limit evaluation, for example): ValueError: Computation failed since Maxima requested additional constraints; using the 'assume' command before integral evaluation *may* help (example of legal syntax is 'assume(a>0)', see assume? for more details) Is  a  positive or negative? So we just assume that a>0 and the integral works:: sage: res = integral(f,x,0.0001414, 1.); res Traceback (most recent call last): ... TypeError: Computation failed since Maxima requested additional constraints (try the command 'assume((y-1)*(y+1)>0)' before integral or limit evaluation, for example): ValueError: Computation failed since Maxima requested additional constraints; using the 'assume' command before integral evaluation *may* help (example of legal syntax is 'assume((y-1)*(y+1)>0)', see assume? for more details) Is  (y-1)*(y+1)  positive, negative, or zero? sage: assume(y>1) sage: res = integral(f,x,0.0001414, 1.); res 2*pi sage: a.simplify_full().simplify_trig() 1 """ """ if isinstance(v, (list, tuple)) and a is None and b is None: if len(v)==1: # bare variable in a tuple v=v