1 line
2.7 KiB
Mathematica
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);
|
|
|