?傅里葉變換算法和Python代碼實(shí)現(xiàn)
來(lái)源:Deephub Imba 本文約2500字,建議閱讀10分鐘
本文我們將使用Python來(lái)實(shí)現(xiàn)一個(gè)連續(xù)函數(shù)的傅立葉變換。
傅立葉變換是物理學(xué)家、數(shù)學(xué)家、工程師和計(jì)算機(jī)科學(xué)家常用的最有用的工具之一。
當(dāng)函數(shù)及其傅立葉變換都被離散化的對(duì)應(yīng)物所取代時(shí),這被稱(chēng)為離散傅立葉變換(DFT)。離散傅立葉變換由于計(jì)算它的一種非常快速的算法而成為數(shù)值計(jì)算的重要工具,這個(gè)算法被稱(chēng)為快速傅立葉變換(FFT),這個(gè)算法最早由高斯(1805年)發(fā)現(xiàn),我們現(xiàn)在使用的形式是由Cooley和Tukey公開(kāi)的
import numpy as npimport matplotlib.pyplot as pltdef fourier_transform_1d(func, x, sort_results=False):"""Computes the continuous Fourier transform of function `func`, following the physicist's conventionGrid 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 transformReturns--------- 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/dtw = np.fft.fftfreq(f.size)*2*np.pi/dx# Multiply by external factorg *= 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, gdef inverse_fourier_transform_1d(func, k, sort_results=False):"""Computes the inverse Fourier transform of function `func`, following the physicist's conventionGrid 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 transformReturns--------- 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/dkif 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
我們來(lái)通過(guò)一些例子看看我們自己實(shí)現(xiàn)是否正確。
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, g = fourier_transform_1d(f, x, sort_results=True) # make it easier to plotkk = 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();
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();
編輯:黃繼彥
評(píng)論
圖片
表情
