Python Forum
What am I doing wrong with this FFT?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
What am I doing wrong with this FFT?
#1
Hi everyone,
I am trying to just FFT four cosines but the results are weird.

This code below gives the following figures:

https://imgur.com/a/FP3ylak

import numpy as np

import scipy.fftpack
from scipy.fftpack import fftfreq
from scipy.fft import fft
from scipy.fft import fft2
from scipy.fft import fftn


from scipy.signal import blackman, flattop, boxcar
import matplotlib.pyplot as plt
import random

plt.rcParams['figure.figsize'] = [9, 5]

gamma = 2.8e6 # short for gamma/2*pi, in Hz, [Hz/G]
tau = 1e-6 # us;
G = np.linspace(0, 1.7e6, 2400) # G_max is 1.7G/um ~ 1.7e6G/m
k = gamma*G*tau # 1/nm


rx = np.linspace(404e-7,416e-7,4)
outer = np.outer(rx,k)

y = 0.5*np.cos(2*np.pi*outer) #+ np.random.normal(0, .1, k.shape)
yy = np.sum(y,axis=0)

plt.figure(0)
#
#plt.xlim(1.0e8, 1.3e8)
plt.plot(k, yy)


f = fftfreq(len(k), np.diff(k)[0])
yf = fft(yy)
plt.figure(1)
plt.xlim(0, 500e-7)
plt.plot(f[:G.size//2], np.abs(yf[:G.size//2]))

r_max = f[:G.size//2][np.argmax(np.abs(yf[:G.size//2]))]
amplitude_max = np.abs(yf[:G.size//2]).max()
I would have figured, that the FFT would be just 4 spikes but not something like this. If I change rx to rx = np.linspace(404e-7,4016e-7,4) I get this:

https://imgur.com/a/ZjTedft


So somehow the spacing is ruining the FFT.
Reply
#2
(Jul-27-2022, 09:50 PM)pyhill00 Wrote: I would have figured, that the FFT would be just 4 spikes but not something like this.
It seems to me the FFT of a cosine is a spike only if the cosine has the form cos(2 pi k / N) where N is the number of samples and k is an integer. For other cosines, there must be some diffusion in the discrete Fourier transform and the curve is smoother than a spike. So your results don't seem so bad to me. Try to study the FFT of a single cosine when the frequency varies.
Reply
#3
(Jul-28-2022, 07:56 AM)Gribouillis Wrote:
(Jul-27-2022, 09:50 PM)pyhill00 Wrote: I would have figured, that the FFT would be just 4 spikes but not something like this.
It seems to me the FFT of a cosine is a spike only if the cosine has the form cos(2 pi k / N) where N is the number of samples and k is an integer. For other cosines, there must be some diffusion in the discrete Fourier transform and the curve is smoother than a spike. So your results don't seem so bad to me. Try to study the FFT of a single cosine when the frequency varies.

Ok thats a really good point and I agree. Do you know by chance why the FFT amplitudes are the not the same for the four? Even when I do more cosines I get an oscillating pattern of the amplitudes: https://imgur.com/a/grjt4fS
Reply
#4
(Jul-28-2022, 09:57 AM)pyhill00 Wrote: Do you know by chance why the FFT amplitudes are the not the same for the four?
I think it is the same effect. If you take the DFT of x[k] = exp(2 pi i k / N), you get spikes that all have the same amplitude, but if you take the DFT of x[k] = exp(i omega k) where omega is not a multiple of 2 pi / N, you get a "smooth spike" which amplitude varies. You can actually compute the DFT by hand and get a closed formula for the result and you will see that the amplitude varies. The conserved quantity is the L^2 norm (Plancherel theorem), not the maximal amplitude.
Reply
#5
(Jul-28-2022, 01:50 PM)Gribouillis Wrote:
(Jul-28-2022, 09:57 AM)pyhill00 Wrote: Do you know by chance why the FFT amplitudes are the not the same for the four?
I think it is the same effect. If you take the DFT of x[k] = exp(2 pi i k / N), you get spikes that all have the same amplitude, but if you take the DFT of x[k] = exp(i omega k) where omega is not a multiple of 2 pi / N, you get a "smooth spike" which amplitude varies. You can actually compute the DFT by hand and get a closed formula for the result and you will see that the amplitude varies. The conserved quantity is the L^2 norm (Plancherel theorem), not the maximal amplitude.



Ah ok thank you I will look into it. Last issue I am having (and the biggest issue) is that I cannot distinguish the frequencies I have in the code below. Is there a way to distinguish the peaks without changing the tmax time of 1.76 and the frequencies?

    import numpy as np
    import scipy.fftpack
    from scipy.fftpack import fftfreq
    from scipy.fft import fft
    import matplotlib.pyplot as plt


    t = np.linspace(0,1.76,2400) 
    f = [400e-3, 500e-3, 600e-3, 700e-3] # these are the frequencies
    yy = 0

    for i in f:
        y = 0.5*np.cos(2*np.pi*i*t)
        yy = yy + y

    plt.figure(0)
    plt.plot(t, yy)


    f = fftfreq(len(t), np.diff(t)[0])
    yf = fft(yy)
    plt.figure(1)
    plt.plot(f[:t.size//2], np.abs(yf[:t.size//2]))
    plt.show()
Reply
#6
I'm getting
Error:
Traceback (most recent call last): File "paillasse/pf/ffprob2.py", line 18, in <module> plt.plot(k, yy) NameError: name 'k' is not defined
Reply
#7
(Jul-28-2022, 02:16 PM)Gribouillis Wrote: I'm getting
Error:
Traceback (most recent call last): File "paillasse/pf/ffprob2.py", line 18, in <module> plt.plot(k, yy) NameError: name 'k' is not defined

I updated the code. Apologies.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Am I wrong or is Udemy wrong? String Slicing! Mavoz 3 2,576 Nov-05-2022, 11:33 AM
Last Post: Mavoz
  python gives wrong string length and wrong character thienson30 2 3,025 Oct-15-2019, 08:54 PM
Last Post: Gribouillis

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020