The Fourier transform is an indispensable technique for carrying out scientific and technical research. ** In this article, scipy's scipy.fftpack module [ The method of high-speed discrete Fourier transform using 1] is summarized through a simple example. ** ** For the usual method of discrete Fourier transform, please refer to the literature as appropriate because there is an elementary text [2,3].
** In this paper, the use of scipy's fast Fourier transform library is brought to the fore in consideration of the usage scene in the workplace [4]. If you practice while checking the operation of Example (1), you will soon be able to use it in the field. ** **
(1) Example of one-dimensional discrete Fourier transform (2) Example of 3D Fourier transform
In this example, the Fourier transform $ g (\ omega) $ of the Gaussian function $ f (t) = e ^ {(-(t-5) ^ 2)} $ is obtained. Only the following two methods are used.
Let the total number of data N be 40 and the sampling width T be from $ t = 0 $ to $ t = 10 $ ($ T = 10 $).
Therefore time sampling
Will be.
Along with that, the discrete points of the frequency $ \ omega $
Will be.
The flow of the program is as follows.
** Fast Fourier transform of the desired function is possible by changing the functional form of $ f (t) $. ** **
FFT1D.py
"""
One-dimensional discrete Fourier transform
"""
import numpy as np
from scipy.fftpack import fft, ifft
import matplotlib.pyplot as plt
#Creating time-series sample data
N = 40 #The number of data
T=10 #Sampling width
del_t= T/N #Sampling interval
del_w=2*np.pi/T #Discrete Fourier Transform Frequency Interval
#
#Discrete point generation
t = np.arange(0,T-del_t,del_t)
w=np.arange(2*np.pi/T, 2*np.pi*N/T, del_w)
#
f = np.exp(-(t-5)**2) # #Function that gives sample data
#
g = fft(f)
g_real=np.real(g)
g_imag=np.imag(g)
#plot
plt.xlabel('w', fontsize=24)
plt.ylabel('g(w)', fontsize=24)
plt.plot(w,g_real,marker='o', markersize=4,label='Fourier transform: Real part')
plt.plot(w,g_imag,marker='o',markersize=4, label='Fourier transform: Imaginary part')
plt.legend(loc='best')
plt.show()
#Power spectrum display
plt.plot(w,np.abs(g)**2,marker='o',markersize=4,label='|g(w)|^2')
plt.xlabel('w', fontsize=24)
plt.ylabel('Power spectrum |g(w)|^2', fontsize=24)
plt.legend(loc='best')
plt.show()
#Inverse discrete Fourier transform
ff = ifft(g)
plt.plot(t, np.real(ff), label='Fourier inverse transform: Real part')
plt.plot(t, np.imag(ff), label='Fourier inverse transform: Imaginary part')
plt.plot(t, f,'o',markersize=4,label='Raw data')
plt.xlabel('t', fontsize=24)
plt.ylabel('f(t)', fontsize=24)
plt.legend(loc='best')
plt.show()
Figure 1. Discrete Fourier Transform $ g (\ omega_n) $
Figure 2.Power spectrum
Figure 3. Comparison between the inverse complex Fourier transform (line) and the sampling data (green circle). Since I was thinking of a real function, the imaginary part of the inverse complex Fourier transform is zero.
In this example, the 3D Gaussian function $ f (t_x, t_y, t_z) = e ^ {-[(t_x-5) ^ 2 + (t_y-5) ^ 2 + (t_z-5) ^ 2)]} $ Is performing a high-speed complex discrete Fourier transform of. Compared to the example (1), which was a one-dimensional problem, the number of subscripts increases, but the content is not significantly difficult.
As with the one-dimensional method, there are only the following two methods used for multidimensional (two or more).
** The dimension of the Fourier transform does not need to be very nervous on the programmer side because scipy arbitrarily determines the dimension of the array when performing the Fourier transform **
This example is intended only for operation check, and is not visualized. But if needed, the desired plot could easily be made.
The flow of the program is as follows.
"""
Multidimensional discrete Fourier transform
August 12, 2017
"""
import numpy as np
from scipy.fftpack import fftn, ifftn #n-dimensional discrete Fourier transform / inverse Fourier transform
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
#Creating time-series sample data
Nx = 4 #Number of data in Nx direction
Ny = 4 #Number of data in Ny direction
Nz = 4 #Number of data in the Nz direction
Tx=10 #Sampling width
Ty = 10
Tz = 10
del_t_x= Tx/Nx #Sampling interval in the tx direction
del_t_y= Ty/Ny #Sampling interval in the ty direction
del_t_z= Tz/Nz #Sampling interval in the ty direction
del_w_x=2*np.pi/Tx #Interval of frequency of x component of discrete Fourier transform
del_w_y=2*np.pi/Ty #Spacing of the y component of the discrete Fourier transform
del_w_z=2*np.pi/Tz #Interval of frequency of z component of discrete Fourier transform
#
t_x, t_y, t_z= np.meshgrid(np.arange(0,Tx-del_t_x,del_t_x),np.arange(0,Ty-del_t_y,del_t_y), np.arange(0,Tz-del_t_z,del_t_z)) #Mesh generation
w_x, w_y, w_z= np.meshgrid(np.arange(2*np.pi/Tx, 2*np.pi*Nx/Tx, del_w_x),np.arange(2*np.pi/Ty, 2*np.pi*Ny/Ty, del_w_y), np.arange(2*np.pi/Tz, 2*np.pi*Nz/Tz, del_w_z)) #Mesh generation
#
f = np.exp(-((t_x-5)**2+(t_y-5)**2+(t_z-5)**2)) #Function that gives sample data
#
g = fftn(f) #Multidimensional fast Fourier transform:3D in this case
g_real=np.real(g) #Real part
g_imag=np.imag(g) #Imaginary part
#Inverse multidimensional discrete Fourier transform
ff = ifftn(g)
ff_real=np.real(ff)#Real part
ff_imag=np.imag(ff) #Imaginary part
Let's output a little numerical value.
print(g[1,2,1])
out: (-0.500000003576+0.862688207649j)
It means that the [1,2,1] component of the Fourier transformed g is -0.5 + 0.86i (complex number).
Next, let's check the inverse Fourier transform.
print(ff[1,2,2])
out: (0.00193045413623+0j)
This is a real number. I can calculate without any problem.
You can get information from many books and websites about the "not fast" ordinary discrete Fourier transform. References 2 and 3 also refer to the Fast Fourier Transform. It is very easy to read due to the careful consideration of the reader. 4 is a foreign book, but the explanation with the essence is worth reading.