示例#1
0
static int
backtrack_other(struct saucy *s)
{
	int cf = s->start[s->lev];
	int cb = cf + s->right.clen[cf];
	int spec = s->specmin[s->lev];
	int min;

	/* Avoid using pairs until we get back to leftmost. */
	pick_all_the_pairs(s);

	clear_undiffnons(s);

	s->npairs = s->ndiffnons = -1;

	if (s->right.lab[cb] == spec) {
		min = find_min(s, cf);
		if (min == cb) {
			min = orbit_prune(s);
		}
		else {
			min -= cf;
		}
	}
	else {
		min = orbit_prune(s);
		if (min != -1 && s->right.lab[min + cf] == spec) {
			swap_labels(&s->right, min + cf, cb);
			min = orbit_prune(s);
		}
	}
	return min;
}
示例#2
0
static void
move_to_back(struct saucy *s, struct coloring *c, int k)
{
	int cf = c->cfront[k];
	int cb = cf + c->clen[cf];
	int offset = s->conncnts[cf]++;

	/* Move this connected label to the back of its cell */
	swap_labels(c, cb - offset, c->unlab[k]);

	/* Add it to the cell list if it's the first one swapped */
	if (!offset) s->clist[s->csize++] = cf;
}
示例#3
0
static int
descend(struct saucy *s, struct coloring *c, int target, int min)
{
	int back = target + c->clen[target];
	int ret;

	/* Count this node */
	++s->stats->nodes;

	/* Move the minimum label to the back */
	swap_labels(c, min, back);

	/* Split the cell */
	s->difflev[s->lev] = s->ndiffs;
	s->undifflev[s->lev] = s->nundiffs;
	++s->lev;
	s->split(s, c, target, back);

	/* Now go and do some work */
	ret = refine(s, c);

	/* This is the new enhancement in saucy 3.0 */
	if (c == &s->right && ret) {
        	int i, j, v, sum1, sum2, xor1, xor2;
		for (i = s->nsplits - 1; i > s->splitlev[s->lev-1]; --i) {
			v = c->lab[s->splitwho[i]];
			sum1 = xor1 = 0;
			for (j = s->adj[v]; j < s->adj[v+1]; j++) {
				sum1 += c->cfront[s->edg[j]];
				xor1 ^= c->cfront[s->edg[j]];
			}
			v = s->left.lab[s->splitwho[i]];
			sum2 = xor2 = 0;
			for (j = s->adj[v]; j < s->adj[v+1]; j++) {
				sum2 += s->left.cfront[s->edg[j]];
				xor2 ^= s->left.cfront[s->edg[j]];
			}
			if ((sum1 != sum2) || (xor1 != xor2)) {
				ret = 0;
				break;
			}
			v = c->lab[s->splitfrom[i]];
			sum1 = xor1 = 0;
			for (j = s->adj[v]; j < s->adj[v+1]; j++) {
				sum1 += c->cfront[s->edg[j]];
				xor1 ^= c->cfront[s->edg[j]];
			}
			v = s->left.lab[s->splitfrom[i]];
			sum2 = xor2 = 0;
			for (j = s->adj[v]; j < s->adj[v+1]; j++) {
				sum2 += s->left.cfront[s->edg[j]];
				xor2 ^= s->left.cfront[s->edg[j]];
			}
			if ((sum1 != sum2) || (xor1 != xor2)) {
				ret = 0;
				break;
			}
		}
	}

	return ret;
}
示例#4
0
//the *BIG* function
void M3LLinear::train()
{
	
    	double starttime=getTime();
	M3LFloat dual=0;	
	int i;
	int update_called=0;
	
	//store all the labels in (easily accessible) arrays to avoid calling accessor functions of LaFVector
	const M3LFloat** labels=new const M3LFloat*[N];
	for(i=0;i<N;i++)
	{
		labels[i]=prob->data[i].labels.getData();
	}

	//initialize stuff
	M3LFloat taulimit=tau*10;
	for(i=0;i<L;i++)
	{
	  	shrink_ub[i]=FLT_MAX;
	  	shrink_lb[i]=-FLT_MAX;
	  	active_size[i] = N;
	  	opt[i]=false;
	  	corr_PG_max[i]=FLT_MAX;
	  	corr_PG_min[i]=-FLT_MAX;
	  	mode[i]=false;
	  
	}
	double PG;
	long long int iter=0;
	long long int totiter=0;
	
	
	bool	shrink=true;
	
	//start training
	while(1)
	{
	
		totiter++;
		
		
		//initialize iteration: initialize some variables and permute training examples
		//for each label
		for(i=0;i<L;i++)
		{
		    
			finish_pass[i]=false;
		    	index[i]=0;
			
			
		    	//if *possibly* optimal skip
		    	if(opt[i] ) 
		    	{
				continue;
		    	}

		    	PG_max[i]=-FLT_MAX;
		    	PG_min[i]=FLT_MAX;
		    	//permute training examples
		    	for (int k=0; k<active_size[i]; k++)
		    	{
				int j = k+rand()%(active_size[i]-k);
				swap_indices(i, k, j);
		    	}
		}
		//end for
		
		//start pass
		int num_passed=0;
		
		//permute labels
		for(int k=0;k<L;k++)
		{
		    	int l=k+rand()%(L-k);
		    	swap_labels(l,k);
		}
		
		//pass through the whole active set
		while(num_passed<L)
		{
		
		  	for(int k=0;k<L;k++)
		  	{
					
		    		i=labelindices[k];
				if(finish_pass[i]) continue;
		    
		    		//optimal - skip
		     		if(opt[i] && shrink) 
		    		{
					if(!finish_pass[i])
					{
			  			finish_pass[i]=true;
			  			num_passed++;
					}
					continue;
		    		}
		    
		    		M3LFloat update_total=0;
		    		bool finished=false;
		    		int maxindex=0;
					
		    		for(;index[i]<active_size[i] &&!finished;index[i]++)	
		    		{	
					
		  			if(iter%10000==0) 
		  			{
			    			printf(".");
			    			fflush(stdout);
		  			}
					int s=index[i];
					iter++;
					int labelk = i;
					int pti=ptindices[i][index[i]];	
					//compute gradient
					
					
					M3LFloat grad=labels[pti][i] - score(i, prob->data[pti].inpt);
					
					//compute lower and upper bounds
					M3LFloat lower=lb[labelk][pti];
					M3LFloat upper = lower+2.0*C;
		
					//compute PG
					PG=0;

					//if \alpha_ij is at its lower bound and grad<shrink_lb shrink
					//else if \alpha_ij is at its upper bound and grad>shrink_ub shrink
					if(lower==0)
					{
						if(grad<shrink_lb[labelk] && shrink)
						{
							active_size[i]--;
							swap_indices(i, active_size[i], s);
							if(index[i]==active_size[i])
							{
								finish_pass[i]=true;
						  		num_passed++;
							}
						
							index[i]--;
							continue;
						}
						else if(grad>0)
						{
							PG=grad;
						}
					}
					else if(upper==0)
					{
						if(grad>shrink_ub[labelk] && shrink)
						{
						
							active_size[i]--;
							swap_indices(i, active_size[i], s);
							if(index[i]==active_size[i])
							{
						  		finish_pass[i]=true;
						  		num_passed++;
							}
							index[i]--;
							continue;
						}
						else if(grad<0)
						{
							PG=grad;
						}
					}
					else
						PG=grad;
					PG_max[i]=max(PG_max[i], PG);
					PG_min[i]=min(PG_min[i], PG);	

					//if PG is nonzero solve
					if(fabs(PG) >= tau)
					{
					
						M3LFloat increase = grad/(K_ii[pti]*R.get(labelk, labelk));
						increase=min(max(increase, lower),upper);
						lb[labelk][pti]-=increase;
						
						//mode[i] dictates whether we are ready to do a sequence of updates along one label or whether we switch to another label immediately. In the initial stages, mode[i] is false and we switch to the next label immediately. Once the PGs fall below a certain threshold we switch to working along one label for some time before switching
						if(!mode[i])
						{

							//perform the full update
							update_all_rows(prob->data[pti].inpt, R.getRow(i), increase);
						}
						else
						{
					
							//update the row of Z^t corresponding to the current label. The other labels will be updated later
 							update_current_row(i, prob->data[pti].inpt, increase*R.get(i,i));
							maxindex=max(maxindex, prob->data[i].inpt.last());
 							update_total+=increase;

							//store some information so that we can update the other rwos of Z^t later
							add(current_update, prob->data[pti].inpt, increase);
						}
				
						dual+=-0.5*increase*increase*(K_ii[pti]*R.get(labelk, labelk))+increase*grad;
				
					}
		  			if(!mode[i]) finished=true;
		  		}
		
				if(mode[i])
				{				
 					//complete the update for other labels  
					int cntupdate=fill(current_update,n,maxindex);
					update_other_rows(i, n, R.getRow(i), 1, update_total,cntupdate);
 		  			clear(current_update, n, cntupdate);	
		 		}   
				if(index[i]==active_size[i])
		    		{
		      			finish_pass[i]=true;
		      			num_passed++;
		    		}
				
			}
		
		  
		  
		}
		int optcount=0;
		int passdcount=0;
		M3LFloat PGabsmax;
		//finish iteration: update shrink_lb and shrink_ub and check if optimum has been reached
		for(i=0;i<L;i++)
		{
			PGabsmax=max(fabs(PG_max[i]),fabs(PG_min[i]));
			if(PGabsmax<taulimit) mode[i]=true;
			
		  	//compute correlated PG max and correlated PG min
		  	corr_PG_max[i]=PG_max[i];
		  	corr_PG_min[i]=PG_min[i];
		  	for(int j=0;j<L;j++)
		  	{
		    		if(opt[j]) continue;
		    		if(R.get(i,j)==0) continue;
		    		corr_PG_max[i]=max(corr_PG_max[i], PG_max[j]*fabs(R.get(i,j)));
		    		corr_PG_min[i]=min(corr_PG_min[i], PG_min[j]*fabs(R.get(i,j)));
		  	}
			M3LFloat pa=max(0,PG_max[i]);
			M3LFloat pb=min(0, PG_min[i]);
		  	//if max |PG| < tau then that label reached its optimum the last time it was passed on its active set
		  	if(max(fabs(pa),fabs(pb)) < tau)
		  	{
				//if active size=N then optimum on the whole set
				//else optimum on smaller set: expand
				if(active_size[i] == N)
				{
					
					opt[i]=true;
					optcount++;
				}
				else
				{
					
					opt[i]=false;
					active_size[i] = N;
					shrink_ub[i] = FLT_MAX;
					shrink_lb[i] = -FLT_MAX;
					continue;
				}
		  	}
		  	else opt[i]=false;
				
		
			//update shrink_lb and shrink_ub
		  	shrink_ub[i] = corr_PG_max[i];
		  	shrink_lb[i] = corr_PG_min[i];
		  	if (shrink_ub[i] <= 0)
				shrink_ub[i] = INF;
		  	if (shrink_lb[i] >= 0)
				shrink_lb[i] = -INF;
		
		}
		
		
		if(optcount==L )
		{
		
			M3LFloat maxPGhere=0;
			//see if optimum has indeed been reached. If not, repeat
			int cnt=0;
		  	for(int i=0;i<L;i++)
	 	 	{
				for(int pti=0;pti<N;pti++)
				{
					int labelk=i;
					M3LFloat grad=prob->data[pti].labels.get(i) - score(i, prob->data[pti].inpt);
			
					//compute lower and upper bounds
					M3LFloat lower=lb[labelk][pti];
					M3LFloat upper = lower+2.0*C;
			
					//compute PG
					PG=0;
					if(lower==0)
					{
						if(grad>0) PG=grad;
					}
					else if(upper==0)
					{
						if(grad<0) PG=grad;
					}
					else PG=grad;
					if(fabs(PG)>tau) 
					{
						opt[i]=false;
						maxPGhere=mymax(maxPGhere, fabs(PG));
						cnt++;
					}
				}
		 	}
		  	if(cnt==0) break;
			else
			{
				printf("*");
				fflush(stdout);
				
				for(int i=0;i<L;i++)
				{
					opt[i]=false;
					mode[i]=false;
					
					fflush(stdout);
				
				}
				taulimit=taulimit/2.0;
			}
		}
		if(optcount==L)
		{
		  
		  	for(i=0;i<L;i++)
		  	{
		    		active_size[i] = N;
		    
				corr_PG_max[i]=FLT_MAX;
				corr_PG_min[i]=-FLT_MAX;
		    		shrink_ub[i] = FLT_MAX;
		    		shrink_lb[i] = -FLT_MAX;
		  	}
		}
	}	
	
	std::cout<<"\nTime = "<<getTime()-starttime<<"\n";
	std::cout<<"Iterations="<<iter<<"\n";
	
}