00001
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #include <limits.h>
00027 #include <math.h>
00028 #include "tsa.h"
00029 #include "tdkdtree.h"
00030 #include "mpi.h"
00031
00032
00033 static void show_options();
00034 static void scan_options();
00035 static double standarddeviation();
00036 static void makedelayvectors();
00040 static FILE* prgerr = NULL;
00044 static FILE* prgout = NULL;
00048 static unsigned long N = ULONG_MAX;
00052 static int med = 1;
00056 static int m = 5;
00060 static int tau = 1;
00064 static double R_tol = 10.0;
00068 static unsigned long exclude = 0;
00072 static unsigned int column = 1;
00076 static char* outfile = NULL;
00080 static char* infile = NULL;
00084 static unsigned int verbosity = 0xff;
00088 static double* x = NULL;
00089
00099 int main
00100 (
00101 int argc ,
00102 char** argv
00103 )
00104 {
00105 double R_A = 0.0 ;
00106 double A_tol = 0.0 ;
00107 int n = 0 ;
00108 double** y = NULL ;
00109 int d = 0 ;
00110 int i = 0 ;
00111 kdtree* tree = NULL ;
00112 int j = 0 ;
00113 double R_i = 0.0 ;
00114 double r_i = 0.0 ;
00115 int* fnn = NULL ;
00116 int* gfnn = NULL ;
00117 int p = 0 ;
00118 int q = 0 ;
00119 double t_s = 0.0 ;
00120 double t_f = 0.0 ;
00121
00122 MPI_Init(&argc,&argv);
00123 MPI_Comm_rank(MPI_COMM_WORLD,&q);
00124 MPI_Comm_size(MPI_COMM_WORLD,&p);
00125 prgerr = stderr;
00126 prgout = stdout;
00127 if( scan_help(argc,argv) )
00128 {
00129 if( q == 0 )
00130 show_options(argv[0]);
00131 MPI_Finalize();
00132
00133 return 0;
00134 }
00135 scan_options(argc,argv);
00136 infile = search_datafile(argc,argv,&column,verbosity);
00137 if( !infile )
00138 {
00139 if( q == 0 )
00140 fprintf(prgerr,"Input file not found. Exiting!\n");
00141 MPI_Finalize();
00142
00143 return 0;
00144 }
00145 if( q == 0 && outfile )
00146 {
00147 prgout = fopen(outfile,"w");
00148 fprintf(prgerr,"Opened %s for writing\n",outfile);
00149 }
00150 x = get_series(infile,&N,exclude,column,verbosity);
00151
00152 if( q == 0 ) t_s = MPI_Wtime();
00153 R_A = standarddeviation(x,N);
00154 A_tol = 2.0;
00155 check_alloc(fnn = (int*)malloc(sizeof(int)*(m+1)));
00156 if( q == 0 )
00157 {
00158 check_alloc(gfnn = (int*)malloc(sizeof(int)*(m+1)));
00159 for( d = med ; d <= m ; d++ )
00160 gfnn[d] = 0;
00161 }
00162 for( d = med ; d <= m ; d++ )
00163 {
00164 fnn[d] = 0;
00165 n = N - d*tau;
00166 check_alloc( y = (double**)malloc(sizeof(double*)*d) );
00167 for( i = 0 ; i < d ; i++ )
00168 check_alloc( y[i] = (double*)malloc(sizeof(double)*n) );
00169 makedelayvectors(n,d,y);
00170 tree = newtdkdtree(y,n,d,p,q);
00171
00172 for( i = 0 ; i < tree->n ; i++ )
00173 {
00174 j = tdnn(tree->perm[i],&R_i);
00175 r_i = fabs(x[tree->perm[i]+d*tau]-x[j+d*tau]);
00176 R_i = sqrt(R_i);
00177 if( r_i / R_i > R_tol || r_i / R_A > A_tol )
00178 fnn[d]++;
00179 }
00180
00181 if( tree ) destroytdkdtree(tree);
00182 if( y )
00183 {
00184 for( i = 0 ; i < d ; i++ )
00185 free(y[i]);
00186 free(y);
00187 }
00188 }
00189 MPI_Reduce(fnn,gfnn,m+1,MPI_INT,
00190 MPI_SUM,0,MPI_COMM_WORLD);
00191 if( q == 0 )
00192 {
00193 for( d = med ; d <= m ; d++ )
00194 fprintf(prgout,"%12d %10.3f %12d %12d\n",
00195 d,(double)gfnn[d]/(N - d*tau),gfnn[d],N - d*tau);
00196
00197 t_f = MPI_Wtime();
00198 fprintf(prgerr,"RUNTIME %-.3lf\n",t_f-t_s);
00199 }
00200
00201
00202 if( q == 0 && gfnn ) free(gfnn);
00203 if( fnn ) free(fnn);
00204 if( q == 0 && outfile )
00205 fclose(prgout);
00206 if( outfile ) free(outfile);
00207 if( infile ) free(infile);
00208 if( x ) free(x);
00209 MPI_Finalize();
00210
00211 return 0;
00212 }
00213
00222 static double standarddeviation
00223 (
00224 double* x ,
00225 int N
00226 )
00227 {
00228 int i = 0 ;
00229 double media = 0.0 ;
00230 double deviation = 0.0 ;
00231 double temp = 0.0 ;
00232 double R_A = 0.0 ;
00233
00234 media = 0.0;
00235 for ( i = 0 ; i < N ; i++ )
00236 media += x[i];
00237 media /= N;
00238 deviation = 0.0;
00239 for ( i = 0 ; i < N ; i++ )
00240 {
00241 temp = x[i] - media;
00242 deviation += temp * temp;
00243 }
00244 R_A = sqrt( deviation / N );
00245
00246 return R_A;
00247 }
00248
00249 static void makedelayvectors
00250 (
00251 int n ,
00252 int d ,
00253 double** y
00254 )
00255 {
00256 int i = 0 ;
00257 int j = 0 ;
00258
00259 for( i = 0 ; i < n ; i++ )
00260 for( j = 0 ; j < d ; j++ )
00261 y[j][i] = x[ i + j * tau ];
00262
00263 return;
00264 }
00265
00275 static void scan_options
00276 (
00277 int argc ,
00278 char** argv
00279 )
00280 {
00281 char* arg = NULL ;
00282
00283 if( ( arg = check_option(argv,argc,'l','u') ) != NULL )
00284 {
00285 sscanf(arg,"%lu",&N);
00286 free(arg);
00287 }
00288 if( ( arg = check_option(argv,argc,'x','u') ) != NULL )
00289 {
00290 sscanf(arg,"%lu",&exclude);
00291 free(arg);
00292 }
00293 if( ( arg = check_option(argv,argc,'c','u') ) != NULL )
00294 {
00295 sscanf(arg,"%u",&column);
00296 free(arg);
00297 }
00298 if( ( arg = check_option(argv,argc,'m','u') ) != NULL )
00299 {
00300 sscanf(arg,"%d",&med);
00301 free(arg);
00302 }
00303 if( ( arg = check_option(argv,argc,'M','u') ) != NULL )
00304 {
00305 sscanf(arg,"%d",&m);
00306 free(arg);
00307 }
00308 if( ( arg = check_option(argv,argc,'d','u') ) != NULL )
00309 {
00310 sscanf(arg,"%d",&tau);
00311 free(arg);
00312 }
00313 if( ( arg = check_option(argv,argc,'f','f') ) != NULL )
00314 {
00315 sscanf(arg,"%lf",&R_tol);
00316 free(arg);
00317 }
00318 if( ( arg = check_option(argv,argc,'o','o') ) != NULL )
00319 {
00320 if( strlen(arg) > 0 )
00321 outfile = arg;
00322 }
00323 }
00324
00325
00326 #define WID_STR "Computing minimal embedding dimension using a\n" \
00327 " false nearest neighbors method by Kennel et al. (1991).\n" \
00328 " This program is a kd-tree data structure approach\n" \
00329 " based on a top-down search algorithm."
00330
00338 static void show_options
00339 (
00340 char* progname
00341 )
00342 {
00343 what_i_do(progname,WID_STR);
00344 fprintf(prgerr,"Usage: %s [options]\n",progname);
00345 fprintf(prgerr,"Options:\n");
00346 fprintf(prgerr,"\t-l # of data [default: whole file]\n");
00347 fprintf(prgerr,"\t-x # of lines to be ignored [default: 0]\n");
00348 fprintf(prgerr,"\t-c column to read [default: 1]\n");
00349 fprintf(stderr,"\t-m minimal embedding dimension [default: 1]\n");
00350 fprintf(stderr,"\t-M maximal embedding dimension [default: 5]\n");
00351 fprintf(prgerr,"\t-d delay [default: 1]\n");
00352 fprintf(stderr,"\t-f tolerance factor [default: 10.0]\n");
00353 fprintf(prgerr,"\t-o outfile [default: standard output]\n");
00354 fprintf(prgerr,"\t-h show these options\n");
00355 fprintf(prgerr,"\n");
00356 fprintf(prgerr,
00357 "Everything not being a valid option will be interpreted as a possible\n"
00358 "datafile. If no datafile is given, the program %s is halted.\n"
00359 "The file reading interface code was copied from TISEAN 3.0.0 (C)\n"
00360 "by R. Hegger, H. Kantz, T. Schreiber (1998-2007)\n\n",
00361 progname);
00362 }