Пример #1
0
LOCAL void harmonic_time(struct dipole_desc *dipole) {
    int half_envelope_length=(int)rint((M_PI*MAX_ENVELOPE_CYCLES)/dipole->time[1]);

    if (dipole->time[2]-- >0) return;
    if (dipole->time[3]== -1) {
        /*{{{  Envelope processed: Initiate new wait state*/
        dipole->time[0]=2*M_PI*((double)rand())/RAND_MAX;
        dipole->time[2]=(int)(half_envelope_length*((double)rand())/RAND_MAX);
        dipole->time[4]=(int)(half_envelope_length*((double)rand())/RAND_MAX)+1; /* Avoid zero envelope */
        dipole->time[3]=2*dipole->time[4];
        array_setto_null(&dipole->dip_moment);
        return;
        /*}}}  */
    }
    if (dipole->time[2]== -1) array_setreadwrite(&dipole->dip_moment);
    array_copy(&dipole->initial_moment, &dipole->dip_moment);
    array_scale(&dipole->dip_moment, sin(dipole->time[0])*(1.0-square((dipole->time[3]-dipole->time[4])/dipole->time[4])));
    dipole->time[0]+=dipole->time[1];	/* time[1] is the frequency */
    dipole->time[3]--;
}
Пример #2
0
/*{{{  scale_by(transform_info_ptr tinfo)*/
METHODDEF DATATYPE *
scale_by(transform_info_ptr tinfo) {
 struct scale_by_storage *local_arg=(struct scale_by_storage *)tinfo->methods->local_storage;
 DATATYPE factor;
 int itempart;
 array indata;

 tinfo_array(tinfo, &indata);
 switch (local_arg->type) {
  /* Operations which are done on maps */
  case SCALE_BY_XDATA:
  case SCALE_BY_INVXDATA:
   if (tinfo->xdata==NULL) create_xaxis(tinfo, NULL);
  case SCALE_BY_NORMALIZE:
  case SCALE_BY_INVNORM:
  case SCALE_BY_INVSQUARENORM:
  case SCALE_BY_INVSUM:
  case SCALE_BY_INVMAX:
  case SCALE_BY_INVMAXABS:
  case SCALE_BY_INVQUANTILE:
   array_transpose(&indata);	/* Vectors are maps */
   if (local_arg->have_channel_list) {
    ERREXIT(tinfo->emethods, "scale_by: Channel subsets are not supported for map operations.\n");
   }
   break;

  /* Operations which are done on channels */
  case SCALE_BY_INVPOINTNORM:
  case SCALE_BY_INVPOINTSQUARENORM:
  case SCALE_BY_INVPOINTSUM:
  case SCALE_BY_INVPOINTMAX:
  case SCALE_BY_INVPOINTMAXABS:
  case SCALE_BY_INVPOINTQUANTILE:
  case SCALE_BY_FACTOR:
   break;

  /* Operations which involve a special but constant factor */
  case SCALE_BY_PI:
   local_arg->factor= M_PI;
   break;
  case SCALE_BY_INVPI:
   local_arg->factor= 1.0/M_PI;
   break;
  case SCALE_BY_SFREQ:
   local_arg->factor= tinfo->sfreq;
   break;
  case SCALE_BY_INVSFREQ:
   local_arg->factor= 1.0/tinfo->sfreq;
   break;
  case SCALE_BY_NR_OF_POINTS:
   local_arg->factor= (tinfo->data_type==FREQ_DATA ? tinfo->nroffreq : tinfo->nr_of_points);
   break;
  case SCALE_BY_INVNR_OF_POINTS:
   local_arg->factor= 1.0/(tinfo->data_type==FREQ_DATA ? tinfo->nroffreq : tinfo->nr_of_points);
   break;
  case SCALE_BY_NR_OF_CHANNELS:
   local_arg->factor= tinfo->nr_of_channels;
   break;
  case SCALE_BY_INVNR_OF_CHANNELS:
   local_arg->factor= 1.0/tinfo->nr_of_channels;
   break;
  case SCALE_BY_NROFAVERAGES:
   local_arg->factor= tinfo->nrofaverages;
   break;
  case SCALE_BY_INVNROFAVERAGES:
   local_arg->factor= 1.0/tinfo->nrofaverages;
   break;
  case SCALE_BY_SQRTNROFAVERAGES:
   local_arg->factor= sqrt(tinfo->nrofaverages);
   break;
  case SCALE_BY_INVSQRTNROFAVERAGES:
   local_arg->factor= 1.0/sqrt(tinfo->nrofaverages);
   break;
 }

 for (itempart=local_arg->fromitem; itempart<=local_arg->toitem; itempart++) {
  array_use_item(&indata, itempart);
  do {
   if (local_arg->have_channel_list && !is_in_channellist(indata.current_vector+1, local_arg->channel_list)) {
    array_nextvector(&indata);
    continue;
   }
   switch (local_arg->type) {
    case SCALE_BY_NORMALIZE:
    case SCALE_BY_INVNORM:
    case SCALE_BY_INVPOINTNORM:
     factor=array_abs(&indata);
     if (factor==0.0) factor=1.0;
     factor=1.0/factor;
     array_previousvector(&indata);
     break;
    case SCALE_BY_INVSQUARENORM:
    case SCALE_BY_INVPOINTSQUARENORM:
     factor=array_square(&indata);
     if (factor==0.0) factor=1.0;
     factor=1.0/factor;
     array_previousvector(&indata);
     break;
    case SCALE_BY_INVSUM:
    case SCALE_BY_INVPOINTSUM:
     factor=array_sum(&indata);
     if (factor==0.0) factor=1.0;
     factor=1.0/factor;
     array_previousvector(&indata);
     break;
    case SCALE_BY_INVMAX:
    case SCALE_BY_INVPOINTMAX:
     factor=array_max(&indata);
     if (factor==0.0) factor=1.0;
     factor=1.0/factor;
     array_previousvector(&indata);
     break;
    case SCALE_BY_INVMAXABS:
    case SCALE_BY_INVPOINTMAXABS: {
     DATATYPE amax=fabs(array_scan(&indata)), hold;
     while (indata.message==ARRAY_CONTINUE) {
      hold=fabs(array_scan(&indata));
      if (hold>amax) amax=hold;
     }
     factor=amax;
     }
     if (factor==0.0) factor=1.0;
     factor=1.0/factor;
     array_previousvector(&indata);
     break;
    case SCALE_BY_INVQUANTILE:
    case SCALE_BY_INVPOINTQUANTILE:
     factor=array_quantile(&indata,local_arg->factor);
     if (factor==0.0) factor=1.0;
     factor=1.0/factor;
     break;
    case SCALE_BY_XDATA:
     factor=tinfo->xdata[indata.current_vector];
     break;
    case SCALE_BY_INVXDATA:
     factor=1.0/tinfo->xdata[indata.current_vector];
     break;
    case SCALE_BY_PI:
    case SCALE_BY_INVPI:
    case SCALE_BY_SFREQ:
    case SCALE_BY_INVSFREQ:
    case SCALE_BY_NR_OF_POINTS:
    case SCALE_BY_INVNR_OF_POINTS:
    case SCALE_BY_NR_OF_CHANNELS:
    case SCALE_BY_INVNR_OF_CHANNELS:
    case SCALE_BY_NROFAVERAGES:
    case SCALE_BY_INVNROFAVERAGES:
    case SCALE_BY_SQRTNROFAVERAGES:
    case SCALE_BY_INVSQRTNROFAVERAGES:
    case SCALE_BY_FACTOR:
     factor=local_arg->factor;
     break;
    default:
     continue;
   }
   array_scale(&indata, factor);
  } while (indata.message!=ARRAY_ENDOFSCAN);
 }

 return tinfo->tsdata;
}
Пример #3
0
/** \brief Principal Components analysis.

	 \ingroup grplinalg

	 This implementation uses SVD to calculate the PCA.
	 Example:
	 \code
	 Array *X = get_data_from_somewhere();
	 Array *var, *X_pca;
	 matrix_pca( X, &var, FALSE ); // overwrite X
	 X_pca = matrix_pca( X, &var, TRUE ); // do not touch X
	 \endcode
	 \param X a 2D array observations x variables containing the data
	 \param var output: vector of eigenvalues of XX^T in decreasing order; if you
 	         pass NULL, it is ignored; 
	 \param alloc if true, new memory is allocated and returned. Else
	            X is overwritten.
	 \return pointer to the PCA'd matrix 
*/
Array* matrix_pca( Array *X, Array **var, bool alloc ){
  Array *out=NULL;
  int i,j;
  bool ismatrix;
  matrix_CHECK( ismatrix, X );
  if( !ismatrix ) return NULL;

  int N,K; /* N observations, K variables */
  N = X->size[0];
  K = X->size[1];

  Array *tmp = array_copy( X, TRUE );

  /* subtract mean from observations */
  Array *mean=matrix_mean( X, 0 ); 
  for( i=0; i<N; i++ ){ 
	 for( j=0; j<K; j++ ){
		array_INDEX2( tmp, double, i, j ) -=
		  array_INDEX1( mean, double, j );
	 }
  }

  array_scale( tmp, 1.0/sqrt((double) N-1 ) );

  gsl_matrix *A=matrix_to_gsl( tmp, TRUE ); /* copy */
  gsl_matrix *V=gsl_matrix_alloc( K, K );
  gsl_vector *S=gsl_vector_alloc( K );
  gsl_vector *workspace=gsl_vector_alloc( K );

  /* A->U, V->V, S->S */
  gsl_linalg_SV_decomp( A, V, S, workspace);
  gsl_matrix_transpose( V );

  if( var ){
	 (*var)=array_fromptr2( DOUBLE, 1, S->data, S->size );
	 S->owner=0; /* transfer ownership to array */
	 (*var)->free_data=1;
	 for( i=0; i<array_NUMEL( *var ); i++ ){ 
		array_INDEX1( *var, double, i ) = SQR( array_INDEX1( *var, double, i ) );
	 }
  }

  Array *Vp=array_fromptr2( DOUBLE, 2, V->data, V->size1, V->size2 );
  matrix_transpose( tmp, FALSE );
  out=matrix_mult( Vp, tmp ); /* PCA'd data */
  matrix_transpose( out, FALSE );

  if( out->size[0]!=X->size[0] || out->size[1]!=X->size[1] ){
	 errprintf("Input/Output dimension mismatch: (%i,%i) vs. (%i,%i)\n",
				  X->size[0], X->size[1], out->size[0], out->size[1] );
  }

  if( !alloc ){ /* write back out->X */
	 memcpy( X->data, out->data, out->nbytes );
	 array_free( out );
	 out = X;
  }

  /* clean up */
  gsl_matrix_free( A );
  gsl_matrix_free( V );
  gsl_vector_free( S );
  gsl_vector_free( workspace );
  array_free( mean );
  array_free( Vp );
  array_free( tmp );

  return out;
}
Пример #4
0
/* Same as test_ergun, but for multi-dimensional transforms: */
void testnd_ergun(int rank, int *n, fftw_direction dir, fftwnd_plan plan)
{
     fftw_complex *inA, *inB, *inC, *outA, *outB, *outC;
     fftw_complex *tmp;
     fftw_complex impulse;

     int N, n_before, n_after, dim;
     int i, which_impulse;
     int rounds = 20;
     FFTW_TRIG_REAL twopin;

     N = 1;
     for (dim = 0; dim < rank; ++dim)
	  N *= n[dim];

     inA = (fftw_complex *) fftw_malloc(N * sizeof(fftw_complex));
     inB = (fftw_complex *) fftw_malloc(N * sizeof(fftw_complex));
     inC = (fftw_complex *) fftw_malloc(N * sizeof(fftw_complex));
     outA = (fftw_complex *) fftw_malloc(N * sizeof(fftw_complex));
     outB = (fftw_complex *) fftw_malloc(N * sizeof(fftw_complex));
     outC = (fftw_complex *) fftw_malloc(N * sizeof(fftw_complex));
     tmp = (fftw_complex *) fftw_malloc(N * sizeof(fftw_complex));

     WHEN_VERBOSE(2,
		  printf("Validating plan, N = %d, dir = %s\n", N,
			 dir == FFTW_FORWARD ? "FORWARD" : "BACKWARD"));

     /* test 1: check linearity */
     for (i = 0; i < rounds; ++i) {
	  fftw_complex alpha, beta;
	  c_re(alpha) = DRAND();
	  c_im(alpha) = DRAND();
	  c_re(beta) = DRAND();
	  c_im(beta) = DRAND();
	  fill_random(inA, N);
	  fill_random(inB, N);
	  fftwnd(plan, 1, inA, 1, N, outA, 1, N);
	  fftwnd(plan, 1, inB, 1, N, outB, 1, N);
	  array_scale(outA, alpha, N);
	  array_scale(outB, beta, N);
	  array_add(tmp, outA, outB, N);
	  array_scale(inA, alpha, N);
	  array_scale(inB, beta, N);
	  array_add(inC, inA, inB, N);
	  fftwnd(plan, 1, inC, 1, N, outC, 1, N);
	  array_compare(outC, tmp, N);
     }

     /*
      * test 2: check that the unit impulse is transformed properly -- we
      * need to test both the real and imaginary impulses 
      */

     for (which_impulse = 0; which_impulse < 2; ++which_impulse) {
	  if (which_impulse == 0) {	/* real impulse */
	       c_re(impulse) = 1.0;
	       c_im(impulse) = 0.0;
	  } else {		/* imaginary impulse */
	       c_re(impulse) = 0.0;
	       c_im(impulse) = 1.0;
	  }

	  for (i = 0; i < N; ++i) {
	       /* impulse */
	       c_re(inA[i]) = 0.0;
	       c_im(inA[i]) = 0.0;

	       /* transform of the impulse */
	       outA[i] = impulse;
	  }
	  inA[0] = impulse;

	  for (i = 0; i < rounds; ++i) {
	       fill_random(inB, N);
	       array_sub(inC, inA, inB, N);
	       fftwnd(plan, 1, inB, 1, N, outB, 1, N);
	       fftwnd(plan, 1, inC, 1, N, outC, 1, N);
	       array_add(tmp, outB, outC, N);
	       array_compare(tmp, outA, N);
	  }
     }

     /* test 3: check the time-shift property */
     /* the paper performs more tests, but this code should be fine too */
     /* -- we have to check shifts in each dimension */

     n_before = 1;
     n_after = N;
     for (dim = 0; dim < rank; ++dim) {
	  int n_cur = n[dim];

	  n_after /= n_cur;
	  twopin = FFTW_K2PI / (FFTW_TRIG_REAL) n_cur;

	  for (i = 0; i < rounds; ++i) {
	       int j, jb, ja;

	       fill_random(inA, N);
	       array_rol(inB, inA, n_cur, n_before, n_after);
	       fftwnd(plan, 1, inA, 1, N, outA, 1, N);
	       fftwnd(plan, 1, inB, 1, N, outB, 1, N);

	       for (jb = 0; jb < n_before; ++jb)
		    for (j = 0; j < n_cur; ++j) {
			 FFTW_TRIG_REAL s = dir * FFTW_TRIG_SIN(j * twopin);
			 FFTW_TRIG_REAL c = FFTW_TRIG_COS(j * twopin);

			 for (ja = 0; ja < n_after; ++ja) {
			      c_re(tmp[(jb * n_cur + j) * n_after + ja]) =
				  c_re(outB[(jb * n_cur + j) * n_after + ja]) * c
				  - c_im(outB[(jb * n_cur + j) * n_after + ja]) * s;
			      c_im(tmp[(jb * n_cur + j) * n_after + ja]) =
				  c_re(outB[(jb * n_cur + j) * n_after + ja]) * s
				  + c_im(outB[(jb * n_cur + j) * n_after + ja]) * c;
			 }
		    }

	       array_compare(tmp, outA, N);
	  }

	  n_before *= n_cur;
     }

     WHEN_VERBOSE(2, printf("Validation done\n"));

     fftw_free(tmp);
     fftw_free(outC);
     fftw_free(outB);
     fftw_free(outA);
     fftw_free(inC);
     fftw_free(inB);
     fftw_free(inA);
}
Пример #5
0
/*
 * Implementation of the FFT tester described in
 *
 * Funda Ergün. Testing multivariate linear functions: Overcoming the
 * generator bottleneck. In Proceedings of the Twenty-Seventh Annual
 * ACM Symposium on the Theory of Computing, pages 407-416, Las Vegas,
 * Nevada, 29 May--1 June 1995.
 */
