2017-02-13 84 views
2

我試圖計算一些數據的導數,並試圖比較有限差分和譜方法輸出的輸出。但結果非常不同,我無法弄清楚爲什麼。`numpy.diff`和`scipy.fftpack.diff`在區分時給出了不同的結果

考慮下面

import numpy as np 
from scipy import fftpack as sp 
from matplotlib import pyplot as plt 
x = np.arange(-100,100,1) 
y = np.sin(x) 

plt.plot(np.diff(y)/np.diff(x)) 
plt.plot(sp.diff(y)) 

plt.show() 

示例代碼本輸出以下結果 enter image description here

橙色輸出作爲fftpack輸出。沒有想到這些微妙之處,這僅僅是爲了舉例。

那麼,他們爲什麼如此不同?他們不應該(大致)相同嗎?

我敢肯定的是,不同的幅度可以fftpack.diff的時期關鍵字進行修正,但我想不通這是正確的時間(我認爲這應該是period=1但不工作)。

此外,如何使用numpy自己的光譜區分?

回答

4

函數scipy.fftpack.diff計算導數,但它假設輸入是週期性的。 period參數給出了輸入序列的週期(即x間隔的總長度)。

在你的情況,這是len(x)*dx,其中dx = x[1] - x[0]

下面是一些使用period參數(紅色)繪製簡單(居中)有限差分(藍色)和diff的結果的代碼。變量xy是相同代碼中使用:

In [115]: plt.plot(0.5*(x[1:]+x[:-1]), np.diff(y)/np.diff(x), 'b') 
Out[115]: [<matplotlib.lines.Line2D at 0x1188d01d0>] 

In [116]: plt.plot(x, sp.diff(y, period=len(x)*(x[1]-x[0])), 'r') 
Out[116]: [<matplotlib.lines.Line2D at 0x1188fc9d0>] 

In [117]: plt.xlabel('x') 
Out[117]: <matplotlib.text.Text at 0x1157425d0> 

plot

注意,如果您輸入實際上不是週期性的,由diff計算出的導數將接近的兩端不準確間隔。

這裏的另一實例中,使用包含在間隔只有一個正弦函數的完整週期[0,1]的較短序列:

In [149]: x = np.linspace(0, 1, 20, endpoint=False) 

In [150]: y = np.sin(2*np.pi*x) 

In [151]: plt.plot(0.5*(x[1:]+x[:-1]), np.diff(y)/np.diff(x), 'b') 
Out[151]: [<matplotlib.lines.Line2D at 0x119872d90>] 

In [152]: plt.plot(x, sp.diff(y, period=len(x)*(x[1]-x[0])), 'r') 
Out[152]: [<matplotlib.lines.Line2D at 0x119c49090>] 

In [153]: plt.xlabel('x') 
Out[153]: <matplotlib.text.Text at 0x1197823d0> 

plot2

+0

我天真地以爲'period'指的是一次測量和另一次測量之間的時間間隔(因此,在我的情況下爲'1')。但是,顯然這很有意義。現在我明白了,我也可以用numpy來重現它,用'i * 2 * pi'乘以fft。 – TomCho

0

1弧度是用於差分近似一個相當粗糙的步幅,你應該想時段整數數據集中

x = np.arange(-200,200,1) 
y = np.sin(np.pi/50*x) 

plt.plot(np.diff(y)/np.diff(x)) 
plt.plot(sp.diff(y,order=1, period=400)) 

匹配得很好 - 但我不知道確切的合理的週期/歸一化函數

相關問題