2
* This file is part of TISEAN
4
* Copyright (c) 1998-2007 Rainer Hegger, Holger Kantz, Thomas Schreiber
6
* TISEAN is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* TISEAN is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with TISEAN; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
/* Author: Rainer Hegger
21
* Modified: Piotr Held <pjheld@gmail.com> (2015).
22
* This function is based on ghkss of TISEAN 3.0.1
23
* https://github.com/heggus/Tisean"
26
#define HELPTEXT "Part of tisean package\n\
27
No argument checking\n\
28
FOR INTERNAL USE ONLY"
30
#include <octave/oct.h>
32
#include "routines_c/tsa.h"
36
int eps_set=0,euclidean=0,dimset=0;
38
octave_idx_type dim,qdim=2,minn=50,iterations=1,embed=5,length;
39
octave_idx_type comp=1;
41
unsigned int verbosity=0;
46
double *d_min,*d_max,d_max_max;
47
double **delta,**corr;
52
unsigned int ibox=BOX-1;
53
unsigned int *index_comp,*index_embed;
55
/*these are global to save time*/
57
double *av,**mat,*matarray,*eig;
60
void sort(double *x,int *n)
81
void mmb(const Matrix &series,double eps)
83
octave_idx_type i,x,y;
90
for (i=emb_offset;i<length;i++) {
91
x=(int)(series(i,0)*ieps)&ibox;
92
y=(int)(series(i-emb_offset,comp-1)*ieps)&ibox;
98
unsigned long fmn(const Matrix &series, long which,double eps)
101
octave_idx_type i,i1,i2,j,j1,k,li;
106
i=(int)(series(which,0)/eps)&ibox;
107
j=(int)(series(which-emb_offset,comp-1)/eps)&ibox;
109
for (i1=i-1;i1<=i+1;i1++) {
111
for (j1=j-1;j1<=j+1;j1++) {
112
element=box[i2][j1&ibox];
113
while (element != -1) {
114
for (k=0;k<embed;k++) {
116
for (li=0;li<comp;li++) {
117
dx=fabs(series(which+k1,li)-series(element+k1,li));
126
element=list[element];
133
void make_correction(const Matrix &series, unsigned long n,octave_idx_type nf)
135
octave_idx_type i,i1,i2,j,j1,j2,k,k1,k2,hs;
138
for (i=0;i<dim;i++) {
143
help += series(flist[j]-i2,i1);
147
for (i=0;i<dim;i++) {
150
for (j=i;j<dim;j++) {
156
help += series(hs-i2,i1)*series(hs-j2,j1);
158
mat[i][j]=(help/nf-av[i]*av[j])*metric[i]*metric[j];
166
for (i=0;i<dim;i++) {
168
for (j=qdim;j<dim;j++) {
170
for (k=0;k<dim;k++) {
173
help += (series(n-k2,k1)-av[k])*mat[k][hs]*mat[i][hs]*metric[k];
176
corr[n][i]=help/metric[i];
180
void handle_trend(unsigned long n,octave_idx_type nf)
182
octave_idx_type i,i1,i2,j;
185
for (i=0;i<dim;i++) {
188
help += corr[flist[j]][i];
192
for (i=0;i<dim;i++) {
195
delta[i1][n-i2] += (corr[n][i]-av[i])/(trace*metric[i]);
199
void set_correction(Matrix &series)
204
OCTAVE_LOCAL_BUFFER (double, hav, comp);
205
OCTAVE_LOCAL_BUFFER (double, hsigma, comp);
209
hav[j]=hsigma[j]=0.0;
211
for (i=0;i<length;i++)
212
for (j=0;j<comp;j++) {
213
hav[j] += (help=delta[j][i]);
214
hsigma[j] += help*help;
217
for (j=0;j<comp;j++) {
219
hsigma[j]=sqrt(fabs(hsigma[j]/length-hav[j]*hav[j]));
222
for (i=0;i<comp;i++) {
223
octave_stdout << "Average shift of component " << i+1 << " = "
224
<< hav[i]*d_max[i] << "\n";
225
octave_stdout << "Average rms correction of comp. " << i+1 << " = "
226
<< hsigma[i]*d_max[i] << "\n\n";
229
for (i=0;i<length;i++)
231
series(i,j) -= delta[j][i];
236
octave_stdout << "Reset minimal neighbourhood size to "
237
<< mineps*d_max_max << "\n";
244
DEFUN_DLD (__ghkss__, args, , HELPTEXT)
248
octave_idx_type iter,nfound,n;
251
unsigned long allfound;
255
int nargin = args.length ();
256
octave_value_list retval;
266
Matrix input = args(0).matrix_value();
267
embed = args(1).int_value();
268
comp = args(2).int_value();
269
delay = args(3).int_value();
270
qdim = args(4).int_value();
271
minn = args(5).int_value();
272
mineps = args(6).double_value();
273
eps_set = args(7).int_value();
274
iterations = args(8).int_value();
275
euclidean = args(9).int_value();
276
verbosity = args(10).int_value();
279
emb_offset=(embed-1)*delay;
280
length = input.rows();
282
// Prepare for noise reduction and allocate memory
283
check_alloc(d_min=(double*)malloc(sizeof(double)*comp));
284
check_alloc(d_max=(double*)malloc(sizeof(double)*comp));
286
for (i=0;i<comp;i++) {
287
rescale_data(input,i,length,&d_min[i],&d_max[i]);
288
if (d_max[i] > d_max_max)
298
check_alloc(box=(long**)malloc(sizeof(long*)*BOX));
300
check_alloc(box[i]=(long*)malloc(sizeof(long)*BOX));
302
check_alloc(list=(long*)malloc(sizeof(long)*length));
303
check_alloc(flist=(unsigned long*)malloc(sizeof(long)*length));
305
check_alloc(metric=(double*)malloc(sizeof(double)*dim));
308
for (i=0;i<dim;i++) {
310
trace += 1./metric[i];
314
for (i=0;i<dim;i++) {
315
if ((i >= comp) && (i < ((long)dim-(long)comp)))
319
trace += 1./metric[i];
323
check_alloc(corr=(double**)malloc(sizeof(double*)*length));
324
for (i=0;i<length;i++)
325
check_alloc(corr[i]=(double*)malloc(sizeof(double)*dim));
326
check_alloc(ok=(int*)malloc(sizeof(int)*length));
327
check_alloc(delta=(double**)malloc(sizeof(double*)*comp));
329
check_alloc(delta[i]=(double*)malloc(sizeof(double)*length));
330
check_alloc(index_comp=(unsigned int*)malloc(sizeof(int)*dim));
331
check_alloc(index_embed=(unsigned int*)malloc(sizeof(int)*dim));
332
check_alloc(av=(double*)malloc(sizeof(double)*dim));
333
check_alloc(sorted=(int*)malloc(sizeof(int)*dim));
334
check_alloc(eig=(double*)malloc(sizeof(double)*dim));
335
check_alloc(matarray=(double*)malloc(sizeof(double)*dim*dim));
336
check_alloc(mat=(double**)malloc(sizeof(double*)*dim));
338
mat[i]=(double*)(matarray+dim*i);
339
check_alloc(hser=(double**)malloc(sizeof(double*)*comp));
343
// Create output matrix
344
Matrix output (length, comp);
346
for (i=0;i<dim;i++) {
347
index_comp[i]=i%comp;
348
index_embed[i]=(i/comp)*delay;
351
// Calculate the noise reduction
353
for (iter=1;iter<=iterations;iter++)
355
for (i=0;i<length;i++) {
367
octave_stdout << "Starting iteration " << iter << "\n";
371
for (n=emb_offset;n<length;n++)
373
nfound=fmn(input,n,epsilon);
374
if (nfound >= minn) {
375
make_correction(input,n,nfound);
385
octave_stdout << "Corrected " << allfound << " points with epsilon= "
386
<< epsilon*d_max_max << "\n";
387
if (std::isinf(epsilon*d_max_max))
389
error_with_id ("Octave:tisean", "cannot reduce noise on input data");
396
octave_stdout << "Start evaluating the trend\n";
400
for (i=1;i<epscount;i++) {
402
for (n=emb_offset;n<length;n++)
404
nfound=fmn(input,n,epsilon);
405
handle_trend(n,nfound);
409
octave_stdout << "Trend subtracted for " << allfound << " points with epsilon= "
410
<< epsilon*d_max_max << "\n";
413
set_correction(input);
415
if (iter == iterations)
416
for (i=0;i<length;i++)
420
// old fprintf(file,"%e ",series[j][i]*d_max[j]+d_min[j]);
421
output(i,j) = input(i,j)*d_max[j]+d_min[j];
427
// Deallocate of all the memory
436
for (i=0;i<length;i++)
444
delete[] index_embed;