0
$\begingroup$

Why fourier transform extrapolation goes to extreme on edges but not in the middle, how to fix it with python

""" Code to create the Fuorier trasfrom  """
data_FT = dataset_ex_df[['Date', 'GS']]
close_fft = np.fft.fft(np.asarray(data_FT['GS'].tolist()))
fft_df = pd.DataFrame({'fft':close_fft})
fft_df['absolute'] = fft_df['fft'].apply(lambda x: np.abs(x))
fft_df['angle'] = fft_df['fft'].apply(lambda x: np.angle(x))
plt.figure(figsize=(14, 7), dpi=100)
fft_list = np.asarray(fft_df['fft'].tolist())
for num_ in [3, 6, 9, 100]:
    fft_list_m10= np.copy(fft_list); fft_list_m10[num_:-num_]=0
    plt.plot(np.fft.ifft(fft_list_m10), label='Fourier transform with {} components'.format(num_))
plt.plot(data_FT['GS'],  label='Real')
plt.xlabel('Days')
plt.ylabel('USD')
plt.title('Figure 3: Goldman Sachs (close) stock prices & Fourier transforms')
plt.legend()
plt.show()

fourier transform edges

$\endgroup$

1 Answer 1

1
$\begingroup$

This happens because the FFT assumes your signal is periodic. This is why you see the reconstruction increase on the left and decrease on the right.

You can avoid this by artificially making your function periodic before taking the fft. Mirroring your signal is one way to do this, eg:

# make a signal 
N = 64
x = np.linspace(0, 1.5 * np.pi, N)
signal = 0.5*x + np.sin( 2*x ) + 0.25*np.random.randn( N )

# mirror it (make it periodic)
signal_mirror = np.append( signal, np.flip(signal)) 

# same thing you're doing
fft = np.fft.fft(signal_mirror)
num = 9
fft[num:-num] = 0
signal_mirror_recon = np.fft.ifft(fft)

# crop it to the length we care about
result = signal_mirror_recon[0:64]

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.