-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfftf_1D.m
123 lines (123 loc) · 3.7 KB
/
fftf_1D.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
function [X, f, y, y2] = fftf_1D(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 my_N
% amplitudes with highest abolute value 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);
Nfft = 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)/max(X);
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