Calculating amplitude from np.fft
Question:
I appear to be calculating incorrect amplitudes for the original waves using np.fft.fft.
The plot of the fft shown is shown, as you can see the amplitudes shown are around 3 and 1.5, but if you look at the code I’m using amplitudes 7 and 3 to generate the signal. This plot should have two spikes which go up to y=3 at x=13 and y=7 at x=15
What do I need to do to see the proper amplitudes (3 and 7) in my graph?
I can experimentally see the constant I need to multiply my amplitudes by is around 2.3, but how do I calculate this number exactly?
import numpy as np
import matplotlib.pyplot as plt
t0 = 0
t1 = 20
n_samples = 1000
xs = np.linspace(t0, t1, n_samples)
# Generate signal with amplitudes 7 and 3
ys = 7*np.sin(15 * 2 * np.pi * xs) + 3*np.sin(13 * 2 * np.pi * xs)
np_fft = np.fft.fft(ys)
amplitudes = 1/n_samples * np.abs(np_fft) #This gives wrong results
frequencies = np.fft.fftfreq(n_samples) * n_samples * 1/(t1-t0)
plt.plot(frequencies[:len(frequencies)//2], amplitudes[:len(np_fft)//2])
plt.show()
Answers:
I think you are miscalculating the amplitude. You should change the
amplitudes = 1 / n_samples * np.abs(np_fft)
to
amplitudes = 2 / n_samples * np.abs(np_fft)
result:
import numpy as np
import matplotlib.pyplot as plt
t0 = 0
t1 = 1
n_samples = 10000
xs = np.linspace(t0, t1, n_samples)
ys = 7 * np.sin(15 * 2 * np.pi * xs) + 3 * np.sin(13 * 2 * np.pi * xs)
plt.subplot(2, 1, 1)
plt.plot(xs, ys)
np_fft = np.fft.fft(ys)
amplitudes = 2 / n_samples * np.abs(np_fft)
frequencies = np.fft.fftfreq(n_samples) * n_samples * 1 / (t1 - t0)
plt.subplot(2, 1, 2)
plt.semilogx(frequencies[:len(frequencies) // 2], amplitudes[:len(np_fft) // 2])
plt.show()
The peaks of amplitudes
are not exactly 7
and 2
but if you increase n_samples
they will become more accurate.
I appear to be calculating incorrect amplitudes for the original waves using np.fft.fft.
The plot of the fft shown is shown, as you can see the amplitudes shown are around 3 and 1.5, but if you look at the code I’m using amplitudes 7 and 3 to generate the signal. This plot should have two spikes which go up to y=3 at x=13 and y=7 at x=15
What do I need to do to see the proper amplitudes (3 and 7) in my graph?
I can experimentally see the constant I need to multiply my amplitudes by is around 2.3, but how do I calculate this number exactly?
import numpy as np
import matplotlib.pyplot as plt
t0 = 0
t1 = 20
n_samples = 1000
xs = np.linspace(t0, t1, n_samples)
# Generate signal with amplitudes 7 and 3
ys = 7*np.sin(15 * 2 * np.pi * xs) + 3*np.sin(13 * 2 * np.pi * xs)
np_fft = np.fft.fft(ys)
amplitudes = 1/n_samples * np.abs(np_fft) #This gives wrong results
frequencies = np.fft.fftfreq(n_samples) * n_samples * 1/(t1-t0)
plt.plot(frequencies[:len(frequencies)//2], amplitudes[:len(np_fft)//2])
plt.show()
I think you are miscalculating the amplitude. You should change the
amplitudes = 1 / n_samples * np.abs(np_fft)
to
amplitudes = 2 / n_samples * np.abs(np_fft)
result:
import numpy as np
import matplotlib.pyplot as plt
t0 = 0
t1 = 1
n_samples = 10000
xs = np.linspace(t0, t1, n_samples)
ys = 7 * np.sin(15 * 2 * np.pi * xs) + 3 * np.sin(13 * 2 * np.pi * xs)
plt.subplot(2, 1, 1)
plt.plot(xs, ys)
np_fft = np.fft.fft(ys)
amplitudes = 2 / n_samples * np.abs(np_fft)
frequencies = np.fft.fftfreq(n_samples) * n_samples * 1 / (t1 - t0)
plt.subplot(2, 1, 2)
plt.semilogx(frequencies[:len(frequencies) // 2], amplitudes[:len(np_fft) // 2])
plt.show()
The peaks of amplitudes
are not exactly 7
and 2
but if you increase n_samples
they will become more accurate.