自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

傅里葉變換算法和Python代碼實現(xiàn)

開發(fā)
傅立葉變換是物理學家、數(shù)學家、工程師和計算機科學家常用的最有用的工具之一。本篇文章我們將使用Python來實現(xiàn)一個連續(xù)函數(shù)的傅立葉變換。

傅立葉變換是物理學家、數(shù)學家、工程師和計算機科學家常用的最有用的工具之一。本篇文章我們將使用Python來實現(xiàn)一個連續(xù)函數(shù)的傅立葉變換。

我們使用以下定義來表示傅立葉變換及其逆變換。

設 f: ? → ? 是一個既可積又可平方積分的復值函數(shù)。那么它的傅立葉變換,記為 f?,是由以下復值函數(shù)給出:

同樣地,對于一個復值函數(shù) g?,我們定義其逆傅立葉變換(記為 g)為

這些積分進行數(shù)值計算是可行的,但通常是棘手的——特別是在更高維度上。所以必須采用某種離散化的方法。

在Numpy文檔中關(guān)于傅立葉變換如下,實現(xiàn)這一點的關(guān)鍵是離散傅立葉變換(DFT):

當函數(shù)及其傅立葉變換都被離散化的對應物所取代時,這被稱為離散傅立葉變換(DFT)。離散傅立葉變換由于計算它的一種非??焖俚乃惴ǘ蔀閿?shù)值計算的重要工具,這個算法被稱為快速傅立葉變換(FFT),這個算法最早由高斯(1805年)發(fā)現(xiàn),我們現(xiàn)在使用的形式是由Cooley和Tukey公開的

根據(jù)Numpy文檔,一個具有 n 個元素的序列 a?, …, a??? 的 DFT 計算如下:

我們將積分分解為黎曼和。在 n 個不同且均勻間隔的點 x? = x? + m Δx 處對 x 進行采樣,其中 m 的范圍從 0 到 n-1,x? 是任意選擇的最左側(cè)點。然后就可以近似表示積分為

現(xiàn)在對變量 k 進行離散化,在 n 個均勻間隔的點 k? = l Δk 處對其進行采樣。然后積分變?yōu)?

這使得我們可以用類似于 DFT 的形式來計算函數(shù)的傅立葉變換。這與DFT的計算形式非常相似,這讓我們可以使用FFT算法來高效計算傅立葉變換的近似值。

最后一點是將Δx和Δk聯(lián)系起來,以便指數(shù)項變?yōu)?2π I ml/n,這是Numpy的實現(xiàn)方法;

這就是不確定性原理,所以我們得到了最終的方程

我們可以對逆變換做同樣的處理。在Numpy中,它被定義為

1/n是歸一化因子:

概念和公式我們已經(jīng)通過Numpy的文檔進行了解了,下面開始我們自己的Python實現(xiàn)

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

我們來通過一些例子看看我們自己實現(xiàn)是否正確。

第一個例子:階躍函數(shù)

函數(shù)在-1/2和1/2之間是1,在其他地方是0。它的傅里葉變換是

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));

畫出傅里葉變換,以及在k的采樣值和整個連續(xù)體上計算的解析解:

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();

看起來是沒問題的,然后我們把它轉(zhuǎn)換回來:

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();

我們可以清楚地看到不連續(xù)邊緣處的 Gibbs 現(xiàn)象——這是傅里葉變換的一個預期特征。

第二個例子:高斯PDF

傅里葉變換

下面,我們繪制數(shù)值傅里葉變換和解析值:

以及傅里葉逆變換與原函數(shù)的對比

可以看到,我們的實現(xiàn)沒有任何問題

最后,如果你對機器學習的基礎計算和算法比較感興趣,可以多多關(guān)注Numpy和SK-learn的文檔(還有scipy但是這個更復雜),這兩個庫不僅有很多方法的實現(xiàn),還有這些方法的詳細解釋,這對于我們學習是非常有幫助的。

例如本文的一些數(shù)學的公式和概念就是來自于Numpy的文檔,有興趣的可以直接看看

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

責任編輯:華軒 來源: DeepHub IMBA
相關(guān)推薦

2022-03-10 08:59:59

傅里葉變換算法系統(tǒng)

2023-08-14 16:51:51

傅里葉變換時間序列去趨勢化

2021-05-10 11:53:13

頁面替換算法

2021-06-02 10:06:52

神經(jīng)網(wǎng)絡數(shù)據(jù)圖形

2023-03-26 12:41:46

2025-02-12 10:28:57

SARIMA可視化分析Python

2023-03-30 15:12:47

2017-04-10 13:01:06

javascripthtml5算法

2019-05-29 17:45:32

JavaScript算法思路代碼實現(xiàn)

2017-04-18 16:09:28

Apriori算法Python

2019-05-21 14:28:35

代碼算法編程

2017-02-09 16:16:24

Java負載均衡算法

2022-04-15 08:07:21

ReactDiff算法

2011-02-17 10:54:59

CSS3變換 簡單快捷

2025-04-07 04:20:00

Linux操作系統(tǒng)內(nèi)存管理

2022-03-07 09:42:21

Go快速排序

2009-05-26 16:33:48

PythonC#Run As

2018-07-27 08:39:44

負載均衡算法實現(xiàn)

2011-01-04 11:02:08

程序員

2024-08-05 11:20:41

點贊
收藏

51CTO技術(shù)棧公眾號