Search code examples
pythonsympysymbolic-math

Recursive substitution of formulas in sympy


I have derived a formula that I want to recursively subsitute later. As an example:

f = Function("f")
expr=f(x,y).diff(x) + f(x,y).diff(x).diff(x)
expr.subs(f(x,y).diff(x),f(x,y+1)) 

This gives me

f(x, y + 1) + Derivative(f(x, y + 1), x)

But what I want is

f(x,y+1) + f(x,y+2)

How do I do this in a nice way?


Solution

  • The nice way is to make the property you want, f(x, y).diff(x) == f(x, y + 1), be a part of function declaration.

    class f(Function):
      def fdiff(self, argindex):
        if argindex == 1:
          return f(self.args[0], self.args[1] + 1)
        else:
          raise ArgumentIndexError(self, argindex)
    

    Now f(x,y).diff(x) + f(x,y).diff(x).diff(x) returns f(x, y + 1) + f(x, y + 2) directly, without any substitution. By the way, note that f(x,y).diff(x, 2) is shorter notation for multiple derivatives.

    Explanation: the method fdiff implements first derivative of a function, and it has to handle the derivatives in all variables. You didn't say how the derivative with respect to 2nd variable should work, so I have to default on that by raising ArgumentIndexError which will be handled higher up in SymPy.

    For example, f(x,y).diff(x, 3) + f(x,y).diff(x, y) is now

    f(x, y + 3) + Subs(Derivative(f(x, _xi_2), _xi_2), (_xi_2,), (y + 1,))
    

    where the Subs with unevaluated Derivative is produced because fdiff didn't implement that partial derivative.