Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
425 views
in Technique[技术] by (71.8m points)

plot - Plotting FFT on octave

I know that FFT changes a function in the time domain to one showed in the frequency domain.

However, when I try plotting said graph in the frequency domain, I can only get it to work properly by using the time as X-axis, when it was obviously supposed to be not that, but the frequency.

Also, I can only get the amplitudes to match the ones in the original signal by dividing the y-axis by a certain integer. Why is that?

Here's my code

t=0:0.001:2

x=2*sin(20*pi*t) + sin(100*pi*t)
subplot(2,1,1)
plot(1000*t,x)
grid
xlabel("Time in milliseconds")
ylabel("Signal amplitude")

subplot(2,1,2)
y=fft(x)
plot(1000*t,abs(y))
xlabel("Frequency")
ylabel("Signal amplitude")

and graphs.

enter image description here

Please help =(

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Frequency relationship (x-axis scaling)

Up to the Nyquist frequency (half the sampling rate), the frequency of each values produced by the FFT is linearly related to the index of the output value through:

f(i) = (i-1)*sampling_frequency/N

Where N is the number of FFT points (ie. N=length(y)). In your case, N=2001. Above the Nyquist frequency, the spectrum shows wrapped around negative frequency components (from a periodic extension of the frequency spectrum).

One can deduct the sampling frequency from your definition of t as 1/T where T is the sampling time interval (T=0.001 in your case). So the sampling frequency is 1000Hz.

Note that since the value of t(i) is also linearly related to the index i, through

t(i) = (i-1)*0.001

it is possible (though not necessarilly advised, as this would just obscure your code) to define f = 1000*t*sampling_frequency/N. Note that you were missing the sampling_frequency/N term which correspondingly resulted in tones being shown at the wrong frequency (from the definition of x there should be peaks at 10Hz and 50Hz and the corresponding aliases at -10Hz and -50Hz, which after the wrapping around shows up at 990Hz and 950Hz).

Amplitude relationship (y-axis scaling)

Note that the observed relationship is only approximate, so the following is not a mathematical proof, but merely a intuitive way to visualize the relationship between the time-domain tone amplitudes and the frequency-domain peak values.

Simplifying the problem to a single tone:

x = A*sin(2*pi*f*t)

The approximate amplitude of the corresponding peak could be derived using Parseval's theorem:

enter image description here

In the time domain (the left side of the equation), the expression is approximately equal to 0.5*N*(A^2).

In the frequency domain (the right side of the equation), making the following assumptions:

  • spectral leakage effects are negligible
  • spectral content of the tone is contained in only 2 bins (at frequency f and the corresponding aliased frequency -f) account for the summation (all other bins being ~0). Note that this typically only holds if the tone frequency is an exact (or near exact) multiple of sampling_frequency/N.

the expression on the right side is approximately equal to 2*(1/N)*abs(X(k))^2 for some value of k corresponding to the peak at frequency f.

Putting the two together yields abs(X(k)) ~ 0.5*A*N. In other words the output amplitude shows a scaling factor of 0.5*N (or approximately 1000 in your case) with respect to the time-domain amplitude, as you had observed.

The idea still applies with more than one tone (although the negligible spectral leakage assumption eventually breaks down).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...