高斯的傅里叶变换不是高斯,但这不对! - Python
我正在尝试使用Numpy的fft函数,但是当我给这个函数一个简单的高斯函数时,得到的高斯函数的傅里叶变换(fft)并不是一个完整的高斯函数,而是被切成了两半,分别位于x轴的两端。
我计算的高斯函数是 y = exp(-x^2)
这是我的代码:
from cmath import *
from numpy import multiply
from numpy.fft import fft
from pylab import plot, show
""" Basically the standard range() function but with float support """
def frange (min_value, max_value, step):
value = float(min_value)
array = []
while value < float(max_value):
array.append(value)
value += float(step)
return array
N = 256.0 # number of steps
y = []
x = frange(-5, 5, 10/N)
# fill array y with values of the Gaussian function
cache = -multiply(x, x)
for i in cache: y.append(exp(i))
Y = fft(y)
# plot the fft of the gausian function
plot(x, abs(Y))
show()
结果不太对,因为高斯函数的傅里叶变换应该还是一个高斯函数……
5 个回答
3
这个图表是以系数索引零为中心(也就是平均值)来显示的。所以看起来右边的部分在左边,反之亦然。
补充说明:看看下面的代码:
import scipy
import scipy.signal as sig
import pylab
x = sig.gaussian(2048, 10)
X = scipy.absolute(scipy.fft(x))
pylab.plot(x)
pylab.plot(X)
pylab.plot(X[range(1024, 2048)+range(0, 1024)])
最后一行代码会从向量的中心开始绘制X
,然后再回到开头。
4
你的结果看起来根本不像一个高斯分布,甚至连分成两半的样子都没有。
要得到你想要的结果,你需要把自己的高斯分布放在索引0的位置,这样结果也会相应地调整。试试下面的代码:
from pylab import *
N = 128
x = r_[arange(0, 5, 5./N), arange(-5, 0, 5./N)]
y = exp(-x*x)
y_fft = fft(y) / sqrt(2 * N)
plot(r_[y[N:], y[:N]])
plot(r_[y_fft[N:], y_fft[:N]])
show()
这些绘图命令会把数组分成两半,然后交换它们的位置,这样看起来会更好看。
18
np.fft.fft
这个函数会返回一个结果,叫做“标准顺序”:(来自文档)
A = fft(a, n),那么
A[0]
里包含的是零频率项(也就是信号的平均值),对于真实的输入,这个值总是纯实数。接下来,A[1:n/2]
里包含的是正频率项,而A[n/2+1:]
里则包含的是负频率项,按照频率从负到更负的顺序排列。
函数 np.fft.fftshift
会把结果重新排列成大多数人习惯的顺序(这对于绘图也很有帮助):
这个过程
np.fft.fftshift(A)
会把变换和它们的频率移动,使得零频率的成分位于中间...
所以使用 np.fft.fftshift
的效果是:
import matplotlib.pyplot as plt
import numpy as np
N = 128
x = np.arange(-5, 5, 10./(2 * N))
y = np.exp(-x * x)
y_fft = np.fft.fftshift(np.abs(np.fft.fft(y))) / np.sqrt(len(y))
plt.plot(x,y)
plt.plot(x,y_fft)
plt.show()