通过 FFT 计算数值导数 - SciPy
Computing numeric derivative via FFT - SciPy
我编写了以下代码来使用 FFT 计算函数的近似导数:
from scipy.fftpack import fft, ifft, dct, idct, dst, idst, fftshift, fftfreq
from numpy import linspace, zeros, array, pi, sin, cos, exp
import matplotlib.pyplot as plt
N = 100
x = linspace(0,2*pi,N)
dx = x[1]-x[0]
y = sin(2*x)+cos(5*x)
dydx = 2*cos(2*x)-5*sin(5*x)
k = fftfreq(N,dx)
k = fftshift(k)
dydx1 = ifft(-k*1j*fft(y)).real
plt.plot(x,dydx,'b',label='Exact value')
plt.plot(x,dydx1,'r',label='Derivative by FFT')
plt.legend()
plt.show()
然而,它给出了意想不到的结果,我认为这与数组 k 给出的波数输入不正确有关:
我知道 FFT 的不同实现处理波数顺序的方式不同,那么我在这里缺少什么?任何想法将不胜感激。
我认为问题出在 fftfreq
上,它并没有像您在 doc.
中看到的那样按照您的想法行事
此外,您的代码中有一个负号我不明白。
哦,作为参考,fftpack.diff
完全符合您的要求。
这是完成这项工作的代码示例:
import numpy as np
import matplotlib.pyplot as plt
from scipy import fftpack
N = 100
L = 2*np.pi
dx = L/N
x = np.linspace(0,L,N)
y = np.sin(2*x)+np.cos(5*x)
dydx = 2*np.cos(2*x)-5*np.sin(5*x)
fhat = np.fft.fft(y)
k = (2*np.pi/L)*np.arange(0,N)
k = fftpack.fftshift(k)
dydx1 = fftpack.ifft(k*1j*fftpack.fft(y)).real
plt.plot(x,dydx,'b',label='Exact value')
plt.plot(x,dydx1,'r',label='Derivative by FFT')
plt.plot(x,fftpack.diff(y),'g',label='Derivative by FFT 2')
plt.legend()
plt.show()
我编写了以下代码来使用 FFT 计算函数的近似导数:
from scipy.fftpack import fft, ifft, dct, idct, dst, idst, fftshift, fftfreq
from numpy import linspace, zeros, array, pi, sin, cos, exp
import matplotlib.pyplot as plt
N = 100
x = linspace(0,2*pi,N)
dx = x[1]-x[0]
y = sin(2*x)+cos(5*x)
dydx = 2*cos(2*x)-5*sin(5*x)
k = fftfreq(N,dx)
k = fftshift(k)
dydx1 = ifft(-k*1j*fft(y)).real
plt.plot(x,dydx,'b',label='Exact value')
plt.plot(x,dydx1,'r',label='Derivative by FFT')
plt.legend()
plt.show()
然而,它给出了意想不到的结果,我认为这与数组 k 给出的波数输入不正确有关:
我知道 FFT 的不同实现处理波数顺序的方式不同,那么我在这里缺少什么?任何想法将不胜感激。
我认为问题出在 fftfreq
上,它并没有像您在 doc.
此外,您的代码中有一个负号我不明白。
哦,作为参考,fftpack.diff
完全符合您的要求。
这是完成这项工作的代码示例:
import numpy as np
import matplotlib.pyplot as plt
from scipy import fftpack
N = 100
L = 2*np.pi
dx = L/N
x = np.linspace(0,L,N)
y = np.sin(2*x)+np.cos(5*x)
dydx = 2*np.cos(2*x)-5*np.sin(5*x)
fhat = np.fft.fft(y)
k = (2*np.pi/L)*np.arange(0,N)
k = fftpack.fftshift(k)
dydx1 = fftpack.ifft(k*1j*fftpack.fft(y)).real
plt.plot(x,dydx,'b',label='Exact value')
plt.plot(x,dydx1,'r',label='Derivative by FFT')
plt.plot(x,fftpack.diff(y),'g',label='Derivative by FFT 2')
plt.legend()
plt.show()