Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 10

function p = nl_test (data, NumSurr, EmbDim, NumNeig);

%
% function p = nl_test (data, NumSurr, EmbDim, NumNeig);
%
% this function performs a testfor non liniearity in a time series by means
of surrogate data.
% surrogate calculation is carried out by phase randomization according to
the method
% of amplitude adjusted fourier transform
%
% input parameters:
%
% data : time series to be tested
% Numsurr : number of surrogetes to be calculated
% EmbDim : embedding dimension
% NumNeig : number of nearest neighbors to be included into calculation of
prredicted values
%
% Return parameter
% p-value
%
% this value should be less than 0.01 to claim that the time series under
study is
% not linier random origin
%
% Note that for HRV signals, after extensive study of optimal value for the
embedding
% dimension and naerest neighbors were found to be 3 and 6 respectively
% nl_test is the main matlab procedure that calls two pascal programs
% histgram.exe (which perform the histogram-transform) and
% forecast.exe (which calculate the prediction error)
%
% data exchange matlab and the external programs is handled through several
% files, see comments in the source code bellow.
% nl_test itself generates an ensemble of surrogate time series from the
rescaled original
% time series, calculates the distribution of our test statistics-the MAE-for
the
% surrogates, and compares it to the mae of the original data set.

[row, cool]= size(data);


if cool > row
data=data';
end
% now the original data is contained in column-vector and we can save
% it to the file HRV.dat which is read by the program hstgram.exe
save HRV.dat data/ascii
recordSize = length(data);
if (nargin==2)
EmbDim=3;
NumNeig=6;
end
if (nargin==3)
NumNeig=6;
end
i=sqrt(-1);
% we have to generate a call-string to invoke to the external program
forecast
callForecastStr = sprintf('!forecast %d %d topred.dat pred_err.dat', EmbDim,
NumNeig);
%and initialize the random number generators
rand('seed', sum(100*clock));
randn('seed', 50000*rand);
% the following loop will generate an array ot the median absolute errors
(MAE)
% for an ensemble of surrogate time series
for h=1:NumSurr
% generate an gaussian time series with the same size as the HRV signal to be
% tested and store it in an array G which is size saved to the file gauss.dat
G = randn(RecordSize,l);
save Gauss.dat G/ascii
% call the histogram transformation program to transform Gauss.dat time
series to
% have the same shape as HRV.dat time series but stil have a gaussian PDF.
the
% transform rescaled time series is stored in a file TGauss.dat ...
!Hstgram HRV.dat Gauss.dat TGauss.dat
% ...from which it is read into a local variable tgauss
load TGauss.dat;
% carry out phase randomization
s=fft(tgauss,RecordSize);
for 1=2:recordsize02
r=*pi*rand;
%modify phase of spectral component no 1
S (1) = real (S(1))*cos(r)+imag (S(1)*sin(r)*i;
%we want the lifft to yield real valued signals, so the phases have to
%be symmetric
S (RecordSize+2-1) = conj (S(1));
end;
SurrData=real (ifft(S));

%Save the generated surrogate data in a file named sg.dat


save sg.dat SurrData / ascii
%call the inverse histogram transformation and store the transformed time
%series in the file Topred.
!Hstgram HRV.dat ToPred.dat

%Store the Median Absolute Error of the prediction error time series and
%store the absolute values of the prediction error time series in the next
%item in the array e
e(h) = median(abs(pred_err));
end
% call the forecasting alogarithm to pridict the oroginal time series under
% study called HRV.dat and store the absolute values of the prediction
% errors in pred_err.dat
callForecaStr = sprintf('!Forecast %d %d HRV.dat pred_err.dat', EmbDim,
NumNeigh);
eval (CallForecastStr);

load pred_err.dat;
% calculate the median absolute error (AME)
E = median (abs(pred_err));
% Compute the p-value
p = erfc(abs(E-mean(e))/std(e))/sqr(2));

