Diff in maxima and sympy

47 views
Skip to first unread message

Andreas Kloeckner

unread,
Apr 14, 2012, 1:18:50 AM4/14/12
to sympy
Hi all,

I've been looking for an explanation for why maxima gives me

(%i3) diff(sqrt((a+b*t)^2+(c+d*t)^2),t, 5);

45*(2*d^2+2*b^2)^2*(2*d*(d*t+c)+2*b*(b*t+a))/(8*((d*t+c)^2+(b*t+a)^2)^(5/2))
-75*(2*d^2+2*b^2)*(2*d*(d*t+c)+2*b*(b*t+a))^3/(8*((d*t+c)^2+(b*t+a)^2)^(7/2))
+105*(2*d*(d*t+c)+2*b*(b*t+a))^5/(32*((d*t+c)^2+(b*t+a)^2)^(9/2))

and sympy gives me

>>> sp.sqrt((a+b*t)**2+(c+d*t)**2).diff(t,5)

(-5*b**2 - 5*d**2)*(-3*b*(a + b*t) - 3*d*(c + d*t))*(-b*(a + b*t) - d*(c
+ d*t))*(b*(a + b*t) + d*(c + d*t))/((a + b*t)**2 + (c + d*t)**2)**(7/2)
+ 3*(-3*b**2 - 3*d**2)*(-b**2 - d**2)*(b*(a + b*t) + d*(c + d*t))/((a +
b*t)**2 + (c + d*t)**2)**(5/2) + 4*(-3*b**2 - 3*d**2)*(b**2 +
d**2)*(-b*(a + b*t) - d*(c + d*t))/((a + b*t)**2 + (c + d*t)**2)**(5/2)
+ 2*(-3*b**2 - 3*d**2)*(-5*b*(a + b*t) - 5*d*(c + d*t))*(-b*(a + b*t) -
d*(c + d*t))*(b*(a + b*t) + d*(c + d*t))/((a + b*t)**2 + (c +
d*t)**2)**(7/2) + 8*(-b**2 - d**2)*(b**2 + d**2)*(-3*b*(a + b*t) -
3*d*(c + d*t))/((a + b*t)**2 + (c + d*t)**2)**(5/2) + 3*(-b**2 -
d**2)*(-5*b*(a + b*t) - 5*d*(c + d*t))*(-3*b*(a + b*t) - 3*d*(c +
d*t))*(b*(a + b*t) + d*(c + d*t))/((a + b*t)**2 + (c + d*t)**2)**(7/2) +
4*(b**2 + d**2)*(-5*b*(a + b*t) - 5*d*(c + d*t))*(-3*b*(a + b*t) -
3*d*(c + d*t))*(-b*(a + b*t) - d*(c + d*t))/((a + b*t)**2 + (c +
d*t)**2)**(7/2) + (-7*b*(a + b*t) - 7*d*(c + d*t))*(-5*b*(a + b*t) -
5*d*(c + d*t))*(-3*b*(a + b*t) - 3*d*(c + d*t))*(-b*(a + b*t) - d*(c +
d*t))*(b*(a + b*t) + d*(c + d*t))/((a + b*t)**2 + (c + d*t)**2)**(9/2)

(and this gets even worse for higher derivatives)

Any hints on how to make this better in sympy?

Thanks,
Andreas

Aaron Meurer

unread,
Apr 14, 2012, 1:40:56 AM4/14/12
to sy...@googlegroups.com
You can get a more simple result in SymPy by factoring between each
derivative, like sqrt((a+b*t)**2+(c+d*t)**2).diff(t,
2).factor().diff(t, 2).factor().diff(t).factor(). Actually, I guess
you get the same thing if you just factor once after taking the fifth
derivative.

It's still not quite as simple, but unfortunately SymPy doesn't have
very good simplification for algebraic expressions like these, as they
require rather complicated algorithms that are not yet implemented.

Can you show what Maxima gives for the first and second derivatives?
We may also be able to get a similar result by applying heuristical
derivative rules based on the form of the expression (e.g., the
quotient rule instead of the product rule for fractions).

Aaron Meurer

Chris Smith

unread,
Apr 14, 2012, 2:52:55 AM4/14/12
to sy...@googlegroups.com
On Sat, Apr 14, 2012 at 11:25 AM, Aaron Meurer <asme...@gmail.com> wrote:
> You can get a more simple result in SymPy by factoring between each
> derivative, like sqrt((a+b*t)**2+(c+d*t)**2).diff(t,
> 2).factor().diff(t, 2).factor().diff(t).factor().  Actually, I guess
> you get the same thing if you just factor once after taking the fifth
> derivative.
>
> It's still not quite as simple, but unfortunately SymPy doesn't have
> very good simplification for algebraic expressions like these, as they
> require rather complicated algorithms that are not yet implemented.
>
> Can you show what Maxima gives for the first and second derivatives?
> We may also be able to get a similar result by applying heuristical
> derivative rules based on the form of the expression (e.g., the
> quotient rule instead of the product rule for fractions).
>

No elaborate factoring is needed, apparently. The cse of both the
maxima and sympy expressions are the same and a little shorter than
the maxima result (at 65 ops rather than 80):

>>> r,e=cse(m)
>>> print filldedent(str(e[0].subs(r[::-1])))

15*(b*(a + b*t) + d*(c + d*t))*(3*(b**2 + d**2)**2 - 10*(b**2 +
d**2)*(b*(a + b*t) + d*(c + d*t))**2/((a + b*t)**2 + (c + d*t)**2) +
7*(b*(a + b*t) + d*(c + d*t))**4/((a + b*t)**2 + (c + d*t)**2)**2)/((a


+ b*t)**2 + (c + d*t)**2)**(5/2)

/c

Chris Smith

unread,
Apr 14, 2012, 3:34:12 AM4/14/12
to sy...@googlegroups.com
On Sat, Apr 14, 2012 at 12:37 PM, Chris Smith <smi...@gmail.com> wrote:
> On Sat, Apr 14, 2012 at 11:25 AM, Aaron Meurer <asme...@gmail.com> wrote:
>> You can get a more simple result in SymPy by factoring between each
>> derivative,

Since multiple derivatives generate many common sub-expressions, cse
is ideal for simplifying such results and that is perhaps why m* does
that. Regular simplification of the cse-simplified result makes no new
simplifications but takes orders of magnitude longer (40 seconds vs
less than a second) to do so:

>>> def csesimp(e):
... r, e = cse(e)
... return e[0].subs(reversed(r))
...

>>> print filldedent(str(csesimp(s)))

15*(b*(a + b*t) + d*(c + d*t))*(3*(b**2 + d**2)**2 - 10*(b**2 +
d**2)*(b*(a + b*t) + d*(c + d*t))**2/((a + b*t)**2 + (c + d*t)**2) +
7*(b*(a + b*t) + d*(c + d*t))**4/((a + b*t)**2 + (c + d*t)**2)**2)/((a
+ b*t)**2 + (c + d*t)**2)**(5/2)

I'll open an issue.

Andreas Klöckner

unread,
Apr 14, 2012, 4:21:24 PM4/14/12
to sy...@googlegroups.com
Great, thanks for all your help! Can you point me to the issue #, so that I can subscribe?

Andreas

Chris Smith

unread,
Apr 14, 2012, 9:07:54 PM4/14/12
to sy...@googlegroups.com
> Great, thanks for all your help! Can you point me to the issue #, so that I
> can subscribe?

http://code.google.com/p/sympy/issues/detail?id=3226

Reply all
Reply to author
Forward
0 new messages