• API Main Page
  • Documentation
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

src/nonlinear.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2008/2009 by Matthias Ihrke   *
00003  *   mihrke@uni-goettingen.de   *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
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; /* compare to sample */
00098   double dist; 
00099 
00100   s = dblp_init( NULL, p->m, 0.0 );
00101   for( nfound=0; nfound==0; epsilon*=1.2 ){ /* increase epsilon if no matching point is found */
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   /* optarg parsing */
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   /* output allocation */
00201   if( !output ){
00202      output = dblpp_init( eeg->ntrials, eeg->ntrials );
00203   }
00204 
00205   /* calculation */
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      /* fill phase-space with data */
00214      reference->x = eeg->data[channel][i];  
00215      if( progress ) progress( PROGRESSBAR_CONTINUE_LONG, i );
00216      for( j=0; j<eeg->ntrials; j++ ){ /* not symmetric */
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   /* rescaling data */
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   //  dblp_min( mutual, corrlength+1, &tau );
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;                             /* index nearest_neighbour */
00389   double d_nn;                        /* dist nn */
00390   int nfnn;                           /* number of false nearest neighbours */
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   /* create distance matrix between points in phase-space */
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   /* for each column, find minimum entry in d -> nearest neighbour;
00416       for this neighbour, determine if it is a false one, or not 
00417   */
00418   nfnn = 0;
00419   /* go up one dimension */
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      /* crit (1) */
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      /* crit (2) */
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   /* dprintf("idx=%i\n", idx); */
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 }

Generated on Fri Jun 25 2010 14:10:20 for libeegtools by  doxygen 1.7.0