繁体   English   中英

numpy.fft在傅立叶空间中进行数值积分

[英]numerical integration in Fourier space with numpy.fft

我想在傅立叶空间中将函数与数值积分相集成。

以下代码显示了一个有效的示例:

import numpy as np
from pylab import *
from numpy.fft import fft, ifft, fftshift, ifftshift

N = 2**16
x = np.linspace(- np.pi , np.pi,N)
y = np.exp(-x**2)                          # function f(x)
ys = np.exp(-x**2) * (-2*x)                # derivative f'(x)
T = x[-1] - x[0] # the whole range
w = (np.arange(N) - N /2.) / T + 0.00000001 # slightly shifted
# integration
fourier =  ifft(ifftshift(1./ ( 2 * np.pi * 1j * w) * fftshift(fft(ys)) )  ) 
# differentiation 
fourier2 =  ifft(ifftshift(( 2 * np.pi * 1j * w) * fftshift(fft(fourier)) )  ) 

您可能会注意到频率w的定义为+ 0.00000001 我需要它,因为否则我会生成ZeroDivisionError或numpy警告。 这是一种变通方法,对于上面的示例来说似乎还可以,但是对于我遇到的更复杂的问题,它却失败了。 一位同事告诉我,如果我得到移位频率值(np.arange(N) - N /2. + 1./2) / T的fft,就可以避免这种情况。 如何在numpy中做到这一点? 有没有办法指定numpy fft的输出网格?

谢谢!

问题是w包含0(应为0),然后除以w w中的0是“ DC”频率; 它对应于傅立叶级数的常数项。

如果将函数与系数为A0的非零DC分量进行积分,则所得函数将包括A0 * t形式的项,该项不在此Fourier技术所应用的周期函数的空间内。 因此,您必须假设输入的DC分量为0。在这种情况下,用w除以得到(0 + 0j)/ 0,即(nan+nanj) 如果输入的直流分量不为零, (inf+nanj)得到(inf+nanj) 无论哪种方式,解决方案都是简单地忽略得到的任何东西,并在使用ifft进行反相之前将DC Fourier系数设置为0。

有几种方法可以实现此目的。 一种方法是更改​​这些行:

w = (np.arange(N) - N /2.) / T + 0.00000001 # slightly shifted
# integration
fourier =  ifft(ifftshift(1./ ( 2 * np.pi * 1j * w) * fftshift(fft(ys)) )  ) 

为此(我添加了几个中间变量):

w = (np.arange(N) - N /2.) / T

# integration
Fys = fft(ys)
with np.errstate(divide="ignore", invalid="ignore"):
    modFys = ifftshift(1./ (2 * np.pi * 1j * w) * fftshift(Fys))

# modFys[0] will hold the result of dividing the DC component of y by 0, so it
# will be nan or inf.  Setting modFys[0] to 0 amounts to choosing a specific
# constant of integration.
modFys[0] = 0

fourier = ifft(modFys).real

我也了解了ifft结果的ifft 理论上,虚部应全部为0; 实际上,由于正常的不精确浮点运算,它们将很小,但不会为零。

顺便说一句,如果您不想实现自己的此技术版本,则可以使用scipy.fftpack.diff

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM