# Ticket #7377: trac_7377-assumptions.patch

File trac_7377-assumptions.patch, 19.8 KB (added by kcrisman, 11 years ago)

Trial patch to improve assumption messages and documentation of helper functions

• ## sage/calculus/calculus.py

# HG changeset patch
# User Karl-Dieter Crisman <kcrisman@gmail.com>
# Date 1299792266 18000
# Node ID c72fe17036dbfd29522db86b07bb6780096c6878
# Parent  d938a99f32105d9325dd770cc3a30a24e7d3c03f
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 d938a99f3210 -r c72fe17036db 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) ECL says: Maxima asks: 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/interfaces/maxima.py

diff -r d938a99f3210 -r c72fe17036db 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)') 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[0]._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[0]._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 d938a99f3210 -r c72fe17036db 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 = var('x, y, k') 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 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 d938a99f3210 -r c72fe17036db sage/symbolic/assumptions.py
 a -  *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: q, a = var('q, a') 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 d938a99f3210 -r c72fe17036db 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 d938a99f3210 -r c72fe17036db sage/symbolic/integration/integral.py
 a 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): ... 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)