-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathfind_periodicity.m
81 lines (67 loc) · 1.64 KB
/
find_periodicity.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
function [period] = find_periodicity(x, thresh, varargin)
%%
% Finds periodicity in autocorrelation function using AMDF
% Inputs:
% x - input time domain signal
% thresh - threshold for peak calculation
% plot_func (optional_ - whether to plot the AMDF function
% Returns:
% period - periodicity of signal in samples
%%
switch nargin
case 2
plot_func = 0;
case 3
plot_func = varargin{1};
otherwise
error("Wrong number of inputs");
end
tau_min = 0;
tau_max = length(x)-1;
period = -1;
D = zeros(1,tau_max - tau_min + 1);
L = length(x);
for n = tau_min:tau_max
for k = n+1:L
D(n-tau_min+1) = D(n-tau_min+1) + abs(x(k) - x(k-n));
end
D(n-tau_min+1) = D(n-tau_min+1)/L;
end
if plot_func
figure;
plot(tau_min:tau_max, D);grid on;
xlabel('Lags in samples');ylabel('AMDF function');
end
local_minima = zeros(length(D),2);
k = 1;
minPos = -1;
for i = 2:tau_max-tau_min-1
if(D(i-1) > D(i) && D(i+1) > D(i) && D(i) <= thresh)
local_minima(k,1) = i-1;
local_minima(k,2) = D(i);
k = k+1;
end
end
local_minima = local_minima(1:k-1,:);
if isempty(local_minima)
return;
end
%again find first minimum among all minima in AMDF
%first local minimum considerably smaller than others
if(local_minima(1,2) < mean(local_minima(:,2)) && ...
local_minima(1,2) > 10)
minPos = local_minima(1,1);
else
for i = 2:k-2
if(local_minima(i-1,2) > local_minima(i,2) && local_minima(i+1,2) > local_minima(i,2))
minPos = local_minima(i,1);
if minPos < 10
continue;
else
break;
end
end
end
end
period = round(minPos);
end