コード例 #1
0
ファイル: energymain.cpp プロジェクト: ssma/CS231BPA2
int main()
{
	// Minimize the following function of 3 binary variables:
	// E(x, y, z) = x - 2*y + 3*(1-z) - 4*x*y + 5*|y-z|
	   
	Energy<float,float,float>::Var varx, vary, varz;
	Energy<float,float,float> *e = new Energy<float,float,float>(3,2);
	varx = e -> add_variable();
	vary = e -> add_variable();
	varz = e -> add_variable();
	e -> add_term1(varx, 0, 1);  // add term x 
	e -> add_term1(vary, 0, -2); // add term -2*y
	e -> add_term1(varz, 3, 0);  // add term 3*(1-z)
	e -> add_term2(varx, vary, 0, 0, 0, -4); // add term -4*x*y
	e -> add_term2(vary, varz, 0, 5, 5, 0); // add term 5*|y-z|

	Energy<float,float,float>::TotalValue Emin = e -> minimize();
	
	printf("Minimum = %f\n", Emin);
	printf("Optimal solution:\n");
	printf("x = %d\n", e->get_var(varx));
	printf("y = %d\n", e->get_var(vary));
	printf("z = %d\n", e->get_var(varz));
	delete e;
	
	return 0;
}
コード例 #2
0
ファイル: GCoptimization.cpp プロジェクト: 151706061/kslice
//-----------------------------------------------------------------------------------
void GCoptimization::solveSwap(SiteID size,SiteID *activeSites,LabelID alpha_label,
							   LabelID beta_label)
{

	SiteID i,site;
	
	if ( !readyToOptimise() ) handleError("Set up data and smoothness terms first. ");
	if ( size == 0 ) return;

	
	Energy *e = new Energy();
	Energy::Var *variables = (Energy::Var *) new Energy::Var[size];

	for ( i = 0; i < size; i++ )
		variables[i] = e ->add_variable();

	set_up_swap_energy(size,alpha_label,beta_label,e,variables,activeSites);
		
	Energy::TotalValue Emin = e -> minimize();
		
	for ( i = 0; i < size; i++ )
	{
		site = activeSites[i];
		if ( e->get_var(variables[i]) == 0 )
			m_labeling[site] = alpha_label;
		else m_labeling[site] = beta_label;
		m_lookupSiteVar[site] = -1;
	}

	delete [] variables;
	delete e;

}
コード例 #3
0
ファイル: GCoptimization.cpp プロジェクト: clusty/vision
void Swap::perform_alpha_beta_swap(LabelType alpha_label, LabelType beta_label)
{
    PixelType i,size = 0;
    Energy *e = new Energy();


    for ( i = 0; i < m_nPixels; i++ )
    {
        if ( m_labeling[i] == alpha_label || m_labeling[i] == beta_label)
        {
            m_pixels[size]    = i;
            m_lookupPixVar[i] = size;
            size++;
        }
    }

    if ( size == 0 ) return;


    Energy::Var *variables = (Energy::Var *) new Energy::Var[size];
    if (!variables) { fprintf(stderr, "Not enough memory!\n"); exit(1); }
    

    for ( i = 0; i < size; i++ )
        variables[i] = e ->add_variable();

    if ( m_dataType == ARRAY ) add_t_links_ARRAY_swap(e,variables,size,alpha_label,beta_label,m_pixels);
    else  add_t_links_FnPix_swap(e,variables,size,alpha_label,beta_label,m_pixels);

    if ( m_grid_graph )
    {
        if ( m_smoothType != FUNCTION )
        {
            if (m_varWeights) set_up_swap_energy_G_ARRAY_VW(size,alpha_label,beta_label,m_pixels,e,variables);
            else set_up_swap_energy_G_ARRAY(size,alpha_label,beta_label,m_pixels,e,variables);
        }
        else  set_up_swap_energy_G_FnPix(size,alpha_label,beta_label,m_pixels,e,variables);
        
    }
    else
    {
        if ( m_smoothType  != FUNCTION  ) set_up_swap_energy_NG_ARRAY(size,alpha_label,beta_label,m_pixels,e,variables);
        else set_up_swap_energy_NG_FnPix(size,alpha_label,beta_label,m_pixels,e,variables);
    }
        

    e -> minimize();

    for ( i = 0; i < size; i++ )
        if ( e->get_var(variables[i]) == 0 )
            m_labeling[m_pixels[i]] = alpha_label;
        else m_labeling[m_pixels[i]] = beta_label;


    delete [] variables;
    delete e;

}
コード例 #4
0
void EnergyAwareRandomWaypointMobility::receiveChangeNotification(int category, const cObject* details) {
    if(category == NF_BATTERY_CHANGED) {
        Energy* energyInformation = check_and_cast<Energy*>(details);
        if (energyInformation->GetEnergy() <= 0) {
            EV << "EnergyAwareRandomWaypointMobility detected that the battery is depleted and will stop moving after next target position has been reached" << std::endl;
            isEnergyDepleted = true;
        }
    }
}
コード例 #5
0
int main(int argc, char** argv){
    Mammut m;
    Energy* energy = m.getInstanceEnergy();

    /** Gets the power plug counter. **/
    CounterPlug* counterPlug = dynamic_cast<CounterPlug*>(energy->getCounter(COUNTER_PLUG));
    if(!counterPlug){
        cout << "Plug counter not present on this machine." << endl;
    }

    /** Gets the CPUs energy counters. **/
    CounterCpus* counterCpus = dynamic_cast<CounterCpus*>(energy->getCounter(COUNTER_CPUS));
    if(!counterCpus){
        cout << "Cpu counters not present on this machine." << endl;
    }

    /** Prints information for each counter. **/
    if(counterCpus){
        cout << "Found Cpus counter ";
        cout << "Has cores counter: " << counterCpus->hasJoulesCores() << " ";
        cout << "Has graphic counter: " << counterCpus->hasJoulesGraphic() << " ";
        cout << "Has Dram counter: " << counterCpus->hasJoulesDram() << " ";
        cout << endl;
    }

    /** Gets the value of the counter every sleepingSecs seconds. **/
    unsigned int sleepingSecs = 10;
    unsigned int iterations = 4;
    for(unsigned int i = 0; i < iterations; i++){
        cout << "Sleeping " << sleepingSecs << " seconds." << endl;
        sleep(sleepingSecs);
        if(counterPlug){
            cout << "Joules consumed at power plug: " << counterPlug->getJoules() << endl;
            counterPlug->reset();
        }

	if(counterCpus){
            vector<Cpu*> cpus = m.getInstanceTopology()->getCpus();
            for(size_t j = 0; j < cpus.size(); j++){
                CpuId id = cpus.at(j)->getCpuId();
                cout << "Joules consumed for CPU " << id << ": ";
                cout << "Cpu: " << counterCpus->getJoulesCpu(id) << " ";
                if(counterCpus->hasJoulesCores()){
                	cout << "Cores: " << counterCpus->getJoulesCores(id) << " ";
                }
                if(counterCpus->hasJoulesGraphic()){
                    cout << "Graphic: " << counterCpus->getJoulesGraphic(id) << " ";
                }
                if(counterCpus->hasJoulesDram()){
                    cout << "Dram: " << counterCpus->getJoulesDram(id) << " ";
                }
                cout << endl;
            }
            counterCpus->reset();
	}
    }
}
コード例 #6
0
ファイル: oldnemo.cpp プロジェクト: hax3l/faunus
double calculateEnergy(std::vector<particle> &p, Energy &ene, int opt) {
  double r = dist(p.at(0),p.at(1));
  if (r < 0.5e-10 || r > 10e-10) {
    return 1e9;
  }

  if (opt == 2 || opt == 4) {
    return ene.q2mu(p.at(0), p.at(1))/(pc::kT);
  } else if (opt == 1 || opt == 3) {
    return ene.mu2mu(p.at(0), p.at(1))/(pc::kT);
  } else if (opt == 5) {
    return ene.q2q(p.at(0),p.at(1))/(pc::kT);
  } else {
    return 0.0;
  }
}
コード例 #7
0
ファイル: example.cpp プロジェクト: UIKit0/SRMP
int main(int argc, char* argv[])
{
	if (0)
	{
		Energy* g = ReadUAI("../grid4x4.UAI.LG");
		
		g->SetFullEdges(1);
		
		Energy::Options options;
		options.method = Energy::Options::MPLP;
		options.iter_max = 100;
		g->Solve(options);
		exit(1);
	}

	int i;

	char* filename = NULL;
	char* save_filename = NULL;
	char* save_rep_filename = NULL;
	bool BLP_relaxation = false;
	bool FULL_relaxation = false;
	bool FULLDUAL_relaxation = false;
	int FULL_relaxation_flag = 0;
	int FULLDUAL_relaxation_flag = 0;
	bool print_stats = false;
	
	Run* current = new Run;

	Block<Run*> run_list(10);
	Run** run_ptr = run_list.New();
	*run_ptr = current;

	for (i=1; i<argc; i++)
	{
		if (argv[i][0] == '+' && !argv[i][1])
		{
			current = new Run;
			run_ptr = run_list.New();
			*run_ptr = current;
			continue;
		}
		if (argv[i][0] != '-')
		{
			if (filename) { printf("Error: filename can be specified only once\n"); ShowUsage(argv[0]); }
			filename = argv[i];
			continue;
		}
		if (!strcmp("h", &argv[i][1]))
		{
			ShowUsage(argv[0], true);
		}
		if (!strncmp("save=", &argv[i][1], 5))
		{
			if (save_filename) { printf("Error: save filename can be specified only once\n"); ShowUsage(argv[0]); }
			save_filename = &argv[i][1+5];
			continue;
		}
		if (!strncmp("saverep=", &argv[i][1], 8))
		{
			if (save_filename) { printf("Error: save filename can be specified only once\n"); ShowUsage(argv[0]); }
			save_rep_filename = &argv[i][1+8];
			continue;
		}
		if (!strncmp("t=", &argv[i][1], 2))
		{
			if (current->tighten_filename) { printf("Error: tightening filename can be specified only once\n"); ShowUsage(argv[0]); }
			current->tighten_filename = &argv[i][1+2];
			continue;
		}
		if (!strncmp("iter=", &argv[i][1], 5))
		{
			current->options.iter_max = atoi(&argv[i][1+5]);
			continue;
		}
		if (!strncmp("time=", &argv[i][1], 5))
		{
			current->options.time_max = atof(&argv[i][1+5]);
			continue;
		}
		if (!strncmp("eps=", &argv[i][1], 4))
		{
			current->options.eps = atof(&argv[i][1+4]);
			continue;
		}
		if (!strcmp("SRMP", &argv[i][1]))
		{
			current->options.method = Energy::Options::SRMP;
			continue;
		}
		if (!strcmp("CMP", &argv[i][1]))
		{
			current->options.method = Energy::Options::CMP;
			continue;
		}
		if (!strcmp("MPLP", &argv[i][1]))
		{
			current->options.method = Energy::Options::MPLP;
			continue;
		}
		if (!strncmp("TRWS=", &argv[i][1], 5))
		{
			current->options.TRWS_weighting = atof(&argv[i][1+5]);
			continue;
		}
		if (!strcmp("BLP", &argv[i][1]))
		{
			BLP_relaxation = true;
			continue;
		}
		if (!strcmp("FULL", &argv[i][1]))
		{
			FULL_relaxation = true;
			continue;
		}
		if (!strncmp("FULL=", &argv[i][1], 5))
		{
			FULL_relaxation = true;
			FULL_relaxation_flag = atoi(&argv[i][1+5]);
			continue;
		}
		if (!strcmp("FULLDUAL", &argv[i][1]))
		{
			FULLDUAL_relaxation = true;
			continue;
		}
		if (!strncmp("FULLDUAL=", &argv[i][1], 9))
		{
			FULLDUAL_relaxation = true;
			FULLDUAL_relaxation_flag = atoi(&argv[i][1+9]);
			continue;
		}
		if (!strncmp("sort=", &argv[i][1], 5))
		{
			current->options.sort_flag = atoi(&argv[i][1+5]);
			continue;
		}
		if (!strncmp("verbose=", &argv[i][1], 8))
		{
			current->options.verbose = (atoi(&argv[i][1+8])) ? true : false;
			continue;
		}
		if (!strcmp("takelog", &argv[i][1]))
		{
			TAKE_LOG = true;
			continue;
		}
		if (!strcmp("stats", &argv[i][1]))
		{
			print_stats = true;
			continue;
		}
		ShowUsage(argv[0]);
	}

	if (!filename) ShowUsage(argv[0]);

	bool start = true;
	Energy* g = ReadUAI(filename);

	if (BLP_relaxation) g->SetMinimalEdges();
	if (FULL_relaxation) g->SetFullEdges(FULL_relaxation_flag);
	if (FULLDUAL_relaxation) g->SetFullEdgesDual(FULLDUAL_relaxation_flag);

	for (run_ptr=run_list.ScanFirst(); run_ptr; run_ptr=run_list.ScanNext())
	{
		current = *run_ptr;
		if (current->tighten_filename)
		{
			if (start) g->SetFullEdges();
			AddTriplets(g, current->tighten_filename);
		}
		g->Solve(current->options);
		delete current;

		start = false;
	}

	if (print_stats)
	{
		g->PrintStats();
	}

	if (save_filename)
	{
		FILE* fp = fopen(save_filename, "w");
		if (!fp) { printf("Can't open %s for writing\n", save_filename); exit(1); }
		for (i=0; i<g->GetNodeNum(); i++) fprintf(fp, "%d ", g->GetSolution(i));
		fclose(fp);
	}

	if (save_rep_filename)
	{
		g->SaveUAI(save_rep_filename, false, true);
	}

	delete g;

	return 0;
}
コード例 #8
0
ファイル: example.cpp プロジェクト: UIKit0/SRMP
Energy* ReadUAI(const char* filename)
{
	ReadLinesFromFile F(filename);
	if (!F.exists()) { printf("Can't open %s\n", filename); exit(1); }

	Energy* g = NULL;
	int phase = 0; // 0: reading # nodes
	               // 1: reading # states
	               // 2: reading # terms
	               // 3: reading term descriptions
	               // 4: reading term costs
	               // 5: finished
	int node_num = 0, t = 0, term_num = 0;
	struct Term
	{
		int arity;
		int* nodes;
	};
	Term* terms = NULL;
	Buffer buf(1024);

	ReadNumbers<int> read_ints;
	ReadNumbers<double> read_doubles;

	char* line;
	while ( (line=F.NextLine()) != NULL )
	{
		int i, num = read_ints.ReadLine(line);
		if (num == 0) continue;

		if (phase == 0)
		{
			if (num != 1) { printf("Error in line %d: # nodes expected\n", F.CurrentLine()); exit(1); }
			node_num = read_ints.GetNumber(0);
			if (node_num < 1) { printf("Error in line %d: # of nodes should be positive\n", F.CurrentLine()); exit(1); }
			g = new Energy(node_num);
			phase ++;
		}
		else if (phase == 1)
		{
			if (num != node_num) { printf("Error in line %d: # of nodes do not match\n", F.CurrentLine()); exit(1); }
			for (i=0; i<node_num; i++) g->AddNode(read_ints.GetNumber(i));
			phase ++;
		}
		else if (phase == 2)
		{
			if (num != 1) { printf("Error in line %d: # terms expected\n", F.CurrentLine()); exit(1); }
			term_num = read_ints.GetNumber(0);
			if (term_num < 0) { printf("Error in line %d: # of terms should be non-negative\n", F.CurrentLine()); exit(1); }
			t = 0;
			terms = new Term[term_num];
			phase ++;
		}
		else if (phase == 3)
		{
			num --;
			if (num != read_ints.GetNumber(0)) { printf("Error in line %d: incorrect term entry\n", F.CurrentLine()); exit(1); }
			if (num < 1) { printf("Error in line %d: arity must be positive\n", F.CurrentLine()); exit(1); }
			terms[t].arity = num;
			terms[t].nodes = (int*)buf.Alloc(num*sizeof(int));
			for (i=0; i<num; i++)
			{
				int q = read_ints.GetNumber(i+1);
				if (q<0 || q>=node_num)  { printf("Error in line %d: incorrect index\n", F.CurrentLine()); exit(1); }
				terms[t].nodes[i] = q;
			}
			t ++;
			if (t == term_num) { phase ++; t = 0; }
		}
		else if (phase == 4)
		{
			if (num != 1) { printf("Error in line %d: # costs expected\n", F.CurrentLine()); exit(1); }
			num = read_ints.GetNumber(0);
			line = F.NextLine();
			if (!line) { printf("Error in line %d: missing cost table\n", F.CurrentLine()); exit(1); }
			int double_num = read_doubles.ReadLine(line);
			double* arr = read_doubles.GetNumbersArray();
			if (TAKE_LOG)
			{
				for (i=0; i<double_num; i++) arr[i] = log(arr[i]);
			}
			for (i=0; i<double_num; i++) arr[i] = -arr[i]; // we are minimizing, not maximizing!
			if (num == -1)
			{
				if (terms[t].arity != 2 || g->GetK(terms[t].nodes[0]) != g->GetK(terms[t].nodes[1]))
				{ printf("Error in line %d: not a potts term\n", F.CurrentLine()); exit(1); }
				if ( 1 )
				{
					if (!potts) potts = new PottsFactorType;
					g->AddFactor(2, terms[t].nodes, arr, potts);
				}
				else
				{
					int x, y, i=0, K = g->GetK(terms[t].nodes[0]);
					double lambda = arr[0];
					double* V = new double[K*K];
					for (x=0; x<K; x++)
					for (y=0; y<K; y++)
					{
						V[i ++] = (x == y) ? 0 : lambda;
					}
					g->AddPairwiseFactor(terms[t].nodes[0], terms[t].nodes[1], V);
				}
			}
			else
			{
				int K = 1;
				for (i=0; i<terms[t].arity; i++) K *= g->GetK(terms[t].nodes[i]);
				if (double_num != K) { printf("Error in line %d: # states doesn't match\n", F.CurrentLine()); exit(1); }
				g->AddFactor(terms[t].arity, terms[t].nodes, arr);
			}
			t ++;
			if (t == term_num) phase ++;
		}
	}

	if (phase < 5)
	{
		if (g) delete g;
		g = NULL;
	}
	return g;

}
コード例 #9
0
ファイル: bvz.cpp プロジェクト: ZhaozhengPlus/stereo
void Match::BVZ_Expand(Coord a)
{
	Coord p, d, q, dq;
	Energy::Var var, qvar;
	int E_old, E00, E0a, Ea0;
	int k;

	/* node_vars stores variables corresponding to nodes */

	Energy *e = new Energy(BVZ_error_function);

	/* initializing */
	for (p.y=0; p.y<im_size.y; p.y++)
	for (p.x=0; p.x<im_size.x; p.x++)
	{
		d = Coord(IMREF(x_left, p), IMREF(y_left, p));
		if (a == d)
		{
			IMREF(node_vars, p) = VAR_ACTIVE;
			e -> add_constant(BVZ_data_penalty(p, d));
		}
		else
		{
			IMREF(node_vars, p) = var = e -> add_variable();
			e -> ADD_TERM1(var, BVZ_data_penalty(p, d), BVZ_data_penalty(p, a));
		}
	}

	for (p.y=0; p.y<im_size.y; p.y++)
	for (p.x=0; p.x<im_size.x; p.x++)
	{
		d = Coord(IMREF(x_left, p), IMREF(y_left, p));
		var = (Energy::Var) IMREF(node_vars, p);

		/* smoothness term */
		for (k=0; k<NEIGHBOR_NUM; k++)
		{
			q = p + NEIGHBORS[k];
			if ( ! ( q>=Coord(0,0) && q<im_size ) ) continue;
			qvar = (Energy::Var) IMREF(node_vars, q);
			dq = Coord(IMREF(x_left, q), IMREF(y_left, q));

			if (var != VAR_ACTIVE && qvar != VAR_ACTIVE)
				E00 = BVZ_smoothness_penalty(p, q, d, dq);
			if (var != VAR_ACTIVE)
				E0a = BVZ_smoothness_penalty(p, q, d, a);
			if (qvar != VAR_ACTIVE)
				Ea0 = BVZ_smoothness_penalty(p, q, a, dq);

			if (var != VAR_ACTIVE)
			{
				if (qvar != VAR_ACTIVE) e -> ADD_TERM2(var, qvar, E00, E0a, Ea0, 0);
				else                    e -> ADD_TERM1(var, E0a, 0);
			}
			else
			{
				if (qvar != VAR_ACTIVE) e -> ADD_TERM1(qvar, Ea0, 0);
				else                    {}
			}
			
		}
	}

	E_old = E;
	E = e -> minimize();

	if (E < E_old)
	{
		for (p.y=0; p.y<im_size.y; p.y++)
		for (p.x=0; p.x<im_size.x; p.x++)
		{
			var = (Energy::Var) IMREF(node_vars, p);
			if (var!=VAR_ACTIVE && e->get_var(var)==VALUE1)
			{
				IMREF(x_left, p) = a.x; IMREF(y_left, p) = a.y;
			}
		}
	}

	delete e;
}
コード例 #10
0
ファイル: LinkerPipe.cpp プロジェクト: loy1991/GMIS_BASE
	/* 流式的处理特定CLinkerPipe接收到的信息,此函数对于理解本类非常重要,
	s为接收到的字节,或多或少
	*/
	void CLinkerPipe::CompileMsg(const char* s, int32 size)
	{
		
		if(m_RecoType == LINKER_BAN)return;   	
				
		CLinkerPipe::RevContextInfo* Info  = NULL;
		
		if( m_ContextStack.size() > 0 ){ 
			Info = m_ContextStack.front(); //取出之前数据的处理信息
		}
		else{
			Info = new CLinkerPipe::RevContextInfo(&m_CurRevMsg);
			
			m_ContextStack.push_front(Info);
		}
		
		assert(Info != NULL);
		

		bool bCompleteOneData = FALSE;
		
		int i=0;
		while(i<size)
		{				
			char ch = s[i++];
			
			Info->InfoLen++;
			
			//在错误状态下将只关心是否有空管道出现
			//在检测到空管道之前,根据要求,即使是出错的数据也将可能被保存起来,以便分析错误原因
			if(m_bRevError)
			{
				if (Info->Buffer.size() < m_ErrorSaveLen)
				{
					Info->Buffer += ch;
				}
				
				if (ch == '@')
				{
					Info->DataLen ++;
					
					if (Info->DataLen ==ERROR_RESUME_LENGTH)
					{
						EndErrorState(Info);
					}
				}else{
					Info->DataLen =0;
				}
				
				continue;
			}
			
			//正常状态
			switch(Info->State){                                              
			case TYPE_PART:                                                    
				{         
					Info->HeaderStr += ch;
					
					if( IsDataType(ch) && Info->DataType == -1){                   
						Info->DataType = CHAR_TO_TYPE(ch);                                
						if(Info->DataType == TYPE_PIPELINE){                      
							Info->Data = new ePipeline();
							Info->ParentPipe->Push_Directly(Info->Data);

						}                                                          
						//不是PIPELINE但是第一个数据则报错,因为信息的第一个数据类型肯定是TYPE_PIPELINE                       
						else if(Info->ParentPipe == this ){               							
							BeginErrorState(Info,ERROR_TYPE_PART);
						}
						else{ //其他类型则预先生成一个空数据
						
							Info->Data = CreateEmptyData(Info->DataType);
							Info->ParentPipe->Push_Directly(Info->Data);

						}
					}  //确定类型后,改变数据处理状态
					else if(ch == '@' && Info->DataType != -1) 
					{						 
						Info->State = (Info->DataType == TYPE_PIPELINE)?ID_PART : LENGTH_PART;
						Info->Buffer="";
						Info->DataLen = NUMBER_LENGTH_LIMIT;
					}
					else{
						BeginErrorState(Info,ERROR_TYPE_PART);
					}
				}
				break;
			case LENGTH_PART:
				{
					Info->HeaderStr += ch;
					
					// ch ->[0-9] 并且 单个数据长度不能超过10位整数				
					if(isdigit(ch) && Info->Buffer.size() < Info->DataLen)
					{
						Info->Buffer  += ch;
					}
					else if(ch == '@' && Info->Buffer.size() >0)
					{
						Info->DataLen = atol(Info->Buffer.c_str());
						Info->Buffer = "";

						//初步检查长度的合理性
						if(Info->DataType == TYPE_PIPELINE)
						{ 
							if (Info->ParentPipe == this)
							{   

							}

							if(Info->DataLen == 0){
								bCompleteOneData = TRUE;
							}else{

								ePipeline  NotifData;
								NotifData.PushInt(Info->DataLen); //总长度
								NotifData.PushInt(0);             //相对于Parent的完成进度,0则表示本Pipe刚开始
								NotifData.Push_Directly(Info->Data->Clone());
								m_Parent->NotifyLinkerState(this,LINKER_RECEIVE_STEP,NotifData);
								

								//对于管道,得到长度以后即压入堆栈,因为它的数据其实是其它数据的集合								
								Info->HeaderStr="";
								
								ePipeline* Parent = (ePipeline*)Info->Data;
								assert(Parent);
								RevContextInfo* NewInfo = new RevContextInfo(Parent);     
								
								m_ContextStack.push_front(NewInfo);
								Info = NewInfo;
							}

							break;    
						}else	if(Info->DataType == TYPE_NULL)
						{
							if(Info->DataLen != 0){
								BeginErrorState(Info,ERROR_LENGTH_PART);
							}else{
								bCompleteOneData = TRUE;
							}
						}
						else if(Info->DataLen ==0 )
						{ 
							if(Info->DataType == TYPE_STRING){ //允许为0
								bCompleteOneData = TRUE;
							}
							else{//	其他数据不能为0 error
								BeginErrorState(Info,ERROR_LENGTH_PART);
							}
						}else if ((Info->DataType==TYPE_INT || Info->DataType==TYPE_FLOAT) && Info->DataLen>20)
						{
							BeginErrorState(Info,ERROR_LENGTH_PART);
						}
						else{	
							Info->State = DATA_PART;   //一切OK,准备开始处理数据本身
						}
					}
					else{
						BeginErrorState(Info,ERROR_LENGTH_PART);
					}
				}
				break;
				
			case DATA_PART:
				{
					Info->Buffer += ch;
					
					if( Info->Buffer.size() == Info->DataLen ){
						
						Info->HeaderStr+=Info->Buffer;							
						int32 n = Info->Data->FromString(Info->HeaderStr,0);
						assert(n!=0);
						
						bCompleteOneData = TRUE;

					}
				}
				break;
			case ID_PART:
				{		
					//	Info->HeaderStr += ch;
					
					// ch ->[0-9] 并且数据ID不能超过20位整数				
					if(isdigit(ch) && Info->Buffer.size() < Info->DataLen)
					{
						Info->Buffer += ch;
					}
					else if(ch == '@' && Info->Buffer.size() >0)
					{
						int64 ID = atoint64(Info->Buffer.c_str());
						
						assert(Info->DataType == TYPE_PIPELINE);
						ePipeline* Data = (ePipeline*)Info->Data;
						Data->SetID(ID); 
						
						Info->State = NAMELEN_PART;
						Info->Buffer = "";
						Info->DataLen = DATA_LENGTH_LIMIT;
					}
					else{
						BeginErrorState(Info,ERROR_ID_PART);						
					}
				}
				break;
			case NAMELEN_PART:
				{
					//	Info->HeaderStr += ch;
					
					// ch ->[0-9] 并且 不能超过10位整数				
					if(isdigit(ch) && Info->Buffer.size() < Info->DataLen)
					{
						Info->Buffer += ch;
					}
					else if(ch == '@' && Info->Buffer.size() >0)
					{
						uint32 len = atol(Info->Buffer.c_str());
						
						Info->DataLen = len; 
						Info->Buffer = "";
						assert(Info->Buffer.size()==0);
						Info->State = NAME_PART;
					}
					else{
						BeginErrorState(Info,ERROR_NAMELEN_PART);		
					}
				}
				break;
			case NAME_PART:
				{
					//	Info->HeaderStr += ch;
					
					// ch ->[0-9] 并且 不能超过约定位数				
					if(Info->Buffer.size() < Info->DataLen)
					{
						Info->Buffer += ch;
					}
					else if(ch == '@'){
						eSTRING s;
						s.FromString(Info->Buffer,0);
						tstring Name = s;

						assert(Info->DataType == TYPE_PIPELINE);
						ePipeline* Data = (ePipeline*)Info->Data;
						Data->SetLabel(Name.c_str()); 
						
						Info->Buffer = "";
						Info->State = LENGTH_PART;
						Info->DataLen = DATA_LENGTH_LIMIT;
					}
					else{
						BeginErrorState(Info,ERROR_NAME_PART);
					}
				}
				break;
			default:
				assert(0);
				break;
				
			}
			
			if(bCompleteOneData){
				bCompleteOneData = FALSE;
				
				//处理得到的实际数据
				while(m_ContextStack.size()){	
					
					//Info->ParentPipe->Push_Directly(Info->Data);
					
					int32 Len = Info->InfoLen;
		            Energy* Data = Info->Data;
					
					if (m_ContextStack.size()>1)
					{
						RevContextInfo* PreInfo = m_ContextStack[1];
						
						PreInfo->InfoLen += Len;
						
						PreInfo->DataLen -= Len;
						
						if (PreInfo->DataLen  == 0) //已经完成一个嵌套Pipe,重复上述步骤
						{
						
							ePipeline  NotifData;
							NotifData.PushInt(Len);   //总长度								
							NotifData.PushInt(PreInfo->InfoLen); //Parent Pipe已经完成的
							NotifData.Push_Directly(Data->Clone());								
							m_Parent->NotifyLinkerState(this,LINKER_RECEIVE_STEP,NotifData);
															
							delete Info;
							m_ContextStack.pop_front();
							Info = m_ContextStack.front();
							
							assert(PreInfo == Info);	

						}else if (PreInfo->DataLen > 0) //继续接收下一个数据
						{
							Info->Reset();  
							break;
						}else{ //错误
							BeginErrorState(Info,ERROR_OTHER_PARNT);
							Info->Reset();
						}
					}else{ //已经完成一个完整信息的组装
						
						assert(m_ContextStack.size()==1);
						assert(m_CurRevMsg.Size()==1);

						eElectron E;
						m_CurRevMsg.Pop(&E);
						
					
						RevOneMsg(E);

						assert(Info->ParentPipe == &m_CurRevMsg);
						Info->Reset();
						break;
					}
				}//while
			}
      }//while
}
コード例 #11
0
void Expansion::perform_alpha_expansion(LabelType alpha_label)
{
    PixelType i,size = 0;
    Energy *e = new Energy();

    for ( i = 0; i < m_nPixels; i++ )
    {
        if ( m_labeling[i] != alpha_label )
        {
            m_lookupPixVar[size] = i;
            size++;
        }
    }


    if ( size > 0 )
    {
        Energy::Var *variables = (Energy::Var *) new Energy::Var[size];
        if ( !variables) {
            printf("\nOut of memory, exiting");
            exit(1);
        }

        for ( i = 0; i < size; i++ )
            variables[i] = e ->add_variable();

        if ( m_dataType == ARRAY ) add_t_links_ARRAY(e,variables,size,alpha_label);
        else  add_t_links_FnPix(e,variables,size,alpha_label);


        if ( m_grid_graph )
        {
            if ( m_smoothType != FUNCTION )
            {
                if (m_varWeights) set_up_expansion_energy_G_ARRAY_VW(size,alpha_label,e,variables);
                else set_up_expansion_energy_G_ARRAY(size,alpha_label,e,variables);
            }
            else set_up_expansion_energy_G_FnPix(size,alpha_label,e,variables);

        }
        else
        {
            if ( m_smoothType != FUNCTION ) set_up_expansion_energy_NG_ARRAY(size,alpha_label,e,variables);
            else if ( m_smoothType == FUNCTION) set_up_expansion_energy_NG_FnPix(size,alpha_label,e,variables);
        }

        e -> minimize();

        for ( i = 0,size = 0; i < m_nPixels; i++ )
        {
            if ( m_labeling[i] != alpha_label )
            {
                if ( e->get_var(variables[size]) == 0 )
                    m_labeling[i] = alpha_label;

                size++;
            }
        }

        delete [] variables;
    }

    delete e;
}
コード例 #12
0
 /// Here we use E=1/2m.v²
 Mass::Mass(const Energy& energy,const Speed& speed)
 : m_value(2*energy.Joule()/(speed.MeterPerSecond().length()*speed.MeterPerSecond().length())), 
   m_unit(_Kilogram)
 {}
