Implementation of derivative and integral steps in Gamma

194 views
Skip to first unread message

David Li

unread,
Mar 14, 2013, 11:22:25 AM3/14/13
to sy...@googlegroups.com
Hello all,

I have implemented a module giving steps for most derivatives and some integrals for SymPy Gamma. However, it was suggested that at least some of this functionality should be added to SymPy itself. If so, what functionality should be added and how should it be integrated into SymPy?

The pull request is at https://github.com/sympy/sympy_gamma/pull/8. There is still some work left to do, which is listed in the pull request. In particular, integral forms involving the application of trigonometric identities need to be implemented.

Examples:

The module builds a tree of rules to apply, with the first rule on the top of the tree. Examples of rules would be AddRule, ChainRule, RewriteRule, AlternativeRule (in case multiple methods exist), and so on. Separate functions apply the rules and return the resulting derivative or integral (currently derivatives and integrals are separate functions). A set of classes walks the tree and generates steps for the rules; there is no translation support but multiple output formats should work (currently only plaintext and HTML+LaTeX are implemented).

The code makes use of context managers, which would need to be replaced in order to maintain Python 2.5 compatibility. 

Thank you,
David Li

Stefan Krastanov

unread,
Mar 14, 2013, 12:12:07 PM3/14/13
to sy...@googlegroups.com
This seems very nice. Have you looked at the rewrite rules and
strategies modules that are currently developed and talked about on
the mailing list? Given that you follow the same paradigm I guess this
would be the correct path to merge your work. I am a bit worried that
you might have reimplemented some of the boilerplate instead of just
using these modules.
> --
> You received this message because you are subscribed to the Google Groups
> "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sympy+un...@googlegroups.com.
> To post to this group, send email to sy...@googlegroups.com.
> Visit this group at http://groups.google.com/group/sympy?hl=en.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

Stefan Krastanov

unread,
Mar 14, 2013, 12:14:14 PM3/14/13
to sy...@googlegroups.com
Just to be clear, your work does definitely a lot more, especially in
terms of presentation and saving the steps. It is impressive. But
there is some overlap with the modules that I already mentioned.

Ronan Lamy

unread,
Mar 14, 2013, 12:31:55 PM3/14/13
to sy...@googlegroups.com
Le 14/03/2013 15:22, David Li a �crit :
>
> The code makes use of context managers, which would need to be replaced
> in order to maintain Python 2.5 compatibility.

That's not a problem, you can use 'from __future__ import with_block'.
OTOH, .format() is 2.7+ only, so it is a compatibility problem.


David Li

unread,
Mar 14, 2013, 4:15:01 PM3/14/13
to sy...@googlegroups.com
Alright, thank you all for the feedback!

I just started looking at the strategies module, I think I could map my rules to rules in the strategies module and have intsteps/diffsteps be a strategy; I'll look into this some more. I can get rid of the format function easily, I'm not really using its features/%-interpolation will be fine.

Also - I have a question about trig simplification. Is there any functionality for applying identities to obtain alternate (not necessarily simpler) forms of an expression? trigsimp doesn't do what I need; the Fu algorithm from https://github.com/sympy/sympy/pull/1737 looks interesting, but it also seems to be aimed mostly at pure simplification. Or would this be another application of rewrite rules? (For instance, I need cos^2(x) = (1+cos(2x)/2.) 

So I'll try to refactor/rewrite using strategies and perhaps resubmit to the main SymPy project.

Matthew Rocklin

unread,
Mar 14, 2013, 5:13:05 PM3/14/13
to sy...@googlegroups.com
The driving idea behind strategies is that you should make lots of little functions that each do one thing.  These should separately be composed together to make larger functions.  This way the little mathematical transformations can be reused in the future or can be wrapped with the kind of reporting your code accomplishes.  If all of SymPy worked this way it would be much simpler to apply your code everywhere.  The Fu work is an excellent example of this.


--

Stefan Krastanov

