Search code examples
pythonsympyderivative

Find the derivative of a piecewise function using the limit definition


So I create a piecewise function like this:

x= sp.symbols('x')
f = sp.Piecewise(
        (1, x==0),
        (sp.sin(x)*(x+1)/x, True))

but if i substitude x with 0 I'll get nan:

f.subs(x,0)
nan

So 1st question is why == doesn't work well with sympy.Piecewise? Well, I change it to that:

f = sp.Piecewise(
        (sp.sin(x)*(x+1)/x, sp.And(x < 0, x > 0)),
        (1, True))

And it works kinda.
Next thing I'd like to do is to calculate a derivative of the function using it's definition in x = 0: I need to calculate a limit:

So I far as I need to calculate it in x = 0, I code this:

Δx = sp.symbols('Δx')
expr = f.subs(x, Δx)/Δx
sp.limit(expr, Δx, 0)

But it outputs oo which means infinity. And that's kinda not true, cuz if I call diff function, I'll gain 0, which is kinda true(at x = 0 the derivative of f is 0):

sp.diff(f, x).subs(x,0)
0

Can someone tell me what's wrong with my code and how can I correct it. Thanks.


Solution

  • Equality == is structural equality, not mathematical equality. It evaluates to True or False at once, there is no "wait until we know the value of x". The object Symbol('x') and the object Integer(0) are not equal structurally, hence Symbol('x') == Integer(0) is False. See SymPy gotchas. What you meant is the relation Eq(x, 0) which represents the equality relation that is not evaluated to a boolean until we know more about x. So, use

    f = sp.Piecewise(
        (1, sp.Eq(x, 0)),
        (sp.sin(x)*(x+1)/x, True))
    

    Second, the definition of derivative (at 0) is the limit of (f(Δx) - f(0))/Δx, and you didn't subtract f(0)

    expr = (f.subs(x, Δx) - f.subs(x, 0))/Δx
    sp.limit(expr, Δx, 0)
    

    results in 1, which is actually correct. (The derivative is 1, not 0).

    Incidentally,

    >>> sp.diff(f, x).subs(x, 0)
    0
    

    is wrong because SymPy (like other CAS) is not very good in calculus with piecewise functions.