%-------------------------------------------------------------------------- % INTRODUCTION TO FFT ANALYSIS with MATLAB PHYS 460/660 %-------------------------------------------------------------------------- % ON-LINE HELP help fft % Figure C.2 of the textbook: dt=0.1; t=0:dt:12.7; signal_1=sin(2*pi*0.2362*t); figure(1),plot(t,signal_1,'-o'); N=128; ft_signal_1=fft(signal_1); F=[0:N/2-1]/(N*dt); figure(2),plot(F(1:64),imag(ft_signal_1(1:64)),'o') % Figure C.3 of the textbook: dt=0.1; t=0:dt:12.7; signal_2=sin(2*pi*0.2362*t+pi/4); N=128; ft_signal_2=fft(signal_2,N); F=[0:N/2-1]/(N*dt); figure(3), subplot(3,1,1) plot(t,signal_2,'-o'),title('Original Signal') subplot(3,1,2) plot(F(1:32),real(ft_signal_2(1:32)),'o'),title('Real part of FFT') subplot(3,1,3) plot(F(1:32),imag(ft_signal_2(1:32)),'o'),title('Imaginary part of FFT') % Figure C.4 of the textbook: dt=0.1; t=0:dt:12.7; signal_3=sin(2*pi*0.5*t)+3*sin(2*pi*1.5*t+pi/8); N=128; ft_signal_3=fft(signal_3,N); F=[0:N/2-1]/(N*dt); figure(4), subplot(3,1,1) plot(t,signal_3,'-o'),title('Original Signal') subplot(3,1,2) plot(F(1:32),real(ft_signal_3(1:32)),'o'),title('Real part of FFT') subplot(3,1,3) plot(F(1:32),imag(ft_signal_3(1:32)),'o'),title('Imaginary part of FFT') %Figure C.5 of the textbook: dt=0.1; t=0:dt:6.3; signal_4=sin(2*pi*4*t); N=64; ft_signal_4=fft(signal_4); F=[0:N/2-1]/(N*dt); figure(6), subplot(3,1,1) plot(t,signal_4,'-o') subplot(3,1,2) plot(F(1:32),real(ft_signal_4(1:32)),'o') subplot(3,1,3) plot(F(1:32),imag(ft_signal_4(1:32)),'o') %Figure C.6 of the textbook: dt=0.2; t=0:dt:6.3; signal_5=sin(2*pi*4*t); N=32; ft_signal_5=fft(signal_5); t1=0:0.05:6.3; signal_4_full=sin(2*pi*4*t1); F=[0:N/2-1]/(N*dt); figure(7), subplot(3,1,1) plot(t,signal_5,'-o',t1,signal_4_full) subplot(3,1,2) plot(F(1:16),real(ft_signal_5(1:16)),'o') subplot(3,1,3) plot(F(1:16),imag(ft_signal_5(1:16)),'o') % COMMENT: Note that "true" frequency of the signal is f_true=4 Hz, % while f_Nyquist=1/(2*dt)=2.5 Hz; So, reflected frequency is f_true-f_Nyquist=1.5 Hz % below f_Nyquist! % Figure C.7 of the textbook: power_signal_3=abs(ft_signal_3).^2/128; N=128; F=[0:N/2-1]/(N*dt); figure(8), plot(F(1:64),power_signal_3(1:64),'-o') % POWER SPECTRUM ANALYSIS WITH MATLAB FFT % A common use of Fourier transforms is to find the frequency components of a signal buried in a % noisy time domain signal. Consider data sampled at 1000 Hz. Form a signal containing 50 Hz and 120 Hz: t = 0:0.001:0.6; x = sin(2*pi*50*t)+sin(2*pi*120*t); % Corrupt the signal with it some zero-mean random noise: y = x + 2*randn(size(t)); help randn % Plot the final signal in time domain: figure(3),plot(y(1:600)) % It is difficult to identify the frequency components from looking at the original signal. % Converting to the frequency domain, the discrete Fourier transform of the noisy signal y % is found by taking the 512-point fast Fourier transform (FFT): Y = fft(y,512); % The power spectral density, a measurement of the energy at various frequencies, is: Pyy = abs(Y).^2 / 512; % The first 256 points (the other 256 points are symmetric) can be graphed on a % frequency axis where we input length of the physical time interval 0.001s: f = 1000*(0:255)/512; figure(4),plot(f,Pyy(1:256)), xlabel('Frequency (Hz)'), ylabel('Power Spectrum') % POWER SPECTRUM ANALYSIS WITH MATLAB FFT on EXTERNAL FILE % Load external file (containing, e.g., time vs. position of particle 27 in % our nonlinear chain of 100 atoms) into a matrix nonlinear_xy.dat load signal_xy.dat; % Copy first column of this matrix into the time vector t=signal_xy(:,1); % Copy second column of this matrix into the fpu_signal vector fpu_signal=signal_xy(:,2); figure(5),plot(t,fpu_signal) Y = fft(fpu_signal,512); % The power spectral density, a measurement of the energy at various frequencies, is: Pyy = abs(Y).^2 / 512; % The first 256 points (the other 256 points are symmetric) can be graphed on a % frequency axis where we input length of the physical time interval 0.001s: f = 1000*(0:255)/512; figure(6),plot(f,Pyy(1:256)), xlabel('Frequency (Hz)'), ylabel('Power Spectrum') % FFT and ARTIFACTS of WINDOWS CONVOLUTED WITH A FUNCTION %Vary the number of repetitions of the fundamental period n=0:30; signal_3=cos(2*pi*n/10); %3 periods signal_6=[signal_3 signal_3]; %6 periods signal_9=[signal_3 signal_3 signal_3]; %9 periods N=512; ampl_s1=abs(fft(signal_3,N)); ampl_s2=abs(fft(signal_6,N)); ampl_s3=abs(fft(signal_9,N)); %A real number signal should have a transform amplitude that is symmetrical for % positive and negative frequencies help fftshift ampl_s1=fftshift(ampl_s1); ampl_s2=fftshift(ampl_s2); ampl_s3=fftshift(ampl_s3); % Spectrum now goes from -f_s/2 to f_s/2 where f_s is the sampling % frequency and f_s/2 is the Nyqist frequency F=[-N/2:N/2-1]/N; figure(2) subplot(3,1,1) plot(F,ampl_s1),title('3 periods'), subplot(3,1,2) plot(F,ampl_s2),title('6 periods'), subplot(3,1,3) plot(F,ampl_s3),title('9 periods'), xlabel('frequency/f_s') % MORE ABOUT ALIASING IN DISCRETE FOURIER TRANSFORM % MATLAB example of a continuous-time signal being sampled at various % frequencies, illustrating the problem of aliasing caused by sampling % at too low of a frequency. % Sampling periods and sampling frequencies to be used. % ws1 = 125.6637, ws2 = 62.8319, ws3 = 31.4159 % fig_size = [232 84 774 624]; Ts1 = 0.05; Ts2 = 0.1; Ts3 = 0.2; ws1 = 2*pi/Ts1; ws2 = 2*pi/Ts2; ws3 = 2*pi/Ts3; % % Frequencies for the continous-time signal and the time vector. % w1 = 7; w2 = 23; t = [0:0.005:2]; % % Original continuous-time signal is the sum of two cosines, with % frequencies of 7 r/s and 23 r/s, respectively. % x = cos(w1*t) + cos(w2*t); figure(5),clf,plot(t,x),grid,xlabel('Time (s)'),ylabel('Amplitude'),... title('Continuous-Time Signal; x(t) = cos(7t) + cos(23t)'),... set(gcf,'Position',fig_size) % % Sampling the continuous-time signal with a sampling period Ts = 0.05 s. % The sampled signal is exactly equal to the continuous-time signal at the % sample times, and the samples accurately model the original signal in % the following respect: if you look at the samples by themselves and % wanted to guess what the continuous-time signal looks like, you would be % able to get pretty close. Note that ws1 is approximately 5.5*w2. % t1 = [0:Ts1:2]; xs1 = cos(w1*t1) + cos(w2*t1); figure(6),clf,stem(t1,xs1);grid,hold on,plot(t,x,'r:'),hold off,... xlabel('Time (s)'),ylabel('Amplitude'),... title('Sampled Version of x(t) with T_s = 0.05 s'),... set(gcf,'Position',fig_size) % % Sampling the continuous-time signal with a sampling period Ts = 0.1 s. % The sampled signal is exactly equal to the continuous-time signal at the % sample times. The samples are a less accurate representation of the % original signal than with the smaller Ts (higher sampling frequency ws). % Note that ws2 is approximately 2.7*w2. % t2 = [0:Ts2:2]; xs2 = cos(w1*t2) + cos(w2*t2); figure(7),clf,stem(t2,xs2);grid,hold on,plot(t,x,'r:'),hold off,... xlabel('Time (s)'),ylabel('Amplitude'),... title('Sampled Version of x(t) with T_s = 0.1 s'),... set(gcf,'Position',fig_size) % % Sampling the continuous-time signal with a sampling period Ts = 0.2 s. % The sampled signal is exactly equal to the continuous-time signal at the % sample times. The samples now are not a good representation of the % original signal at all. Note that ws3 is approximately 1.37*w2. % t3 = [0:Ts3:2]; xs3 = cos(w1*t3) + cos(w2*t3); figure(8),clf,stem(t3,xs3);grid,hold on,plot(t,x,'r:'),hold off,... xlabel('Time (s)'),ylabel('Amplitude'),... title('Sampled Version of x(t) with T_s = 0.2 s'),... set(gcf,'Position',fig_size) % % Since ws3 < 2*w2, the Nyquist Sampling Theorem is violated, and x(t) % could not be recovered from the samples obtained with Ts3 using an ideal % low-pass filter. Aliasing has occurred. The samples of the original % x(t) using a sampling period Ts3 have exactly the same values that the % signal x1(t) = cos(w1*t) + cos((w2-ws3)*t) would have when sampled with % a sampling period Ts3. w2 - w3 = -8.4159 r/s. % w2s3 = w2 - ws3; x1 = cos(w1*t) + cos(w2s3*t); % figure(9),clf,stem(t3,xs3);grid,hold on,plot(t,x,'k:',t,x1,'r:'),... hold off,xlabel('Time (s)'),ylabel('Amplitude'),... title('Sampling x(t) and x_1(t) with T_s = 0.2 s'),... set(gcf,'Position',fig_size),... text(1.13,1.2,'x(t)'),text(0.1,1.6,'x_1(t)')