如何在Python中手动复现ifft2?问题排查与修正
手动实现二维逆傅里叶变换(ifft2)的问题与解决
我尝试找出可累加还原原始二维实数据的FFT2正弦波集合,参考了一个一维FFT实现示例(感谢@mark snyder)。手动实现ifft2时遇到两个现象:
- 仅保留第一维度计算时,第一列数据始终能匹配原始数据
- 疑惑为何需要对dimT的输入减1才能对齐相位
以下是最初的尝试代码:
import pandas as pd import numpy as np from scipy.fftpack import fftfreq, fft2 import cmath df=pd.DataFrame( { 'Ang':[ 0.091, -0.141, -0.114], 'Con':[ -0.139, -0.259, -0.573], 'EAC':[ 0.016, -0.106, -0.044] } , columns=['Ang', 'Con', 'EAC'] , index=[2011,2012,2013] ) my_fft = fft2(df) T , B =len(df) , len(df.columns) freqsT , freqsB = fftfreq(T,1) , fftfreq(B,1) def ifft2Manually(option): recombine = np.zeros((T,B)) #recombineine for t in list(range(T)): for b in list(range(B)): coef = abs(my_fft[t][b])/(T*B) tfreq , bfreq = freqsT[t] , freqsB[b] ps = cmath.phase(my_fft[t][b]) dimT = coef*np.cos(tfreq*2*np.pi*( np.array([df.index]).T - 1 ) + ps ) dimB = coef*np.cos(bfreq*2*np.pi*( np.array(list(range(B))) ) + ps ) if option==1: sinusoid = dimT + dimB else: sinusoid= dimT #exclude dimB here recombine=sinusoid +recombine #print('\nt={}\nb={}\ndimT={}\ndimB={}\nsinusoid={}'.format(t,b,dimT,dimB,sinusoid)) if option==1: print('\n nothing matches when both dimensions used') else: print('\n first column matches when ONLY the first dimension (dimT) is used') print('\n original data:\n{} \n\n my attempt to match:\n{}'.format(df, recombine )) ifft2Manually(option=1) ifft2Manually(option=2)
修正后的可行代码
以下代码已能正常运行。主要错误在于:之前是将两个维度的余弦计算结果相加,正确的做法应该是把维度项放在cos()函数内部相加。希望这个示例能帮助遇到类似问题的人。
import pandas as pd import numpy as np from scipy.fftpack import fftfreq, fft2 import cmath row=2 # arbitrary col=3 # arbitrary df=pd.DataFrame( { 'A':[ 0.09, -0.12, -0.11], 'B':[ -0.13, 0.29, -0.57], 'C':[ 0.01, -0.16, -0.04], 'D':[ 0.10, 0.65, 0.46] } , columns=['A', 'B', 'C','D'] , index=[2011,2012,2013] ) print('here is the df:\n', df) actual = np.array(df)[row][col] my_fft2 = fft2(df) T , B =df.shape[0] , df.shape[1] mysum= 0 for t in range(T): for b in range(B): coef = abs(my_fft2[t][b])/(T*B) bfreq , tfreq = fftfreq(B,1)[b] , fftfreq(T,1)[t] ps = cmath.phase(my_fft2[t][b]) mysum += coef*np.cos( 2*np.pi*(tfreq*row + bfreq*col) + ps ) print('\n replicate value at row={}, col={}'.format( row, col)) print('\n yhat :', mysum) print(' actual :' , actual )
内容的提问来源于stack exchange,提问作者bri85
相关产品推荐
相关产品推荐

