In [2]:
import numpy as np
import matplotlib.pyplot as plt

def f(x):   return np.sin(3*x)*np.log(x)

In [3]:
x = 0.7
h_exp = range( 1, 30 )
hs = map( lambda p: 10 ** -p, h_exp )
h_len = len(hs)

In [12]:
dfdx = 3 * np.cos( 3*x)*np.log(x) + np.sin(3*x) / x
dfdx_finite_diff = map( lambda h: abs( (f(x + h) - f(x))/h - dfdx ) / dfdx, hs )
dfdx_central_diff = map( lambda h: abs( (f(x+h)-f(x-h))/(2*h) - dfdx ) / dfdx, hs )
dfdx_complex_step = map( lambda h: abs( np.imag(f(x + np.complex(0, h))/h) - dfdx ) / dfdx, hs )

In [13]:
fig, axes = plt.subplots(figsize=(12,10))
axes.set_title('calculated derivative as a function of N, where the step size is 10 ** -N')
axes.set_xlabel('N')
axes.set_ylabel('relative error in derivative calculation ')
axes.plot(h_exp, dfdx_finite_diff, color="grey", linestyle='-', linewidth=2.00, marker='+',label="finite diff")
axes.plot(h_exp, dfdx_central_diff, color="green", linestyle='-.', label="central diff")
axes.plot(h_exp, dfdx_complex_step, color="red", linestyle=":", marker='+',label="complex step")
axes.legend(loc=3)
axes.set_yscale("log")