% get_Fourier_transform.m
%
% [ft_power,ft,omega,iflag] = ...
% get_Fourier_transform(
...
% dt,t0,f_val,iplot,ipad,omega_plot_max,
...
% filter_factor);
%
% This MATLAB function calculates and plots
% (optionally) the Fourier transform data
% of an input signal.
%
% dt = time sampling interval
% t0 = initial time of signal data
% f_val = vector of f(t) values at sample
times
% iplot = if non-zero, plot results
% ipad = if non-zero, pad data vector as
necessary
%
to make number of samples a power of 2
% omega_plot_max = if 0, plot entire
frequency range,
%
if non-zero, denotes upper frequency for plot
% filter_factor = if not supplied or zero,
no filtering
%
of the data is performed. Otherwise, the
%
routine applies a digital bandpass filter
%
with an upper cutoff of filter_factor times
%
the Nyquist critical sampling fequency, pi/dt.
%
A value of 0.5 should guard stringently against
%
aliasing.
%
% K. Beers. MIT ChE. 8/13/2002
function [ft_power,ft,omega,iflag] = ...
get_Fourier_transform(
...
dt,t0,f_val,iplot,ipad,omega_plot_max,
...
filter_factor);
iflag = 0;
% Get the length of the input signal data
vector.
N = length(f_val);
% make sure that f_val is a row vector
if(size(f_val,1)~=1)
f_val = f_val';
end
% If requested through the optional argument
% filter_factor, a bandpass filter is
applied
% to the data to remove any high-frequency
% signals that may cause aliasing.
% The filter coefficients are taken from
% Press et al., Numerical Recipies in C,
% 2nd ed., 1992, p. 562.
if(exist('filter_factor'))
if(filter_factor~=0)
P = N*dt/2;
omega_filter_min = pi/(4*P);
omega_crit = pi/dt;
omega_filter_max =
filter_factor*omega_crit;
w_min = tan(pi*omega_filter_min/(2*pi)*dt);
w_max = tan(pi*omega_filter_max/(2*pi)*dt);
a_filter = zeros(1,3);
a_filter(1) = 1;
a_filter(2) = ...
-(
(1+w_min)*(1-w_max) + (1-w_min)*(1+w_max) ) ...
/
(1+w_min) / (1 + w_max);
a_filter(3) = (1-w_min)*(1-w_max)
...
/
(1+w_min)/(1+w_max);
b_filter = zeros(1,3);
b_filter(1) = -w_max/(1+w_min)/(1+w_max);
b_filter(3) = w_max/(1+w_min)/(1+w_max);
f_val = -filter(b_filter,a_filter,f_val);
end
end
% We now remove any linear trend in the data.
% This is done because the sample
measurements
% might have a long-term drift.
f_val = detrend(f_val);
% if N is not even, add a zero at the end
% to ensure that it is
if(rem(N,2))
N = N + 1;
f_val = [f_val 0];
end
% If ipad is non-zero, we round up the
number of
% points to the next highest power of 2 by
adding
% zeros.
if(ipad)
two_power = log2(N);
if(rem(two_power,1))
% two_power is not an integer
N
= pow2(floor(two_power)+ipad);
end
num_pad = N - length(f_val);
f_val = [f_val zeros(1,num_pad)];
end
% calculate the sampled angular frequencies.
P = N*dt/2; % assummed half-period of
input signal
omega_Nyquist = pi/dt; % max. sampled
frequency
d_omega = pi/P; % difference between
successive frequencies
omega_max = (N-1)*d_omega;
omega = [0 : d_omega : omega_max];
if(omega_plot_max==0)
omega_plot_max =
omega_max;
end
% We invoke the MATLAB function fft() to
calculate
% to calculate the Fourier transform
coefficients.
if(ipad)
ft = fft(f_val,N);
else
ft = fft(f_val);
end
% correct for time step
ft = (dt/sqrt(2*pi)).*ft;
% we compute now the power spectrum
ft_power = conj(ft).*ft;
% plot the time signal and Fourier series
if(iplot)
% if a filter was used,
we only report at most the
% data in the frequency
range below the cutoff.
if(exist('filter_factor'))
if(omega_plot_max
> omega_filter_max)
omega_plot_max = omega_filter_max;
end
end
j_plot = find(omega <=
omega_plot_max);
figure;
% plot input signal
subplot(2,2,1);
t_end = t0 + (N-1)*dt;
plot([t0:dt:t_end],f_val);
xlabel('t');
ylabel('f(t)');
title('Input signal');
axis tight;
% real part of Fourier
transform
subplot(2,2,3);
plot(omega(j_plot),real(ft(j_plot)));
xlabel('\omega (radians/time)');
ylabel('Real part of FFT');
axis tight;
% imaginary part
subplot(2,2,4);
plot(omega(j_plot),imag(ft(j_plot)));
xlabel('\omega (radians/time)');
ylabel('Imaginary part of
FFT');
axis tight;
% power spectrum
subplot(2,2,2);
plot(omega(j_plot),ft_power(j_plot));
xlabel('\omega (radians/time)');
ylabel('|F(\omega)|^2');
title('Power spectrum');
axis tight;
end
iflag = 1;
return;