void test_ergun(int n, fftw_direction dir, fftw_plan plan)
{
     fftw_complex *inA, *inB, *inC, *outA, *outB, *outC;
     fftw_complex *tmp;
     fftw_complex impulse;
     int i;
     int rounds = 20;
     FFTW_TRIG_REAL twopin = FFTW_K2PI / (FFTW_TRIG_REAL) n;

     inA = (fftw_complex *) fftw_malloc(n * sizeof(fftw_complex));
     inB = (fftw_complex *) fftw_malloc(n * sizeof(fftw_complex));
     inC = (fftw_complex *) fftw_malloc(n * sizeof(fftw_complex));
     outA = (fftw_complex *) fftw_malloc(n * sizeof(fftw_complex));
     outB = (fftw_complex *) fftw_malloc(n * sizeof(fftw_complex));
     outC = (fftw_complex *) fftw_malloc(n * sizeof(fftw_complex));
     tmp = (fftw_complex *) fftw_malloc(n * sizeof(fftw_complex));

     WHEN_VERBOSE(2,
		  printf("Validating plan, n = %d, dir = %s\n", n,
			 dir == FFTW_FORWARD ? "FORWARD" : "BACKWARD"));

     /* test 1: check linearity */
     for (i = 0; i < rounds; ++i) {
	  fftw_complex alpha, beta;
	  c_re(alpha) = DRAND();
	  c_im(alpha) = DRAND();
	  c_re(beta) = DRAND();
	  c_im(beta) = DRAND();
	  fill_random(inA, n);
	  fill_random(inB, n);
	  fftw_out_of_place(plan, n, inA, outA);
	  fftw_out_of_place(plan, n, inB, outB);
	  array_scale(outA, alpha, n);
	  array_scale(outB, beta, n);
	  array_add(tmp, outA, outB, n);
	  array_scale(inA, alpha, n);
	  array_scale(inB, beta, n);
	  array_add(inC, inA, inB, n);
	  fftw_out_of_place(plan, n, inC, outC);
	  array_compare(outC, tmp, n);
     }

     /* test 2: check that the unit impulse is transformed properly */

     c_re(impulse) = 1.0;
     c_im(impulse) = 0.0;
     
     for (i = 0; i < n; ++i) {
	  /* impulse */
	  c_re(inA[i]) = 0.0;
	  c_im(inA[i]) = 0.0;
	  
	  /* transform of the impulse */
	  outA[i] = impulse;
     }
     inA[0] = impulse;
     
     for (i = 0; i < rounds; ++i) {
	  fill_random(inB, n);
	  array_sub(inC, inA, inB, n);
	  fftw_out_of_place(plan, n, inB, outB);
	  fftw_out_of_place(plan, n, inC, outC);
	  array_add(tmp, outB, outC, n);
	  array_compare(tmp, outA, n);
     }

     /* test 3: check the time-shift property */
     /* the paper performs more tests, but this code should be fine too */
     for (i = 0; i < rounds; ++i) {
	  int j;

	  fill_random(inA, n);
	  array_rol(inB, inA, n, 1, 1);
	  fftw_out_of_place(plan, n, inA, outA);
	  fftw_out_of_place(plan, n, inB, outB);
	  for (j = 0; j < n; ++j) {
	       FFTW_TRIG_REAL s = dir * FFTW_TRIG_SIN(j * twopin);
	       FFTW_TRIG_REAL c = FFTW_TRIG_COS(j * twopin);
	       c_re(tmp[j]) = c_re(outB[j]) * c - c_im(outB[j]) * s;
	       c_im(tmp[j]) = c_re(outB[j]) * s + c_im(outB[j]) * c;
	  }

	  array_compare(tmp, outA, n);
     }

     WHEN_VERBOSE(2, printf("Validation done\n"));

     fftw_free(tmp);
     fftw_free(outC);
     fftw_free(outB);
     fftw_free(outA);
     fftw_free(inC);
     fftw_free(inB);
     fftw_free(inA);
}
Пример #6
0
/*{{{  project_init(transform_info_ptr tinfo)*/
METHODDEF void
project_init(transform_info_ptr tinfo) {
 struct project_args_struct *project_args=(struct project_args_struct *)tinfo->methods->local_storage;
 transform_argument *args=tinfo->methods->arguments;
 transform_info_ptr side_tinfo= &project_args->side_tinfo;
 array *vectors= &project_args->vectors;
 growing_buf buf;
#define BUFFER_SIZE 80
 char buffer[BUFFER_SIZE];

 side_tinfo->methods= &project_args->methods;
 side_tinfo->emethods=tinfo->emethods;
 select_readasc(side_tinfo);
 growing_buf_init(&buf);
 growing_buf_allocate(&buf, 0);
 if (args[ARGS_FROMEPOCH].is_set) {
  snprintf(buffer, BUFFER_SIZE, "-f %ld ", args[ARGS_FROMEPOCH].arg.i);
  growing_buf_appendstring(&buf, buffer);
 }
 if (args[ARGS_EPOCHS].is_set) {
  project_args->epochs=args[ARGS_EPOCHS].arg.i;
  if (project_args->epochs<=0) {
   ERREXIT(tinfo->emethods, "project_init: The number of epochs must be positive.\n");
  }
 } else {
  project_args->epochs=1;
 }
 snprintf(buffer, BUFFER_SIZE, "-e %d ", project_args->epochs);
 growing_buf_appendstring(&buf, buffer);
 growing_buf_appendstring(&buf, args[ARGS_PROJECTFILE].arg.s);
 if (!buf.can_be_freed || !setup_method(side_tinfo, &buf)) {
  ERREXIT(tinfo->emethods, "project_init: Error setting readasc arguments.\n");
 }

 project_args->points=(args[ARGS_POINTS].is_set ? args[ARGS_POINTS].arg.i : 1);
 project_args->nr_of_item=(args[ARGS_NROFITEM].is_set ? args[ARGS_NROFITEM].arg.i : 0);
 project_args->orthogonalize_vectors_first=args[ARGS_ORTHOGONALIZE].is_set;
 if (args[ARGS_SUBSPACE].is_set) {
  project_args->project_mode=PROJECT_MODE_SSP;
 } else if (args[ARGS_SUBTRACT_SUBSPACE].is_set) {
  project_args->project_mode=PROJECT_MODE_SSPS;
 } else if (args[ARGS_MULTIPLY].is_set) {
  project_args->project_mode=PROJECT_MODE_MULTIPLY;
 } else {
  project_args->project_mode=PROJECT_MODE_SCALAR;
 }
 if (args[ARGS_CHANNELNAMES].is_set) {
  project_args->channel_list=expand_channel_list(tinfo, args[ARGS_CHANNELNAMES].arg.s);
  if (project_args->channel_list==NULL) {
   ERREXIT(tinfo->emethods, "project_init: Zero channels were selected by -N!\n");
  }
 } else {
  project_args->channel_list=NULL;
 }

 (*side_tinfo->methods->transform_init)(side_tinfo);

 /*{{{  Read first project_file epoch and allocate vectors array accordingly*/
 if ((side_tinfo->tsdata=(*side_tinfo->methods->transform)(side_tinfo))==NULL) {
  ERREXIT(tinfo->emethods, "project_init: Can't get the first project epoch.\n");
 }
 if (project_args->project_mode==PROJECT_MODE_MULTIPLY) {
  /* Save channel names and positions for later */
  project_args->save_side_tinfo.nr_of_channels=side_tinfo->nr_of_channels;
  copy_channelinfo(&project_args->save_side_tinfo, side_tinfo->channelnames, side_tinfo->probepos);
 }
 if (project_args->points==0) project_args->points=side_tinfo->nr_of_points;
 if (project_args->points>side_tinfo->nr_of_points) {
  ERREXIT1(tinfo->emethods, "project_init: There are only %d points in the project_file epoch.\n", MSGPARM(side_tinfo->nr_of_points));
 }
 if (args[ARGS_AT_XVALUE].is_set) {
  project_args->nr_of_point=find_pointnearx(side_tinfo, (DATATYPE)atof(args[ARGS_NROFPOINT].arg.s));
 } else {
 project_args->nr_of_point=gettimeslice(side_tinfo, args[ARGS_NROFPOINT].arg.s);
 }
 vectors->nr_of_vectors=project_args->epochs*project_args->points;
 vectors->nr_of_elements=side_tinfo->nr_of_channels;
 vectors->element_skip=1;
 if (array_allocate(vectors)==NULL) {
  ERREXIT(tinfo->emethods, "project_init: Error allocating vectors memory\n");
 }
 /*}}}  */

 do {
  /*{{{  Copy [points] vectors from project_file to vectors array*/
  array indata;
  int point;

  if (vectors->nr_of_elements!=side_tinfo->nr_of_channels) {
   ERREXIT(side_tinfo->emethods, "project_init: Varying channel numbers in project file!\n");
  }
  if (project_args->nr_of_point>=side_tinfo->nr_of_points) {
   ERREXIT2(side_tinfo->emethods, "project_init: nr_of_point=%d, nr_of_points=%d\n", MSGPARM(project_args->nr_of_point), MSGPARM(side_tinfo->nr_of_points));
  }
  if (project_args->nr_of_item>=side_tinfo->itemsize) {
   ERREXIT2(side_tinfo->emethods, "project_init: nr_of_item=%d, itemsize=%d\n", MSGPARM(project_args->nr_of_item), MSGPARM(side_tinfo->itemsize));
  }

  for (point=0; point<project_args->points; point++) {
   tinfo_array(side_tinfo, &indata);
   array_transpose(&indata);	/* Vector = map */
   if (vectors->nr_of_elements!=indata.nr_of_elements) {
    ERREXIT(side_tinfo->emethods, "project_init: vector size doesn't match\n");
   }
   indata.current_vector=project_args->nr_of_point+point;
   array_setto_vector(&indata);
   array_use_item(&indata, project_args->nr_of_item);
   array_copy(&indata, vectors);
  }
  /*}}}  */
  free_tinfo(side_tinfo);
 } while ((side_tinfo->tsdata=(*side_tinfo->methods->transform)(side_tinfo))!=NULL);

 if (vectors->message!=ARRAY_ENDOFSCAN) {
  ERREXIT1(tinfo->emethods, "project_init: Less than %d epochs in project file\n", MSGPARM(vectors->nr_of_vectors));
 }
 
 /*{{{  Set unused channels to zero if requested*/
 if (args[ARGS_ZERO_UNUSEDCOEFFICIENTS].is_set) {
  if (project_args->channel_list!=NULL) {
   do {
    do {
     if (is_in_channellist(vectors->current_element+1, project_args->channel_list)) {
      array_advance(vectors);
     } else {
      array_write(vectors, 0.0);
     }
    } while (vectors->message==ARRAY_CONTINUE);
   } while (vectors->message!=ARRAY_ENDOFSCAN);
  } else {
   ERREXIT(tinfo->emethods, "project_init: Option -z only makes sense in combination with -N!\n");
  }
 }
 /*}}}  */
 /*{{{  De-mean vectors if requested*/
 if (args[ARGS_CORRELATION].is_set) {
  do {
   DATATYPE mean=0.0;
   int nrofaverages=0;
   do {
    if (project_args->channel_list!=NULL && !is_in_channellist(vectors->current_element+1, project_args->channel_list)) {
     array_advance(vectors);
    } else {
     mean+=array_scan(vectors);
     nrofaverages++;
    }
   } while (vectors->message==ARRAY_CONTINUE);
   mean/=nrofaverages;
   array_previousvector(vectors);
   do {
    array_write(vectors, READ_ELEMENT(vectors)-mean);
   } while (vectors->message==ARRAY_CONTINUE);
  } while (vectors->message!=ARRAY_ENDOFSCAN);
 }
 /*}}}  */
 /*{{{  Orthogonalize vectors if requested*/
 if (project_args->orthogonalize_vectors_first) {
  array_make_orthogonal(vectors);
  if (vectors->message==ARRAY_ERROR) {
   ERREXIT(tinfo->emethods, "project_init: Error orthogonalizing projection vectors\n");
  }
 }
 /*}}}  */
 if (!args[ARGS_NONORMALIZATION].is_set) {
 /*{{{  Normalize vectors*/
 do {
  DATATYPE length=0.0;
  do {
   if (project_args->channel_list!=NULL && !is_in_channellist(vectors->current_element+1, project_args->channel_list)) {
    array_advance(vectors);
   } else {
    const DATATYPE hold=array_scan(vectors);
    length+=hold*hold;
   }
  } while (vectors->message==ARRAY_CONTINUE);
  length=sqrt(length);

  array_previousvector(vectors);
  if (length==0.0) {
   ERREXIT1(tinfo->emethods, "project_init: Vector %d has zero length !\n", MSGPARM(vectors->current_vector));
  }
  array_scale(vectors, 1.0/length);
 } while (vectors->message!=ARRAY_ENDOFSCAN);
 /*}}}  */
 }
 /*{{{  Dump vectors if requested*/
 if (args[ARGS_DUMPVECTORS].is_set) {
  FILE * const fp=fopen(args[ARGS_DUMPVECTORS].arg.s, "w");
  if (fp==NULL) {
   ERREXIT1(tinfo->emethods, "project_init: Error opening output file >%s<.\n", MSGPARM(args[ARGS_DUMPVECTORS].arg.s));
  }
  array_transpose(vectors); /* We want one vector to be one column */ 
  array_dump(fp, vectors, ARRAY_MATLAB);
  array_transpose(vectors);
  fclose(fp);
 }
 /*}}}  */

 (*side_tinfo->methods->transform_exit)(side_tinfo);
 free_methodmem(side_tinfo);
 growing_buf_free(&buf);

 tinfo->methods->init_done=TRUE;
}