//this IS the EM...estimate away int classifier::fit2(segment * data, vector<double> mu_seeds, int topology, int elon_move ){ //========================================================================= //compute just a uniform model...no need for the EM if (K == 0){ ll = 0; double l = (data->maxX-data->minX); double pos = 0; double neg = 0; for (int i = 0; i < data->XN; i++){ pos+=data->X[1][i]; neg+=data->X[2][i]; } double pi = pos / (pos + neg); for (int i = 0; i < data->XN; i++){ if (pi > 0){ ll+=log(pi / l)*data->X[1][i]; } if (pi < 1){ ll+=log((1-pi) / l)*data->X[2][i]; } } components = new component[1]; return 1; } random_device rd; mt19937 mt(rd()); int add = noise_max>0; components = new component[K+add]; //=========================================================================== //initialize(1) components with user defined hyperparameters for (int k = 0; k < K; k++){ components[k].set_priors(ALPHA_0, BETA_0, ALPHA_1, BETA_1, ALPHA_2, ALPHA_3,data->N, K); } //=========================================================================== //random seeding, initialize(2), center of pausing components int i = 0; double mu; double mus[K]; for (int k = 0; k < K; k++){ if (mu_seeds.size()>0 ){ i = sample_centers(mu_seeds , p); mu = mu_seeds[i]; if (r_mu > 0){ normal_distribution<double> dist_r_mu(mu, r_mu); mu = dist_r_mu(mt); } }else{ normal_distribution<double> dist_MU((data->minX+data->maxX)/2., r_mu); mu = dist_MU(mt); } mus[k] = mu; if (mu_seeds.size() > 0 ){ mu_seeds.erase (mu_seeds.begin()+i); } } sort_vector(mus, K); for (int k = 0; k < K;k++){ //random seeding, intializ(3) other parameters components[k].initialize_bounds(mus[k], data, K, data->SCALE , 0., topology,foot_print, data->maxX, data->maxX); } sort_components(components, K); for (int k = 0; k < K; k++){ if (k > 0){ components[k].reverse_neighbor = &components[k-1]; }else{ components[k].reverse_neighbor = NULL; } if (k+1 < K){ components[k].forward_neighbor = &components[k+1]; }else{ components[k].forward_neighbor = NULL; } } if (add){ components[K].initialize_bounds(0., data, 0., 0. , noise_max, pi, foot_print, data->minX, data->maxX); } //=========================================================================== int t = 0; //EM loop ticker double prevll = nINF; //previous iterations log likelihood converged = false; //has the EM converged? int u = 0; //elongation movement ticker double norm_forward, norm_reverse,N; //helper variables while (t < max_iterations && not converged){ //====================================================== //reset old sufficient statistics for (int k=0; k < K+add; k++){ //components[k].print(); components[k].reset(); if (components[k].EXIT){ converged=false, ll=nINF; return 0; } } //====================================================== //E-step, grab all the stats and responsiblities ll = 0; for (int i =0; i < data->XN;i++){ norm_forward=0; norm_reverse=0; for (int k=0; k < K+add; k++){ //computing the responsbility terms if (data->X[1][i]){//if there is actually data point here... norm_forward+=components[k].evaluate(data->X[0][i],1); } if (data->X[2][i]){//if there is actually data point here... norm_reverse+=components[k].evaluate(data->X[0][i],-1); } } if (norm_forward > 0){ ll+=LOG(norm_forward)*data->X[1][i]; } if (norm_reverse > 0){ ll+=LOG(norm_reverse)*data->X[2][i]; } //now we need to add the sufficient statistics, need to compute expectations for (int k=0; k < K+add; k++){ if (norm_forward){ components[k].add_stats(data->X[0][i], data->X[1][i], 1, norm_forward); } if (norm_reverse){ components[k].add_stats(data->X[0][i], data->X[2][i], -1, norm_reverse); } } } //====================================================== //M-step N=0; //get normalizing constant for (int k = 0; k < K+add; k++){ N+=(components[k].get_all_repo()); } for (int k = 0; k < K+add; k++){ components[k].update_parameters(N, K); } if (abs(ll-prevll)<convergence_threshold){ converged=true; } if (not isfinite(ll)){ ll = nINF; return 0; } //====================================================== //should we try to move the uniform component? if (u > 200 ){ sort_components(components, K); //check_mu_positions(components, K); if (elon_move){ update_j_k(components,data, K, N); update_l(components, data, K); } u = 0; } u++; t++; prevll=ll; } return 1; }
int osb::run() { s_l=min_step; double prev_p_distance = DBL_MAX; //double min_p_distance = DBL_MAX; double p_distance = DBL_MAX; double prev_w_distance = DBL_MAX; //double min_w_distance = DBL_MAX; double w_distance = DBL_MAX; //double *best_l = new double [lines]; //double *best_w = new double [lines]; //bool first_run=true; bool reset_l=true; bool reset_w=true; while ( !(converged()) ) { //psd->print_cache_size(); prev_p_distance = p_distance; prev_w_distance = w_distance; if (reset_l) { prev_p_distance=DBL_MAX; } reset_l=false; if (reset_w) { prev_w_distance=DBL_MAX; } reset_w=false; for (int user=0;user<lines;user++) { last_rate[user]=current_rate[user]; last_pow[user]=current_pow[user]; } optimise_p(); for (int user=0;user<lines;user++) { current_rate[user]=rate(user); current_pow[user]=tot_pow(user); } p_distance = calc_p_distance(); printf("previous l distance was %lf\n",prev_p_distance); printf("current l distance is %lf\n",p_distance); printf("current lstep is %lf\n",s_l); update_l(); /* if (p_distance <= prev_p_distance) { if (p_distance <= min_p_distance) { min_p_distance=p_distance; for (int user=0;user<lines;user++) best_l[user]=l[user]; } update_l(); s_l *= 2; printf("l step size increased to %lf\n",s_l); } else { printf("Starting a new l trajectory\n"); for (int user=0;user<lines;user++) l[user] = best_l[user]; p_distance=min_p_distance; s_l = min_step; reset_l=true; continue; } */ /* w_distance = calc_w_distance(); printf("previous distance was %lf\n",prev_w_distance); printf("current distance is %lf\n",w_distance); printf("current step is %lf\n",s_w); if (w_distance <= prev_w_distance) { if (w_distance <= min_w_distance) { min_w_distance=w_distance; for (int user=1;user<lines;user++) best_w[user]=w[user]; } update_w(); s_w *= 2; printf("w step size increased to %lf\n",s_w); } else { printf("Starting a new w trajectory\n"); for (int user=1;user<lines;user++) w[user] = best_w[user]; w_distance=min_w_distance; s_w = min_w_step; reset_w=true; } */ /* if (!first_run) { int osc=0; for (int user=0;user<lines;user++) { if (pow_oscillating(user)) { osc++; } //printf("user %d's power is oscillating\n",user); if (osc==6) { s_l/=2; printf("Reducing step size to %lf\n",s_l); break; } } } */ //update_l(); //update_w(); // //getchar(); //first_run=false; } init_lines(); calculate_snr(); return 0; }