So it's been about 6 years since I've done calculus, and in fact the only math I see from day to day is pretty much 100% symbolic. That being said, I've attached a script that may help, or at least satisfy some curiosity. It's crude, but simple enough to toy around with and checks that the integral of the diff is the same as the original (not sure what to do to check this doesn't require constant factors). Just running it a few times finds NotImplemented errors, odd looking results, etc. This is about all I can offer as far as testing the thing goes ;).
Cheers On Thu, Aug 19, 2010 at 12:50 PM, Christian Muise <christian.mu...@gmail.com > wrote: > Apparently the setup.py is dated: > > cjmu...@haz:~/Projects/sympy$ git diff > diff --git a/setup.py b/setup.py > index bdec104..538904d 100755 > --- a/setup.py > +++ b/setup.py > @@ -71,6 +71,7 @@ > 'sympy.mpmath.matrices', > 'sympy.mpmath.calculus', > 'sympy.polys', > + 'sympy.polys.domains', > 'sympy.printing', > 'sympy.printing.pretty', > 'sympy.series', > cjmu...@haz:~/Projects/sympy$ > > On Thu, Aug 19, 2010 at 12:39 PM, Christian Muise < > christian.mu...@gmail.com> wrote: > >> I'm having issues with the branch: >> >> >>> from sympy import * >> Traceback (most recent call last): >> File "<input>", line 1, in <module> >> File "/usr/local/lib/python2.6/dist-packages/sympy/__init__.py", line >> 24, in <module> >> from polys import * >> File "/usr/local/lib/python2.6/dist-packages/sympy/polys/__init__.py", >> line 3, in <module> >> from polytools import ( >> File "/usr/local/lib/python2.6/dist-packages/sympy/polys/polytools.py", >> line 66, in <module> >> from sympy.polys.domains import FF, QQ >> ImportError: No module named domains >> >>> >> >> I guess it's the version I'm using? Python 2.6.5 is installed. >> >> On Wed, Aug 18, 2010 at 11:43 PM, Aaron S. Meurer <asmeu...@gmail.com>wrote: >> >>> So a few words. First, if you just pass it a strictly rational function, >>> it is nothing new. It will return the exact same result as integrate() >>> because it uses the exact same function, which is the already existing >>> ratint() (however, there is a fix in my branch for rational functions with >>> symbolic coefficients that fail in master). >>> >>> To really test this, you need to pass it a function that has exp and/or >>> log in it. For example, here are some functions that you might try that >>> better test the algorithm: >>> >>> In [2]: risch_integrate(1/(exp(x)**9 + 1), x) >>> Out[2]: >>> ⎛ 9⋅x⎞ >>> log⎝1 + ℯ ⎠ >>> x - ───────────── >>> 9 >>> >>> (your example with x replaced with exp(x)) >>> >>> In [18]: risch_integrate(diff(exp(x)*log(x)/(x + 1), x), x) >>> Out[18]: >>> x >>> ℯ ⋅log(x) >>> ───────── >>> 1 + x >>> >>> This seems to be a simple example, but observe that our current >>> integrate() cannot handle it: >>> >>> In [19]: integrate(diff(exp(x)*log(x)/(x + 1), x), x) >>> Out[19]: >>> ⌠ >>> ⎮ ⎛ x x x ⎞ >>> ⎮ ⎜ℯ ⋅log(x) ℯ ⋅log(x) ℯ ⎟ >>> ⎮ ⎜───────── - ───────── + ─────────⎟ dx >>> ⎮ ⎜ 1 + x 2 x⋅(1 + x)⎟ >>> ⎮ ⎝ (1 + x) ⎠ >>> ⌡ >>> >>> Also, it's fun to pass it functions that you know do not have elementary >>> anti-derivatives, to see if it can verify that fact: >>> >>> In [20]: risch_integrate(exp(x**2), x) >>> Out[20]: >>> ⌠ >>> ⎮ ⎛ 2⎞ >>> ⎮ ⎝x ⎠ >>> ⎮ ℯ dx >>> ⌡ >>> >>> In [21]: risch_integrate(1/log(x), x) >>> Out[21]: >>> ⌠ >>> ⎮ 1 >>> ⎮ ────── dx >>> ⎮ log(x) >>> ⌡ >>> >>> Also, remember what I said about integrating random functions. If you >>> try to integrate a random function, the chances are pretty good that it will >>> not be elementary, and even if it is, the result could be quite complicated >>> and it could take a long time to compute. Much better is to come up with an >>> expression that is as complex or not complex as you like, then differentiate >>> it and see if risch_integrate() can give you the original thing back again. >>> >>> On Aug 18, 2010, at 9:05 PM, Ondrej Certik wrote: >>> >>> > Hi Aaron! >>> > >>> > On Thu, Aug 5, 2010 at 2:01 PM, Aaron S. Meurer <asmeu...@gmail.com> >>> wrote: >>> >> (copied from issue 2010) >>> >> >>> >> I have ready in my integration3 branch a prototype risch_integrate() >>> function, that is a user-level function for the full Risch Algorithm I have >>> been implementing this summer. Pull from >>> http://github.com/asmeurer/sympy/tree/integration3 >>> > >>> > This is just excellent! >>> > >>> > I would like to invite everyone to try this. (Read Aaron's email above >>> > for things to try and not to try yet.) So here are some tougher cases: >>> > >>> > In [1]: risch_integrate(1/(x**8+1), x) >>> > [hangs] >>> >>> This is our old friend expand() again (if you break anything that hangs >>> in sympy these days, it usually ends up being in expand in the traceback). >>> I am hoping that Mateusz's continual Poly improvements will make this go >>> away eventually. >>> >>> > >>> > >>> > In [4]: cancel(risch_integrate(1/(x**9+1), x).diff(x)) >>> > Out[4]: >>> > d ⎛ ⎛ 6 3 ⎞⎞ 3 d >>> ⎛ >>> > 1 + 3⋅──⎝RootSum⎝531441⋅t + 729⋅t + 1, Λ(t, t⋅log(x + 9⋅t))⎠⎠ + 3⋅x >>> ⋅──⎝Root >>> > dx >>> dx >>> > >>> ────────────────────────────────────────────────────────────────────────────── >>> > 3 >>> > 3 + 3⋅x >>> > >>> > ⎛ 6 3 ⎞⎞ >>> > Sum⎝531441⋅t + 729⋅t + 1, Λ(t, t⋅log(x + 9⋅t))⎠⎠ >>> > >>> > ────────────────────────────────────────────────── >>> > >>> > >>> > It should be equivalent but it's a bit messy. Maybe we need to >>> > implement some symbolic manipulation of RootSum(). >>> >>> Mateusz should look at this. >>> >>> > >>> > In [18]: risch_integrate(sqrt(1+exp(x)), x) >>> > NotImplementedError: Couldn't find an elementary transcendental >>> > extension for (1 + exp(x))**(1/2). Try using a manual extension with >>> > the extension flag. >>> >>> No, and it won't be any time soon. The algorithm I am implementing is >>> only the transcendental case (no algebraic functions like sqrt). Now, the >>> algebraic part does exist, but it is much more difficult to implement, and I >>> won't even start to do it until the transcendental case is finished. If you >>> get the above error, and you believe that the function is really not >>> algebraic, please post it here because it could be a bug in my preparser >>> algorithm, (be aware that you could be wrong, though). >>> >>> > >>> > >>> > [18] is probably not supported yet. >>> > >>> > >>> > Otherwise it works great. I wasn't able to make it break. >>> >>> Well, I know it's possible, because I do it all the time (and then I go >>> and fix the bug). >>> >>> > >>> > >>> > Ondrej >>> >>> Aaron Meurer >>> >>> -- >>> You received this message because you are subscribed to the Google Groups >>> "sympy" group. >>> To post to this group, send email to sy...@googlegroups.com. >>> To unsubscribe from this group, send email to >>> sympy+unsubscr...@googlegroups.com<sympy%2bunsubscr...@googlegroups.com> >>> . >>> For more options, visit this group at >>> http://groups.google.com/group/sympy?hl=en. >>> >>> >> > -- You received this message because you are subscribed to the Google Groups "sympy" group. To post to this group, send email to sy...@googlegroups.com. To unsubscribe from this group, send email to sympy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sympy?hl=en.
from sympy import * import random x = Symbol('x') unops = [exp, log, lambda x: 0-x] binops = [lambda x,y: x+y, lambda x,y: x-y, lambda x,y: x*y, lambda x,y: x/y] TRIALS = 5 def build_func(starting_vars = 2, starting_nums = 4, prob_unary = 0.5): parts = [x] * starting_vars for i in range(starting_nums): parts.append(random.randrange(1,10)) #print "Working with the following building blocks: %s" % str(parts) while len(parts) > 1: if random.random() < prob_unary: index = random.randrange(0,len(parts)) parts[index] = random.choice(unops)(parts[index]) else: random.shuffle(parts) parts.append(random.choice(binops)(parts.pop(), parts.pop())) return parts[0] for i in range(TRIALS): eq = build_func() print "\n\n------------------------------\nTesting the following equation:\n" pretty_print(eq) print "\n\nDiff:\n" d = diff(eq,x) pretty_print(d) print "\n\nIntegral of Diff:\n" res = risch_integrate(d, x) pretty_print(res) print "\nMatch? %s" % str(res == eq) print "------------------------------"