bool rjMcMC1DSampler::propose_move(rjMcMC1DModel& mcur, rjMcMC1DModel& mpro) { np_move++; size_t n = mcur.nlayers(); if (n <= 1)return false; size_t index = irand((size_t)1, n - 1); double pold = mcur.layers[index].ptop; //double std = sd_move; double std = DEFAULTMOVESTDFRACTION*pold; double pnew = pold + std*nrand(); double qpdfforward = gaussian_pdf(pold, pold*DEFAULTMOVESTDFRACTION, pnew); double qpdfreverse = gaussian_pdf(pnew, pnew*DEFAULTMOVESTDFRACTION, pold); bool isvalid = mpro.move_interface(index, pnew); if (isvalid == false)return false; set_misfit(mpro); double pqratio = qpdfreverse / qpdfforward; double logpqratio = log(pqratio); double loglr = -(mpro.misfit() - mcur.misfit()) / 2.0; double logar = logpqratio + loglr; double logu = log(urand()); if (logu < logar){ na_move++; return true; } return false; }
bool rjMcMC1DSampler::propose_birth(rjMcMC1DModel& mcur, rjMcMC1DModel& mpro) { np_birth++; size_t n = mcur.nlayers(); if (n >= nl_max)return false; double pos = urand(0.0, pmax); size_t index = mcur.which_layer(pos); double vold = mcur.layers[index].value; double vnew, pqratio; if (mBirthDeathFromPrior){ vnew = urand(vmin, vmax); pqratio = 1.0; } else{ double vcpdf; double logstd = DEFAULTLOGSTDDECADES; if (param_value == LINEAR){ double m = (pow(10.0, logstd) - pow(10.0, -logstd)) / 2.0; vnew = vold + m*vold*nrand(); vcpdf = gaussian_pdf(vold, m*vold, vnew); } else{ vnew = vold + logstd*nrand(); vcpdf = gaussian_pdf(vold, logstd, vnew); } pqratio = 1.0 / ((vmax - vmin)*vcpdf); } //pqratio *= (double)(n) / double(n + 1); bool isvalid = mpro.insert_interface(pos, vnew); if (isvalid == false)return false; set_misfit(mpro); double logpqratio = log(pqratio); double loglikeratio = -(mpro.misfit() - mcur.misfit()) / 2.0; double logar = logpqratio + loglikeratio; if (log(urand()) < logar){ na_birth++; return true; } return false; }
/** * for all data compute p(x|i) prob that state i generated data point x * correspond to the E step of EM. * * @param *pix is an alloc'd float table of dimension nstates*data_len * returns total log_likelihood */ _fgmm_real fgmm_e_step(struct gmm * GMM, const _fgmm_real * data, int data_len, _fgmm_real * pix) { /* E step */ _fgmm_real log_lik=0; _fgmm_real like; _fgmm_real * pxi; int data_i=0; int state_i; pxi = (_fgmm_real *) malloc(sizeof(_fgmm_real) * GMM->nstates); for(;data_i<data_len;data_i++) { like=0; for(state_i=0;state_i<GMM->nstates;state_i++) { pxi[state_i] = gaussian_pdf(&GMM->gauss[state_i], data + data_i*GMM->dim) ; //printf("state %d -> lik : %f\n",state_i,pxi[state_i]); like += pxi[state_i]* GMM->gauss[state_i].prior; /* pdata++; ppxi++; */ } if(like<= FLT_MIN) { /* printf("too far from current distrib %d\n",data_i); */ // in order to avoid us some numerical instabilities, // we are gooing to boost the likelihood for this point // // yep .. for(state_i = 0;state_i<GMM->nstates;state_i++) pxi[state_i] += FLT_MIN; like = FLT_MIN * GMM->nstates; } log_lik += log(like); /* if(isnan(log_lik) || isinf(log_lik)) exit(0); */ for(state_i=0;state_i<GMM->nstates;state_i++) { pix[data_i + state_i*data_len] = pxi[state_i] * GMM->gauss[state_i].prior / like; if(pix[data_i + state_i*data_len] <= FLT_MIN) pix[data_i + state_i*data_len] = FLT_MIN; } } free(pxi); return log_lik; }
bool rjMcMC1DSampler::propose_death(rjMcMC1DModel& mcur, rjMcMC1DModel& mpro) { np_death++; size_t n = mcur.nlayers(); if (n <= nl_min)return false; size_t index = irand((size_t)1, n - 1); bool isvalid = mpro.delete_interface(index); if (isvalid == false)return false; set_misfit(mpro); double pqratio; if (mBirthDeathFromPrior){ pqratio = 1.0; } else{ double logstd = DEFAULTLOGSTDDECADES; double vnew = mcur.layers[index - 1].value; double vold = mcur.layers[index].value; double vcpdf; if (param_value == LINEAR){ double m = (pow(10.0, logstd) - pow(10.0, -logstd)) / 2.0; vcpdf = gaussian_pdf(vnew, m*vnew, vold); } else{ vcpdf = gaussian_pdf(vnew, logstd, vold); } pqratio = (vmax - vmin)*vcpdf; } //pqratio *= (double)(n) / double(n - 1); double logpqratio = log(pqratio); double loglikeratio = -(mpro.misfit() - mcur.misfit()) / 2.0; double logar = logpqratio + loglikeratio; if (log(urand()) < logar){ na_death++; return true; } return false; }
/** * for all data compute p(x|i) prob that state i generated data point x * correspond to the E step of EM. * * @param *pix is an alloc'd float table of dimension nstates*data_len * returns total log_likelihood */ _fgmm_real fgmm_e_step(struct gmm * GMM, const _fgmm_real * data, int data_len, _fgmm_real * pix) { /* E step */ _fgmm_real log_lik=0; _fgmm_real like; _fgmm_real * pxi; int data_i=0; int state_i; pxi = (_fgmm_real *) malloc(sizeof(_fgmm_real) * GMM->nstates); for(;data_i<data_len;data_i++) { like=0; for(state_i=0;state_i<GMM->nstates;state_i++) { pxi[state_i] = gaussian_pdf(&GMM->gauss[state_i], data + data_i*GMM->dim) ; //printf("state %d -> lik : %f\n",state_i,pxi[state_i]); like += pxi[state_i]* GMM->gauss[state_i].prior; /* pdata++; ppxi++; */ } if(like<= FLT_MIN) { //printf("too far from current distrib %d\n",data_i); // exit(0); } else log_lik += log(like); /* if(isnan(log_lik) || isinf(log_lik)) exit(0); */ for(state_i=0;state_i<GMM->nstates;state_i++) { pix[data_i + state_i*data_len] = pxi[state_i] * GMM->gauss[state_i].prior / like; if(pix[data_i + state_i*data_len] <= FLT_MIN) pix[data_i + state_i*data_len] = FLT_MIN; } } free(pxi); return log_lik; }
bool rjMcMC1DSampler::propose_valuechange(rjMcMC1DModel& mcur, rjMcMC1DModel& mpro) { np_valuechange++; size_t index = irand((size_t)0,mcur.nlayers() - 1); double logstd = DEFAULTLOGSTDDECADES; double vold = mcur.layers[index].value; double vnew; double pqratio; if (param_value == LINEAR){ double m = (pow(10.0, logstd) - pow(10.0, -logstd)) / 2.0; vnew = vold + m*vold*nrand(); double qpdfforward = gaussian_pdf(vold, m*vold, vnew); double qpdfreverse = gaussian_pdf(vnew, m*vnew, vold); pqratio = qpdfreverse / qpdfforward; } else{ vnew = vold + logstd*nrand(); pqratio = 1.0; } bool isvalid = isinbounds(vmin, vmax, vnew); if (isvalid == false)return false; mpro.layers[index].value = vnew; set_misfit(mpro); double logpqratio = log(pqratio); double logliker = -(mpro.misfit() - mcur.misfit()) / 2.0; double logar = logpqratio + logliker; if (log(urand()) < logar){ na_valuechange++; return true; } return false; }
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; }