scipy 控制fft系数的数目

siotufzp  于 2022-11-10  发布在  其他
关注(0)|答案(1)|浏览(197)

我有一个5000个点xy的信号当我手动使用离散傅立叶变换时,可以创建一个控制系数数量的系数列表,系数越多,对原始信号的近似度越大。
在下面的示例中,存在5000 points的信号,其在经过DFT之后生成具有201 coefficients的列表。
但是当使用fft()函数时,我无法控制系数的数量。
有没有办法使用numpyscipy,或者它们的fft functions来生成同样的201个系数,而不是生成5000个系数?

  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. from math import tau
  4. from scipy.integrate import quad_vec
  5. from scipy.fft import fft
  6. def f(t, t_list, x_list, y_list):
  7. return np.interp(t, t_list, x_list + 1j*y_list)
  8. N = 5000
  9. t_list = np.linspace(0, 2*np.pi, N)
  10. r = (((0.0*np.pi<=t_list) * (t_list<=0.5*np.pi)) * 1/np.cos(t_list-0.25*np.pi) +
  11. ((0.5*np.pi<t_list) * (t_list<=1.0*np.pi)) * 1/np.cos(t_list-0.75*np.pi) +
  12. ((1.0*np.pi<t_list) * (t_list<=1.5*np.pi)) * 1/np.cos(t_list-1.25*np.pi) +
  13. ((1.5*np.pi<t_list) * (t_list<=2.0*np.pi)) * 1/np.cos(t_list-1.75*np.pi))
  14. # create de signal a square form
  15. x_list, y_list = np.cos(t_list) * r, np.sin(t_list) * r
  16. fig, ax = plt.subplots(figsize=(5, 5))
  17. ax.set_aspect('equal')
  18. ax.plot(x_list, y_list)
  19. print('x length list: ', len(x_list)) #5000 points
  20. print('y length list: ', len(y_list)) #5000 points
  21. order = 100 # -order to order i.e -100 to 100
  22. # you can change the order to get proper figure
  23. # too much is also not good, and too less will not produce good result
  24. print("generating coefficients ...")
  25. # lets compute fourier coefficients from -order to order
  26. c = []
  27. # we need to calculate the coefficients from -order to order
  28. for n in range(-order, order+1):
  29. # calculate definite integration from 0 to 2*PI
  30. # formula is given in readme
  31. coef = 1/tau*quad_vec(lambda t: f(t, t_list, x_list, y_list)*np.exp(-n*t*1j), 0, tau, limit=100, full_output=1)[0]
  32. c.append(coef)
  33. print("completed generating coefficients.")
  34. c = np.array(c)
  35. print('c length list: ', len(c))
  36. # convert x and y to complex number
  37. z = x_list + 1j*y_list
  38. # get coeff of all element of list
  39. coeff_fft = fft(z)
  40. print('coeff_fft length list: ', len(coeff_fft))

输出

  1. x length list: 5000
  2. y length list: 5000
  3. generating coefficients ...
  4. completed generating coefficients.
  5. c length list: 201
  6. coeff_fft length list: 5000

bvk5enib

bvk5enib1#

N个样本的DFT有N个值,如果小于N,变换就不可逆,当然你可以计算变换的各个元素。
FFT(调用fft()时使用)是一种计算DFT的快速算法。它之所以快是因为它计算的是整个变换,而不是单个元素。
我不知道标准库中有哪个函数可以计算DFT的单个值。但正如你所展示的,编写这样的函数很容易。所以,要么像现在这样手动计算这201个值,要么使用fft()计算整个DFT并挑选出你需要的值。哪一种更快取决于你需要多少值以及你有多少样本。

相关问题