Contents

function [X, f, y, y2] = fftf(t, x, varargin)
% fftf - fft filter;
%   [X, f, y, y2] = fftf(t, x); with t the time vector and x the signal,
%   displays the original signal, the Fourier transform (absolute values)
%   and the reconstructed signal generated by the inverse transform ifft
%   with a selected subset of the frequencies.
%   By default, the frequencies in the filtered signal are cut at 1/8 the
%   sampling frequency.
%   The function returns X - reconstructed signal, f - vector of frequencies, y -
%   full vector of amplitudes, y2 - the filtered vector of amplitudes.
%   [X, f, y, y2] = fftf(t, x, cutoff); the user may set the cutoff
%   frequency in units of Hertz.
%   [X, f, y, y2] = fftf(t, x, cutoff, my_N); the user may select a number of my_N
%   amplitudes with highest absolute values to participate in the
%   reconstruction.
%   Examples
%   (suppose you have t and x defined already, both 1-dimensional vectors of the same length.)
%   fftf(t, x, 1e6); - reconstruct the signal with frequencies lower or
%   equal to cutoff value of 1MHz.
%   fftf(t, x, [], 20); - use only 20 biggest amplitudes for
%   reconstruction.
%   fftf(t, x, 1e6, 20); - select 20 biggest amplitudes within cutoff.
% Shmuel Ben-Ezra, Ultrashape ltd. August 2009

Verifying input

if ~any(size(t)==1),
   disp('Unexpected vector size! - should be 1D vectors.')
   return
end
if ~any(size(x)==1),
   disp('Unexpected vector size! - should be 1D vectors.')
   return
end
if length(t)~=length(x),
   disp('Unexpected vector size! - should be same length.')
   return
end

Definitions

Fs=1/(t(2)-t(1)); %sampling freq
N=length(x);
Nfft=2^nextpow2(N);
f=Fs/2*linspace(0,1,1+Nfft/2); % create freqs vector
cutoff_freq=Fs/8;
my_freqs=[];
if nargin>2,
    cutoff_freq=varargin{1};
end
if nargin>3,
    my_freqs=varargin{2};
end

main

y=fft(x,Nfft)/N; % perform fft transform
y2=filterfft(f, y, cutoff_freq, my_freqs); % filter amplitudes
%X=ifft(y2,'symmetric'); % the inverse transform. 'symmetric' is not recognized in older versions of matlab
X=ifft(y2); % inverse transform
X=X(1:N)*N;
ind1 = find(y2(1:1+Nfft/2)); % get the nonzero elements in y2
nf1 = length(ind1); % count nonzero elements

display

figname = 'fftf - FFT at work'; ifig = findobj('type', 'figure', 'name', figname); if isempty(ifig), ifig = figure('name', figname); % on my machine: ..., 'position', [360 120 600 800]); end figure(ifig); % first plot subplot(3,1,1) plot(t*1e6,x) xlabel('uSec') axis tight title('Original signal') % second plot subplot(3,1,2) yplot=abs(y(1:1+Nfft/2)); yplot=yplot/max(yplot); semilogy(f*1e-6, yplot, f(ind1)*1e-6, yplot(ind1), '.r'); xlabel('MHz') title('Amplitudes') legend('full spectrum', 'selected frequencies') % third plot subplot(3,1,3) plot(t*1e6,X) xlabel('uSec') if isempty(cutoff_freq), scutoff='No cutoff.'; else scutoff=sprintf('Cutoff = %g [Mhz]', cutoff_freq/1e6); end stitle3=sprintf('Reconstructed signal with %d selected frequencies; %s', nf1, scutoff); title(stitle3) axis tight return

function y2=filterfft(f, y, cutoff, wins)
nf=length(f);
ny=length(y);
if ~(ny/2+1 == nf),
    disp('unexpected dimensions of input vectors!')
    y2=-1;
    return
end

% cutoff filter
y2=zeros(1,ny);
if ~isempty(cutoff)
    ind1=find(f<=cutoff);
    y2(ind1) = y(ind1); % insert required elements
else
    y2=y;
end

% dominant freqs filter
if ~isempty(wins),
    temp=abs(y2(1:nf));
    y2=zeros(1,ny);
    for k=1:wins,   % number of freqs that I want
        [tmax, tmaxi]=max(temp);
        y2(tmaxi) = y(tmaxi); % insert required element
        temp(tmaxi)=0; % eliminate candidate from list
    end
end

% create a conjugate symmetric vector of amplitudes
for k=nf+1:ny,
    y2(k) = conj(y2(mod(ny-k+1,ny)+1)); % formula from the help of ifft
end
return