在python中获取数据的衍生物

时间:2016-06-03 15:27:25

标签: python numpy scipy derivative

我写了一个程序来获得衍生物。 InterpolatedUnivariateSpline用于计算f(x + h)。红线是余弦的导数,绿线是余弦consine,蓝线是-sine函数。红色和蓝色线匹配。它在以下情况下运作良好。

Result

from scipy.interpolate import InterpolatedUnivariateSpline
import numpy as np 
import matplotlib.pyplot as plt

pi = np.pi
x = np.arange(0,5*pi,0.2*pi)
y = np.cos(x) 
f2 = InterpolatedUnivariateSpline(x, y)
#Get dervative
der = []
for i in range(len(y)):

    h = 1e-4
    der.append( ( f2(x[i]+h)-f2(x[i]-h) )/(2*h) )
der = np.array(der)   

plt.plot(x, der, 'r', x, y, 'g', x, -np.sin(x),'b')
plt.show()

但是我遇到了一些问题。在我的项目中,我的变量x(频率)从10 ^ 7变化到2.2812375 * 10 ^ 9,其步长为22487500,所以我改变了数组x。 结果,我得到以下结果。

Result2

导数是一条直线,几乎接近于0,它不是-sine函数。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

您遇到loss of significance问题。这意味着当向一个小浮点数添加一个大的浮点数时,小的浮点数的精度会部分丢失,因为numpy double只能容纳64位信息。

要解决此问题,您必须确保添加/乘/除的数字的比例不会太大。一个简单的解决方案是将x除以1e9或将h乘以1e9。如果这样做,您将获得与示例中相同的精度。

此外,如果x具有足够高的分辨率,则在数字上区分函数的简单方法是der = np.diff(y) / np.diff(x)。这样您就不必担心设置h了。但是在这种情况下请注意dyy的一个元素,dy[i]实际上是`(x [i] + x [i + 1])的导数的近似值/ 2.所以要绘制它你会做:

der = np.diff(y) / np.diff(x)
x2 = (x[:-1] + x[1:]) / 2
plt.plot(x2, der, 'r', x, y, 'g', x, -np.sin(x),'b')