コード例 #13
0
ファイル: robustpn_mex.cpp プロジェクト: erli2/robustpn
void robustpn(int nout, mxArray* pout[], int nin, const mxArray* pin[])
{

    /*
     *********************************************************
     * Check inputs and construct the energy
     **********************************************************
     */
    
    int nLabel, nVar, nPair, nHigher, ii;
    int hop_fields_indices[HOP_N_OF_FIELDS]; // indices to fields in hop struct
    
    // check pin[0] is sparse
    if ( ! mxIsSparse(pin[0]) || ! mxIsDouble(pin[0]) || mxIsComplex(pin[0]))
        mexErrMsgIdAndTxt("robustpn:inputs","sparseG must be a sparse double matrix");
    // check pin[0] is square
    const mwSize *spd = mxGetDimensions(pin[0]);
    if (spd[0] != spd[1])
        mexErrMsgIdAndTxt("robustpn:inputs","sparseG must be a square matrix");
    nVar = spd[0];
    
    nPair = 0;
    // read the sparse matrix
    double* Pr = mxGetPr(pin[0]);
    mwIndex  *ir = mxGetIr(pin[0]);
    mwIndex *jc = mxGetJc(pin[0]);
    mwIndex col, starting_row_index, stopping_row_index, current_row_index, tot(0);
    
    mwSize max_npair = mxGetNzmax(pin[0]);
    int * pairs = new int[2 * max_npair]; // will be de-alocate on ~Energy
    termType* sc = new termType[max_npair]; // will be de-alocate on ~Energy

    // mexPrintf("Preparing to read sG\n");
    
    // traverse the sparseG matrix - pick only connections from the upper tri of the matrix
    // (since its symmetric and we don't want to count each potential twice).
    for (col=0; col<nVar; col++)  {
        starting_row_index = jc[col];
        stopping_row_index = jc[col+1];
        if (starting_row_index == stopping_row_index)
            continue;
        else {
            for (current_row_index = starting_row_index;
              current_row_index < stopping_row_index  ; 
              current_row_index++)  {
                if ( ir[current_row_index] >= col ) { // ignore lower tri of matrix
                    pairs[nPair*2] = ir[current_row_index]; // from
                    pairs[nPair*2 + 1] = col; // to
                    sc[nPair] = (termType)Pr[tot]; // potential weight
                    nPair++;
                }
                tot++;
            }
        }
    }
       
    // mexPrintf("Done reading sG got %d pairs\n", nPair);
    
    // check pin[1] has enough columns (=#nodes)
    const mwSize *sdc = mxGetDimensions(pin[1]);
    if (sdc[1] != spd[0])
        mexErrMsgIdAndTxt("robustpn:inputs","Dc must have %d columns to match graph structure", spd[0]);
    nLabel = sdc[0];
    
    
    // check pin[2] is struct array with proper feilds
    if ( mxGetClassID(pin[2]) != mxSTRUCT_CLASS )
        mexErrMsgIdAndTxt("robustpn:inputs","hop must be a struct array");
    nHigher = mxGetNumberOfElements(pin[2]);
    // expecting HOP_N_OF_FIELDS fieds
    if ( mxGetNumberOfFields(pin[2]) != HOP_N_OF_FIELDS )
        mexErrMsgIdAndTxt("robustpn:inputs","hop must have %d fields", HOP_N_OF_FIELDS);
    // chack that we have the right fields
    for ( ii = 0; ii < HOP_N_OF_FIELDS ; ii++ ) {
        hop_fields_indices[ii] = mxGetFieldNumber(pin[2], HOP_FIELDS[ii]);
        if ( hop_fields_indices[ii] < 0 )
            mexErrMsgIdAndTxt("robustpn:inputs","hop is missing %s field", HOP_FIELDS[ii]);
    }
    
    Energy<termType> *energy = new Energy<termType>(nLabel, nVar, nPair, nHigher);

    energy->SetUnaryCost( (termType*)mxGetData(pin[1]) );
    energy->SetPairCost(pairs, sc);
    delete[] pairs; // were copied into energy
    delete[] sc;
    
    // Add the HO potentials
    mxArray *xind, *xw, *xgamma, *xQ;
    int * ind, n;
    termType* w;
    termType* gamma;
    termType Q;
    for ( ii = 0 ; ii < nHigher; ii++ ) {
        xind = mxGetFieldByNumber(pin[2], ii, hop_fields_indices[0]);
        n = mxGetNumberOfElements(xind);
        ind = new int[n]; // allocation for energy
        GetArr(xind, ind, -1); // bias = -1 convert from 1-ind of matlab to 0-ind of C
        
        xw = mxGetFieldByNumber(pin[2], ii, hop_fields_indices[1]);
        if ( mxGetNumberOfElements(xw) != n ) {
            delete energy;
            delete[] ind;
            mexErrMsgIdAndTxt("robustpn:inputs","hop %d: number of indices is different than number of weights", ii);
        }
        w = new termType[n]; // allocation for energy
        GetArr(xw, w);
        
        xgamma = mxGetFieldByNumber(pin[2], ii, hop_fields_indices[2]);
        if ( mxGetNumberOfElements(xgamma) != nLabel+1 ) {
            delete energy;
            delete[] ind;
            delete[] w;
            mexErrMsgIdAndTxt("robustpn:inputs","hop %d: must have exactly %d gamma values", ii, nLabel+1);
        }
        gamma = new termType[nLabel+1];
        GetArr(xgamma, gamma);
        
        xQ = mxGetFieldByNumber(pin[2], ii, hop_fields_indices[3]);
        Q = (termType)mxGetScalar(xQ);
        
        if ( energy->SetOneHOP(n, ind, w, gamma, Q) < 0 ) {
            delete energy;
            delete[] gamma;
            mexErrMsgIdAndTxt("robustpn:inputs","failed to load hop #%d", ii);
        }
        delete[] gamma; // this array is being allocated inside energy
        // mexPrintf("Done reading hop(%d) / %d\n", ii, nHigher);
    }
    
    // mexPrintf("Done reading hops\n");
    /*
     *********************************************************
     * Minimize energy
     **********************************************************
     */
    //initialize alpha expansion - max MAX_ITER iterations
	AExpand<termType> *expand = new AExpand<termType>(energy, MAX_ITER);

    // must have at least one output for the labels
    pout[0] = mxCreateNumericMatrix(1, nVar, mxINT32_CLASS, mxREAL);
    int *solution = (int*)mxGetData(pout[0]);

    // Do we have an initial guess of labeling ?
    if ( nin == 4 ) {
        if ( mxGetNumberOfElements(pin[3]) != nVar )
            mexErrMsgIdAndTxt("robustpn:inputs","Initial guess of labeling must have exactly %d elements", nVar);
        GetArr(pin[3], solution, -1); // convert Matlab's 1-ind labeling to C's 0-ind labeling
    } else {
        // default initial labeling
        memset(solution, 0, nVar*sizeof(int));
    }
    termType ee[3];
    termType E(0);
    E = expand->minimize(solution, ee);

    if (nout>1) {
        pout[1] = mxCreateNumericMatrix(1, 4, mxGetClassID(pin[1]), mxREAL);
        termType *pE = (termType*)mxGetData(pout[1]);
        pE[0] = ee[0];
        pE[1] = ee[1];
        pE[2] = ee[2];
        pE[3] = E;
    }
    // de-allocate
    delete expand;
    delete energy;
}
コード例 #14
0
ファイル: superpixels.cpp プロジェクト: bwhite/imseg
void expandOnLabel(int label,int width,int height,int num_pixels,
				   vector<int> &Seeds,int numSeeds, vector<int> &labeling,
				   vector<Value> &horizWeights,vector<Value> &vertWeights,Value lambda,
				   vector<Value> &diag1Weights,vector<Value> &diag2Weights,int PATCH_SIZE,
				   vector<int> &changeMask, vector<int> &changeMaskNew,image<uchar> *I,
				   int TYPE,float variance)
{
	int seedX,seedY,startX,startY,endX,endY,numVars,blockWidth;
	getBounds(width,height,Seeds,&seedX,&seedY,&startX,&startY,&endX,&endY,label,PATCH_SIZE);

	int somethingChanged = 0;

	for ( int y = startY; y <= endY; y++ )
		for ( int x = startX; x <= endX; x++ )
			if ( changeMask[x+y*width] == 1 )
			{
				somethingChanged = 1;
				break;
			}

	
	if ( somethingChanged == 0)
		return;
		
	blockWidth = endX-startX+1;
	numVars   = (endY-startY+1)*blockWidth;
	

	vector<Var> variables(numVars);
	Energy<int,int,int> *e = new Energy<int,int,int>(numVars,numVars*3);

	for ( int i = 0; i < numVars; i++ )
		variables[i] = e->add_variable();

	Value LARGE_WEIGHT = lambda*NUM_COLORS*8;

	// First fix the border to old labels, except the edges of the image
	for ( int y = startY; y <= endY; y++ ){
		if ( startX != 0 )
			e->add_term1(variables[(y-startY)*blockWidth],0,LARGE_WEIGHT);
		else if ( y == startY || y == endY)
			e->add_term1(variables[(y-startY)*blockWidth],0,LARGE_WEIGHT);

		if( endX != width -1 )
			e->add_term1(variables[(endX-startX)+(y-startY)*blockWidth],0,LARGE_WEIGHT);
		else if ( y == startY || y == endY)
			e->add_term1(variables[(endX-startX)+(y-startY)*blockWidth],0,LARGE_WEIGHT);
	}

	for ( int x = startX+1; x < endX; x++){
		if ( startY != 0 )
			e->add_term1(variables[(x-startX)],0,LARGE_WEIGHT);
		if ( endY != height - 1)
			e->add_term1(variables[(x-startX)+(endY-startY)*blockWidth],0,LARGE_WEIGHT);
	}

	// add links to center of the patch for color constant superpixels
	if ( TYPE == 1 )
	{
		int color = imRef(I,seedX,seedY);

		for ( int y = startY+1; y < endY; y++ )
			for ( int x = startX+1; x < endX; x++){
				Value E00=0,E01=0,E10=LARGE_WEIGHT,E11=0;

				if (seedX != x && seedY != y)
					e->add_term2(variables[(x-startX)+(y-startY)*blockWidth],
					         variables[(seedX-startX)+(seedY-startY)*blockWidth],E00,E01,E10,E11);

				int diff = abs(imRef(I,x,y)-color);
				int maxD = (int) variance*MULTIPLIER_VAR;
				if ( diff > maxD ) diff = maxD;

				int oldLabel = labeling[x+y*width];
				int oldY = Seeds[oldLabel]/width;
				int oldX = Seeds[oldLabel]-oldY*width;
				int oldColor = imRef(I,oldX,oldY);
				int oldDiff = abs(imRef(I,x,y)-oldColor);
				if ( oldDiff > maxD ) oldDiff = maxD;

				if ( oldDiff > diff) 
					 e->add_term1(variables[(x-startX)+(y-startY)*blockWidth],oldDiff-diff,0);
				else e->add_term1(variables[(x-startX)+(y-startY)*blockWidth],0,diff-oldDiff);
			}
	}


	// First set up horizontal links 
	for ( int y = startY; y <= endY; y++ )
		for ( int x = startX+1; x <=endX; x++){
			int oldLabelPix       = labeling[x+y*width];
			int oldLabelNeighbPix = labeling[x-1+y*width];
			Value E00,E01,E10,E11=0;

			if ( oldLabelPix != oldLabelNeighbPix ) 
				E00 = horizWeights[x-1+y*width];
			else E00 = 0;
			if ( oldLabelNeighbPix != label ) 
				E01 = horizWeights[x-1+y*width];
			else E01 = 0;
			if ( label != oldLabelPix )
				E10 = horizWeights[x-1+y*width];
			else E10 = 0;
			
			e->add_term2(variables[(x-startX)-1+(y-startY)*blockWidth],variables[(x-startX)+(y-startY)*blockWidth],E00,E01,E10,E11);
		}

	// Next set up vertical links
	for ( int y = startY+1; y <= endY; y++ )
		for ( int x = startX; x <=endX; x++){
			int oldLabelPix       = labeling[x+y*width];
			int oldLabelNeighbPix = labeling[x+(y-1)*width];
			Value E00,E01,E10,E11=0;

			if ( oldLabelPix != oldLabelNeighbPix ) 
				E00 = vertWeights[x+(y-1)*width];
			else E00 = 0;
			if ( oldLabelNeighbPix != label ) 
				E01 = vertWeights[x+(y-1)*width];
			else E01 = 0;
			if ( label != oldLabelPix )
				E10 = vertWeights[x+(y-1)*width];
			else E10 = 0;

			
			e->add_term2(variables[(x-startX)+(y-startY-1)*blockWidth],variables[(x-startX)+(y-startY)*blockWidth],E00,E01,E10,E11);
		}

	// Next set up diagonal links 
	float SQRT_2= 1/sqrt(2.0);
	for ( int y = startY+1; y <= endY; y++ )
		for ( int x = startX+1; x <=endX; x++){
			int oldLabelPix       = labeling[x+y*width];
			int oldLabelNeighbPix = labeling[x-1+(y-1)*width];
			Value E00,E01,E10,E11=0;
			
			if ( oldLabelPix != oldLabelNeighbPix ) 
				E00 = SQRT_2*diag1Weights[x-1+(y-1)*width];
			else E00 = 0;
			if ( oldLabelNeighbPix != label ) 
				E01 = SQRT_2*diag1Weights[x-1+(y-1)*width];
			else E01 = 0;
			if ( label != oldLabelPix )
				E10 = SQRT_2*diag1Weights[x-1+(y-1)*width];
			else E10 = 0;
			
			e->add_term2(variables[(x-startX)-1+(y-startY-1)*blockWidth],variables[(x-startX)+(y-startY)*blockWidth],E00,E01,E10,E11);
		}
	
	// More diagonal links
	for ( int y = startY+1; y <= endY; y++ )
		for ( int x = startX; x <=endX-1; x++){
			int oldLabelPix       = labeling[x+y*width];
			int oldLabelNeighbPix = labeling[(x+1)+(y-1)*width];
			Value E00,E01,E10,E11=0;

			if ( oldLabelPix != oldLabelNeighbPix ) 
				E00 = SQRT_2*diag2Weights[(x+1)+(y-1)*width];
			else E00 = 0;
			if ( oldLabelNeighbPix != label ) 
				E01 = SQRT_2*diag2Weights[(x+1)+(y-1)*width];
			else E01 = 0;
			if ( label != oldLabelPix )
				E10 = SQRT_2*diag2Weights[(x+1)+(y-1)*width];
			else E10 = 0;

			e->add_term2(variables[(x-startX+1)+(y-startY-1)*blockWidth],variables[(x-startX)+(y-startY)*blockWidth],E00,E01,E10,E11);
		}


	e->minimize();

	for ( int y = startY; y <= endY; y++ )
		for ( int x = startX; x <= endX; x++){
			if ( e->get_var(variables[(x-startX)+(y-startY)*blockWidth]) != 0 )
			{
				if ( labeling[x+y*width] != label ){
					labeling[x+y*width] = label; 
					changeMaskNew[x+y*width] = 1;
					changeMask[x+y*width] = 1;
				}
			}
		}


	delete e;
}
コード例 #15
0
ファイル: kz1.cpp プロジェクト: ZhaozhengPlus/stereo
/* computes the minimum a-expansion configuration */
void Match::KZ1_Expand(Coord a)
{
	Coord p, q, d, dq;
	Energy::Var var, qvar;
	int E_old, delta, E00, E0a, Ea0, Eaa;
	int k;

	Energy *e = new Energy(KZ1_error_function);

	/* initializing */
	for (p.y=0; p.y<im_size.y; p.y++)
	for (p.x=0; p.x<im_size.x; p.x++)
	{
		d = Coord(IMREF(x_left, p), IMREF(y_left, p));
		if (a == d) IMREF(node_vars_left, p) = VAR_ACTIVE;
		else
		{
			IMREF(node_vars_left, p) = var = e -> add_variable();
			if (d.x == OCCLUDED) e -> ADD_TERM1(var, KZ1_OCCLUSION_PENALTY, 0);
		}

		d = Coord(IMREF(x_right, p), IMREF(y_right, p));
		if (a == -d) IMREF(node_vars_right, p) = VAR_ACTIVE;
		else
		{
			IMREF(node_vars_right, p) = var = e -> add_variable();
			if (d.x == OCCLUDED) e -> ADD_TERM1(var, KZ1_OCCLUSION_PENALTY, 0);
		}
	}

	for (p.y=0; p.y<im_size.y; p.y++)
	for (p.x=0; p.x<im_size.x; p.x++)
	{
		/* data and visibility terms */
		d = Coord(IMREF(x_left, p), IMREF(y_left, p));
		var = (Energy::Var) IMREF(node_vars_left, p);
		if (d != a && d.x != OCCLUDED)
		{
			q = p + d;
			if (q>=Coord(0,0) && q<im_size)
			{
				qvar = (Energy::Var) IMREF(node_vars_right, q);
				dq = Coord(IMREF(x_right, q), IMREF(y_right, q));
				if (d == -dq)
				{
					delta = (is_blocked(a, d)) ? INFINITY : 0;
					e -> ADD_TERM2(var, qvar, KZ1_data_penalty(p, q), delta, delta, 0);
				}
				else if (is_blocked(a, d))
				{
					e -> ADD_TERM2(var, qvar, 0, INFINITY, 0, 0);
				}
			}
		}

		q = p + a;
		if (q>=Coord(0,0) && q<im_size)
		{
			qvar = (Energy::Var) IMREF(node_vars_right, q);
			dq = Coord(IMREF(x_right, q), IMREF(y_right, q));

			E0a = (is_blocked(d, a)) ? INFINITY : 0;
			Ea0 = (is_blocked(-dq, a)) ? INFINITY : 0;
			Eaa = KZ1_data_penalty(p, q);

			if (var != VAR_ACTIVE)
			{
				if (qvar != VAR_ACTIVE) e -> ADD_TERM2(var, qvar, 0, E0a, Ea0, Eaa);
				else                    e -> ADD_TERM1(var, E0a, Eaa);
			}
			else
			{
				if (qvar != VAR_ACTIVE) e -> ADD_TERM1(qvar, Ea0, Eaa);
				else                    e -> add_constant(Eaa);
			}
		}

		/* left smoothness term */
		for (k=0; k<NEIGHBOR_NUM; k++)
		{
			q = p + NEIGHBORS[k];
			if ( ! ( q>=Coord(0,0) && q<im_size ) ) continue;
			qvar = (Energy::Var) IMREF(node_vars_left, q);
			dq = Coord(IMREF(x_left, q), IMREF(y_left, q));

			if (var != VAR_ACTIVE && qvar != VAR_ACTIVE)
				E00 = KZ1_smoothness_penalty_left(p, q, d, dq);
			if (var != VAR_ACTIVE)
				E0a = KZ1_smoothness_penalty_left(p, q, d, a);
			if (qvar != VAR_ACTIVE)
				Ea0 = KZ1_smoothness_penalty_left(p, q, a, dq);

			if (var != VAR_ACTIVE)
			{
				if (qvar != VAR_ACTIVE) e -> ADD_TERM2(var, qvar, E00, E0a, Ea0, 0);
				else                    e -> ADD_TERM1(var, E0a, 0);
			}
			else
			{
				if (qvar != VAR_ACTIVE) e -> ADD_TERM1(qvar, Ea0, 0);
				else                    {}
			}
		}

		/* right smoothness term */
		d = Coord(IMREF(x_right, p), IMREF(y_right, p));
		var = (Energy::Var) IMREF(node_vars_right, p);
		for (k=0; k<NEIGHBOR_NUM; k++)
		{
			q = p + NEIGHBORS[k];
			if ( ! ( q>=Coord(0,0) && q<im_size ) ) continue;
			qvar = (Energy::Var) IMREF(node_vars_right, q);
			dq = Coord(IMREF(x_right, q), IMREF(y_right, q));

			if (var != VAR_ACTIVE && qvar != VAR_ACTIVE)
				E00 = KZ1_smoothness_penalty_right(p, q, d, dq);
			if (var != VAR_ACTIVE)
				E0a = KZ1_smoothness_penalty_right(p, q, d, -a);
			if (qvar != VAR_ACTIVE)
				Ea0 = KZ1_smoothness_penalty_right(p, q, -a, dq);

			if (var != VAR_ACTIVE)
			{
				if (qvar != VAR_ACTIVE) e -> ADD_TERM2(var, qvar, E00, E0a, Ea0, 0);
				else                    e -> ADD_TERM1(var, E0a, 0);
			}
			else
			{
				if (qvar != VAR_ACTIVE) e -> ADD_TERM1(qvar, Ea0, 0);
				else                    {}
			}
		}

		/* visibility term */
		if (d.x != OCCLUDED && is_blocked(a, -d))
		{
			q = p + d;
			if (q>=Coord(0,0) && q<im_size)
			{
				if (d.x != -IMREF(x_left, q) || d.y != -IMREF(y_left, q))
					e -> ADD_TERM2(var, (Energy::Var) IMREF(node_vars_left, q),
					               0, INFINITY, 0, 0);
			}
		}
	}

	E_old = E;
	E = e -> minimize();

	if (E < E_old)
	{
		for (p.y=0; p.y<im_size.y; p.y++)
		for (p.x=0; p.x<im_size.x; p.x++)
		{
			var = (Energy::Var) IMREF(node_vars_left, p);

			if (var != VAR_ACTIVE && e->get_var(var)==VALUE1)
			{
				IMREF(x_left, p) = a.x; IMREF(y_left, p) = a.y;
			}

			var = (Energy::Var) IMREF(node_vars_right, p);

			if (var != VAR_ACTIVE && e->get_var(var)==VALUE1)
			{
				IMREF(x_right, p) = -a.x; IMREF(y_right, p) = -a.y;
			}
		}
	}

	delete e;
}