{
this program implements the Histogram and inverse histogram
transformation
the way this transformation is implemented is by storing the two time
series
in an array LIST where each element in the array consists of four values

valx : is the data point in the first time series


indx : is the time index of the point in valx
valg : is the data point in the second time series
indg : is the time index of the point in valg
the program reads the two time series and store them in LIST, indx is
equal indg

The first step:


is to sort the first time series in valx using the quik sort algorithm.
this sorting will preserve the indices of data point, that is when we
swap two
data point in valx we swap the indices in indx as well.

The second step :


is sort the time series in valg in freserving the indices as done in step
one.
this well resuls in having both time series sorted out in descending
order in their
corresponding indices are stored in indx and indg.

The third step :


Now if we sort the list Array using indx values, that is if sort the
values in indx in
descending ordrer and end we swap values, we swap the whole item,that is
the complete
record (indx, valx, valg, indgh). This will result in the first time
series restored in
valx
in term of its oroginal shape and the second time series sorted in valg
being sorted
out in such a way to mimic the shape of the first time series. That is
the second
time series is a non-linearly rescaled version of the first time series.

if we simply swap the inputs passed to the program, we are simply doing
the inverse
histogram transformation.
}
program hstgram;
uses crt;
type
element=node;

node=record
indx:real;
valx:real;
indg:real;
valg:real;
arraytype=array[1..1024] of element;
indextype=0..1024;
var list:arraytype;
number,i:integer;
fp,fp2:text;
temp:element;
filename:string[20];

procedure inter_swap(n:integer);
for i:=1 to number do
begin
temp'.valx:=list[i]'.valx;
temp'.indx:=list[i]'.indg;
if n=1 then
begin
list[i]'.valx:=list[i]'.valg;
list[i]'.indx:=list[i]'.indg;
end
else
begin
list[i]'.valx:=list[i]'.valg;
list[i]'.indx:=list[i]'.indg;
end;
list[i]'.valx:=temp'.valx;
list[i]'.indx:=temp'.indx;
end;

end
procedure swap (var x,y:element;n:integer);
begin
temp'.indx:=x'.indx;temp'.valx:=x'.valx;
if n=2 then begin temp'.indg:=x'.indg;temp'.valg:=x'.valg;end;
x'.indx:=y'.indx;x'.valx:=y'.valx;
if n=2 then begin x'.indg:=y'.indg;x'.valg:=y'.valg;end;
y'.indx:=temp'.indx;y'.valx:=temp'.valx;
if n=2 then begin y'.indg:=temp'.indg'y'.valg:=temp'.valg;end;
end;
(this procedure is called resurcevely by the quicksort procedure qsort)

Procedure qsort (var list: arraytype;first,last:indextype;n:integer);