unread,
Mar 14, 2013, 5:22:25 PM3/14/13
to sy...@googlegroups.com
Slightly off topic: I think that many people would be interested to
see a blog post on planet.sympy.org about this development. On one
hand you have done a lot of work on gamma itself, on the other your
work with this integrator shows a nice way to extend sympy without
worrying too much about upstream (obviously we love to have this
merged to sympy, but the fact that you extended it without worrying
too much about that can be a selling point for people searching for
libraries).

David Li

unread,
Mar 15, 2013, 12:42:06 PM3/15/13
to sy...@googlegroups.com
Okay, so I'd just like to make sure I'm using strategies/rules correctly. I have the gist of the derivative implementation at https://gist.github.com/lidavidm/5171100.
  • The rules convert the function to be differentiated into a namedtuple corresponding to the derivative rule to be applied.
  • Two strategies are used: one is an identity (I'll replace it with the identity strategy in SymPy) and the other evaluates the rule.
  • The switch strategy is used to determine which rule to apply.
  • The rules all operate on Derivative objects so as to keep the function and the variable of differentiation together as one object. (Perhaps just using a namedtuple would be clearer, though.)
This separates the decision of which rule to use, the processing of the input, and the evaluation of the derivative.

If this an "idiomatic" use of strategies then I'll convert the rest of the code.

Aaron Meurer

unread,
Mar 15, 2013, 12:58:23 PM3/15/13
to sy...@googlegroups.com
I don't know if it's idiomatic, but one suggestion is to derive the derivative rules automatically from diff. At the very least use a fallback so it works for functions you don't have rules for. 

Aaron Meurer
--

Matthew Rocklin

unread,
Mar 15, 2013, 1:01:54 PM3/15/13
to sy...@googlegroups.com
If this an "idiomatic" use of strategies then I'll convert the rest of the code.

There is no idiomatic or agreed upon use of strategies.  They're new, experimental, and used almost exclusively by me.

The only good idea I can push with confidence is that you should strive to separate your functions into small-but-meaningful pieces when possible.  I think this helps with future flexibility.  At the very least it means that someone else can come by later and rearrange everything you've done without understanding the math you've written down.


--

Matthew Rocklin

unread,
Mar 15, 2013, 1:05:13 PM3/15/13
to sy...@googlegroups.com
I don't know if it's idiomatic, but one suggestion is to derive the derivative rules automatically from diff. At the very least use a fallback so it works for functions you don't have rules for. 

I agree that it'd be unfortunate to rewrite all of the differentiation logic.  Maybe there is a way to subtly refactor diff to provide the functions you need? 

David Li

unread,
Mar 15, 2013, 1:11:03 PM3/15/13
to sy...@googlegroups.com

That would be a good idea. Looking at the code, everything has an _eval_derivative method which should work. My only concern is that, for instance, in Pow it combines the power, chain, and exponential rules into one expression.

In any case, most of the code I added was related to printing and formatting, which would need minimal modification.

On Mar 15, 2013 10:05 AM, "Matthew Rocklin" <mroc...@gmail.com> wrote:

I don't know if it's idiomatic, but one suggestion is to derive the derivative rules automatically from diff. At the very least use a fallback so it works for functions you don't have rules for. 

I agree that it'd be unfortunate to rewrite all of the differentiation logic.  Maybe there is a way to subtly refactor diff to provide the functions you need? 

--
You received this message because you are subscribed to a topic in the Google Groups "sympy" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/sympy/nLRxBzEyWcs/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to sympy+un...@googlegroups.com.

Aaron Meurer

unread,
Mar 15, 2013, 7:22:04 PM3/15/13
to sy...@googlegroups.com
For multiargument functions (including Pow), you could replace the arguments that depend on x with x and those that don't with a (if there are more than one of the first type you might use f(x) instead of x). For example, if you have x**2, use the rule derived from x**a.  For x**x, use f(x)**g(x). This will also work nicely for multiargument special functions. 

You might want to continue to special case Add and Mul (and also Pow when both are symbolic if you want to use something like logarithmic differentiation or x**x = exp(x*log(x)) to derive the rule). 

Aaron Meurer
You received this message because you are subscribed to the Google Groups "sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.

Ramana Venkata

unread,
Mar 16, 2013, 9:34:22 AM3/16/13
to sy...@googlegroups.com
Hi David,

Great work. Just wanted to point you out one small thing in http://sympy-gamma-li.appspot.com/input/?i=integrate%28exp%28x%29%20/%20%281%20%2B%20exp%282x%29%29%29  In the first step after "Let u = e^x"; "then let du = e^x ..." But I think it be some thing like this "then du = e^x dx ..."

David Li

unread,
Mar 16, 2013, 10:47:57 PM3/16/13
to sy...@googlegroups.com
Alright, thank you for pointing out that typo. I've fixed it.

I have finished porting; the code is still at the same place, https://github.com/sympy/sympy_gamma/pull/8. If this is something SymPy would want, how best should be integrated? Which module(s) does it belong in and what should the API be?

Aaron Meurer

unread,
Mar 16, 2013, 10:57:12 PM3/16/13
to sy...@googlegroups.com
This is something SymPy wants. It's even on the GSoC ideas list.

I would put the integration stuff in the integration module. As I
pointed out on the pull request, what you really have here is a new
integration heuristic, which can (should) be "integrated" with
integrate() itself. It is already giving better results than
integrate() for some integrals (namely the one you posted as your
example).

The diff code I'm not sure. I guess it could go in the same file for
now. If you derive the rules automatically, then the code will be
short (it will only consist of special cases like Add and Mul).

In general, there are a lot of things that this could be applied to
beyond diff() and integrate(): solve(), simplify(), the core (like x +
x => 2*x). For some, the code could naturally live very close to the
code that currently does the work. For others, the way that the
algorithm works and the way it works "by hand" are much different.

To be clear, the symbolic manipulation should go in SymPy. The part
about the text "now make the u substitution u = exp(x)" or the css
formatting should go in SymPy Gamma. The SymPy objects should be easy
to parse into those things, but they should be intended for machine
consumption more than human consumption.

Aaron Meurer

David Li

unread,
Mar 16, 2013, 11:02:26 PM3/16/13
to sy...@googlegroups.com
Okay, I'll start on that once I manage to get the integration algorithm to handle most problems that a high-school/freshman college student would encounter. (Currently it won't handle any trig integrands involving more than a u-substitution, and does not use integration by parts.)

Perhaps the derivative implementation doesn't need to be in SymPy? I haven't seen a case yet where it provides a better result (usually it is less simplified, especially when trigonometry is involved). 

Aaron Meurer

unread,
Mar 16, 2013, 11:11:30 PM3/16/13
to sy...@googlegroups.com
On Sat, Mar 16, 2013 at 9:02 PM, David Li <li.da...@gmail.com> wrote:
> Okay, I'll start on that once I manage to get the integration algorithm to
> handle most problems that a high-school/freshman college student would
> encounter. (Currently it won't handle any trig integrands involving more
> than a u-substitution, and does not use integration by parts.)

Actually, trig integrals (like sin^n*cos^m) are one example of
integrals that are computed exactly as you learned in calculus, via
the reduction formula*. So you could look into extending
trigintegrate to work with this.

(*) With the caveat that if the integral is reduced to a rational
function via a substitution, it is computed with ratint, which works
nothing like the partial fractions that you learned in calculus. For
example, the integral of tan(x) is reduced to the integral of u/(1 -
u**2), where u = sin(x).

Aaron Meurer

>
> Perhaps the derivative implementation doesn't need to be in SymPy? I haven't
> seen a case yet where it provides a better result (usually it is less
> simplified, especially when trigonometry is involved).

Actually, you could argue for that. Once you generalize it to use diff
automatically, it should just be a few lines, so perhaps it should
just live entirely in SymPy Gamma. It can be a good example of what
you can do with SymPy without editing library code.

Aaron Meurer
Reply all
Reply to author
Forward
0 new messages