1

I recently wrote a little python program to compute a fourier transform of a signal from the basics for the sake of learning and checking my understanding of how this function works:

import numpy as np
from scipy import integrate
import matplotlib.pyplot as plt
import math

def fourier_single_point(signal_y, signal_x, frequency):
    exponent = signal_x * -2j * math.pi * frequency
    fourier_internals = np.multiply(signal_y, np.exp(exponent))
    return integrate.trapezoid(fourier_internals, dx=signal_x[1]-signal_x[0])

#Signal in Time-Domain
SAMPLES_PER_SEC = 48000
# Time values for 1.5s of a 48kHz sample
x_vals = np.linspace(start=0, stop=1.5, num=int(SAMPLES_PER_SEC*1.5))
# Single-Frequency signal at 314 Hz
sample = np.sin(314*(2*np.pi)*x_vals)

# Frequency Domain
min_val = 0
max_val = 400
step = 0.1
frequencies = np.linspace(start=min_val, stop=max_val, num=int((max_val-min_val)/step+1))

fourier_transform = [fourier_single_point(sample, x_vals, f) for f in frequencies]
plt.plot(frequencies, np.abs(fourier_transform), alpha=0.5)
plt.show()

After running it on a simple sine wave and graphing the results, I see the expected large spike at 314 Hz, but I also see smaller, periodic spikes surrounding that and tapering off. With some fiddling, I realized the frequency of the surrounding spikes is inversely correlated to the width of the window I'm integrating over (If I integrate over 1 second, I get these spikes every 1 Hz. Below I'm integrating over 1.5 sec. and getting them every 2/3 Hz.)

output spike at 314 Hz with surrounding periodic spikes

I would like to understand where these spikes come from, but as far as I can tell I have the math correct: Formula I referenced from Wikipedia

Maybe since the Fourier transform is on discrete values, some sort of adjustment must be made from the continous Fourier Transform function I was referencing?

Since it seems like the reason for these spikes is somehow related to the window over which I integrate, I did some searching about windowing functions and while I still didn't fully find an explanation, I did see some other examples like this one here that seem to have similar artifacts in the frequency domain, which makes me think maybe it isn't a bug or miscalculation, but simply my expectations that were wrong, in which case I'd want to know what the explanation for this occurance is.

Any insight is appreciated! Thanks!

  • 1
    Welcome to numerical analysis... If you start a google search on "numerical artefacts fourier transform" you will find many hits. – Carlos Horn Jul 18 '22 at 08:16

1 Answers1

0

To see the difficulty for the numeric approximation, I recommend to plot the variable fourier_internals.real for a given frequency.

Keep in mind that integration to first order is just a summation times the spacing (the Trapezoidal rule you are using boils down to sum of midpoints which does not change the following argument). You will see that the values you are integrating (real and imaginary) are strongly oscillating and changing sign. This is where numerical errors accumulate.

If you want to learn more about the limits of the discrete Fourier transform, have a look at https://mathoverflow.net/questions/160844/error-of-discrete-fourier-transform-on-finite-domain-vs-continuous-ft-in-term which is a mathematical question and therefore out of scope of stack overflow.

Carlos Horn
  • 1,115
  • 4
  • 17