var splitptl1,splitpt2:indextype;
begin
if first<last then
begin
(list,first,last,splitpt1,splitpt2,n);
if splitpt1<last then
qsort(list,splitpt1,last,n);
if first<splitpt2 then
qsort(list,first,splitpt2,n);
end;
end;
Begin
if paramcount <> 3 then
Begin
writeeln('');
writeln('ERROR-wrong number of parameter');
writeln('correct call');
writeln('Hstgram InFile1 InFile2 OutFile')'
exit
end;
clrscr;
assign(fp, ParamStr(1));
reset(fp);
assign(fp, ParamStr(2));
reset(fp2);
new(temp);
( Read the two time series into the array LIST-each item in the array
stores the index of the time series and the tow corresponding data
points)
number := 0;
while not eof(fp) do
begin
inc(number);
new(list[number]);
readln(fp,list[number]'.valx);
list[number]'.indx:=number;
list[number]'.indg:=number;
readln(fp2,list[number]'.valg);
end;

Close(fp);

Close(fp2);

(sort the first time series in descending order-the data points and keep track of the indices)

Qsort(list,1,number,1);

(swap the two time series)

Inter_swap(1);

(sort the second time series in descending order-the data points and keep track of the indices)

Qsort(list,1,number,1);
(swap the indices)

Inter_swap(2);

(sort the indices)

Qsort(list,1,number,2);

Assign(fp,paramStr(3));

Rewrite(fp);

For i:=1 to number do

Writeln(fp.list(i)’.valg);

Close(fp);

End.

(this program implements the non linear prediction algorithm)

Program forecast;

Uses crt;

Const

Dmax=50;

Tiny=1e-20;

Type

X_arr=array[1..511] of double;

Int=array [1..dmax] of integer;

One= array [1..dmax] of double;

Two=array [1..dmax, 1..dmax] of double;

Var

Filename:string[20];

convErr, number, n,w,dim,kv,i,j,k,d,ii:integer


b:one;

temp:double;

indx,ndex:int;

a:two;

fp1,fp:text;

X:array[0..1024] of double;

Deff.x_pred:x_arr;

(the source code of of the following procedure is omitted due to copyright reasons it can be found on
the book

w.h.press,S.A.teukolsky,w.t.vetterling,B.P.flannery

NUMERICAL RECIPES IN PASCAL

1st Edition

Cambridge Univercity Press

These procedures perform an L/U-decomposition of a matrix.

Procedure ludcmp(var indx:int;var d:integer);

Procedure lubksb (var a:two;n:integer;var inx:int;var b:one);

(the following procedure used to select the k nearest neighbors to the


predected point using the euclidean Norm as basis for comparison)
procedure selectsort (var deff:x_arr;n:integer;var ndex:int);
var
m,k,mindex:integer;
Begin
m:=1;
while m<= do
begin
if deff[m]<deff[mindex] then mindex:=m;
m:=m+1;
end;

ndex[k]:=mindex;
deff[mindex]:=300000;
end;
end;
begin
writeln('');
writeln('ERROR-wrong number in parameters');
writeln('forecast Embdim NumNeig PredFile PredErrFile');
writeln('Parameters');
writeln('EmbDim embedding demention');
writeln(NumNieg number of neighbors to include in linear fit');
writeln('predfile input ASCII-File containing values of time series to be
predicted');
writeln('PredErrFile output ASCII-File containing prediction error');
exit;
end;
clrscr;
val(paramstr(1), dim, converr);
if converr <> 0 then
begin
writeln ('cannot evaluate expression for command line argument EmbDim');
exit
end;
val(paramStr (2), kv, converr);
if convErr <> 0 then
begin
writeln ('cannot evaluate expression for command line argument
NumbNeig');
exit
end;
(fp point to the file containing the time series to be predicted)
assign(fp,paramstr(3));
reset(fp);
(fp1 points to the prediction-error file)
assign(fp1,paramstr(4));
rewrite(fp1);
n:=1;
number := 0;
while not eof (fp) do
begin
for i:=1 to dim-1 do deff[i]:= 30000;
for i:=dim to ( number div 2-2) do
begin
temp:=0;
for ii:=0 to dim-1 do temp:=temp+sqr(x[j-ii]-x[i-ii]);
deff[i]:=sqrt(temp);
end;
selectsort(deff, (number div 2-2),ndex);

For i:=1 to dim do

Begin

For k:=1 to dim do

Begin

A[I,k]:=0
For ii:=1 to kv do a[i,k]:= a[I,k]+x[ndex[ii]-k+1]*x[ndex[ii]-i+1];
end;
a[i,dim+1]:=0;

For ii:=1 to kv do a[i,dim+1]:=a[i,dim+1]+ x[ndex[ii]-i+1];

End;

For i:=1 to dim do

Begin

a[dim+1,k]:=0;

For ii:=1 to kv do a[dim+1,k]:=a[dim+1,k]+ x[ndex[ii]-k+1];

a[dim+1, dim+1]:=kv;

For i:=1 to dim do

Begin

b[i]:=0

for ii:=1 to kv do b[i]:= b[i]+ x[ndex[ii]+1]; *x[ndex[ii]-i+1];


end;

b[dim+1]:=0;

For ii:=1 to kv do b[dim+1]:=b[dim+1]+ x[ndex[ii]+1];

Ludcmp(a,dim+1,indx,d);

Lubksb(a, dim+1,indx,b);

x_pred[n]:=0;

for ii:=1 to dim do

x_pred[n]:=x_pred(n)+x[j-ii+1]*b(ii);

x_pred[n]:=x_pred(n)+b[dim+1];

Writeln(fpl,abs(x_pred[n]-x[j+1]));
Inc(n);

End;

End.

You might also like