Beispiel #1
0
//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;
}
Beispiel #2
0
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;
}