00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "nonlinear.h"
00022
00024 double make_cond_entropy(long t, long *h1, long *h11, long **h2, long *array,
00025 int partitions, int length)
00026 {
00027 long i,j,hi,hii,count=0;
00028 double hpi,hpj,pij,cond_ent=0.0,norm;
00029
00030 for (i=0;i<partitions;i++) {
00031 h1[i]=h11[i]=0;
00032 for (j=0;j<partitions;j++){
00033 h2[i][j]=0;
00034 }
00035 }
00036
00037 for (i=0;i<length;i++){
00038 if (i >= t) {
00039 hii=array[i];
00040 hi=array[i-t];
00041 h1[hi]++;
00042 h11[hii]++;
00043 h2[hi][hii]++;
00044 count++;
00045 }
00046 }
00047
00048 norm=1.0/(double)count;
00049 cond_ent=0.0;
00050
00051 for (i=0;i<partitions;i++) {
00052 hpi=(double)(h1[i])*norm;
00053 if (hpi > 0.0) {
00054 for (j=0;j<partitions;j++) {
00055 hpj=(double)(h11[j])*norm;
00056 if (hpj > 0.0) {
00057 pij=(double)h2[i][j]*norm;
00058 if (pij > 0.0){
00059 cond_ent += pij*log(pij/hpj/hpi);
00060 }
00061 }
00062 }
00063 }
00064 }
00065
00066 return cond_ent;
00067 }
00093 double tdelay_predict_simple( TimeDelayReconstruction *p, double *sample, int npredict, double epsilon ){
00094 double predict=0;
00095 int nfound;
00096 int i;
00097 double *s;
00098 double dist;
00099
00100 s = dblp_init( NULL, p->m, 0.0 );
00101 for( nfound=0; nfound==0; epsilon*=1.2 ){
00102 dprintf("epsilon=%f\n", epsilon );
00103 for( i=0; i<p->xn-npredict; i++ ){
00104 tdelay_index_i( p, i, s );
00105 dist = vectordist_euclidean( s, sample, p->m, NULL );
00106 if( dist<epsilon ){
00107 nfound++;
00108 predict+=p->x[i+npredict];
00109 }
00110 }
00111 }
00112 dprintf("nfound after alg=%i\n", nfound);
00113 free( s );
00114
00115 return predict/(double)nfound;
00116 }
00117
00138 double tdelay_simple_nonlinear_prediction_error( TimeDelayReconstruction *reference, double *y, int yn,
00139 int npredict, double epsilon ){
00140 int i;
00141 double crmse=0.0;
00142 TimeDelayReconstruction *Y;
00143 double *ysample;
00144 double pred;
00145 Y = tdelay_init( reference->m, reference->tau, y, yn );
00146 ysample = dblp_init( NULL, reference->m, 0.0 );
00147
00148 for( i=0; i<yn-npredict; i++ ){
00149 tdelay_index_i( Y, i, ysample );
00150 pred = tdelay_predict_simple( reference, ysample, npredict, epsilon );
00151 crmse += rmse( &pred, &(y[i+npredict]), 1 );
00152 }
00153
00154 free( ysample );
00155 tdelay_free( Y );
00156 return crmse/(double)(yn-npredict);
00157 }
00158
00175 double** eeg_nonlinear_prediction_error( const EEG *eeg, int embedding_dim, int time_lag,
00176 int npredict, double epsilon,
00177 double** output, OptArgList *optargs ){
00178 #ifdef FIXEEG
00179 int channel=0;
00180 double x;
00181 int i, j;
00182 void *ptr;
00183 ProgressBarFunction progress=NULL;
00184
00185
00186 if( optarglist_has_key( optargs, "channel" ) ){
00187 x = optarglist_scalar_by_key( optargs, "channel" );
00188 if( !isnan( x ) ) channel=(int)x;
00189 }
00190 if( eeg->nbchan<=channel ){
00191 errprintf( "Channel '%i' is not in EEG-set which holds only '%i' channels\n",
00192 channel, eeg->nbchan );
00193 return NULL;
00194 }
00195 if( optarglist_has_key( optargs, "progress" ) ){
00196 ptr = optarglist_ptr_by_key( optargs, "progress" );
00197 if( ptr ) progress = (ProgressBarFunction)ptr;
00198 }
00199
00200
00201 if( !output ){
00202 output = dblpp_init( eeg->ntrials, eeg->ntrials );
00203 }
00204
00205
00206 TimeDelayReconstruction *reference;
00207 reference = tdelay_init( embedding_dim, time_lag, NULL, eeg->n );
00208
00209 if( progress ){
00210 progress( PROGRESSBAR_INIT, eeg->ntrials );
00211 }
00212 for( i=0; i<eeg->ntrials; i++ ){
00213
00214 reference->x = eeg->data[channel][i];
00215 if( progress ) progress( PROGRESSBAR_CONTINUE_LONG, i );
00216 for( j=0; j<eeg->ntrials; j++ ){
00217 output[i][j] = tdelay_simple_nonlinear_prediction_error( reference, eeg->data[channel][j], eeg->n,
00218 npredict, epsilon );
00219 if( progress ) progress( PROGRESSBAR_CONTINUE_SHORT, j );
00220 }
00221 }
00222
00223 if( progress ) progress( PROGRESSBAR_FINISH, 0 );
00224 return output;
00225 #endif
00226 }
00227
00228
00246 int tdelay_estimate_timelag_mutual( TimeDelayReconstruction *p, long partitions, long corrlength, double *mutual ){
00247 long *array,*h1,*h11,**h2;
00248 long tau,i,length;
00249 double *series,min,interval,shannon;
00250 int free_mutual=0;
00251
00252 if(partitions<=0)
00253 partitions=16;
00254 if(corrlength<=0)
00255 corrlength=20;
00256
00257 series = p->x;
00258 length = p->xn;
00259
00260 h1 =(long *)malloc(sizeof(long) *partitions);
00261 h11=(long *)malloc(sizeof(long) *partitions);
00262 h2 =(long**)malloc(sizeof(long*)*partitions);
00263 for (i=0;i<partitions;i++)
00264 h2[i]=(long *)malloc(sizeof(long)*partitions);
00265 array=(long *)malloc(sizeof(long)*length);
00266
00267
00268 min=interval=series[0];
00269 for (i=1;i<length;i++) {
00270 if (series[i] < min)
00271 min=series[i];
00272 if (series[i] > interval)
00273 interval=series[i];
00274 }
00275 if (interval != 0.0) {
00276 for (i=0;i<length;i++){
00277 series[i]=(series[i]- min)/ (double)interval;
00278 }
00279 }
00280
00281
00282 for (i=0;i<length;i++){
00283 if (series[i] < 1.0){
00284 array[i]=(long)(series[i]*(double)partitions);
00285 } else {
00286 array[i]=partitions-1;
00287 }
00288 }
00289
00290 shannon=make_cond_entropy(0, h1, h11, h2, array, partitions, length );
00291 if (corrlength >= length){
00292 corrlength=length-1;
00293 }
00294
00295 if( !mutual ){
00296 free_mutual=1;
00297 mutual = (double*) malloc( (corrlength+1)*sizeof(double) );
00298 }
00299
00300 mutual[0] = shannon;
00301 for (tau=1;tau<=corrlength;tau++) {
00302 mutual[tau] = make_cond_entropy(tau, h1, h11, h2, array, partitions, length );
00303 }
00304
00305 for( i=0; i<corrlength; i++ ) {
00306 dprintf("mutual[%li,%li] = %f,%f\n", i,i+1, mutual[i], mutual[i+1]);
00307 if( mutual[i+1]>mutual[i] ){
00308 tau = i;
00309 break;
00310 }
00311 }
00312
00313
00314
00315 free( h1 );
00316 free( h11 );
00317 for( i=0; i<partitions; i++ )
00318 free( h2[i] );
00319 free( h2 );
00320 free( array );
00321 if( free_mutual )
00322 free( mutual );
00323
00324 return tau;
00325 }
00326
00327
00331 int tdelay_estimate_timelag_autocorr( TimeDelayReconstruction *p ){
00332 int tau=-1;
00333 int i,j;
00334 double Rxx;
00335 for( i=0; i<p->xn; i++ ){
00336 Rxx = 0.0;
00337 for( j=0; j<p->xn; j++ ){
00338 Rxx += p->x[j]*p->x[ABS(j-i)];
00339 }
00340 dprintf("Rxx(%i)=%f\n", i, Rxx);
00341 if( Rxx<=0 ){
00342 tau=i;
00343 break;
00344 }
00345 }
00346 if( tau<0 ){
00347 warnprintf("Sorry, have not been able to compute tau properly."
00348 "There was no zero crossing in the autocorrelation fucntion\n");
00349 }
00350 return tau;
00351 }
00352
00364 int tdelay_estimate_dimension_fnn( TimeDelayReconstruction *p, double Rtol, double Atol, int num_dim ){
00365 errprintf("Not implemented ?!?!?\n");
00366 return -1;
00367 }
00368
00386 double tdelay_fnn_ratio( TimeDelayReconstruction *p, double Rtol, double Atol ){
00387 int i, j;
00388 int i_nn=0;
00389 double d_nn;
00390 int nfnn;
00391 double ratio_fnn;
00392 double **d;
00393 double **X;
00394 TimeDelayReconstruction pnext;
00395 double Ra;
00396 double crit1,crit2;
00397
00398
00399 if( p->m <= 0){
00400 errprintf("p->m=%i is <=0", p->m);
00401 return -1;
00402 }
00403
00404 Ra = tdelay_attractor_size( p );
00405 dprintf( "Ra=%f\n", Ra);
00406
00407 X = dblpp_init( p->xn, p->m );
00408 for( i=0; i<p->xn; i++ ){
00409 tdelay_index_i( p, i, X[i] );
00410 }
00411 d = vectordist_distmatrix( vectordist_euclidean, (const double**)X, p->xn, p->m, ALLOC_IN_FCT, NULL, NULL );
00412 dprintf( "dmin,dmax=%f,%f\n",
00413 dblpp_min((const double**)d,p->xn,p->xn,NULL,NULL),
00414 dblpp_max((const double**)d,p->xn,p->xn,NULL,NULL) );
00415
00416
00417
00418 nfnn = 0;
00419
00420 pnext.m = p->m+1;
00421 pnext.tau=p->tau;
00422 pnext.x = p->x;
00423 pnext.xn = p->xn;
00424
00425 for( i=0; i<p->xn; i++ ){
00426 d_nn = DBL_MAX;
00427 for( j=0; j<p->xn; j++ ){
00428 if( i==j ) continue;
00429 if( d[i][j]<d_nn ){
00430 d_nn = d[i][j];
00431 i_nn = j;
00432 }
00433 }
00434 dprintf( "d_nn = %f, i_nn = %i\n", d_nn, i_nn );
00435
00436
00437 crit1 = (ABS( tdelay_index_ij(&pnext, i, p->m) - tdelay_index_ij(&pnext, i_nn, p->m) )/d_nn);
00438 dprintf( "crit1=%f, Rtol=%f\n", crit1, Rtol );
00439 if( crit1 > Rtol ){
00440 dprintf(" Crit 1 for %i failed\n", i);
00441 nfnn++;
00442 continue;
00443 }
00444
00445
00446 crit2 = sqrt( SQR( d_nn ) +
00447 SQR( tdelay_index_ij(&pnext, i, p->m) -
00448 tdelay_index_ij(&pnext, i_nn, p->m) ) )/Ra;
00449 dprintf( "crit2=%f, Rtol=%f\n", crit2, Rtol );
00450
00451 if( crit2 > Atol ){
00452 dprintf(" Crit 2 for %i failed\n", i);
00453 nfnn++;
00454 continue;
00455 }
00456 }
00457 ratio_fnn = nfnn/(double)p->xn*100.0;
00458 dprintf(" nfnn=%i, ratio=%f\n", nfnn, ratio_fnn );
00459
00460 dblpp_free( X, p->xn );
00461 dblpp_free( d, p->xn );
00462
00463 return ratio_fnn;
00464 }
00465
00475 double tdelay_attractor_size( TimeDelayReconstruction *p ){
00476 double R=0.0;
00477 double mean=0.0;
00478 int i;
00479
00480 for( i=0; i<p->xn; i++ ){
00481 mean += p->x[i];
00482 }
00483 mean /= (double)p->xn;
00484
00485 for( i=0; i<p->xn; i++ ){
00486 R += SQR ( p->x[i] - mean );
00487 }
00488 R /= (double)p->xn;
00489
00490 return sqrt( R );
00491 }
00492
00500 double tdelay_index_ij( TimeDelayReconstruction *p, int i, int j ){
00501 int idx;
00502
00503 if( i<0 || i>p->xn || j<0 || j>=p->m ){
00504 errprintf("i=%i, p->xn=%i\n, j=%i, p->m=%i\n", i, p->xn, j, p->m);
00505 return 0;
00506 }
00507 idx = i - (((p->m) - (j+1)) * (p->tau));
00508 if( idx<0 ){
00509 idx = (p->xn)+idx;
00510 }
00511
00512 return(p->x[idx]);
00513 }
00514
00523 void tdelay_index_i( TimeDelayReconstruction *p, int i, double *x){
00524 int idx, j;
00525
00526 if( i<0 || i>p->xn ){
00527 errprintf("i=%i, p->xn=%i\n", i, p->xn);
00528 return;
00529 }
00530 for( j=0; j<p->m; j++ ){
00531 idx = i - (((p->m) - (j+1)) * (p->tau));
00532 if( idx<0 ){
00533 idx = (p->xn)+idx;
00534 }
00535 x[j] = p->x[idx];
00536 }
00537 }
00546 void tdelay_index_j( TimeDelayReconstruction *p, int j, double *x){
00547 int idx, i;
00548
00549 if( j<0 || j>=p->m ){
00550 errprintf("j=%i, p->m=%i\n", j, p->m);
00551 return;
00552 }
00553 for( i=0; i<p->xn; i++ ){
00554 idx = i - (((p->m) - (j+1)) * (p->tau));
00555 if( idx<0 ){
00556 idx = (p->xn)+idx;
00557 }
00558 x[i] = p->x[idx];
00559 }
00560 }
00561
00562 TimeDelayReconstruction* tdelay_init( int m, int tau, double *x, int n ){
00563 TimeDelayReconstruction *p;
00564 p = (TimeDelayReconstruction*)malloc(sizeof(TimeDelayReconstruction));
00565 p->m = m;
00566 p->tau = tau;
00567 p->x = x;
00568 p->xn= n;
00569 return p;
00570 }
00571
00572 void tdelay_free( TimeDelayReconstruction *p ){
00573 free(p);
00574 }
00575
00576 void tdelay_print( FILE *out, TimeDelayReconstruction *p){
00577 fprintf( out, "TimeDelayReconstruction '%p':\n"
00578 " m = %i\n"
00579 " tau = %i\n"
00580 " x = %p\n"
00581 " xn = %i\n", p, p->m, p->tau, p->x, p->xn );
00582 }