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]--; }
/*{{{ 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; }
/** \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; }
/* 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); }
/* * 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); }
/*{{{ 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; }