void ica(gsl_matrix *A, gsl_matrix *S, gsl_matrix *X, int verbose){ /* Checking the existance of the enviroment variable for controlling the number of threads used by openblas*/ const size_t NCOMP = A->size2; const size_t NSUB = X->size1; const size_t NVOX = X->size2; gsl_matrix *weights = gsl_matrix_alloc(NCOMP, NCOMP); gsl_matrix *inv_weights = gsl_matrix_alloc(NCOMP, NCOMP); gsl_matrix *white_X = gsl_matrix_alloc(NCOMP, NVOX); gsl_matrix *white = gsl_matrix_alloc(NCOMP, NSUB); gsl_matrix *dewhite = gsl_matrix_alloc(NSUB, NCOMP); pca_whiten(X, NCOMP, white_X, white, dewhite, 1); if (verbose) printf("Done."); if (verbose) printf("\nINFOMAX ..."); if (verbose) printf("\nPCA decomposition ..."); infomax(white_X, weights, S, verbose); if (verbose) printf("Done"); matrix_inv(weights, inv_weights); matrix_mmul(dewhite, inv_weights, A); gsl_matrix_free(weights); gsl_matrix_free(white_X); gsl_matrix_free(white); gsl_matrix_free(dewhite); }
int main(int argc, char** argv) { if (argc != 3) { fprintf(stderr, "Usage: %s <size> <n>\n", argv[0]); return 1; } int size = atoi(argv[1]); int n = atoi(argv[2]); printf("%d\n", n); matrix* m = matrix_new(size, size); int num_cells = size * size; int print_interval = num_cells / n; int i; timer* t = timer_new(); for (i = 0; i < num_cells; i++) { int next = i; int row = next / size; int col = next % size; matrix_set(m, row, col, (double) i); if (i % print_interval == 0) { timer_start(t); m = matrix_mmul(m, m); printf("%2f %lu\n", ((i + 0.0) / num_cells) * 100, timer_nsec(t)); } } matrix_free(m); return 0; }
double experiment(size_t NSUB, size_t NCOMP, size_t NVOX, int verbose){ gsl_matrix *estimated_a = gsl_matrix_alloc(NSUB, NCOMP); gsl_matrix *estimated_s = gsl_matrix_alloc(NCOMP, NVOX); gsl_matrix *estimated_x = gsl_matrix_alloc(NSUB, NVOX); gsl_matrix *true_a = gsl_matrix_alloc(NSUB, NCOMP); gsl_matrix *true_s = gsl_matrix_alloc(NCOMP, NVOX); gsl_matrix *true_x = gsl_matrix_alloc(NSUB, NVOX); gsl_matrix *cs = gsl_matrix_alloc(NCOMP, NCOMP); gsl_matrix *noise = gsl_matrix_alloc(NSUB, NVOX); // Random gaussian mixing matrix A random_matrix(true_a, 1.0, gsl_ran_gaussian); // Random logistic mixing matrix S random_matrix(true_s, 1.0, gsl_ran_logistic); // Random gaussian noise random_matrix(noise, 1, gsl_ran_gaussian); // matrix_apply_all(true_s, gsl_pow_3); // X = AS matrix_mmul(true_a, true_s, true_x); // add noise gsl_matrix_add(true_x, noise); double start, end; double cpu_time_used; start = omp_get_wtime(); // A,S <- ICA(X, NCOMP) ica(estimated_a, estimated_s, true_x, verbose); end = omp_get_wtime(); cpu_time_used = ((double) (end - start)); printf("\nTime used : %g\n", cpu_time_used); //Clean gsl_matrix_free(true_a); gsl_matrix_free(true_s); gsl_matrix_free(true_x); gsl_matrix_free(estimated_a); gsl_matrix_free(estimated_s); gsl_matrix_free(estimated_x); gsl_matrix_free(cs); return (cpu_time_used); }
int w_update( gsl_matrix *weights, gsl_matrix *x_white, gsl_matrix *bias, gsl_matrix *shuffled_x_white, //work space for shuffled x_white gsl_permutation *p, // random permutation gsl_rng *r, // random stream from gsl double lrate){ int error = 0; size_t i; const size_t NVOX = x_white->size2; const size_t NCOMP = x_white->size1; size_t block = (size_t)floor(sqrt(NVOX/3.0)); gsl_matrix *ib = gsl_matrix_alloc(1,block); gsl_matrix_set_all( ib, 1.0); gsl_ran_shuffle (r, p->data, NVOX, sizeof(size_t)); // gsl_matrix *shuffled_x_white = gsl_matrix_alloc(NCOMP,NVOX); // gsl_matrix_memcpy(shuffled_x_white, x_white); gsl_vector_view arow; #pragma omp parallel for private(i,arow) for (i = 0; i < x_white->size1; i++) { arow = gsl_matrix_row(shuffled_x_white,i); gsl_permute_vector (p, &arow.vector); } size_t start; gsl_matrix *unmixed = gsl_matrix_alloc(NCOMP,block); gsl_matrix *unm_logit = gsl_matrix_alloc(NCOMP,block); gsl_matrix *temp_I = gsl_matrix_alloc(NCOMP,NCOMP); gsl_matrix *ones = gsl_matrix_alloc(block,1); gsl_matrix_set_all(ones, 1.0); double max; gsl_matrix_view sub_x_white_view; // gsl_matrix *d_unmixer = gsl_matrix_alloc(NCOMP,NCOMP); for (start = 0; start < NVOX; start = start + block) { if (start + block > NVOX-1){ block = NVOX-start; gsl_matrix_free(ib); ib = gsl_matrix_alloc(1,block); gsl_matrix_set_all( ib, 1.0); gsl_matrix_free(unmixed); unmixed = gsl_matrix_alloc(NCOMP,block); gsl_matrix_free(unm_logit); unm_logit = gsl_matrix_alloc(NCOMP,block); gsl_matrix_free(ones); ones = gsl_matrix_alloc(block,1); gsl_matrix_set_all(ones, 1.0); } // sub_x_white = xwhite[:, permute[start:start+block]] sub_x_white_view = gsl_matrix_submatrix(shuffled_x_white, 0,start, NCOMP, block ); // Compute unmixed = weights . sub_x_white + bias . ib matrix_mmul(weights, &sub_x_white_view.matrix, unmixed); gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, bias, ib, 1.0, unmixed); // Compute 1-2*logit gsl_matrix_memcpy(unm_logit, unmixed); matrix_apply_all(unm_logit, logit); // weights = weights + lrate*(block*I+(unm_logit*unmixed.T))*weights gsl_matrix_set_identity(temp_I); // temp_I = I // (1) temp_I = block*temp_I +unm_logit*unmixed.T gsl_blas_dgemm( CblasNoTrans,CblasTrans, 1.0, unm_logit, unmixed, (double)block , temp_I); // BE CAREFUL with aliasing here! use d_unmixer if problems arise // gsl_matrix_memcpy(d_unmixer, weights); // (2) weights = weights + lrate*temp_I*weights gsl_blas_dgemm( CblasNoTrans,CblasNoTrans, lrate, temp_I, weights, 1.0, weights); // Update the bias gsl_blas_dgemm( CblasNoTrans, CblasNoTrans, lrate, unm_logit, ones, 1.0, bias); // check if blows up max = gsl_matrix_max(weights); if (max > MAX_W){ if (lrate<1e-6) { printf("\nERROR: Weight matrix may not be invertible\n"); error = 2; break; } error = 1; break; } } // set number of threads back to normal // openblas_set_num _threads(MAX_THREAD); //clean up // gsl_rng_free (r); // gsl_permutation_free (p); // gsl_matrix_free(d_unmixer); gsl_matrix_free(ib); gsl_matrix_free(unmixed); gsl_matrix_free(temp_I); gsl_matrix_free(ones); gsl_matrix_free(unm_logit); // gsl_matrix_free(shuffled_x_white); return(error); }
void infomax(gsl_matrix *x_white, gsl_matrix *weights, gsl_matrix *S, int verbose){ /*Computes ICA infomax in whitened data Decomposes x_white as x_white=AS *Input x_white: whitened data (Use PCAwhiten) *Output A : mixing matrix S : source matrix */ // int verbose = 1; //true size_t NCOMP = x_white->size1; size_t NVOX = x_white->size2; //getting permutation vector const gsl_rng_type * T; gsl_rng * r; gsl_permutation * p = gsl_permutation_alloc (NVOX); // gsl_rng_env_setup(); T = gsl_rng_default; r = gsl_rng_alloc (T); gsl_permutation_init (p); gsl_matrix *old_weights = gsl_matrix_alloc(NCOMP,NCOMP); gsl_matrix *bias = gsl_matrix_calloc(NCOMP, 1); gsl_matrix *d_weights = gsl_matrix_calloc(NCOMP,NCOMP); gsl_matrix *temp_change = gsl_matrix_alloc(NCOMP,NCOMP); gsl_matrix *old_d_weights = gsl_matrix_calloc(NCOMP,NCOMP); gsl_matrix *shuffled_x_white = gsl_matrix_calloc(NCOMP,x_white->size2); gsl_matrix_memcpy(shuffled_x_white, x_white); gsl_matrix_set_identity(weights); gsl_matrix_set_identity(old_weights); double lrate = 0.005/log((double)NCOMP); double change=1; double angle_delta =0; size_t step = 1; int error = 0; while( (step < MAX_STEP) && (change > W_STOP)){ error = w_update(weights, x_white, bias, shuffled_x_white, p, r, lrate); if (error==1 || error==2){ // It blowed up! RESTART! step = 1; // change = 1; error = 0; lrate *= ANNEAL; gsl_matrix_set_identity(weights); gsl_matrix_set_identity(old_weights); gsl_matrix_set_zero(d_weights); gsl_matrix_set_zero(old_d_weights); gsl_matrix_set_zero(bias); if (lrate > MIN_LRATE){ printf("\nLowering learning rate to %g and starting again.\n",lrate); } else{ printf("\nMatrix may not be invertible"); } } else if (error==0){ gsl_matrix_memcpy(d_weights, weights); gsl_matrix_sub(d_weights, old_weights); change = matrix_norm(d_weights); if (step > 2){ // Compute angle delta gsl_matrix_memcpy(temp_change, d_weights); gsl_matrix_mul_elements(temp_change, old_d_weights); angle_delta = acos(matrix_sum(temp_change) / sqrt(matrix_norm(d_weights)*(matrix_norm(old_d_weights)))); angle_delta *= (180.0 / M_PI); } gsl_matrix_memcpy(old_weights, weights); if (angle_delta > 60){ lrate *= ANNEAL; gsl_matrix_memcpy(old_d_weights, d_weights); } else if (step==1) { gsl_matrix_memcpy(old_d_weights, d_weights); } if ((verbose && (step % 10)== 0) || change < W_STOP){ printf("\nStep %zu: Lrate %.1e, Wchange %.1e, Angle %.2f", step, lrate, change, angle_delta); } step ++; } } matrix_mmul(weights, x_white, S); gsl_matrix_free(old_d_weights); gsl_matrix_free(old_weights); gsl_matrix_free(bias); gsl_matrix_free(d_weights); gsl_matrix_free(shuffled_x_white); gsl_rng_free (r); gsl_permutation_free (p); }