MAP_Gait_Dynamics/div_calc.m

1 line
2.7 KiB
Mathematica

function Divergence=div_calc(state,ws_sec,fs,period_sec,progress)
% calculate divergence curve (needed for max lyapunov exponent).
% Input:
% state: state space
% ws_sec: window size over which divergence will be calculated(in seconds)
% fs: sample frequency
% period_sec: indicates period of time-wise near samples to exclude in
% nearest neighbour search
% progress: show progress or not
%
% Output:
% Divergence: the divergence curve
%
% History:
% August 2011: v1, Sietse Rispens based on version KvS en SMB
% 1 November 2012, Sietse Rispens: Use div_calc_shorttimeseries for short
% time series
if size(state,1) <= 10000
Divergence=div_calc_shorttimeseries(state,ws_sec,fs,period_sec,progress);
return;
end
[N,D]=size(state);
ws=round(ws_sec*fs);
Period=round(period_sec*fs);
if N<ws, error('ws shall not be larger than N'); end
NCompleteWindow = N-ws+1;
Divergence_sum=zeros(1,ws);
Divergence_count=zeros(1,ws);
SumStd = sqrt(sum(std(state,1).^2));
DistLimStart = SumStd*nthroot(1/NCompleteWindow,D);
DistLim = DistLimStart;
TreeRoot=kdtree_build(state(1:NCompleteWindow,:));
k0 = 2; % The initial number of nearest neighbors to look for
kmax = min(2*Period + 2, NCompleteWindow); % The maximum number of nearest neighbors to look for
for i = 1:NCompleteWindow
StateI = state(i,:);
if ~isnan(StateI)
DistLim = DistLim*nthroot(1/5,D);
DistLim = min(DistLim,DistLimStart);
Index = [];
k=k0;
kmaxreached = 0;
while isempty(Index) && ~kmaxreached
[Idx, Dist] = kdtree_k_nearest_neighbors(TreeRoot,StateI,k);
Dist(abs(i-Idx) < Period)=nan;
Index = Idx(find(Dist==min(Dist),1,'first'));
if k >= kmax
kmaxreached = 1;
elseif isempty(Index)
k = min(kmax,k*2);
end
end
if ~isempty(Index)
if i+ws>N || Index+ws>N
% do not use these data
else
if ~isempty(Index)
DistCurve = log(sqrt(sum((state(i:i+ws-1,:)-state(Index:Index+ws-1,:)).^2,2)));
NotNan = ~isnan(DistCurve);
Divergence_sum(NotNan) = Divergence_sum(NotNan) + DistCurve(NotNan)';
Divergence_count(NotNan) = Divergence_count(NotNan) + 1;
end
end
end
end
if progress > 0
if mod(i,round(progress))==0
if i>round(progress)
fprintf('\b\b\b\b\b\b\b\b\b\b');
end
fprintf('i=%8d', i);
end
end
end
kdtree_delete(TreeRoot); % Free the pointer to k-d-tree
if progress > 0
fprintf('\n');
end
Divergence= (Divergence_sum./Divergence_count);