我正在尝试将两个用(SciPy's FFTPACK RFFT)转换的二维数组相乘fftpack_rfft2d()
,结果与我从scipy_rfft2d()
(SciPy's FFT RFFT)得到的结果不兼容。
下图共享脚本的输出,其中显示:
- 两个输入数组的初始化值;
- 两个数组在使用 SciPy 对 RFFT 的 FFT 实现进行转换后,使用 ;
scipy_rfft2d()
进行反向转换后的乘法输出scipy_irfft2d()
; - 使用 SciPy 对 RFFT 的 FFTPACK 实现与
fftpack_rfft2d()
和相同的事情fftpack_irfft2d()
; - 一个测试的结果
np.allclose()
是检查两个乘法的结果在它们被转换回它们各自的 IRFFT 实现后是否相同。
需要说明的是,红色矩形显示的是逆变换IRFFT后的乘法结果:左边的矩形使用了SciPy的FFT IRFFT;右边的矩形,SciPy 的 FFTPACK IRFFT。当与 FFTPACK 版本的乘法固定时,它们应该呈现相同的数据。
我认为 FFTPACK 版本的乘法结果不正确,因为scipy.fftpack返回结果 RFFT 数组中的实部和虚部与 scipy.fft 的 RFFT不同:
- 我相信来自scipy.fftpack 的RFFT返回一个数组,其中一个元素包含实部,下一个元素包含其虚部;
- 在来自 scipy.fft 的RFFT中,每个元素都是一个复数,因此能够同时保存实部和虚部;
如果我错了,请纠正我!我还想指出,由于scipy.fftpack不提供用于转换 2D 数组的函数,例如rfft2()
and irfft2()
,我在下面的代码中提供了我自己的实现:
import numpy as np
from scipy import fftpack as scipy_fftpack
from scipy import fft as scipy_fft
# SCIPY RFFT 2D
def scipy_rfft2d(matrix):
fftRows = [scipy_fft.rfft(row) for row in matrix]
return np.transpose([scipy_fft.fft(row) for row in np.transpose(fftRows)])
# SCIPY IRFFT 2D
def scipy_irfft2d(matrix, s):
fftRows = [scipy_fft.irfft(row) for row in matrix]
return np.transpose([scipy_fft.ifft(row) for row in np.transpose(fftRows)])
# FFTPACK RFFT 2D
def fftpack_rfft2d(matrix):
fftRows = [scipy_fftpack.rfft(row) for row in matrix]
return np.transpose([scipy_fftpack.rfft(row) for row in np.transpose(fftRows)])
# FFTPACK IRFFT 2D
def fftpack_irfft2d(matrix):
fftRows = [scipy_fftpack.irfft(row) for row in matrix]
return np.transpose([scipy_fftpack.irfft(row) for row in np.transpose(fftRows)])
print('\n#################### INPUT DATA ###################\n')
# initialize two 2D arrays with random data for testing
in1 = np.array([[0, 0, 0, 0], \
[0, 255, 255, 0], \
[0, 0, 255, 255], \
[0, 0, 0, 0]])
print('\nin1 shape=', in1.shape, '\n', in1)
in2 = np.array([[0, 0, 0, 0], \
[0, 0, 255, 0], \
[0, 255, 255, 0], \
[0, 255, 0, 0]])
print('\nin2 shape=', in2.shape, '\n', in2)
print('\n############### SCIPY: 2D RFFT (MULT) ###############\n')
# transform both inputs with SciPy RFFT for 2D
scipy_rfft1 = scipy_fft.rfftn(in1)
scipy_rfft2 = scipy_fft.rfftn(in2)
print('* Output from scipy_fft.rfftn():')
print('scipy_fft1 shape=', scipy_rfft1.shape, '\n', scipy_rfft1.real)
print('\nscipy_fft2 shape=', scipy_rfft2.shape, '\n', scipy_rfft2.real)
# perform multiplication between two 2D arrays from SciPy RFFT
scipy_rfft_mult = scipy_rfft1 * scipy_rfft2
# perform inverse RFFT for 2D arrays using SciPy
scipy_data = scipy_fft.irfftn(scipy_rfft_mult, in1.shape) # passing shape guarantees the output will have the original data size
print('\n* Output from scipy_fft.irfftn():')
print('scipy_data shape=', scipy_data.shape, '\n', scipy_data)
print('\n############### FFTPACK: 2D RFFT (MULT) ###############\n')
# transform both inputs with FFTPACK RFFT for 2D
fftpack_rfft1 = fftpack_rfft2d(in1)
fftpack_rfft2 = fftpack_rfft2d(in2)
print('* Output from fftpack_rfft2d():')
print('fftpack_rfft1 shape=', fftpack_rfft1.shape, '\n', fftpack_rfft1)
print('\nfftpack_rfft2 shape=', fftpack_rfft2.shape, '\n', fftpack_rfft2)
# TODO: perform multiplication between two 2D arrays from FFTPACK RFFT
fftpack_rfft_mult = fftpack_rfft1 * fftpack_rfft2 # this doesn't work
# perform inverse RFFT for 2D arrays using FFTPACK
fftpack_data = fftpack_irfft2d(fftpack_rfft_mult)
print('\n* Output from fftpack_irfft2d():')
print('fftpack_data shape=', fftpack_data.shape, '\n', fftpack_data)
print('\n##################### RESULT #####################\n')
# compare FFTPACK result with SCIPY
print('\nIs fftpack_data equivalent to scipy_data?', np.allclose(fftpack_data, scipy_data), '\n')
假设我的猜测是正确的,那么将生成的两个二维数组相乘的函数的正确实现是fftpack_rfft2d()
什么?请记住:生成的数组必须能够用fftpack_irfft2d()
.
仅邀请解决二维问题的答案。那些对如何乘以一维 FFTPACK 数组感兴趣的人可以查看这个线程。