代码之家  ›  专栏  ›  技术社区  ›  ThunderBiggi

在Python中使用DFT查找一阶导数

  •  1
  • ThunderBiggi  · 技术社区  · 8 年前

    我想找到的一阶导数 exp(sin(x)) 关于间隔 [0, 2/pi] 使用离散傅里叶变换。基本思想是首先评估 exp(sin(x)) 在给定的时间间隔,给你说 v_k ,然后计算逆DFT ikv_k 给你想要的答案。实际上,由于在编程语言中实现了傅里叶变换,您可能需要在某处对输出重新排序和/或在某处乘以不同的因子。

    FourierParameters ,它允许您为转换指定约定。首先,我得到了高斯函数的傅里叶级数,为了看看我必须乘以哪些归一化因子,然后继续求导数。不幸的是,后来我把Mathematica代码翻译成了Python(因此我又第一次做了高斯傅里叶级数——这是成功的),我没有得到相同的结果。这是我的代码:

    N=1000
    xmin=0
    xmax=2.0*np.pi
    step = (xmax-xmin)/(N)
    xdata = np.linspace(xmin, xmax-step, N)
    v = np.exp(np.sin(xdata))
    derv = np.cos(xdata)*v
    vhat = np.fft.fft(v)
    kvals1 = np.arange(0, N/2.0, 1)
    kvals2 = np.arange(-N/2.0, 0, 1)
    what1 = np.zeros(kvals1.size+1)
    what2 = np.empty(kvals2.size)
    it = np.nditer(kvals1, flags=['f_index'])
    while not it.finished:
        np.put(what1, it.index, 1j*(2.0*np.pi)/((xmax-xmin))*it[0]*vhat[[int(it[0])]])
        it.iternext()
    it = np.nditer(kvals2, flags=['f_index'])
    while not it.finished:
        np.put(what2, it.index, 1j*(2.0*np.pi)/((xmax-xmin))*it[0]*vhat[[int(it[0])]])
        it.iternext()
    xdatafull = np.concatenate((xdata, [2.0*np.pi]))
    what = np.concatenate((what1, what2))
    w = np.real(np.fft.ifft(what))
    
    fig = plt.figure()
    ax = plt.gca()
    ax.spines['right'].set_color('none')
    ax.spines['top'].set_color('none')
    ax.xaxis.set_ticks_position('bottom')
    ax.spines['bottom'].set_position(('data',0))
    ax.yaxis.set_ticks_position('left')
    ax.spines['left'].set_position(('data',0))
    
    plt.plot(xdata, derv, color='blue')
    plt.plot(xdatafull, w, color='red')
    plt.show()
    

    如果有人想,我可以发布Mathematica代码。

    1 回复  |  直到 8 年前
        1
  •  2
  •   ThunderBiggi    8 年前

    问题是 np.zeros 给你一个实数零而不是复数零的数组,因此后面的赋值不会改变任何东西,因为它们是虚构的。

    因此,解决方案非常简单

    import numpy as np
    
    N=100
    xmin=0
    xmax=2.0*np.pi
    step = (xmax-xmin)/(N)
    xdata = np.linspace(step, xmax, N)
    v = np.exp(np.sin(xdata))
    derv = np.cos(xdata)*v
    vhat = np.fft.fft(v)
    
    what = 1j*np.zeros(N)
    what[0:N/2.0] = 1j*np.arange(0, N/2.0, 1)
    what[N/2+1:] = 1j*np.arange(-N/2.0 + 1, 0, 1)
    what = what*vhat
    w = np.real(np.fft.ifft(what))
    
    # Then plotting
    

    据此 np.零 1j*np.zeros