Python FFT Toollit

Jacky | Jul 30, 2022 min read

此內容由 Notion 編輯並經由 Notion API 自動轉成 Hugo 頁面
The content write by Notion, and use Notion API convert to Hugo page.

前言

整理目前在 Python 所用過的 FFT Library。所有安裝都是在 Windows 10 下完成,其他平台沒試過,會遇到甚麼坑我也不知道XD

NumPy

一種 Python 的矩陣運算工具,主要用 C-code 寫成,因此計算速度很快。

  • 安裝
pip install numpy
  • 範例
import numpy as np
A = np.ones((10,10))

## fft2
B = np.fft.fftshift(A)
B = np.fft.fft2(B)
B = np.fft.fftshift(B)

## ifft2
C = np.fft.fftshift(B)
C = np.fft.ifft2(C)
C = np.fft.fftshift(C)

SciPy

基於 NumPy 的科學計算工具,內部計算也是用 C-code 寫成,並延伸出更實用的計算工具。

  • 安裝
pip install scipy
  • 範例
import numpy as np
from scipy.fft import fft, ifft
from scipy.fft import fft2, ifft2
from scipy.fft import fftn, ifftn
from scipy.fft import dct, idct
from scipy.fft import dctn, idctn
from scipy.fft import fftshift

## alloc 2d array
A = np.ones((10,10))
## fft2
B = fftshift(fft2(fftshift(A)))
## ifft2
C = fftshift(ifft2(fftshift(B)))

## alloc 2d array
D = np.ones((10,10))
## dct2
E = dctn(D)
## dct2
F = idctn(E)

CuPy

CuPy 是用 GPU 進行加速運算,最重要特點是可以像 NumPy, SciPy 方式呼叫 API,因此很容易將原本程式碼轉換即可使用 GPU 加速,目前支持大部分 NumPy API,SciPy API 也陸續增加中。

  • 安裝

需要先安裝 NVIDIA 的 CUDA Toolkit

pip install cupy-cuda***

***: 表示 Cuda 版本

  • 範例
import numpy as np
import scipy.fft
import cupy as cp
import cupyx.scipy.fft as cufft
from cupyx.scipy.fft import dctn, idctn
from cupyx.scipy.fft import fft, ifft
from cupyx.scipy.fft import fft2, ifft2
from cupyx.scipy.fft import fftn, ifftn
from cupyx.scipy.fft import dct, idct
from cupyx.scipy.fft import dctn, idctn
from cupyx.scipy.fft import fftshift
scipy.fft.set_global_backend(cufft)

## alloc 2d array
A_cpu = np.ones((10,10))
A_gpu = cp.asarray(A_cpu)  # cpu -> gpu
## fft2
B_gpu = fftshift(fft2(fftshift(A_gpu)))
## ifft2
C_gpu = fftshift(ifft2(fftshift(B_gpu)))
C_cpu = C_gpu.get()  # gpu -> cpu

## alloc 2d array
D_cpu = np.ones((10,10))
D_gpu = cp.asarray(D_cpu)  # cpu -> gpu
## dct2
E_gpu = dctn(D_gpu)
## dct2
F_gpu = idctn(E_gpu)
F_cpu = F_gpu.get()  # gpu -> cpu

PyVkFFT

pyFFTW

基於 FFTW 的 CPU 平行計算工具

pip install pyfftw
  • 範例
import pyfftw
import scipy.signal
import scipy.fft
import scipy.io
import numpy as np
import time
import matplotlib.pyplot as plt

from pyfftw.interfaces.numpy_fft import fft2, ifft2


ar = np.eye(512)

t1 = time.time()
aa = np.fft.fft2(ar)
bb = np.fft.ifft2(aa)
t2 = time.time()
print(t2-t1)


pyfftw.config.NUM_THREADS = 1

a = pyfftw.empty_aligned((512, 512), dtype='complex64')
b = pyfftw.empty_aligned((512, 512), dtype='complex64')
c = pyfftw.empty_aligned((512, 512), dtype='complex64')

a[:] = ar

fft_object = pyfftw.FFTW(a, b, axes=(-2,-1), direction='FFTW_FORWARD')
ifft_object = pyfftw.FFTW(b, c, axes=(-2,-1), direction='FFTW_BACKWARD')

t1 = time.time()
fft_a = fft_object()
ifft_b = ifft_object()
t2 = time.time()
print(t2-t1)

print(np.allclose(aa, fft_a))
print(np.allclose(bb, ifft_b))

print(aa[0])
print(fft_a[0])
print(bb[0])
print(ifft_b[0])

plt.imshow(np.log(np.abs(aa))); plt.show()
plt.imshow(np.log(np.abs(fft_a))); plt.show()
plt.imshow(np.abs(bb)); plt.show()
plt.imshow(np.abs(ifft_b)); plt.show()
comments powered by Disqus