获取 python 中数据的导数
Get derivative of data in python
我写了一个程序来求导数。 InterpolatedUnivariateSpline 用于计算 f(x+h)。红线是余弦的导数,绿线是余弦正弦函数,蓝线是-sine函数。红线和蓝线是匹配的。它在以下方面运作良好。
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(frequency) 从 10^7 变化到 2.2812375*10^9,它的步长是 22487500,所以我改变了数组 x。
结果,我得到以下结果。
导数是一条线,几乎接近于0,不是正弦函数。我该如何解决?
您有 loss of significance 个问题。这意味着当将一个大的浮点数与一个小的浮点数相加时,小的精度会部分丢失,因为 numpy double 只能容纳 64 位信息。
要解决此问题,您必须确保 add/multiply/divide 的数字比例没有太大差异。一种简单的解决方案是将 x
除以 1e9
或将 h
乘以 1e9
。如果这样做,您将获得与示例中基本相同的精度。
此外,如果 x
具有足够高的分辨率,则更简单的方法可以对函数进行数值微分 der = np.diff(y) / np.diff(x)
。这样你就不用担心设置 h 了。但是,在这种情况下,请注意 dy
比 y
短一个元素,而 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')
使用 np.渐变()
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)
der = np.gradient(y,x)
plt.plot(x, der, 'r', x, y, 'g', x, -np.sin(x),'b')
plt.show()
我可以使用样条曲线平滑绘图。如果你需要,我会post.
我写了一个程序来求导数。 InterpolatedUnivariateSpline 用于计算 f(x+h)。红线是余弦的导数,绿线是余弦正弦函数,蓝线是-sine函数。红线和蓝线是匹配的。它在以下方面运作良好。
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(frequency) 从 10^7 变化到 2.2812375*10^9,它的步长是 22487500,所以我改变了数组 x。 结果,我得到以下结果。
导数是一条线,几乎接近于0,不是正弦函数。我该如何解决?
您有 loss of significance 个问题。这意味着当将一个大的浮点数与一个小的浮点数相加时,小的精度会部分丢失,因为 numpy double 只能容纳 64 位信息。
要解决此问题,您必须确保 add/multiply/divide 的数字比例没有太大差异。一种简单的解决方案是将 x
除以 1e9
或将 h
乘以 1e9
。如果这样做,您将获得与示例中基本相同的精度。
此外,如果 x
具有足够高的分辨率,则更简单的方法可以对函数进行数值微分 der = np.diff(y) / np.diff(x)
。这样你就不用担心设置 h 了。但是,在这种情况下,请注意 dy
比 y
短一个元素,而 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')
使用 np.渐变()
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)
der = np.gradient(y,x)
plt.plot(x, der, 'r', x, y, 'g', x, -np.sin(x),'b')
plt.show()
我可以使用样条曲线平滑绘图。如果你需要,我会post.