Search code examples
pythonfunctionsympyderivative

How to overload the fdiff method of a personal function inheriting from the Function class?


I would like to create a polynomial function P(n,x,y) whose derivative is equal to n/x*E(n,x,y). I've created the function like this :

from sympy.core.function import Function as Func, ArgumentIndexError

class P(Func) :        
    @classmethod     
    def eval(cls,n,x,y):        
        return Function('P')(n,x,y)  

class E(Func):    
    @classmethod     
    def eval(cls,n,x,y):        
        return Function('E')(n,x,y)

I have put:

def fdiff(self, argindex=1):
    if argindex == 1:
        return self.args[2]/self.args[0]*E(*self.args)        
    else:
        raise ArgumentIndexError(self, argindex)  

right after the "eval" definition of the function P, as it is done for example in the trigonometric.py to define the derivative of cos thanks to sin.

Yet, when I try:

>>> P(r, R, n).fdiff()

I obtain:

Derivative(P(n,x,y), n)

in the console, whereas I would like to obtain n/x*E(n,x,y).


Solution

  • Your eval is returning Function('P'), which is a completely different object (an anonymous function named "P"). eval should be used to evaluate specific values (like numbers). If you don't have any values to evaluate at, don't define eval.

    When I define P and E like

    class P(Function):
        def fdiff(self, argindex=1):
            if argindex == 1:
                return self.args[2]/self.args[0]*E(*self.args)
            else:
                raise ArgumentIndexError(self, argindex)
    
    
    class E(Function):
        pass
    

    it works just fine

    In [32]: P(r, R, n).diff(r)
    Out[32]:
    n⋅E(r, R, n)
    ────────────
         r