Search code examples
pythongraphnumerical-methodsderivative

Approximating derivatives using python


I have attempted to solve the following problem. I tried to solve it first with a set step size h using 0.1. However I need to change this in my code and use a for loop to loop through the values 0,1,..,20. I am a little confused how to do this problem but I was hoping to get some help with fixing the code I produced so far. Thanks!

enter image description here

import numpy as np
from math import sin

def derivative(func , x, h ):
    for h in range(20):
    return (func(x+h)-func(x))/h

def f(x):
    return sin(x)

print(derivative(f, pi/4))

Gives the output

0.6706029729039897

MY EDIT:

def derivative(func , x, h ):
    for h in range(20):
    return (func(x+h)-func(x))/h

Solution

  • The exercise is asking you to compute the derivative using varying precision (represented using the variable h), and compare that to the exact/real derivative of the function.

    Let h = 10 ^ -j, with j varying from 0 to 20. This means h will go (discretely) from 10⁻⁰ to 10⁻²⁰. You can use a for-loop and the range(...) function for that. Then pass that to the derivative function (to which you can a third parameter for the value of h)

    def derivative(func, x, h):
        return (func(x + h) - func(x)) / h
    

    Next, you need to compare that to the exact derivative. The function f(x) = sin(x) has a known (exact) derivative which is cos(x). In math notation, d(sin x)/dx = cos x. This means that for any x, cos(x) will give you the exact derivative of sin at that x.

    So you need to compare the result of the derivative(...) function to the value of cos(x). This will give you the difference. You can then use the basic Python function abs(x) to get the absolute value of that difference, which will give you the absolute difference, which is the desired result. Do that for each j from 0 to 20 and store the results somewhere, in an array or a dict.

    from math import sin, cos, pi
    
    x = pi / 4
    diffs = {}
    
    for j in range(21): # range is exclusive so range(21) will stop at 20
        h = 10 ** -j
        deriv = derivative(sin, x, h)
        exact = cos(x)
        diff = abs(deriv - exact)
        diffs[h] = diff
    

    Then, you can use pyplot's loglog function to plot those results on a graph, passing as X the range(...) result and as Y the array containing the results.

    import matplotlib.pyplot as plt
    
    ordered = sorted(diffs.items())
    x, y = zip(*ordered)
    plt.loglog(x, y)