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

src/averaging.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2008 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 
00024 #include "averaging.h"
00025 #include "clustering.h"
00026 #include "eeg.h"
00027 #include "linalg.h"
00028 
00040 Array* average_example( const Array *data, uint idx[2], double weights[2], OptArgList *optargs ){
00041   int i,j;
00042   if( data->ndim!=3 || data->dtype!=DOUBLE ){
00043      errprintf("data must be 3D and DOUBLE, have %i, %i\n", data->ndim, data->dtype );
00044      return NULL;
00045   } 
00046   int N,C,n;
00047   N = data->size[0];
00048   C = data->size[1];
00049   n = data->size[2];
00050   Array *avg = array_new2( DOUBLE, 2, C, n );
00051   for( i=0; i<C; i++ ){
00052      for( j=0; j<n; j++ ){
00053         mat_IDX( avg, i, j )=
00054           (weights[0]*array_INDEX3( data, double, idx[0], i, j ))+
00055           (weights[1]*array_INDEX3( data, double, idx[1], i, j ));
00056      }
00057   }                                 
00058 
00059   return avg;
00060 }
00061 Array* average_warpmarkers( const Array *data, uint idx[2], double weights[2], OptArgList *optargs ){
00062 }
00063 
00092 Array* hierarchical_average( const Array *data, const Array *distmat, 
00093                                       SignalAverageFunction avgfct, OptArgList *optargs ){
00094   Dendrogram *T, *Tsub; 
00095   ProgressBarFunction progress=NULL;  
00096   LinkageFunction linkage=dgram_dist_completelinkage;
00097   void *ptr;
00098 
00099   bool ismatrix;
00100   matrix_CHECKSQR( ismatrix, distmat );
00101   if( !ismatrix ) return NULL;
00102   if( data->ndim>3 || data->ndim<2 || data->dtype!=DOUBLE ){
00103      errprintf( "Data needs to be 2D or 3D, got %iD and of type DOUBLE\n", data->ndim );
00104      return NULL;
00105   }
00106 
00107   optarg_PARSE_PTR( optargs, "linkage", linkage, LinkageFunction, ptr );
00108   optarg_PARSE_PTR( optargs, "progress", progress, ProgressBarFunction, ptr );
00109 
00110   int N,C,n;
00111   N = data->size[0];
00112   C = (data->ndim==2)?1:(data->size[1]);
00113   n = (data->ndim==2)?(data->size[1]):(data->size[2]);
00114   dprintf("Data is (%i x %i x %i)\n", N, C, n );
00115 
00116   /* wrapper for 2D-data -> work on d instead of data */
00117   Array *d=array_copy( data, TRUE );
00118   if( d->ndim==2 ){
00119      d->ndim=3;
00120      free( d->size );
00121      d->size=(uint*)malloc( 3*sizeof(uint) );
00122      d->size[0]=N; d->size[1]=C; d->size[2]=n;
00123   }
00124 
00125   /*------------------- computation --------------------------*/
00126   /* build hierarchical dendrogram */
00127   T = agglomerative_clustering( distmat, linkage );
00128 
00129   int i;
00130   double weights[2];
00131   int *indices = (int*)malloc( N*sizeof(int) );
00132   for( i=0; i<N; i++ ){
00133      indices[i] = 1;
00134   }  
00135 
00136   /* now walk the tree to find pairs of trials to match */
00137   Array *new, 
00138      *avg=array_new2( DOUBLE, 2, C, n );
00139   int trials_left = N;
00140   uint idx[2]={0,0};
00141   if( progress ) progress( PROGRESSBAR_INIT, N );
00142 
00143   while( trials_left >= 2 ){
00144      if( progress ) progress( PROGRESSBAR_CONTINUE_LONG, N-trials_left );
00145      
00146      Tsub = dgram_get_deepest( T );
00147      idx[0] = Tsub->left->val;
00148      idx[1] = Tsub->right->val;
00149      
00150      weights[0] = indices[idx[0]]/(double)(indices[idx[0]]+indices[idx[1]]);
00151      weights[1] = indices[idx[1]]/(double)(indices[idx[0]]+indices[idx[1]]);
00152      /* Array* average_example( const AADTWrray *data, uint idx[2], 
00153                double weights[2], OptArgList *optargs ) */
00154      new=avgfct( d, idx, weights, optargs );
00155      memcpy( array_INDEXMEM3( d, idx[0], 0, 0 ),
00156                 new->data, C*n*sizeof( double ) );
00157      array_free( new );
00158 
00159      indices[idx[0]] += indices[idx[1]];
00160      indices[idx[1]]=-1;              /* never to be used again */
00161      
00162      /* replace node by leaf representing average(idx1, idx2) */
00163      Tsub->val = idx[0];
00164      Tsub->left = NULL;
00165      Tsub->right = NULL;    
00166      trials_left--;
00167   }
00168   /* idx[0] is the final average */
00169   memcpy( avg->data, array_INDEXMEM3( d, idx[0], 0, 0 ),
00170              C*n*sizeof( double ) );
00171   /*------------------- /computation --------------------------*/
00172 
00173   free( indices );
00174   array_free( d );
00175 
00176   array_dimred( avg );
00177   return avg;
00178 }
00179 
00180 
00181 
00189 EEG*     eeg_simple_average( const EEG *eeg ){
00190 #ifdef FIXEEG
00191   EEG *out;
00192   int c;
00193 
00194   out = eeg_init( eeg->nbchan, 1, eeg->n ); /* the average */
00195   out->sampling_rate=eeg->sampling_rate;
00196   if( eeg->times ){
00197      out->times = (double*) malloc( eeg->n*sizeof(double) );
00198      memcpy( out->times, eeg->times, eeg->n*sizeof(double) );
00199   }
00200   if( eeg->chaninfo ){
00201      out->chaninfo = (ChannelInfo*) malloc( eeg->nbchan*sizeof(ChannelInfo) );
00202      memcpy( out->chaninfo, eeg->chaninfo,  eeg->nbchan*sizeof(ChannelInfo) );
00203   }
00204   eeg_append_comment( out, "output from eegtrials_simple_average()\n" );
00205   for( c=0; c<eeg->nbchan; c++ ){
00206      /* TODO */
00207   }
00208   return out;
00209 #endif
00210 }
00211 
00212 
00213 #ifdef EXPERIMENTAL
00214 
00222 EEG*     eeg_average_channels( const EEG *eeg ){
00223 #ifdef FIXEEG
00224 
00225   EEG *out;
00226   int c, i, j;
00227 
00228   out = eeg_init( 1, eeg->ntrials, eeg->n ); /* the average */
00229   out->sampling_rate=eeg->sampling_rate;
00230   if( eeg->times ){
00231      out->times = (double*) malloc( eeg->n*sizeof(double) );
00232      memcpy( out->times, eeg->times, eeg->n*sizeof(double) );
00233   }
00234   eeg_append_comment( out, "output from eegtrials_average_channels()\n" );
00235 
00236   for( i=0; i<eeg->ntrials; i++ ){
00237      for( j=0; j<eeg->n; j++ ){
00238         out->data[0][i][j] = 0;
00239         for( c=0; c<eeg->nbchan; c++ ){
00240           out->data[0][i][j] += eeg->data[c][i][j];
00241         }
00242         out->data[0][i][j] /= (double)eeg->nbchan;
00243      }
00244   }
00245   return out;
00246 #endif
00247 }
00248 
00257 Array* average_unequal_warp( Array **data, uint idx[2], double weights[2], OptArgList *optargs ){
00258   int i,j;
00259 
00260   int N,C,n;
00261   C = data[idx[0]]->size[1];
00262   Array *a=data[idx[0]];
00263   Array *b=data[idx[1]];
00264 
00265   Array *d = distmatrix_signaldist( vectordist_euclidean, 
00266                                                 a, b, NULL, NULL );
00267 
00268   OptArgList *opts=optarglist( "slope_constraint=int", SLOPE_CONSTRAINT_NONE );
00269   Array *m1 = matrix_dtw_cumulate( d, TRUE, opts );
00270   optarglist_free( opts );
00271 
00272   Array *p = matrix_dtw_backtrack( m1 );
00273   
00274   opts =  optarglist( "weights=double*", weights);
00275   Array *avg = dtw_add_signals( a, b, C, opts);
00276   optarglist_free( opts );
00277 
00278   array_free( d );
00279   array_free( m1 );
00280   array_free( p );
00281 
00282   return avg;
00283 }
00286 Array* hierarchical_average_unequal_length( Array **data, const Array *distmat, 
00287                                                           SignalAverageFunctionUnequalLength avgfct, 
00288                                                           OptArgList *optargs ){
00289   Dendrogram *T, *Tsub; 
00290   ProgressBarFunction progress=NULL;  
00291   LinkageFunction linkage=dgram_dist_completelinkage;
00292   void *ptr;
00293 
00294   bool ismatrix;
00295   matrix_CHECKSQR( ismatrix, distmat );
00296   if( !ismatrix ) return NULL;
00297 
00298 
00299   optarg_PARSE_PTR( optargs, "linkage", linkage, LinkageFunction, ptr );
00300   optarg_PARSE_PTR( optargs, "progress", progress, ProgressBarFunction, ptr );
00301 
00302   int N,C;
00303   N = distmat->size[0];
00304   C = data[0]->size[1];
00305 
00308   dprintf("Data is (%i x %i)\n", N, C );
00309 
00310   /*------------------- computation --------------------------*/
00311   /* build hierarchical dendrogram */
00312   T = agglomerative_clustering( distmat, linkage );
00313 
00314   int i;
00315   double weights[2];
00316   int *indices = (int*)malloc( N*sizeof(int) );
00317   for( i=0; i<N; i++ ){
00318      indices[i] = 1;
00319   }  
00320 
00321   /* now walk the tree to find pairs of trials to match */
00322   Array *new, *avg;
00323   int trials_left = N;
00324   uint idx[2]={0,0};
00325   if( progress ) progress( PROGRESSBAR_INIT, N );
00326 
00327 
00328   Array **d = (Array*)malloc( N*sizeof(Array*) );
00329   for( i=0; i<N; i++ ){
00330      d[i] = data[i];
00331   }
00332 
00333   while( trials_left >= 2 ){
00334      if( progress ) progress( PROGRESSBAR_CONTINUE_LONG, N-trials_left );
00335      
00336      Tsub = dgram_get_deepest( T );
00337      idx[0] = Tsub->left->val;
00338      idx[1] = Tsub->right->val;
00339      
00340      weights[0] = indices[idx[0]]/(double)(indices[idx[0]]+indices[idx[1]]);
00341      weights[1] = indices[idx[1]]/(double)(indices[idx[0]]+indices[idx[1]]);
00342 
00343      new=avgfct( d, idx, weights, optargs );
00344      
00345      d[idx[0]]=new;
00346      d[idx[1]]=NULL;
00347 
00348      indices[idx[0]] += indices[idx[1]];
00349      indices[idx[1]]=-1;              /* never to be used again */
00350      
00351      /* replace node by leaf representing average(idx1, idx2) */
00352      Tsub->val = idx[0];
00353      Tsub->left = NULL;
00354      Tsub->right = NULL;    
00355      trials_left--;
00356   }
00357   /* idx[0] is the final average */
00358   avg = d[idx[0]];
00359   /*------------------- /computation --------------------------*/
00360 
00361   free( d );
00362   free( indices );
00363 
00364   return avg;
00365 }
00366 
00367 #endif

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