更改点数会改变fft的结果

时间:2015-06-09 13:24:56

标签: python numpy fft

我写了一个脚本来生成一个函数(sech(x)),生成fft,然后测量结果的FWTH。现在奇怪的是,当我改变用于生成函数的点数时,fft和FWTH测量的结果也发生了很大的变化。这是由于准确度提高还是其他原因? 我使用的脚本是:

from __future__ import division
import numpy as np
from math import *
import numpy.fft as fft
from matplotlib import pyplot as plt


def formula(t, fwhm = 0):
    if fwhm == 0:
        t0 = 68e-15#15#68e-15#*1.76#25e-15#68e-15
    else:
        t0 = fwhm/(2*log(2+sqrt(3)))
    #print t0*84e-9
    E0 = 0.68e-9
    p = 1e10
    #if E0 != 0:
#        p = E0/t0
    print("p is: " + str(p))
    inifield = []
    inifield = np.sqrt(p) * 1/np.cosh(t/t0)
    return inifield

def find_nearest(array, values):
    values = np.atleast_1d(values)
    indices = np.abs(np.subtract.outer(array, values)).argmin(0)
    out = array[indices]
    return out if len(out) > 1 else out[0]

def get_FWHM(data, time, inverse):
    epsilon = 1e-12
    max_val = max(data)
    h_max = max_val/2
    idx_max = np.where(data == max_val)
    #idx_h = find_nearest(data, h_max)
    idx_h = []
    print "H_max/2 = " + str(h_max)
    print "Highest values is: " + str(find_nearest(data, h_max * 2))
    subdata = np.split(data, 2)
    for elem in subdata:
        idx_h.append(np.where(elem == find_nearest(elem, h_max)))
    for i, elem in enumerate(idx_h):
        idx_h[i] = int(elem[0])
    idx_h[1] += len(data)/2
    print idx_max
    print "idx_max = " + str(data[int(idx_max[0][0])])
    for elem in idx_h:
        print "idx_h = " + str(elem) + ' ' + str(data[elem])
    if inverse:
        print "Frequency is: " + str(1/time[idx_h[0]]) + " " + str(1/time[idx_h[1]]) + " " + str((1/time[idx_h[1]] - 1/time[idx_h[0]]))
    else:
        print "Time is: " + str(time[idx_h[0]]) + " " + str(time[idx_h[1]]) + " " + str((time[idx_h[1]] - time[idx_h[0]]))

Ntime = 2**17
Tmax = Ntime/2
dt = 2*Tmax/(Ntime-1)
c = 2.99792458e8
t = np.linspace(-1.633e-12, 1.633e-12, Ntime)
#for i, elem in enumerate(t):
#    t[i] *= dt
#for elem in t:
#    print(str(elem/T0))
#    y.append(1/cosh(elem/T0))
y = formula(t, 68e-15)
#get_FWHM(y, t, False)
h = fft.fftshift(fft.ifft(fft.fftshift(y)))
print "get_FWHM for h"
get_FWHM(h, t, True)
print "Target FWHM is: " + str(c/88e-9)
plt.plot(t, y, 'b:', t, h)
plt.show()

使用Ntime=2**13运行时,输出为:

Frequency is: -1.51997624747e+14 1.4331204619e+14 2.95309670937e+14
Target FWHM is: 3.40673247727e+15

使用2**17点时,输出为:

Frequency is: -2.4322403459e+15 2.29325518327e+15 4.72549552917e+15
Target FWHM is: 3.40673247727e+15

1 个答案:

答案 0 :(得分:1)

您的问题出在移位信号的逆FFT中。

通过将ifft应用于移位信号,您将信号解释为处于频域中。通过添加点,您可以有效地提高奈奎斯特频率。但你保持你的形状“相同”,在更宽的频率范围内涂抹它。较高频率的内容使得ifft峰值更窄(时域/频域中的窄峰意味着相应时域/频域中的宽峰)。

最终,这更像是一个数学问题,而不是一个代码问题。 fftshift / fft / ifft 表现正常。我不确定你要完成什么,因为你正在使用频率修改函数(fftshift)看似时域信号,然后将ifft应用于结果,并将结果修改为频率再次发出信号。

在脚本底部运行以下代码,以查看点数依赖关系的出现位置。

plt.figure()

for Ntime in 2**np.arange(14,18):

    # Ntime = 2**14
    Tmax = Ntime/2
    dt = 2*Tmax/(Ntime-1)
    c = 2.99792458e8
    t = np.linspace(-1.633e-12, 1.633e-12, Ntime)
    #for i, elem in enumerate(t):
    #    t[i] *= dt
    #for elem in t:
    #    print(str(elem/T0))
    #    y.append(1/cosh(elem/T0))
    y = formula(t, 68e-15)
    #get_FWHM(y, t, False)
    h1 = fft.fftshift(y)
    h2 = ifft(h1)
    h3 = fft.fftshift(h2)
    h = h3
    # h = fft.fftshift(fft.ifft(fft.fftshift(y)))
    print "get_FWHM for h"
    get_FWHM(h, t, True)
    print "Target FWHM is: " + str(c/88e-9)

    plt.subplot(4,1,1)
    plt.plot(t, y)
    plt.subplot(4,1,2)
    plt.plot(t, h1)
    plt.subplot(4,1,3)
    plt.plot(t, h2)
    plt.subplot(4,1,4)
    plt.plot(t, h3,label='%e'%Ntime)
    plt.show()

plt.legend()