脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|shell|

服务器之家 - 脚本之家 - Python - 傅里叶变换算法和Python代码实现

傅里叶变换算法和Python代码实现

2024-03-12 15:03DeepHub IMBA Python

傅立叶变换是物理学家、数学家、工程师和计算机科学家常用的最有用的工具之一。本篇文章我们将使用Python来实现一个连续函数的傅立叶变换。

傅立叶变换是物理学家、数学家、工程师和计算机科学家常用的最有用的工具之一。本篇文章我们将使用Python来实现一个连续函数的傅立叶变换。

我们使用以下定义来表示傅立叶变换及其逆变换。

设 f: ℝ → ℂ 是一个既可积又可平方积分的复值函数。那么它的傅立叶变换,记为 f̂,是由以下复值函数给出:

傅里叶变换算法和Python代码实现

同样地,对于一个复值函数 ĝ,我们定义其逆傅立叶变换(记为 g)为

傅里叶变换算法和Python代码实现

这些积分进行数值计算是可行的,但通常是棘手的——特别是在更高维度上。所以必须采用某种离散化的方法。

在Numpy文档中关于傅立叶变换如下,实现这一点的关键是离散傅立叶变换(DFT):

当函数及其傅立叶变换都被离散化的对应物所取代时,这被称为离散傅立叶变换(DFT)。离散傅立叶变换由于计算它的一种非常快速的算法而成为数值计算的重要工具,这个算法被称为快速傅立叶变换(FFT),这个算法最早由高斯(1805年)发现,我们现在使用的形式是由Cooley和Tukey公开的

根据Numpy文档,一个具有 n 个元素的序列 a₀, …, aₙ₋₁ 的 DFT 计算如下:

傅里叶变换算法和Python代码实现

我们将积分分解为黎曼和。在 n 个不同且均匀间隔的点 xₘ = x₀ + m Δx 处对 x 进行采样,其中 m 的范围从 0 到 n-1,x₀ 是任意选择的最左侧点。然后就可以近似表示积分为

傅里叶变换算法和Python代码实现

现在对变量 k 进行离散化,在 n 个均匀间隔的点 kₗ = l Δk 处对其进行采样。然后积分变为:

傅里叶变换算法和Python代码实现

这使得我们可以用类似于 DFT 的形式来计算函数的傅立叶变换。这与DFT的计算形式非常相似,这让我们可以使用FFT算法来高效计算傅立叶变换的近似值。

最后一点是将Δx和Δk联系起来,以便指数项变为-2π I ml/n,这是Numpy的实现方法;

傅里叶变换算法和Python代码实现

这就是不确定性原理,所以我们得到了最终的方程

傅里叶变换算法和Python代码实现

我们可以对逆变换做同样的处理。在Numpy中,它被定义为

傅里叶变换算法和Python代码实现

1/n是归一化因子:

傅里叶变换算法和Python代码实现

概念和公式我们已经通过Numpy的文档进行了解了,下面开始我们自己的Python实现

import numpy as np
 import matplotlib.pyplot as plt
 
 
 def fourier_transform_1d(func, x, sort_results=False):
 
     """
    Computes the continuous Fourier transform of function `func`, following the physicist's convention
    Grid x must be evenly spaced.
 
    Parameters
    ----------
 
    - func (callable): function of one argument to be Fourier transformed
    - x (numpy array) evenly spaced points to sample the function
    - sort_results (bool): reorders the final results so that the x-axis vector is sorted in a natural order.
        Warning: setting it to True makes the output not transformable back via Inverse Fourier transform
 
    Returns
    --------
    - k (numpy array): evenly spaced x-axis on Fourier domain. Not sorted from low to high, unless `sort_results` is set to True
    - g (numpy array): Fourier transform values calculated at coordinate k
    """
     x0, dx = x[0], x[1] - x[0]
     f = func(x)
     
     g = np.fft.fft(f) # DFT calculation
 
     # frequency normalization factor is 2*np.pi/dt
     w = np.fft.fftfreq(f.size)*2*np.pi/dx
 
     # Multiply by external factor
     g *= dx*np.exp(-complex(0,1)*w*x0) 
     
     if sort_results:    
         zipped_lists = zip(w, g)
         sorted_pairs = sorted(zipped_lists)
         sorted_list1, sorted_list2 = zip(*sorted_pairs)
         w = np.array(list(sorted_list1))
         g = np.array(list(sorted_list2))
         
     return w, g
 
 
 def inverse_fourier_transform_1d(func, k, sort_results=False):
     """
    Computes the inverse Fourier transform of function `func`, following the physicist's convention
    Grid x must be evenly spaced.
 
    Parameters
    ----------
 
    - func (callable): function of one argument to be inverse Fourier transformed
    - k (numpy array) evenly spaced points in Fourier space to sample the function
    - sort_results (bool): reorders the final results so that the x-axis vector is sorted in a natural order.
        Warning: setting it to True makes the output not transformable back via Fourier transform
 
    Returns
    --------
    - y (numpy array): evenly spaced x-axis. Not sorted from low to high, unless `sort_results` is set to True
    - h (numpy array): inverse Fourier transform values calculated at coordinate x
    """
     dk = k[1] - k[0]
     
     f = np.fft.ifft(func) * len(k) * dk /(2*np.pi)
     x = np.fft.fftfreq(f.size)*2*np.pi/dk
 
     if sort_results:    
         zipped_lists = zip(x, f)
         sorted_pairs = sorted(zipped_lists)
         sorted_list1, sorted_list2 = zip(*sorted_pairs)
         x = np.array(list(sorted_list1))
         f = np.array(list(sorted_list2))
     return x, f

