Simple DFT Coefficients => Amplitude/Frequencies

126 Views Asked by At

Im trying on DFT and FFT in Python with numpy and pyplot.

My Sample Vector is

x = np.array([1,2,4,3]

The DFT coefficients for that vector are

K = [10+0j, -3+1j, 0+0j, -3-1j]

so basically we have 10, -3+i, 0 and -3-1i as DFT coefficients.

My problem now is to get a combination of sin and cos to fit all 4 points.

Let's assume we have a sample Rate of 1hz.

This is my code :

from matplotlib import pyplot as plt
import numpy as np

x = np.array([1,2,4,3])

fft = np.fft.fft(x)

space = np.linspace(0,4,50)
values = np.array([1,2,3,4])

# only frequencies below N/2
cos0 = fft[0].real * np.cos(0 * space)

cos1 = fft[1].real * np.cos(1/4 * np.pi * space)
sin1 = fft[1].imag * np.sin(1/4 * np.pi * space)

res = cos0 + cos1 + sin1

plt.scatter(values, x, label="original")
plt.plot(space, cos0, label="cos0")
plt.plot(space, cos1, label="cos1")
plt.plot(space, sin1, label="sin1")
plt.plot(space, res, label="combined")

plt.legend()

As result i get the plot:

https://heeser-it.de/static/plot.png

Why isnt the final curve hitting any point?

I would appreciate your help. Thanks!

1

There are 1 best solutions below

0
On
  1. You forgot the negative sign for the sinusoidal component, e.g. taking, for instance, the first harmonic with complex value $-3+j$: $$\Re\left[(-3+j)\middle(\cos\frac{2\pi t}{4T}+j\sin\frac{2\pi t}{4T}\middle)\right]=-3\cos\frac{2\pi t}{4T}\underset{\stackrel{\uparrow}{missed}}{-}\sin\frac{2\pi t}{4T}$$

  2. Plotting the original signal you used a time interval $[1, 4]$ instead of $[0,3]$

  3. You need to consider all harmonics not only 2: from the $0$-th to the $3$-rd. Or, alternatively, you can consider only half the spectrum, but than harmonics must be multiplied by $2$.

  4. The sum must be divided by $4$ (the number of samples) to have the original signal reconstructed.

Here the code corrected:

from matplotlib import pyplot as plt
import numpy as np

x = np.array([1,2,4,3])

fft = np.fft.fft(x)

space = np.linspace(0,4,100)
values = np.array([0, 1,2,3])

# only frequencies below N/2
cos0 = fft[0].real * np.cos(0 * space)

cos1 =  2*fft[1].real * np.cos(1/4. * 2 * np.pi * space)
sin1 = -2*fft[1].imag * np.sin(1/4. * 2 * np.pi * space)

res = 1/4.*(cos0 + cos1 + sin1)

plt.scatter(values, x, label="original")
plt.plot(space, cos0, label="cos0")
plt.plot(space, cos1, label="cos1")
plt.plot(space, sin1, label="sin1")
plt.plot(space, res, label="combined")
plt.show()

plt.legend()