Idiomatic use of derivative replacements

33 views
Skip to first unread message

Marcel Oliver

unread,
Oct 5, 2021, 1:34:08 PM10/5/21
to sympy

Hello,

I am currently converting, for teaching purposes, a number of code examples from Mathematica to sympy in order to have a purely Python-based teaching environment (the numerical part has long been done in Numpy/Scipy). 

I have now run into a situation where I can get some code to work in a mathematically correct way, but produce output that makes me think I am not doing things quite right.

The task is to use sympy to verify the order of a finite difference time integrator for an ODE (for the sake of simplicity, autonomous), which involves Taylor expanding the error with respect to the stepsize parameter, the substituting the differential equation and its derivatives.

The attached code does just that, here with the implicit midpoint rule as a simple example.   The issue I have is that sympy does not seem to have the notion of an abstract derivative, so the series expansion produces terms where Subs is used to represent derivatives with an argument that is not simply a symbol.  In the end, however, I have to force evaluation with doit((), so that terms cancel properly, which has the side effect that all Subs are resolved and I get nonsense terms like

  Derivative(f(y(0)), y(0))

Of course, I could just ignore this as I have already achieved my goal, but I am trying to teach "good" sympy and this result strikes me as not being formulated the way it should.

Any comments highly appreciated!

Marcel

order-sympy.py

gu...@uwosh.edu

unread,
Oct 5, 2021, 1:44:03 PM10/5/21
to sympy
Marcel,

I believe you are correct that sympy has a problem with this. I ran into issues when trying to define the behavior of integration and differentiation for the equation class I have defined. Unfortunately, I am completely swamped with committee and large class administration duties right now, so cannot really spend time on this. My basic thoughts are that to make this work well, SymPy would need to be expanded to include the concept of a partial differential. I believe some of that has been discussed on this list. I will write again, if I find time to dig up the discussions.

Jonathan

Oscar Benjamin

unread,
Oct 5, 2021, 2:04:03 PM10/5/21
to sympy
I think that the basic problem is just this (which is a bug):

In [86]: expr = f(y(t)).diff(y(t))

In [87]: print(expr)
Derivative(f(y(t)), y(t))

In [88]: print(expr.subs(t, 0))
Derivative(f(y(0)), y(0))

There is code to detect this in some cases but it doesn't work for your example. If y(t) was just t then you'd get:

In [89]: expr2 = f(t).diff(t)

In [90]: print(expr2)
Derivative(f(t), t)

In [91]: print(expr2.subs(t, 0))
Subs(Derivative(f(t), t), t, 0)

The two cases diverge at this line:

Also yes you are right that this would be a lot easier if sympy had functions as first class objects and could represent abstract derivatives.

--
Oscar

--
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 view this discussion on the web visit https://groups.google.com/d/msgid/sympy/3a35d4c8-c439-4259-bf03-5ba8a27e4cf3n%40googlegroups.com.

Marcel Oliver

unread,
Oct 6, 2021, 5:48:23 AM10/6/21
to sy...@googlegroups.com
Oscar Benjamin writes:
> I think that the basic problem is just this (which is a bug):
>
> In [86]: expr = f(y(t)).diff(y(t))
>
> In [87]: print(expr)
> Derivative(f(y(t)), y(t))
>
> In [88]: print(expr.subs(t, 0))
> Derivative(f(y(0)), y(0))

Thank you for your detailed answer.

Arguably, it's already the first expression that should not be
allowed, or must be forced into the respective Subs-expression
immediately.

Is that your understanding of where the bug is?

However it is fixed, the resulting Subs must then be undoable by
doit()...

There is one related annoyance I noticed: The expression returned by
'series' contains Subs-expressions with a dummy variable 'xi' which is
not defined in the global context. Hence, output from 'print' is not
pastable into the console, which is an impediment to interactive
exploration of expressions.

--Marcel
> https://groups.google.com/d/msgid/sympy/CAHVvXxTW0Dj1BDJBPM9W36L%2BXr-tv7dG9BDEMk6WGkUN-Es88g%40mail.gmail.com
> .
>

Aaron Meurer

unread,
Oct 6, 2021, 5:04:06 PM10/6/21
to sympy
I wonder if we should somehow refactor Derivative so that derivatives
wrt non-Symbols are represented internally by a Subs object. The logic
in Subs should handle this sort of thing correctly. For instance, this
is correct

>>> expr = Subs(f(x).diff(x), x, y(t))
>>> expr.subs(t, 0)
Subs(Derivative(f(x), x), x, y(0))

(although calling doit() on that final expression just produces the
same wrong f(y(0)).diff(y(0)) object again).

Otherwise, the logic in Derivative is going to just duplicate the
logic of Subs, but in more buggy ways because most derivatives aren't
wrt more complex expressions, so they aren't tested as well.

Aaron Meurer
> To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/CAHVvXxTW0Dj1BDJBPM9W36L%2BXr-tv7dG9BDEMk6WGkUN-Es88g%40mail.gmail.com.
Reply all
Reply to author
Forward
0 new messages