我们来通过一些例子看看我们自己实现是否正确。

第一个例子:阶跃函数

傅里叶变换算法和Python代码实现

函数在-1/2和1/2之间是1,在其他地方是0。它的傅里叶变换是

傅里叶变换算法和Python代码实现

N = 2048
 
 # Define the function f(x)
 f = lambda x: np.where((x >= -0.5) & (x <= 0.5), 1, 0)
 x = np.linspace(-1, 1, N) 
 plt.plot(x, f(x));

傅里叶变换算法和Python代码实现

画出傅里叶变换,以及在k的采样值和整个连续体上计算的解析解:

k, g = fourier_transform_1d(f, x, sort_results=True) # make it easier to plot
 kk = np.linspace(-30,30, 100)
 
 plt.plot(k, np.real(g), label='Numerical'); 
 plt.plot(k, np.sin(k/2)/(k/2), linestyle='-.', label='Analytic (samples)')
 plt.plot(kk, np.sin(kk/2)/(kk/2), linestyle='--', label='Analytic (full)')
 plt.xlim(-30, 30)
 plt.legend();

傅里叶变换算法和Python代码实现

看起来是没问题的,然后我们把它转换回来:

k, g = fourier_transform_1d(f, x)
 y, h = inverse_fourier_transform_1d(g, k, sort_results=True)
 
 plt.plot(y, np.real(h), label='Numerical transform')
 plt.plot(x, f(x), linestyle='--', label='Analytical')
 plt.legend();

傅里叶变换算法和Python代码实现

我们可以清楚地看到不连续边缘处的 Gibbs 现象——这是傅里叶变换的一个预期特征。

第二个例子:高斯PDF

傅里叶变换算法和Python代码实现

傅里叶变换

傅里叶变换算法和Python代码实现

下面,我们绘制数值傅里叶变换和解析值:

傅里叶变换算法和Python代码实现

以及傅里叶逆变换与原函数的对比

傅里叶变换算法和Python代码实现

可以看到,我们的实现没有任何问题

最后,如果你对机器学习的基础计算和算法比较感兴趣,可以多多关注Numpy和SK-learn的文档(还有scipy但是这个更复杂),这两个库不仅有很多方法的实现,还有这些方法的详细解释,这对于我们学习是非常有帮助的。

例如本文的一些数学的公式和概念就是来自于Numpy的文档,有兴趣的可以直接看看

https://numpy.org/doc/stable/reference/routines.fft.html

原文地址:https://mp.weixin.qq.com/s?__biz=MzU5OTM2NjYwNg==&mid=2247506130&idx=1&sn=b5c954a467359bf363b54fe97d9cf3b1

延伸 · 阅读

精彩推荐
  • PythonPython实现Mysql数据库连接池实例详解

    Python实现Mysql数据库连接池实例详解

    这篇文章主要介绍了Python实现Mysql数据库连接池实例详解的相关资料,需要的朋友可以参考下...

    zbc10905498395502020-09-29
  • Pythonpython实现决策树C4.5算法详解(在ID3基础上改进)

    python实现决策树C4.5算法详解(在ID3基础上改进)

    下面小编就为大家带来一篇python实现决策树C4.5算法详解(在ID3基础上改进)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来...

    Python教程网8592020-11-13
  • Python对Python3.6 IDLE常用快捷键介绍

    对Python3.6 IDLE常用快捷键介绍

    今天小编就为大家分享一篇对Python3.6 IDLE常用快捷键介绍,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    放狼的爷们12192021-03-17
  • Python5 分钟读懂Python 中的 Hook 钩子函数

    5 分钟读懂Python 中的 Hook 钩子函数

    这篇文章主要介绍了5 分钟掌握 Python 中的 Hook 钩子函数,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的...

    Python中文社区10692021-08-11
  • PythonDjango实现表单验证

    Django实现表单验证

    这篇文章主要为大家详细介绍了Django实现表单验证的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    不凡De老五6912021-04-01
  • PythonPython+xlwings制作天气预报表

    Python+xlwings制作天气预报表

    python操作Excel的模块,网上提到的模块大致有:xlwings、xlrd、xlwt、openpyxl、pyxll等。本文将利用xlwings模块制作一个天气预报表,需要的可以参考一下...

    戴沐白8542022-08-31
  • Python用Django写天气预报查询网站

    用Django写天气预报查询网站

    今天小编就为大家分享一篇关于用Django写天气预报查询网站的文章,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随...

    回忆不说话8612021-04-10
  • PythonPython数据分析库pandas基本操作方法

    Python数据分析库pandas基本操作方法

    下面小编就为大家分享一篇Python数据分析库pandas基本操作方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    birdlove19877752021-01-28