Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
CRP Toolbox for MATLAB
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Norbert Marwan
CRP Toolbox for MATLAB
Commits
f9ea45fb
Commit
f9ea45fb
authored
9 years ago
by
marwan
Browse files
Options
Downloads
Patches
Plain Diff
complete recoding based on an implementation by Maik Riedl (much faster calculations)
parent
b3bf95f1
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
twinsurr.m
+156
-39
156 additions, 39 deletions
twinsurr.m
with
156 additions
and
39 deletions
twinsurr.m
+
156
−
39
View file @
f9ea45fb
...
@@ -14,6 +14,11 @@ function [y nTw] = twinsurr(varargin)
...
@@ -14,6 +14,11 @@ function [y nTw] = twinsurr(varargin)
% [Y,NTWINS]=TWINSURR(...) where NTWINS is the total number
% [Y,NTWINS]=TWINSURR(...) where NTWINS is the total number
% of twins in the RP.
% of twins in the RP.
%
%
% Note: Please check before use the recurrence parameters M, T, and
% E by visual inspection of the recurrence plot! Please also
% check the number of twins NTWINS whether enough twins have
% been found.
%
% Example: x = rand(3,1);
% Example: x = rand(3,1);
% a = [.8 .3 -.25 .9]';
% a = [.8 .3 -.25 .9]';
% for i = 4:1000,
% for i = 4:1000,
...
@@ -28,8 +33,8 @@ function [y nTw] = twinsurr(varargin)
...
@@ -28,8 +33,8 @@ function [y nTw] = twinsurr(varargin)
% Twin Surrogates to Test for Complex Synchronisation,
% Twin Surrogates to Test for Complex Synchronisation,
% Europhys. Lett., 75, 2006.
% Europhys. Lett., 75, 2006.
% Copyright (c) 2008-20
09
% Copyright (c) 2008-20
16
% Norbert Marwan, Potsdam Institute for Climate Impact Research, Germany
% Norbert Marwan,
Maik Riedl,
Potsdam Institute for Climate Impact Research, Germany
% http://www.pik-potsdam.de
% http://www.pik-potsdam.de
%
%
% Copyright (c) 2008
% Copyright (c) 2008
...
@@ -40,6 +45,9 @@ function [y nTw] = twinsurr(varargin)
...
@@ -40,6 +45,9 @@ function [y nTw] = twinsurr(varargin)
% $Revision$
% $Revision$
%
%
% $Log$
% $Log$
% Revision 5.4 2009/03/24 08:33:47 marwan
% copyright address changed
%
% Revision 5.3 2009/03/17 09:18:17 marwan
% Revision 5.3 2009/03/17 09:18:17 marwan
% serious bug fix, zero columns were also considered as twins!
% serious bug fix, zero columns were also considered as twins!
%
%
...
@@ -60,8 +68,8 @@ sil = 0;
...
@@ -60,8 +68,8 @@ sil = 0;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% check the input
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% check the input
error
(
nargchk
(
1
,
7
,
nargin
)
);
narg
in
chk
(
1
,
7
);
if
nargout
>
2
,
error
(
'Too many output arguments'
),
end
nargout
chk
(
0
,
2
)
...
@@ -88,10 +96,10 @@ end
...
@@ -88,10 +96,10 @@ end
varargin
{
8
}
=
[];
varargin
{
8
}
=
[];
i_double
=
find
(
cellfun
(
'isclass'
,
varargin
,
'double'
));
i_double
=
find
(
cellfun
(
'isclass'
,
varargin
,
'double'
));
i_char
=
find
(
cellfun
(
'isclass'
,
varargin
,
'char'
));
i_char
=
find
(
cellfun
(
'isclass'
,
varargin
,
'char'
));
check_meth
=
{
'ma'
,
'eu'
,
'mi'
,
'nr'
,
'rr'
,
'fa'
,
'in'
,
'om'
,
'op'
,
'di'
};
% maxnorm, euclidean, nrmnorm, fan, distance
check_meth
=
{
'ma'
,
'eu'
,
'mi'
};
% maxnorm, euclidean, nrmnorm, fan, distance
check_norm
=
{
'non'
,
'nor'
};
% nonormalize, normalize
check_norm
=
{
'non'
,
'nor'
};
% nonormalize, normalize
check_sil
=
{
've'
,
'si'
};
% verbose, silent
check_sil
=
{
've'
,
'si'
};
% verbose, silent
nonorm
=
0
;
if
isnumeric
(
varargin
{
1
})
% read commandline input
if
isnumeric
(
varargin
{
1
})
% read commandline input
% check the text input parameters for method, gui
% check the text input parameters for method, gui
temp_meth
=
0
;
temp_meth
=
0
;
...
@@ -110,7 +118,7 @@ if isnumeric(varargin{1}) % read commandline input
...
@@ -110,7 +118,7 @@ if isnumeric(varargin{1}) % read commandline input
for
i
=
1
:
length
(
i_char
);
temp2
(
i
,:)
=
varargin
{
i_char
(
i
)}(
1
:
3
);
end
for
i
=
1
:
length
(
i_char
);
temp2
(
i
,:)
=
varargin
{
i_char
(
i
)}(
1
:
3
);
end
if
isempty
(
sil
),
sil
=
0
;
end
if
isempty
(
sil
),
sil
=
0
;
end
if
isempty
(
nonorm
),
nonorm
=
1
;
end
if
isempty
(
nonorm
),
nonorm
=
0
;
end
if
nonorm
>
1
,
nonorm
=
1
;
end
if
nonorm
>
1
,
nonorm
=
1
;
end
if
isempty
(
method_n
),
method_n
=
1
;
end
if
isempty
(
method_n
),
method_n
=
1
;
end
if
method_n
>
length
(
check_meth
),
method0
=
length
(
check_meth
);
end
if
method_n
>
length
(
check_meth
),
method0
=
length
(
check_meth
);
end
...
@@ -140,52 +148,161 @@ end
...
@@ -140,52 +148,161 @@ end
if
size
(
x
,
1
)
<
size
(
x
,
2
),
x
=
x
'
;
end
if
size
(
x
,
1
)
<
size
(
x
,
2
),
x
=
x
'
;
end
m0
=
size
(
x
,
2
);
if
size
(
x
,
2
)
>
1
warning
(
'Multicolumn vectors are not supported. Only first column will be used.'
)
x
=
x
(:,
1
);
end
N
=
length
(
x
);
N
=
length
(
x
);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% make surrogates
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% main part: create surrogates
surr
=
zeros
(
N
,
nsur
);
X
=
crp
(
x
,
m
,
t
,
e
,
method
,
norm_str
,
'sil'
);
X
=
double
(
X
)
.*
(
1
-
eye
(
size
(
X
)));
NX
=
length
(
X
);
%% find twins
if
~
sil
,
h
=
waitbar
(
0
,
'Searching Twins'
);
end
for
i
=
1
:
NX
,
if
~
sil
,
waitbar
(
i
/
NX
);
end
A
=
repmat
(
X
(:,
i
),
1
,
NX
);
% S{i} = find(all(X == A & X == 1));
S
{
i
}
=
[
i
find
(
all
(
X
==
A
)
&
any
(
X
(:,
i
)))];
nTwins
(
i
)
=
numel
(
S
{
i
});
end
if
~
sil
,
delete
(
h
);
end
nTwins
=
sum
(
nTwins
)
-
NX
;
%% find twins
h
=
[];
if
~
sil
&
N
>
3000
,
h
=
waitbar
(
0
,
'Find recurrences'
);
end
twinList
=
findTwins
(
x
,
m
,
t
,
e
,
method
,
nonorm
,
sil
,
h
);
nTwins
=
length
(
twinList
);
% number of twins
if
nTwins
<
1
if
nTwins
<
1
warning
([
'No twins found!'
,
10
,
'The derived surrogates are identical with the original data.'
]
'
)
error
([
'No twins found!'
,
10
,
'The derived surrogates would identical with the original data.'
]
'
)
end
%% marker list for number of twins
markerTwin
=
zeros
(
N
,
1
);
for
i
=
1
:
nTwins
markerTwin
(
twinList
{
i
})
=
i
;
end
end
%% remove the last twin from twinList
temp_ind
=
find
(
markerTwin
);
temp_ind2
=
find
(
twinList
{
markerTwin
(
temp_ind
(
end
))}
==
temp_ind
(
end
));
twinList
{
markerTwin
(
temp_ind
(
end
))}(
temp_ind2
)
=
[];
for
k
=
1
:
nsur
%% create twin surrogate
%% chose randomly first point
cnt
=
0
;
i
=
ceil
(
NX
*
rand
);
while
cnt
<
nsur
xs
=
x
(
i
,:);
idxSurr
=
ceil
(
rand
(
1
)
*
N
);
% random starting point
r_ind
=
rand
(
N
,
1
);
%% jump randomly between twins until length of surrogate is reached
i
=
2
;
while
length
(
xs
)
<
N
while
(
idxSurr
(
i
-
1
)
+
1
)
<=
N
% just go through the time series (the next point after the last found point)
j
=
S
{
i
};
if
markerTwin
(
idxSurr
(
i
-
1
)
+
1
)
~=
0
% we have twins: let's jump!
j_i
=
ceil
(
length
(
j
)
*
rand
);
nr_sel
=
ceil
(
r_ind
(
i
)
*
length
(
twinList
{
markerTwin
(
idxSurr
(
i
-
1
)
+
1
)}));
% select randomly a new point
i
=
j
(
j_i
);
idxSurr
(
i
)
=
twinList
{
markerTwin
(
idxSurr
(
i
-
1
)
+
1
)}(
nr_sel
);
% jump to this new point
i
=
i
+
1
;
else
if
i
>
NX
idxSurr
(
i
)
=
idxSurr
(
i
-
1
)
+
1
;
% just use the next point from the time series
i
=
ceil
(
NX
*
rand
);
end
continue
i
=
i
+
1
;
% just go through the time series
if
i
>
N
break
end
end
if
length
(
idxSurr
)
==
N
cnt
=
cnt
+
1
;
surr
(:,
cnt
)
=
x
(
idxSurr
);
if
~
sil
&
exist
(
'h'
)
&
mod
(
cnt
,
100
)
==
0
waitbar
((
2
*
N
+
N
*
cnt
/
nsur
)/(
3
*
N
),
h
,
'Create surrogates'
)
end
end
xs
=
[
xs
;
x
(
i
,:)];
end
end
y
(:,
k
,
1
:
m0
)
=
reshape
(
xs
(:),
N
,
1
,
m0
);
end
end
if
~
sil
&
exist
(
'h'
)
&
ishandle
(
h
),
close
(
h
),
end
if
nargout
>
0
;
y
=
surr
;
else
surr
end
if
nargout
==
2
;
if
nargout
==
2
;
nTw
=
nTwins
;
nTw
=
nTwins
;
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function
twinList
=
findTwins
(
x
,
m
,
t
,
thr
,
method
,
nonorm
,
sil
,
h
)
% FINDTWINS Find twins in recurrence plot.
%
% twinList=TWIN_MAIK(X,M,TAU,THR)
%
%The function look for the twins in a time series X.
%Therefore the phase space is reconstructed by time delay embedding
%approach where M is the dimension of the phase space and TAU is
%the time delay.
%Neighbouring points are two points with a distance smaller than the
%threshold THR.
%Twins are points with the same neighbourhood.
%% Reconstruct phase space
if
nonorm
if
~
sil
,
disp
(
'Normalize data.'
),
end
x
=
zscore
(
x
);
end
updateTime
=
100
;
N
=
length
(
x
);
Nx
=
N
-
(
m
-
1
)
*
t
;
xEmb
=
zeros
(
Nx
,
m
);
for
i
=
1
:
m
xEmb
(:,
i
)
=
x
(((
i
-
1
)
*
t
+
1
):(
end
-
t
*
(
m
-
i
)));
end
%% Find recurrence points (= neighbours) for each state
% this is a list of neighbours for each time point/state
idxNeighbours
=
[];
nNeighbours
=
[];
for
i
=
1
:
Nx
,
if
~
sil
&
~
isempty
(
h
)
&
mod
(
i
,
updateTime
)
==
0
,
waitbar
(
i
/(
3
*
N
)),
end
% distance between current state and all other states
switch
method
case
'eu'
d
=
sqrt
(
sum
((
xEmb
(
1
:
end
,:)
-
xEmb
(
i
,:))
.^
2
,
2
));
case
'mi'
d
=
sum
(
abs
(
xEmb
(
1
:
end
,:)
-
xEmb
(
i
,:)),
2
);
otherwise
d
=
max
(
abs
(
xEmb
(
1
:
end
,:)
-
xEmb
(
i
,:)),[],
2
);
end
% indices of the Neighbours
idxNeighbours
{
i
}
=
find
(
d
<
thr
);
% number of Neighbours found (useful for acceleration of the algorithm)
nNeighbours
(
i
)
=
length
(
idxNeighbours
{
i
});
end
%% Find twins
ind_p
=
1
:
Nx
;
% set of states
twinList
=
[];
% list of twins
cnt
=
1
;
while
length
(
ind_p
)
>
1
,
if
~
sil
&
~
isempty
(
h
)
&
mod
(
i
,
updateTime
)
==
0
,
waitbar
((
2
*
N
-
length
(
ind_p
))/(
3
*
N
),
h
,
'Find twins'
),
end
currentTwins
=
1
;
% start with the first entry in the (remaining) set
% find only those columns in the RP that have the same number of neighbours
potentialTwins
=
find
(
nNeighbours
==
nNeighbours
(
1
));
% this will speed up the code
for
i
=
2
:
length
(
potentialTwins
)
if
sum
(
abs
(
idxNeighbours
{
1
}
-
idxNeighbours
{
potentialTwins
(
i
)}))
==
0
&
any
(
idxNeighbours
{
1
})
currentTwins
=
[
currentTwins
,
potentialTwins
(
i
)];
end
end
if
length
(
currentTwins
)
>
1
twinList
{
cnt
}
=
ind_p
(
currentTwins
);
cnt
=
cnt
+
1
;
end
% remove all states that are already found
ind_p
(
currentTwins
)
=
[];
idxNeighbours
(
currentTwins
)
=
[];
nNeighbours
(
currentTwins
)
=
[];
end
if
~
sil
&
~
isempty
(
h
),
waitbar
(
2
/
3
,
h
),
end
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment