void fgmm_m_step(struct gmm * GMM, const _fgmm_real * data, int data_len, _fgmm_real * pix, int * reestimate_flag, enum COVARIANCE_TYPE covar_t) { int state_i,k; int random_point = 0; for(state_i=0; state_i<GMM->nstates; state_i++) { GMM->gauss[state_i].prior = 0; for(k=0; k<GMM->dim; k++) GMM->gauss[state_i].mean[k] = 0; switch(covar_t) { case COVARIANCE_DIAG : GMM->gauss[state_i].prior = smat_covariance_diag(GMM->gauss[state_i].covar, data_len, &pix[state_i*data_len], data, GMM->gauss[state_i].mean); break; case COVARIANCE_SPHERE : GMM->gauss[state_i].prior = smat_covariance_single(GMM->gauss[state_i].covar, data_len, &pix[state_i*data_len], data, GMM->gauss[state_i].mean); break; default : GMM->gauss[state_i].prior = smat_covariance(GMM->gauss[state_i].covar, data_len, &pix[state_i*data_len], data, GMM->gauss[state_i].mean); break; } // If no point belong to us, reassign to a random one .. if(GMM->gauss[state_i].prior == 0) { random_point = rand()%data_len; for(k=0; k<GMM->dim; k++) GMM->gauss[state_i].mean[k] = data[random_point*GMM->dim + k]; *reestimate_flag = 1; // then we shall restimate mean/covar of this cluster } else { GMM->gauss[state_i].prior /= data_len; invert_covar(&GMM->gauss[state_i]); } } }
int main(int argc,char **argv) { char fnameInit[256]; if(argc!=2) { fprintf(stderr,"Usage: ./mvqe <params_file>\n"); exit(1); } sprintf(fnameInit,"%s",argv[1]); ParamMVQE *par=read_params(fnameInit); flouble *map_invcov=my_calloc(par->npix,sizeof(flouble)); flouble *fisher=my_calloc(par->nbins*par->nbins,sizeof(flouble)); invert_covar(par->map,map_invcov,par); fisher_avg(par,fisher); // int ii; // create_unit_variance(par,pix_data); // flouble mean=0,rms=0; // for(ii=0;ii<par->npix_seen;ii++) { // mean+=pix_data[ii]; // rms+=pix_data[ii]*pix_data[ii]; // } // mean/=par->npix_seen; // rms=sqrt(rms/par->npix_seen-mean*mean); // printf("%lE %lE\n",mean,rms); free_param_mvqe(par); free(map_invcov); free(fisher); return 0; }
/** perform em on the giver data * @param data : the given dataset (data_length*3 floats) * /!\ aligned malloc'd float * * @param num_states : number of states of the GMM * @return # of iterations */ int fgmm_em( struct gmm * GMM, const _fgmm_real * data, int data_length, _fgmm_real * end_loglikelihood, _fgmm_real likelihood_epsilon, enum COVARIANCE_TYPE covar_t, const _fgmm_real * weights) // if not NULL, weighted version .. { _fgmm_real * pix; _fgmm_real log_lik; int niter=0; _fgmm_real oldlik=0; _fgmm_real deltalik=0; int state_i; int d=0; int reestimate_flag=0; // shall we do one more iteration ?? pix = (_fgmm_real *) malloc( sizeof(_fgmm_real) * data_length * GMM->nstates); for(state_i=0; state_i<GMM->nstates; state_i++) { invert_covar(&GMM->gauss[state_i]); } for(niter=0; niter<max_iter; niter++) { reestimate_flag = 0; log_lik = fgmm_e_step(GMM,data,data_length,pix); log_lik/=data_length; #ifndef NDEBUG //printf("Log lik :: %f \n",log_lik); #endif // M step deltalik = log_lik - oldlik; oldlik = log_lik; if(fabs(deltalik) < likelihood_epsilon && !reestimate_flag) break; if(weights != NULL) { for(d=0; d<data_length; d++) { for(state_i=0; state_i< GMM->nstates; state_i++) pix[d*GMM->nstates + state_i] *= weights[d]; } } fgmm_m_step(GMM,data,data_length,pix,&reestimate_flag,covar_t); // pdata = data; } if(end_loglikelihood != NULL) *end_loglikelihood = log_lik; free(pix); return niter; }
int fgmm_kmeans( struct gmm * GMM, const _fgmm_real * data, int data_length, _fgmm_real likelihood_epsilon, const _fgmm_real * weights) // if not NULL, weighted version .. { _fgmm_real * pix; _fgmm_real total_distance; int niter=0; _fgmm_real oldlik=0; _fgmm_real deltalik=0; int state_i; int d=0; int reestimate_flag = 0; pix = (_fgmm_real *) malloc( sizeof(_fgmm_real) * data_length * GMM->nstates); for(state_i=0; state_i<GMM->nstates; state_i++) { invert_covar(&GMM->gauss[state_i]); } for(niter=0; niter<max_iter; niter++) { reestimate_flag = 0; total_distance = fgmm_kmeans_e_step(GMM,data,data_length,pix); total_distance/=data_length; #ifndef NDEBUG printf("Kmeans distance :: %f \n",total_distance); #endif // M step deltalik = total_distance - oldlik; oldlik = total_distance; if(fabs(deltalik) < likelihood_epsilon && !reestimate_flag) break; if(weights != NULL) { for(d=0; d<data_length; d++) { for(state_i=0; state_i< GMM->nstates; state_i++) pix[d + state_i*data_length] *= weights[d]; } } // the song remains the same .. fgmm_m_step(GMM,data,data_length,pix,&reestimate_flag,COVARIANCE_FULL); } free(pix); return niter; }
int main(int argc,char ** argv) { int i; float vn=0; int sig_perc=0, sig3_perc=0; struct gaussian g; float v[] = {1.,1.,1.}; float pdf=0; _fgmm_real samp[3]; _fgmm_real * data; _fgmm_real * weights; int k=0; struct smat * cv=NULL; _fgmm_real mean[3]; _fgmm_real * pcv; srand(time(NULL)); printf("gaussian test suite, each test uses %d samples \n",randn_samples); printf("box_muller testing :\n"); for(i=0;i<randn_samples;i++) { vn = randn_boxmuller(); if( fabs(vn) < 1.) sig_perc++; else if( fabs(vn) >= 2.) sig3_perc++; } //printf("%d %d\n",sig_perc,sig3_perc); assert( abs(sig_perc - one_sigma*randn_samples) < randn_samples / 400); assert( abs(sig3_perc - three_sigma*randn_samples) < randn_samples / 400); printf("..pass \n"); /* ----------------------------------------------- */ printf("simple gaussian pdf test :\n"); gaussian_init(&g,3); invert_covar(&g); assert(g.dim == 3); pdf = gaussian_pdf(&g,v); assert(fabs(pdf - value) < 1e-5); printf("..pass \n"); /* ----------------------------------------------- */ printf("drawing sample from gaussian test :\n"); data = (_fgmm_real *) malloc( sizeof(_fgmm_real) * randn_samples * 3); weights = (_fgmm_real *) malloc(sizeof(_fgmm_real) * randn_samples); for(i=0;i<randn_samples;i++) { weights[i] = 1.; gaussian_draw(&g,samp); //printf("%f %f %f\n",samp[0],samp[1],samp[2]); for(k=0;k<3;k++) { data[3*i+k] = samp[k]; } } smat_zero(&cv,3); smat_covariance(cv,randn_samples,weights,data,mean); // smat_pmatrix(cv); /* checking covariance is identity */ pcv = cv->_; for(i=0;i<3;i++) { assert(fabs(mean[i]) < 1e-2); assert( fabs(*(pcv++)- 1.) < 2e-2); for(k=i+1;k<3;k++) assert(fabs(*pcv++) < 1e-2); } printf("..pass\n"); return EXIT_SUCCESS; }