00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
00126
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
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
00153
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;
00161
00162
00163 Tsub->val = idx[0];
00164 Tsub->left = NULL;
00165 Tsub->right = NULL;
00166 trials_left--;
00167 }
00168
00169 memcpy( avg->data, array_INDEXMEM3( d, idx[0], 0, 0 ),
00170 C*n*sizeof( double ) );
00171
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 );
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
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 );
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
00311
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
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;
00350
00351
00352 Tsub->val = idx[0];
00353 Tsub->left = NULL;
00354 Tsub->right = NULL;
00355 trials_left--;
00356 }
00357
00358 avg = d[idx[0]];
00359
00360
00361 free( d );
00362 free( indices );
00363
00364 return avg;
00365 }
00366
00367 #endif