Example #1
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  // variables for GBP  
  int*** assignInd = 0;
  double* bethe = 0;
  GBPPreProcessor* processor = 0;
  MRF* reg_mrf = 0;
  int* extractSingle = 0;
  int** extractPairs = 0;
  RegionLevel* regions = 0;
  vector<RegionLevel>* in_allRegions = 0;
  // variables for user
  Region** all_regions = 0;

  // **************************************************************************
  // reading input arguments
  // **************************************************************************

  if (nrhs != 8) {
    mexErrMsgTxt("Incorrect number of input arguments.");
  }

  // check number of output arguments
  if ((nlhs > 0) && (nlhs != 7)) {
    mexErrMsgTxt("Incorrect number of output arguments.");
  }

  // get number of nodes and adjMat
  vector<Nodes>* adjMat = new vector<Nodes>();
  fillAdjMat(prhs[0],*adjMat);
  int num_nodes = adjMat->size();

  // define the MRF
  MRF* mrf = new MRF(*adjMat);
  // get local potentials
  fillLocalMat(prhs[2],mrf);
  
  // get pairwise potentials
  fillPsiMat(prhs[1],mrf);
  
  // get regions
  bool allLevels = (int)(mxGetScalar(prhs[4])) > 0;
  if (allLevels) {
    in_allRegions = new vector<RegionLevel>();
    in_allRegions->clear();
    fillRegionLevels(prhs[3],*in_allRegions);
  }
  else {
    regions = new RegionLevel();
    fillRegions(prhs[3],*regions);
  }

  bool trw = (int)(mxGetScalar(prhs[5])) > 0;
  double* countingNode = 0;
  if (trw) {
    countingNode = new double[num_nodes];
    fillDouble(prhs[6], countingNode, num_nodes);
  }

  bool full = (int)(mxGetScalar(prhs[7])) > 0;


  // **************************************************************************
  // making pre-process
  // **************************************************************************

  if (allLevels) {
    processor = new GBPPreProcessor(in_allRegions, mrf, trw, full, countingNode);
  }
  else {
    processor = new GBPPreProcessor(*regions, mrf, trw, full, countingNode);
    regions->clear();
    delete regions;
    regions = 0;
  }

  all_regions = processor->getAllRegions();
  reg_mrf = processor->getRegionMRF();
  assignInd = processor->getAssignTable();
  bethe = processor->getBethe();
  extractSingle = processor->getExtractSingle();
  extractPairs = processor->getExtractPairs();

  
  // **************************************************************************
  // writing output arguments
  // **************************************************************************

  // output: 1. regions - a cell array with vectors of the nodes in each region
  //         2. regions' adj-matrix
  //         3. regions' local potentials
  //         4. assignment-indices (for each parent's assignment, the index of
  //                                the relevant son's assignment)
  //         5. bethe
  //         6. extractSingle (for each node, from which region its belief
  //                           should be extracted)
  //         7. extractPairs  (for each pair of neighbours, from which region
  //                           its pairwise beliefs should be extracted)
  
  if (nlhs > 0) {

    int num_regs = reg_mrf->N;
    int regs_dims[2] = {1,num_regs};
    
    // assign: 1. regions 2. regions' adj-matrix & 3. regions' local potentials
    plhs[0] = mxCreateCellArray(2,regs_dims);
    plhs[1] = mxCreateCellArray(2,regs_dims);
    plhs[2] = mxCreateCellArray(2,regs_dims);

    for (int i=0; i<num_regs; i++) {

      // regions
      Region* region = all_regions[i];
      int reg_i_size = (int)(region->size());
      int reg_i_dims[2] = {1,reg_i_size};
      mxArray* reg_i = mxCreateNumericArray(2,reg_i_dims,mxDOUBLE_CLASS, mxREAL);
      double* reg_i_ptr = mxGetPr(reg_i);
      for (int n=0; n<reg_i_size; n++) {
	reg_i_ptr[n] = (double)((*region)[n]);
      }
      mxSetCell(plhs[0],i,reg_i);
      
      // adj-matrix
      int adj_dims[2] = {1,reg_mrf->neighbNum(i)};
      mxArray* adj_i = mxCreateNumericArray(2,adj_dims,mxDOUBLE_CLASS, mxREAL);
      double* adj_i_ptr = mxGetPr(adj_i);
      for (int n=0; n<reg_mrf->neighbNum(i); n++) {
	adj_i_ptr[n] = (double)(reg_mrf->adjMat[i][n] + 1);
      }
      mxSetCell(plhs[1],i,adj_i);

      // local potentials
      int local_dims[2] = {reg_mrf->V[i],1};
      mxArray* local_i = mxCreateNumericArray(2, local_dims, mxDOUBLE_CLASS, mxREAL);
      double* local_i_ptr = mxGetPr(local_i);
      for (int xi=0; xi<reg_mrf->V[i]; xi++) {
	local_i_ptr[xi] = reg_mrf->localMat[i][xi];
      }
      mxSetCell(plhs[2],i,local_i);

    }

    // assign: 4. assignment indices
    int ass_dims[2] = {1,num_regs};
    plhs[3] = mxCreateCellArray(2,ass_dims);

    for (int i=0; i<num_regs; i++) {
      
      int ass_i_dims[2] = {1,reg_mrf->neighbNum(i)};
      mxArray* ass_i = mxCreateCellArray(2,ass_i_dims);
      
      for (int n=0; n<reg_mrf->neighbNum(i); n++) {
	int j = reg_mrf->adjMat[i][n];
	if (i<j) {
	  int ass_val_dims[2] = {1,reg_mrf->V[i]};
	  mxArray* ass_ij = mxCreateNumericArray(2, ass_val_dims, mxDOUBLE_CLASS, mxREAL);
	  double* ass_ij_ptr = mxGetPr(ass_ij);
	  for (int xi=0; xi<reg_mrf->V[i]; xi++) {
	    ass_ij_ptr[xi] = (double)(assignInd[i][n][xi]);
	  }
	  mxSetCell(ass_i, n, ass_ij);
	}
      }
      
      mxSetCell(plhs[3], i, ass_i);
    }

    // assign: 5. bethe
    plhs[4] = mxCreateNumericArray(2, regs_dims, mxDOUBLE_CLASS, mxREAL);
    double* bethe_ptr = mxGetPr(plhs[4]);
    for (int i=0; i<num_regs; i++) {
      bethe_ptr[i] = bethe[i];
    }

    // assign: 6. extractSingle
    int extract_dims[2] = {1,num_nodes};

    plhs[5] = mxCreateNumericArray(2, extract_dims, mxDOUBLE_CLASS, mxREAL);
    double* exSing_ptr = mxGetPr(plhs[5]);
    for (int i=0; i<num_nodes; i++) {
      exSing_ptr[i] = extractSingle[i];
    }
    
    // assign: 7. extractPairs
    plhs[6] = mxCreateCellArray(2, extract_dims);

    for (int i=0; i<num_nodes; i++) {

      int exPair_i_dim[2] = {1,mrf->neighbNum(i)};
      mxArray* exPair_i = mxCreateNumericArray(2, exPair_i_dim, mxDOUBLE_CLASS, mxREAL);
      double* exPair_i_ptr = mxGetPr(exPair_i);
      for (int n=0; n<mrf->neighbNum(i); n++) {
	exPair_i_ptr[n] = extractPairs[i][n];
      }

      mxSetCell(plhs[6], i, exPair_i);
    }
    
  }

  // **************************************************************************
  // free memory
  // **************************************************************************

  delete mrf;
  mrf = 0;
  delete adjMat;
  adjMat = 0;
  if (countingNode != 0) {
    delete[] countingNode;
    countingNode = 0;
  }
}
Example #2
0
int main(int argc, char **argv)
{
    try {
        // parse command line
        if (argc != 3)
            throw CError(usage, argv[0]);
        int argn = 1;
        char *dataFileName = argv[argn++];
	char *outstem = argv[argn++];

	int writeParams = 1;
	int writeTimings = 1;

	FILE *debugfile = createDebugFile(writeParams, outstem, verbose, argc, argv);

	// Load datafile 
	int width, height, nLabels;
	std::vector<int> gt, data, lrPairwise, udPairwise;
	MRF::CostVal *dataCostArray, *hCue, *vCue;

	if (verbose)
	    fprintf(stderr, "Loading datafile...\n");
	
	LoadDataFile(dataFileName, width, height, nLabels, dataCostArray, hCue, vCue);

	DataCost *dcost = new DataCost(dataCostArray);
	SmoothnessCost *scost = new SmoothnessCost(1, 1, 1, hCue, vCue);
	EnergyFunction *energy = new EnergyFunction(dcost, scost);

	if (verbose)
	    fprintf(stderr, "Running optimization...\n");
	fflush(stderr);

	int MRFalg = aRunAll;

	int outerIter, innerIter;
	MRF *mrf = NULL;
	for (int numAlg = aICM; numAlg <= aBPM; numAlg++) {
	    outerIter = MAXITER;
	    innerIter = 1;
	    if (MRFalg < aRunAll && numAlg != MRFalg) continue;

	    startAlgInitTimer();

	    switch (numAlg) {
	    case aICM:       mrf = new ICM(width, height, nLabels, energy); innerIter = 5; break;
	    case aExpansion: mrf = new Expansion(width, height, nLabels, energy); break;
	    case aSwap:      mrf = new Swap(width, height, nLabels, energy); break;
	    case aTRWS:      mrf = new TRWS(width, height, nLabels, energy); break;
	    case aBPS:       mrf = new BPS(width, height, nLabels, energy);  
		//innerIter = 5; 
		break;
	    case aBPM:       mrf = new MaxProdBP(width, height, nLabels, energy);
		//innerIter = 2; 
		break;
	    default: throw new CError("unknown algorithm number");
	    }
	    if (debugfile)
		fprintf(debugfile, "******* Running %s for up to %d x %d iterations\n",
			algs[numAlg], outerIter, innerIter);

	    mrf->initialize();
	    mrf->clearAnswer();

	    bool initializeToWTA = false;
	    if (initializeToWTA) {
		if (debugfile)
		    fprintf(debugfile, "performing WTA\n");
		CByteImage disp;
		WTA(dataCostArray, width, height, nLabels, disp);
		writeDisparities(disp, 255, "WTA.png", debugfile);
		setDisparities(disp, mrf);
	    } else {
		mrf->clearAnswer();
	    }

	    float initTime = getAlgInitTime();
	    
	    FILE *timefile = createTimeFile(writeTimings, outstem, algs[numAlg], debugfile);

	    runAlg(mrf, numAlg, debugfile, timefile, outerIter, innerIter, initTime);

	    // save resulting labels as image
	    CShape sh(width, height, 1);
	    CByteImage outimg(sh);
	    int n = 0;
	    for (int y = 0; y < height; y++) {
		for (int x = 0; x < width; x++) {
		    outimg.Pixel(x, y, 0) = 255* mrf->getLabel(n);
		    n++;
		}
	    }

	    char fname[500];
	    sprintf(fname, "%s-%s.png", outstem, algs[numAlg]);
	    WriteImageVerb(outimg, fname, 1);
	    delete mrf;
	}

	if (writeParams)
	    fclose(debugfile);

	delete energy;
	delete scost;
	delete dcost;
	delete [] dataCostArray;
	delete [] hCue;
	delete [] vCue;
    }
    catch (CError &err) {
        fprintf(stderr, err.message);
        fprintf(stderr, "\n");
        return -1;
    }
    catch (bad_alloc) {
	fprintf(stderr, "*** Error: not enough memory\n");
	exit(1);
    }

    return 0;
}
Example #3
0
dtype compute_graph2(int num_parts_y,int num_parts_x,dtype *costs,int num_lab_y,int num_lab_x,dtype *data,int numhyp,dtype* lscr,int *reslab)
{
    MRF* mrf;
    //Expansion* mrf; 
    //EnergyFunction *energy;
    MRF::EnergyVal E;
    double lowerBound;
    float t,tot_t;
    int iter;

    int seed = 1124285485;
    srand(seed);

    dtype scr;
    //copy costs in local memory
    //dtype V[maxlab*maxlab];
    st_cost_v_y=costs;
    st_cost_v_x=costs+num_parts_x*num_parts_y;
    st_cost_h_y=costs+2*num_parts_x*num_parts_y;
    st_cost_h_x=costs+3*num_parts_x*num_parts_y;
    st_parts_x=num_parts_x;
    st_parts_y=num_parts_y;
    st_num_lab_x=num_lab_x;
    st_num_lab_y=num_lab_y;
    st_numlab=num_lab_y*num_lab_x;//num_parts_x*num_parts_y;//num_labels;
    //dtype* V=(dtype*)malloc(st_numlab*st_numlab*sizeof(dtype));
    clock_t t0,t1;
    t0 = clock ();
    int l1,l2;

         DataCost *dt         = new DataCost(data);
        //SmoothnessCost *sm   = new SmoothnessCost(smoothApp2);
        //SmoothnessCost *sm   = new SmoothnessCost(smoothApp3);
        //SmoothnessCost *sm   = new SmoothnessCost(smoothApp4);
        SmoothnessCost *sm   = new SmoothnessCost(smoothApp5);
        //SmoothnessCost *sm   = new SmoothnessCost(V, st_cost_x, st_cost_y);
        //SmoothnessCost *sm   = new SmoothnessCost(1, 100, 1, st_cost_v_x, st_cost_v_y);
        EnergyFunction *energy = new EnergyFunction(dt,sm);

        //int *ilaborder = new int[st_numlab];
        //int *sumpart = new int[st_numlab];
        ///new way
        //printf("%d,%d\n",num_parts_x,num_parts_y);
        //mrf = new MaxProdBP(num_parts_x,num_parts_y,num_parts_x*num_parts_y,energy);
        //mrf = new BPS(num_parts_x,num_parts_y,num_parts_x*num_parts_y,energy);
        //mrf = new Swap(num_parts_x,num_parts_y,num_lab_y*num_lab_x,energy);
        mrf = new Expansion(num_parts_x,num_parts_y,num_lab_y*num_lab_x,energy);
        //((Expansion*)mrf)->setLabelOrder(0);
        //if (laborder!=NULL)
        //    ((Expansion*)mrf)->setMyLabelOrder(laborder);
        Energy* trees=NULL;
        //((Expansion*)mrf)->setEnergies(trees);
        int* sol=NULL;
        //((Expansion*)mrf)->setSolutions(sol);
#include<time.h>
        //clock_t t0,t1;
        //mrf = new TRWS(num_parts_x,num_parts_y,num_lab_y*num_lab_x,energy);
        //mrf = new ICM(num_parts_x,num_parts_y,st_numlab,energy);

	    // can disable caching of values of general smoothness function:
	    //mrf->dontCacheSmoothnessCosts();
        //t0 = clock ();
	    mrf->initialize();
        tot_t = 0;
        //printf("Before C\n");
	    for (iter=0; iter<numhyp; iter++) 
        {
            //((Expansion*)mrf)->setLabelOrder(0);
            /*for (int lab=0;lab<st_numlab;lab++)
                for (int part=0;part<num_parts_y*num_parts_x;part++)
                    sumpart[lab]+=data[part*st_numlab+lab];
            argsort(sumpart,ilaborder,st_numlab);*/
            /*for (int i = 0; i < st_numlab; i++)
                ilaborder[i]=i;*/
            //((Expansion*)mrf)->setMyLabelOrder(ilaborder);
		    mrf->optimize(3, t);
            //printf("After C\n");
    		E = mrf->totalEnergy();
    		lowerBound = mrf->lowerBound();
    		tot_t = tot_t + t ;
		*lscr=-E;
		lscr++;
            //t0 = clock ();
            for ( int  i = 0; i < num_parts_y*num_parts_x; i++ )
            {
                int aux=mrf->getLabel(i);
    			reslab[iter*num_parts_y*num_parts_x+i] = aux;//gc->whatLabel(i);
                //data[i*st_numlab+aux]=1;//delete solution
                for (int rx=-1;rx<2;rx++)
                {
                    for (int ry=-1;ry<2;ry++)  
                    {                       
                        int pp=aux+rx+ry*st_num_lab_x;
                        pp=maxi(pp,0);
                        pp=mini(pp,st_numlab);
                        data[pp+i*st_numlab]=1;//delete solution
                    }
                }
                //printf("%d ",reslab[i]);
            }
            //t1 = clock ();   
            //printf("t0=%d t1=%d Diff %f \n",t0,t1,float(t1-t0)/CLOCKS_PER_SEC);
            //trees=((Expansion*)mrf)->getEnergies();
            //sol=((Expansion*)mrf)->getSolutions();        
	    }

	    delete mrf;
    t1 = clock ();
    //printf("t0=%d t1=%d Diff %f \n",t0,t1,float(t1-t0)/CLOCKS_PER_SEC);
    return -E;
}
Example #4
0
int main()
{
    MRF* mrf;
    EnergyFunction *eng;
    MRF::EnergyVal E;
    float t,tot_t;
    int iter;

    int seed = 1124285485;
    srand(seed);

    // There are 4 sample energies below to play with. Uncomment 1 at a time 

    //eng = generate_DataARRAY_SmoothFIXED_FUNCTION();
    //eng = generate_DataARRAY_SmoothTRUNCATED_LINEAR();
    eng = generate_DataARRAY_SmoothTRUNCATED_QUADRATIC();
    //eng = generate_DataFUNCTION_SmoothGENERAL_FUNCTION();



    ////////////////////////////////////////////////
    //                     ICM                    //
    ////////////////////////////////////////////////
    printf("\n*******Started ICM *****\n");

    mrf = new ICM(sizeX,sizeY,K,eng);
    mrf->initialize();
    mrf->clearAnswer();
    
    E = mrf->totalEnergy();
    printf("Energy at the Start= %d (%d,%d)\n", E,mrf->smoothnessEnergy(),mrf->dataEnergy());

    tot_t = 0;
    for (iter=0; iter<6; iter++)
    {
        mrf->optimize(10, t);

        E = mrf->totalEnergy();
        tot_t = tot_t + t ;
        printf("energy = %d (%f secs)\n", E, tot_t);
    }

    delete mrf;

    ////////////////////////////////////////////////
    //          Graph-cuts expansion              //
    ////////////////////////////////////////////////
    printf("\n*******Started the graph-cuts expansion *****\n");
    mrf = new Expansion(sizeX,sizeY,K,eng);
    mrf->initialize();
    mrf->clearAnswer();
    
    E = mrf->totalEnergy();
    printf("Energy at the Start= %d (%d,%d)\n", E,mrf->smoothnessEnergy(),mrf->dataEnergy());

    tot_t = 0;
    for (iter=0; iter<6; iter++)
    {
        mrf->optimize(1, t);

        E = mrf->totalEnergy();
        tot_t = tot_t + t ;
        printf("energy = %d (%f secs)\n", E, tot_t);
    }

    delete mrf;

    ////////////////////////////////////////////////
    //          Graph-cuts swap                   //
    ////////////////////////////////////////////////

    printf("\n*******Started the graph-cuts swap *****\n");
    mrf = new Swap(sizeX,sizeY,K,eng);
    mrf->initialize();
    mrf->clearAnswer();
    
    E = mrf->totalEnergy();
    printf("Energy at the Start= %d (%d,%d)\n", E,mrf->smoothnessEnergy(),mrf->dataEnergy());

    tot_t = 0;
    for (iter=0; iter<6; iter++)
    {
        mrf->optimize(1, t);

        E = mrf->totalEnergy();
        tot_t = tot_t + t ;
        printf("energy = %d (%f secs)\n", E, tot_t);
    }

    
    delete mrf;


    ////////////////////////////////////////////////
    //          Belief Propagation                //
    ////////////////////////////////////////////////

    printf("\n*******  Started MaxProd Belief Propagation *****\n");
    mrf = new MaxProdBP(sizeX,sizeY,K,eng);
    mrf->initialize();
    mrf->clearAnswer();
    
    E = mrf->totalEnergy();
    printf("Energy at the Start= %d (%d,%d)\n", E,mrf->smoothnessEnergy(),mrf->dataEnergy());

    tot_t = 0;
    for (iter=0; iter < 10; iter++)
    {
        mrf->optimize(1, t);

        E = mrf->totalEnergy();
        tot_t = tot_t + t ;
        printf("energy = %d (%f secs)\n", E, tot_t);
    }

    
    delete mrf;

    return 0;
}
Example #5
0
dtype compute_graph(int num_parts_y,int num_parts_x,dtype *costs,int num_lab_y,int num_lab_x,dtype *data,int *laborder,int *reslab)
{
    MRF* mrf;
    //Expansion* mrf; 
    //EnergyFunction *energy;
    MRF::EnergyVal E;
    double lowerBound;
    float t,tot_t;
    int iter;

    int seed = 1124285485;
    srand(seed);

    dtype scr;
    //copy costs in local memory
    //dtype V[maxlab*maxlab];
    st_cost_v_y=costs;
    st_cost_v_x=costs+num_parts_x*num_parts_y;
    st_cost_h_y=costs+2*num_parts_x*num_parts_y;
    st_cost_h_x=costs+3*num_parts_x*num_parts_y;
    st_parts_x=num_parts_x;
    st_parts_y=num_parts_y;
    st_num_lab_x=num_lab_x;
    st_num_lab_y=num_lab_y;
    st_numlab=num_lab_y*num_lab_x;//num_parts_x*num_parts_y;//num_labels;
    //dtype* V=(dtype*)malloc(st_numlab*st_numlab*sizeof(dtype));
    clock_t t0,t1;
    t0 = clock ();
    int l1,l2;

    //printf("At least here!!!\n");

    /*for (l1=0;l1<st_numlab;l1++)
    {
        for (l2=0;l2<st_numlab;l2++)
        {    
            int x1=l1%num_lab_x;
            int y1=l1/num_lab_x;
            int x2=l2%num_lab_x;    
            int y2=l2/num_lab_x;            
            V[l1*st_numlab+l2]=abs(x1-x2)+abs(y1-y2); 
        }
    }*/
    t1 = clock ();
    //printf("t0=%d t1=%d Diff %f",t0,t1,float(t1-t0)/CLOCKS_PER_SEC);
	//try{
        DataCost *dt         = new DataCost(data);
        //SmoothnessCost *sm   = new SmoothnessCost(smoothApp2);
        //SmoothnessCost *sm   = new SmoothnessCost(smoothApp3);
        //SmoothnessCost *sm   = new SmoothnessCost(smoothApp4);
        SmoothnessCost *sm   = new SmoothnessCost(smoothApp5);
        //SmoothnessCost *sm   = new SmoothnessCost(V, st_cost_x, st_cost_y);
        //SmoothnessCost *sm   = new SmoothnessCost(1, 100, 1, st_cost_v_x, st_cost_v_y);
        EnergyFunction *energy = new EnergyFunction(dt,sm);

//		GCoptimizationGeneralGraph *gc = new GCoptimizationGeneralGraph(num_parts,num_labels);

//		// set up the needed data to pass to function for the data costs
//		//ForDataFn toFn;
//		//toFn.data = data;
//		//toFn.numLab = num_labels;
//		//gc->setDataCost(&dataFn,&toFn);

//        gc->setDataCost(data);
//		
//		// smoothness comes from function pointer
//		gc->setSmoothCost(&smoothApp);

//        // now set up a graph neighborhood system
//        // use only the upper part of the matrix
//        for (int py=0; py<num_parts; py++ )
//            for (int px=py+1; px<num_parts; px++)
//                if (connect[py*num_parts+px]>0)
//                {
//                    //gc->setNeighbors(px,py);
//                    gc->setNeighbors(py,px);
//                }
//		
//		//printf("\nBefore optimization energy is %f",gc->compute_energy());
//		gc->expansion(10);// run expansion for 2 iterations. For swap use gc->swap(num_iterations);
//        scr=gc->compute_energy();
//		//printf("\nAfter optimization energy is %f \n",scr);

        ///new way
        //printf("%d,%d\n",num_parts_x,num_parts_y);
        //mrf = new MaxProdBP(num_parts_x,num_parts_y,num_parts_x*num_parts_y,energy);
        //mrf = new BPS(num_parts_x,num_parts_y,num_parts_x*num_parts_y,energy);
        //mrf = new Swap(num_parts_x,num_parts_y,num_lab_y*num_lab_x,energy);
        mrf = new Expansion(num_parts_x,num_parts_y,num_lab_y*num_lab_x,energy);
        //((Expansion*)mrf)->setLabelOrder(0);
        if (laborder!=NULL)
            ((Expansion*)mrf)->setMyLabelOrder(laborder);
        Energy* trees=NULL;
        //((Expansion*)mrf)->setEnergies(trees);
        int* sol=NULL;
        //((Expansion*)mrf)->setSolutions(sol);
#include<time.h>
        //clock_t t0,t1;
        //mrf = new TRWS(num_parts_x,num_parts_y,num_lab_y*num_lab_x,energy);
        //mrf = new ICM(num_parts_x,num_parts_y,st_numlab,energy);

	    // can disable caching of values of general smoothness function:
	    //mrf->dontCacheSmoothnessCosts();
        t0 = clock ();
	    mrf->initialize();
        t1 = clock ();
        //mrf->setCues(st_cost_x,st_cost_y);
	    //mrf->clearAnswer();

//        for ( int  i = 0; i < num_parts_y*num_parts_x; i++ )
//        {
//            mrf->setLabel(i,reslab[i]);
//			reslab[i] = mrf->getLabel(i);//gc->whatLabel(i);
//            printf("%d ",reslab[i]);
//        }           
	    //printf("+++++\n");
//	    E = mrf->totalEnergy();
	    //printf("Energy at the Start= %g (%g,%g)\n", (float)E,
		//   (float)mrf->smoothnessEnergy(), (float)mrf->dataEnergy());
        //printf("t0=%d t1=%d Diff %f",t0,t1,float(t1-t0)/CLOCKS_PER_SEC);
	    tot_t = 0;
        //printf("Before C\n");
	    for (iter=0; iter<1; iter++) 
        {
		    mrf->optimize(1, t);
            //printf("After C\n");
    		E = mrf->totalEnergy();
    		lowerBound = mrf->lowerBound();
    		tot_t = tot_t + t ;
            //printf("Energy= %g (%g,%g)\n", (float)E,
		   //(float)mrf->smoothnessEnergy(), (float)mrf->dataEnergy());
    		//printf("energy = %g, lower bound = %f (%f secs)\n", (float)E, lowerBound, tot_t);
	    }
        for ( int  i = 0; i < num_parts_y*num_parts_x; i++ )
        {
			reslab[i] = mrf->getLabel(i);//gc->whatLabel(i);
            //printf("%d ",reslab[i]);
        }   
        trees=((Expansion*)mrf)->getEnergies();
        sol=((Expansion*)mrf)->getSolutions();        

	    delete mrf;
	//}
	//catch (GCException e){
	//	e.Report();
	//}

	//delete [] result;
	//delete [] data;
    //free(V);
    return -E;

}
int main(int argc, char **argv)
{
    MRF* mrf;
    EnergyFunction *energy;
    MRF::EnergyVal E;
    double lowerBound;
    float t,tot_t;
    int iter;

    int seed = 1124285485;
    srand(seed);

    int Etype = 0;

    if (argc != 2) {
	fprintf(stderr, usage, argv[0]);
	exit(1);
    }
    
    if (argc > 1)
	Etype = atoi(argv[1]);

    try {
	switch(Etype) {
	    // Here are 4 sample energies to play with.
	case 0:
	    energy = generate_DataARRAY_SmoothFIXED_FUNCTION();
	    fprintf(stderr, "using fixed (array) smoothness cost\n");
	    break;
	case 1:
	    energy = generate_DataARRAY_SmoothTRUNCATED_LINEAR();
	    fprintf(stderr, "using truncated linear smoothness cost\n");
	    break;
	case 2:
	    energy = generate_DataARRAY_SmoothTRUNCATED_QUADRATIC();
	    fprintf(stderr, "using truncated quadratic smoothness cost\n");
	    break;
	case 3:
	    energy = generate_DataFUNCTION_SmoothGENERAL_FUNCTION();
	    fprintf(stderr, "using general smoothness functions\n");
	    break;
	default:
	    fprintf(stderr, usage, argv[0]);
	    exit(1);
	}

	bool runICM       = true;
	bool runExpansion = true;
	bool runSwap      = true;
	bool runMaxProdBP = true;
	bool runTRWS      = true;
	bool runBPS       = true;

	////////////////////////////////////////////////
	//                     ICM                    //
	////////////////////////////////////////////////
	if (runICM) {
	    printf("\n*******Started ICM *****\n");

	    mrf = new ICM(sizeX,sizeY,numLabels,energy);
	    mrf->initialize();
	    mrf->clearAnswer();

	    E = mrf->totalEnergy();
	    printf("Energy at the Start= %g (%g,%g)\n", (float)E,
		   (float)mrf->smoothnessEnergy(), (float)mrf->dataEnergy());

	    tot_t = 0;
	    for (iter=0; iter<6; iter++) {
		mrf->optimize(10, t);
		
		E = mrf->totalEnergy();
		tot_t = tot_t + t ;
		printf("energy = %g (%f secs)\n", (float)E, tot_t);
	    }

	    delete mrf;
	}

	////////////////////////////////////////////////
	//          Graph-cuts expansion              //
	////////////////////////////////////////////////
	if (runExpansion) {
	    printf("\n*******Started graph-cuts expansion *****\n");
	    mrf = new Expansion(sizeX,sizeY,numLabels,energy);
	    mrf->initialize();
	    mrf->clearAnswer();
	    
	    E = mrf->totalEnergy();
	    printf("Energy at the Start= %g (%g,%g)\n", (float)E,
		   (float)mrf->smoothnessEnergy(), (float)mrf->dataEnergy());

#ifdef COUNT_TRUNCATIONS
	    truncCnt = totalCnt = 0;
#endif
	    tot_t = 0;
	    for (iter=0; iter<6; iter++) {
		mrf->optimize(1, t);

		E = mrf->totalEnergy();
		tot_t = tot_t + t ;
		printf("energy = %g (%f secs)\n", (float)E, tot_t);
	    }
#ifdef COUNT_TRUNCATIONS
	    if (truncCnt > 0)
		printf("***WARNING: %d terms (%.2f%%) were truncated to ensure regularity\n", 
		       truncCnt, (float)(100.0 * truncCnt / totalCnt));
#endif

	    delete mrf;
	}

	////////////////////////////////////////////////
	//          Graph-cuts swap                   //
	////////////////////////////////////////////////
	if (runSwap) {
	    printf("\n*******Started graph-cuts swap *****\n");
	    mrf = new Swap(sizeX,sizeY,numLabels,energy);
	    mrf->initialize();
	    mrf->clearAnswer();
	    
	    E = mrf->totalEnergy();
	    printf("Energy at the Start= %g (%g,%g)\n", (float)E,
		   (float)mrf->smoothnessEnergy(), (float)mrf->dataEnergy());

#ifdef COUNT_TRUNCATIONS
	    truncCnt = totalCnt = 0;
#endif
	    tot_t = 0;
	    for (iter=0; iter<8; iter++) {
		mrf->optimize(1, t);

		E = mrf->totalEnergy();
		tot_t = tot_t + t ;
		printf("energy = %g (%f secs)\n", (float)E, tot_t);
	    }
#ifdef COUNT_TRUNCATIONS
	    if (truncCnt > 0)
		printf("***WARNING: %d terms (%.2f%%) were truncated to ensure regularity\n", 
		       truncCnt, (float)(100.0 * truncCnt / totalCnt));
#endif

   
	    delete mrf;
	}

	////////////////////////////////////////////////
	//          Belief Propagation                //
	////////////////////////////////////////////////
	if (runMaxProdBP) {
	    printf("\n*******  Started MaxProd Belief Propagation *****\n");
	    mrf = new MaxProdBP(sizeX,sizeY,numLabels,energy);
	    mrf->initialize();
	    mrf->clearAnswer();
	    
	    E = mrf->totalEnergy();
	    printf("Energy at the Start= %g (%g,%g)\n", (float)E,
		   (float)mrf->smoothnessEnergy(), (float)mrf->dataEnergy());

	    tot_t = 0;
	    for (iter=0; iter < 10; iter++) {
		mrf->optimize(1, t);

		E = mrf->totalEnergy();
		tot_t = tot_t + t ;
		printf("energy = %g (%f secs)\n", (float)E, tot_t);
	    }

	    
	    delete mrf;
	}

	////////////////////////////////////////////////
	//                  TRW-S                     //
	////////////////////////////////////////////////
	if (runTRWS) {
	    printf("\n*******Started TRW-S *****\n");
	    mrf = new TRWS(sizeX,sizeY,numLabels,energy);

	    // can disable caching of values of general smoothness function:
	    //mrf->dontCacheSmoothnessCosts();

	    mrf->initialize();
	    mrf->clearAnswer();

	    
	    E = mrf->totalEnergy();
	    printf("Energy at the Start= %g (%g,%g)\n", (float)E,
		   (float)mrf->smoothnessEnergy(), (float)mrf->dataEnergy());

	    tot_t = 0;
	    for (iter=0; iter<10; iter++) {
		mrf->optimize(10, t);

		E = mrf->totalEnergy();
		lowerBound = mrf->lowerBound();
		tot_t = tot_t + t ;
		printf("energy = %g, lower bound = %f (%f secs)\n", (float)E, lowerBound, tot_t);
	    }

	    delete mrf;
	}

	////////////////////////////////////////////////
	//                  BP-S                     //
	////////////////////////////////////////////////
	if (runBPS) {
	    printf("\n*******Started BP-S *****\n");
	    mrf = new BPS(sizeX,sizeY,numLabels,energy);

	    // can disable caching of values of general smoothness function:
	    //mrf->dontCacheSmoothnessCosts();
		
	    mrf->initialize();
	    mrf->clearAnswer();
	    
	    E = mrf->totalEnergy();
	    printf("Energy at the Start= %g (%g,%g)\n", (float)E,
		   (float)mrf->smoothnessEnergy(), (float)mrf->dataEnergy());

	    tot_t = 0;
	    for (iter=0; iter<10; iter++) {
		mrf->optimize(10, t);

		E = mrf->totalEnergy();
		tot_t = tot_t + t ;
		printf("energy = %g (%f secs)\n", (float)E, tot_t);
	    }

	    delete mrf;
	}
    }
    catch (std::bad_alloc) {
	fprintf(stderr, "*** Error: not enough memory\n");
	exit(1);
    }

    return 0;
}
Example #7
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{

  // **************************************************************************
  // reading input arguments
  // **************************************************************************
  
  if (nrhs != 12) {
    mexErrMsgTxt("Incorrect number of inputs.");
  }

  // check number of output arguments
  if (nlhs > 3) {
    mexErrMsgTxt("Too many output arguments.");
  }
  
  // get factors
  RegionLevel* factors = new RegionLevel();
  fillRegions(prhs[0],*factors);

  // get number of nodes and local potentials
  Potentials* local = 0;
  int* V = 0;
  // get N
  int num_nodes = (int)(mxGetScalar(prhs[1]));
  int local_nd = mxGetNumberOfDimensions(prhs[2]);
  const int* local_dim = mxGetDimensions(prhs[2]);
  bool local_given = (local_nd == 2 && mxIsCell(prhs[2]));
  
  V = new int[num_nodes];

  if (local_given) {
    if (num_nodes != local_dim[0]*local_dim[1]) {
      mexErrMsgTxt("number of nodes inconsistent with size of local potentials\n");
    }
    // get V and local potentials
    local = new Potentials[num_nodes];
    for (int i=0; i<num_nodes; i++) {
      mxArray* local_i = mxGetCell(prhs[2],i);
      int i_nd = mxGetNumberOfDimensions(local_i);
      const int* i_dim = mxGetDimensions(local_i);
      if (i_nd != 2 || i_dim[1] != 1) {
	mexErrMsgTxt("each cell {i} in the local cell-array must be a column vector (num_values(i))x1");
      }

      // get V
      V[i] = i_dim[0];
      // get local
      local[i] = new Potential[V[i]];
      double* localPtr = mxGetPr(local_i);
      for (int xi=0; xi<V[i]; xi++) {
	local[i][xi] = localPtr[xi];
      }
    
    }
  }
  else {
    // get V
    if (local_dim[0]*local_dim[1] > 1) {
      if (num_nodes != local_dim[0]*local_dim[1]) {
	mexErrMsgTxt("number of nodes inconsistent with size of cardinalities\n");
      }
      double* VPtr = mxGetPr(prhs[2]);
      for (int i=0; i<num_nodes; i++) {
	V[i] = (int)(VPtr[i]);
      }
    }
    else {
      int card = (int)(mxGetScalar(prhs[2]));
      for (int i=0; i<num_nodes; i++) {
	V[i] = card;
      }
    }
  }

  // create adjacencies matrix with edges between nodes in the same factor
  int num_factors = factors->size();
  vector<Nodes>* adjMat = new vector<Nodes>();
  adjMat->resize(num_nodes);
  for (int r=0; r<num_factors; r++) {
    Region& reg = (*factors)[r];
    for (int i=0; i<reg.size(); i++) {
      for (int j=0; j<reg.size(); j++) {
	if (i!= j) {
	  bool insert = true;
	  for (int k=0; k<(*adjMat)[reg[i]].size(); k++) {
	    if ((*adjMat)[reg[i]][k] == reg[j]) {
	      insert = false;
	      break;
	    }
	  }
	  if (insert) {
	    (*adjMat)[reg[i]].push_back(reg[j]);
	  }
	}
      }
    }
  }

  MRF* mrf = new MRF(*adjMat);
  for (int i=0; i<num_nodes; i++) {
    mrf->V[i] = V[i];
  }
  delete[] V;

  if (local != 0) {
    mrf->initLocalPotentials();

    // fill localMat
    for (int i=0; i<num_nodes; i++) {
      for (int xi=0; xi<mrf->V[i]; xi++) {
	mrf->localMat[i][xi] = local[i][xi];
      }
      delete[] local[i];
    }
    delete[] local;
  }
  // read the factor-potentials

  Potentials* factorPot = new Potentials[num_factors];
  
  int fac_nd = mxGetNumberOfDimensions(prhs[3]);
  const int* fac_dim = mxGetDimensions(prhs[3]);
  if (fac_nd != 2 || fac_dim[0]*fac_dim[1] != num_factors || !mxIsCell(prhs[3])) {
    mexErrMsgTxt("factor-potentials must be a cell array in size 1x(num_factors), each cell {i} is a column vector in length (num_values(i))");
  }
  for (int i=0; i<num_factors; i++) {
    mxArray* facPot_i = mxGetCell(prhs[3],i);
    const int* i_dim = mxGetDimensions(facPot_i);

    int num_states = i_dim[0] * i_dim[1];
    factorPot[i] = new Potential[num_states];

    // get potentials
    fillDouble(facPot_i,factorPot[i],num_states);
  }

  // read the rest of parameters
  
  int maxIter = (int)(mxGetScalar(prhs[4]));

  SumOrMax sumOrMax = (SumOrMax)((int)(mxGetScalar(prhs[5])));
  double gbp_alpha = mxGetScalar(prhs[6]);

  bool trw = ((int)(mxGetScalar(prhs[7]))) > 0;
  double* countingNode = new double[num_nodes];
  fillDouble(prhs[8], countingNode, num_nodes);

  bool full = ((int)(mxGetScalar(prhs[9]))) > 0;
  
  // get initial messages, if given
  double*** initMsg = 0;
  int initM_nd = mxGetNumberOfDimensions(prhs[10]);
  const int* initM_dim = mxGetDimensions(prhs[10]);
  if ((initM_nd == 2) && mxIsCell(prhs[10])) {
    int num_regs = initM_dim[0] * initM_dim[1];
    initMsg = new double**[num_regs];
    for (int i=0; i<num_regs; i++) {

      mxArray* initMsg_i = mxGetCell(prhs[10],i);

      int msg_i_nd = mxGetNumberOfDimensions(initMsg_i);
      const int* msg_i_dim = mxGetDimensions(initMsg_i);
      if ((msg_i_nd != 2) || !mxIsCell(initMsg_i)) {
	mexErrMsgTxt("each cell {i} in initMsg for GBP should be a cell array in length of number of neighbour-regions to region i\n");
      }
      int Ni = msg_i_dim[0] * msg_i_dim[1];
      initMsg[i] = new double*[Ni];
      for (int n=0; n<Ni; n++) {
	mxArray* initMsg_ij = mxGetCell(initMsg_i,n);
	const int* msg_ij_dim = mxGetDimensions(initMsg_ij);
	int numStates = msg_ij_dim[0] * msg_ij_dim[1];
	initMsg[i][n] = new double[numStates];
	fillDouble(initMsg_ij,initMsg[i][n],numStates);
      }
    }
  }

  // get tepmerature
  double temperature = mxGetScalar(prhs[11]);
  mrf->setTemperature(temperature);
  
  // **************************************************************************
  // pre-process
  // **************************************************************************
  GBPPreProcessor* processor = new GBPPreProcessor(*factors, mrf, trw, full, countingNode, factorPot);
  MRF* reg_mrf = processor->getRegionMRF();
  int*** assignInd = processor->getAssignTable();
  double* bethe = processor->getBethe();

  // **************************************************************************
  // create the algorithm
  // **************************************************************************
  GBP* algorithm = new GBP(reg_mrf,assignInd,bethe,sumOrMax,gbp_alpha,maxIter,initMsg);

  // **************************************************************************
  // make inference
  // **************************************************************************
  int converged;
  double** beliefs = algorithm->inference(&converged);
  bool marg;
  if (sumOrMax==SUM) {
    marg = ((GBP*)algorithm)->isSumMarg(.0001);
  }
  else {
    marg = ((GBP*)algorithm)->isMaxMarg(.0001);
  }
  if (!marg) {
    converged = (converged>0 ? -2 : -1);
    mexWarnMsgTxt("resulted beliefs are not marginalizable\n");
  }

  // extract single beliefs
  double** singleBeliefs = new double*[num_nodes];
  for (int i=0; i<num_nodes; i++) {
    singleBeliefs[i] = new double[mrf->V[i]];      
  }
  processor->extractSingle(beliefs,singleBeliefs,sumOrMax);
  // **************************************************************************
  // assign results to output argument
  // **************************************************************************
  if (nlhs > 0) {
    int nodes_dims[2] = {1,num_nodes};
    plhs[0] = mxCreateCellArray(2,nodes_dims); // single beliefs

    for (int i=0; i<num_nodes; i++) {

      // node beliefs
      int val_dims[2] = {mrf->V[i],1};
      mxArray* bel_i = mxCreateNumericArray(2,val_dims,mxDOUBLE_CLASS, mxREAL);
      double* resBelPtr = mxGetPr(bel_i);
      for (int xi=0; xi<mrf->V[i]; xi++) {
	resBelPtr[xi] = singleBeliefs[i][xi];
      }
      mxSetCell(plhs[0],i,bel_i);

    }
    if (nlhs > 1) {
      plhs[1] = mxCreateDoubleScalar(converged); // convergence flag

      if (nlhs > 2) {
	int factors_dims[2] = {1,num_factors};
	plhs[2] = mxCreateCellArray(2,factors_dims); // factor beliefs

	for (int i=0; i<num_factors; i++) {

	  // factor beliefs
	  int val_dims[2] = {reg_mrf->V[i],1};
	  mxArray* bel_i = mxCreateNumericArray(2,val_dims,mxDOUBLE_CLASS, mxREAL);
	  double* resBelPtr = mxGetPr(bel_i);
	  for (int xi=0; xi<reg_mrf->V[i]; xi++) {
	    resBelPtr[xi] = beliefs[i][xi];
	  }
	  mxSetCell(plhs[2],i,bel_i);

	}
      }
    }
  } 

  // **************************************************************************
  // free memory
  // **************************************************************************
  delete algorithm;
  algorithm = 0;
  
  if (singleBeliefs != 0) {
    for (int i=0; i<num_nodes; i++) {
      delete[] singleBeliefs[i];
    }
    delete[] singleBeliefs;    
    singleBeliefs = 0;
  }
  if (processor != 0) {
    delete processor;
    processor = 0;
  }

  delete factors;
  factors = 0;

  delete[] countingNode;
  countingNode = 0;

  delete mrf;
  mrf = 0;
  delete adjMat;
  adjMat = 0;
}
Example #8
0
int main(int argc, char **argv)
{
    MRF* mrf;
    EnergyFunction *energy;
    MRF::EnergyVal E;
    double lowerBound;
    float t,tot_t;
    int iter;

    int seed = 1124285485;
    srand(seed);

    int Etype = 0;

    if (argc != 2) {
	fprintf(stderr, usage, argv[0]);
	exit(1);
    }
    
    if (argc > 1)
	Etype = atoi(argv[1]);

    try {
	switch(Etype) {
	    // Here are 4 sample energies to play with.
	case 0:
	    energy = generate_DataARRAY_SmoothFIXED_FUNCTION();
	    fprintf(stderr, "using fixed (array) smoothness cost\n");
	    break;
	case 1:
	    energy = generate_DataARRAY_SmoothTRUNCATED_LINEAR();
	    fprintf(stderr, "using truncated linear smoothness cost\n");
	    break;
	case 2:
	    energy = generate_DataARRAY_SmoothTRUNCATED_QUADRATIC();
	    fprintf(stderr, "using truncated quadratic smoothness cost\n");
	    break;
	case 3:
	    energy = generate_DataFUNCTION_SmoothGENERAL_FUNCTION();
	    fprintf(stderr, "using general smoothness functions\n");
	    break;
	default:
	    fprintf(stderr, usage, argv[0]);
	    exit(1);
	}

	////////////////////////////////////////////////
	//          Belief Propagation                //
	////////////////////////////////////////////////
	if (runMaxProdBP) {
	    printf("\n*******  Started MaxProd Belief Propagation *****\n");
	    mrf = new MaxProdBP(sizeX,sizeY,numLabels,energy);
	    mrf->initialize();
	    mrf->clearAnswer();
	    
	    E = mrf->totalEnergy();
	    printf("Energy at the Start= %g (%g,%g)\n", (float)E,
		   (float)mrf->smoothnessEnergy(), (float)mrf->dataEnergy());

	    tot_t = 0;
	    for (iter=0; iter < 10; iter++) {
		mrf->optimize(1, t);

		E = mrf->totalEnergy();
		tot_t = tot_t + t ;
		printf("energy = %g (%f secs)\n", (float)E, tot_t);
	    }

	    
	    delete mrf;
	}
    return 0;
}
Example #9
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{

  // **************************************************************************
  // variables declaration
  // **************************************************************************

  // variables for both Loopy and GBP
  double*** initMsg = 0;
  bool trw = false;
  bool full = true;
  double* countingNode = 0; // relevant for loopy, or for gbp if trw = true
  
  
  // variables for Loopy
  Strategy strategy;
  SumOrMax sumOrMax;
  double gbp_alpha;
  double** rho = 0; // relevant if trw = true
  bool saveTime = false;

  // variables for GBP
  int*** assignInd = 0;
  double* bethe = 0;
  GBPPreProcessor* processor = 0;
  MRF* reg_mrf = 0;
  RegionLevel* regions = 0;
  vector<RegionLevel>* allRegions = 0;
  Potentials* bigRegsPot = 0;
  bool allLevels = false;
  bool regBeliefs = false;
  int num_regs = 0;

  // variables for Monte-Carlo
  int burningTime, samplingInterval, num_samples;
  int* startX = 0;

  // for Loopy, Mean-Field
  bool logspace = false;
  bool logBels = false;

  // for Loopy,GBP,Mean-Field
  int maxIter;
  double threshold;

  
  // **************************************************************************
  // reading input arguments
  // **************************************************************************

  // check number of input arguments.
  // arguments should be:
  //
  // adjMat - 1xN cell array, each cell {i} is a row vector with the indices of
  //          i's neighbours
  //
  // lambda - there are 2 forms for lambda:
  //          1. in general MRF algorithms (loopy, gbp, gibbs, mean-field) :
  //             lambda should be a cell array of 1xN, each cell {i} is a cell
  //             array of 1xneighbNum(i). each cell {i}{n} is a VixVj matrix,
  //             where j is the n-th neighbour of i
  //          2. in PottsMRF alhorithms (monte-carlo algorithms which are planned
  //             for Potts model, i.e. metropolis and the cluster algorithms
  //             wolff and swendsen-wang) :
  //             here lambda should be 1xN cell array, each cell {i} is a row
  //             vector with the strength of interaction of i with each of its
  //             neighbours
  // note: Psi{i,j} = exp( [lambda(i,j), 0; 0, lambda(i,j)] )
  //
  // local - cell array of Nx1, each cell {i} is a row vector of length Vi
  //
  // algorithm - integer representing the inference algorithm to use, see the
  //             enumerator algorithmType at the top of this page
  //
  // temperature - double scalar, the temperature of the system
  //
  // model - integeger representing the model, see the enumerator in "definitions.h"
  //
  // trw - use Tree-Reweighted
  //
  // for other parameters required for each algorithm see the header of "inference.m"
  //
  //
  // note: N = number of nodes, V = number of possible values
  
  if (nrhs < 10 || nrhs > 20) {
    mexErrMsgTxt("Incorrect number of inputs.");
  }

  // get algorithm-type
  algorithmType algo_type = (algorithmType)((int)(mxGetScalar(prhs[3])));
  Model model = (Model)((int)(mxGetScalar(prhs[5])));
  bool potts_model = ((model==POTTS) ||
		      (algo_type==AT_WOLFF) ||
		      (algo_type==AT_SWENDSEN_WANG));
  bool monte_carlo = ((algo_type==AT_GIBBS) ||
		      (algo_type==AT_WOLFF) ||
		      (algo_type==AT_SWENDSEN_WANG) ||
		      (algo_type==AT_METROPOLIS));
  // check number of output arguments
  if ((nlhs > 6) || ((nlhs > 2) && (algo_type != AT_GBP) && (algo_type != AT_LOOPY))) {
    mexErrMsgTxt("Too many output arguments.");
  }

  // get number of nodes and adjMat
  vector<Nodes>* adjMat = new vector<Nodes>();
  fillAdjMat(prhs[0],*adjMat);
  int num_nodes = adjMat->size();

  // define the MRF
  MRF* mrf = 0;
  if (potts_model) {
    mrf = new PottsMRF(*adjMat);
  }
  else {
    mrf = new MRF(*adjMat);
  }
  
  // get local potentials
  fillLocalMat(prhs[2],mrf);
  
  // get pairwise potentials
  if (potts_model) {
    fillLambdaMat(prhs[1],(PottsMRF*)mrf);
  }
  else {
    fillPsiMat(prhs[1],mrf);
  }

  // For monte-carlo algorithms (gibbs, wolff, swendsen-wang), get
  // the initial state and the sampling parameters
  if (monte_carlo) {
    if (nrhs != 10) {
      mexErrMsgTxt("incorrect number of inputs");
    }

    startX = new int[num_nodes];
    fillInitialAssignment(prhs[6], startX, num_nodes);

    // get burningTime, samplingInterval, num_samples
    burningTime = (int)(mxGetScalar(prhs[7]));
    samplingInterval = (int)(mxGetScalar(prhs[8]));
    num_samples = (int)(mxGetScalar(prhs[9]));
    
  }
  else {
    // for all non-monte-carlo-algorithms (Mean-Field, BP & GBP)
    maxIter = (int)(mxGetScalar(prhs[6]));
    threshold = mxGetScalar(prhs[7]);
    // get log-space flag
    logspace = ((int)(mxGetScalar(prhs[8]))) > 0;
    mrf->logspace = logspace;
    logBels = ((int)(mxGetScalar(prhs[9]))) > 0;

    if (algo_type == AT_LOOPY) {

      // for loopy belief propagation:
      // get sum-or-max-flag and strategy

      if (nrhs != 17) {
	mexErrMsgTxt("incorrect number of inputs");
      }
	
      sumOrMax = (SumOrMax)((int)(mxGetScalar(prhs[10])));
      strategy = (Strategy)((int)(mxGetScalar(prhs[11])));
      trw = ((int)(mxGetScalar(prhs[12]))) > 0;
      if (trw) {
	rho = new double*[num_nodes];
	for (int i=0; i<num_nodes; i++) {
	  rho[i] = new double[mrf->neighbNum(i)];
	}
	fillRhoMat(prhs[13],mrf,rho);
      }
	
      // get save-time flag
      saveTime = ((int)(mxGetScalar(prhs[15]))) > 0;

      // get initial messages, if given
      int initM_nd = mxGetNumberOfDimensions(prhs[14]);
      const int* initM_dim = mxGetDimensions(prhs[14]);
      if ((initM_nd == 2) && (initM_dim[0] == 1) &&
	  (initM_dim[1] == num_nodes) && mxIsCell(prhs[14])) {
	initMsg = new double**[num_nodes];
	for (int i=0; i<num_nodes; i++) {
	  mxArray* initMsg_i = mxGetCell(prhs[14],i);
	  int Ni = mrf->neighbNum(i);
	  int len = (saveTime ? num_nodes : Ni);
	  initMsg[i] = new double*[len];
	  if (saveTime) {
	    for (int j=0; j<num_nodes; j++) {
	      initMsg[i][j] = 0;
	    }
	  }
	  for (int n=0; n<Ni; n++) {
	    int j = mrf->adjMat[i][n];
	    int nei = (saveTime ? j : n);
	    initMsg[i][nei] = new double[mrf->V[j]];
	    mxArray* initMsg_ij = mxGetCell(initMsg_i,nei);
	    fillDouble(initMsg_ij,initMsg[i][nei],mrf->V[j]);
	  }
	}
      }

      int count_nd = mxGetNumberOfDimensions(prhs[16]);
      const int* count_dim = mxGetDimensions(prhs[16]);
      if ((count_nd==2) && (count_dim[0]*count_dim[1]==num_nodes)) {
	countingNode = new double[num_nodes];
	fillDouble(prhs[16], countingNode, num_nodes);

	// incorporate local potentials into pairwise
	for (int i=0; i<num_nodes; i++) {
	  if (mrf->neighbNum(i)>0) {
	    int j = mrf->adjMat[i][0];
	    if (i<j) {
	      for (int xi=0; xi<mrf->V[i]; xi++) {
		for (int xj=0; xj<mrf->V[j]; xj++) {
		  mrf->lambdaMat[i][0][xi][xj] *= mrf->localMat[i][xi];
		}
		mrf->localMat[i][xi] = 1.0;
	      }
	    }
	    else {
	      int n = 0;
	      while (mrf->adjMat[j][n] != i) {
		n++;
	      }
	      for (int xi=0; xi<mrf->V[i]; xi++) {
		for (int xj=0; xj<mrf->V[j]; xj++) {
		  mrf->lambdaMat[j][n][xj][xi] *= mrf->localMat[i][xi];
		}
		mrf->localMat[i][xi] = 1.0;
	      }	      
	    }
	  }
	  else {
	    mexPrintf("warning: the graph is not connected\n");
	  }
	}
      }
    }

    if (algo_type == AT_GBP) {

      // for generalized belief propagation:
      // get regions, regions-adj (if given), sum-or-max-flag
      // and alpha

      if (nrhs != 20) {
	mexErrMsgTxt("incorrect number of inputs");
      }

      allLevels = (int)(mxGetScalar(prhs[11])) > 0;
      if (allLevels) {
	allRegions = new vector<RegionLevel>();
	allRegions->clear();
	fillRegionLevels(prhs[10],*allRegions);
      }
      else {
	regions = new RegionLevel();
	fillRegions(prhs[10],*regions);
      }

      sumOrMax = (SumOrMax)((int)(mxGetScalar(prhs[12])));
      gbp_alpha = mxGetScalar(prhs[13]);

      trw = ((int)(mxGetScalar(prhs[14]))) > 0;
      if (trw) {
	countingNode = new double[num_nodes];
	fillDouble(prhs[15], countingNode, num_nodes);
      }
      full = ((int)(mxGetScalar(prhs[16]))) > 0;

      // get initial messages, if given
      int initM_nd = mxGetNumberOfDimensions(prhs[17]);
      const int* initM_dim = mxGetDimensions(prhs[17]);
      if ((initM_nd == 2) && mxIsCell(prhs[17])) {
	num_regs = initM_dim[0] * initM_dim[1];
	initMsg = new double**[num_regs];
	for (int i=0; i<num_regs; i++) {

	  mxArray* initMsg_i = mxGetCell(prhs[17],i);

	  int msg_i_nd = mxGetNumberOfDimensions(initMsg_i);
	  const int* msg_i_dim = mxGetDimensions(initMsg_i);
	  if ((msg_i_nd != 2) || !mxIsCell(initMsg_i)) {
	    mexErrMsgTxt("each cell {i} in initMsg for GBP should be a cell array in length of number of neighbour-regions to region i\n");
	  }
	  int Ni = msg_i_dim[0] * msg_i_dim[1];
	  initMsg[i] = new double*[Ni];
	  for (int n=0; n<Ni; n++) {
	    mxArray* initMsg_ij = mxGetCell(initMsg_i,n);
	    const int* msg_ij_dim = mxGetDimensions(initMsg_ij);
	    int numStates = msg_ij_dim[0] * msg_ij_dim[1];
	    initMsg[i][n] = new double[numStates];
	    fillDouble(initMsg_ij,initMsg[i][n],numStates);
	  }
	}
      }

      // get potentials for the big regions, if given
      int regPot_nd = mxGetNumberOfDimensions(prhs[18]);
      const int* regPot_dim = mxGetDimensions(prhs[18]);
      if ((regPot_nd == 2) && mxIsCell(prhs[18])) {
	num_regs = regPot_dim[0] * regPot_dim[1];
	bigRegsPot = new Potentials[num_regs];
	for (int i=0; i<num_regs; i++) {

	  mxArray* regPot_i = mxGetCell(prhs[18],i);

	  int regPot_i_nd = mxGetNumberOfDimensions(regPot_i);
	  const int* regPot_i_dim = mxGetDimensions(regPot_i);
	  if (regPot_i_nd != 2) {
	    mexErrMsgTxt("each cell {i} in big-regions' potentials for GBP should be a vector in length of number of possible states for the region i\n");
	  }
	  int Vi = regPot_i_dim[0] * regPot_i_dim[1];
	  bigRegsPot[i] = new Potential[Vi];
	  fillDouble(regPot_i,bigRegsPot[i],Vi);
	}	
      }

      // if true - get the region beliefs (instead of the single beliefs)
      regBeliefs = ((int)(mxGetScalar(prhs[19]))) > 0;

    }
  }

  // get tepmerature
  double temperature = mxGetScalar(prhs[4]);
  mrf->setTemperature(temperature);
  
  // **************************************************************************
  // create the algorithm
  // **************************************************************************

  InferenceAlgorithm* algorithm = 0;
  switch (algo_type) {

    case AT_LOOPY:

      if (saveTime) {
	if (logspace) {
	  algorithm = new LogLoopySTime(mrf,sumOrMax,strategy,maxIter,rho,initMsg,logBels,threshold);
	}
	else {
	  algorithm = new LoopySTime(mrf,sumOrMax,strategy,maxIter,rho,initMsg,threshold);
	}
      }
      else {
	if (logspace) {
	  if (countingNode != 0) {
	    algorithm = new LogPairsGBP(mrf,sumOrMax,strategy,maxIter,countingNode,initMsg,logBels,threshold);
	  }
	  else {
	    algorithm = new LogLoopy(mrf,sumOrMax,strategy,maxIter,rho,initMsg,logBels,threshold);
	  }
	}
	else {
	  if (countingNode != 0) {
	    algorithm = new PairsGBP(mrf,sumOrMax,strategy,maxIter,countingNode,initMsg,threshold);
	  }
	  else {
	    algorithm = new Loopy(mrf,sumOrMax,strategy,maxIter,rho,initMsg,threshold);
	  }
	}
      }
      break;

    case AT_GBP:
      if (allLevels) {
	processor = new GBPPreProcessor(allRegions, mrf, trw, full, countingNode, bigRegsPot);
      }
      else {
	processor = new GBPPreProcessor(*regions, mrf, trw, full, countingNode, bigRegsPot);
	regions->clear();
	delete regions;
	regions = 0;
      }

      reg_mrf = processor->getRegionMRF();
      assignInd = processor->getAssignTable();
      bethe = processor->getBethe();

      if (logspace) {
	algorithm = new LogGBP(reg_mrf,assignInd,bethe,sumOrMax,gbp_alpha,maxIter,initMsg,logBels,threshold);
      }
      else {
	algorithm = new GBP(reg_mrf,assignInd,bethe,sumOrMax,gbp_alpha,maxIter,initMsg,threshold);
      }
      
      break;

    case AT_GIBBS:

      algorithm = new Gibbs(mrf,startX,burningTime,samplingInterval,num_samples);

      delete[] startX;
      startX = 0;
      
      break;

    case AT_WOLFF:

      algorithm = new Wolff((PottsMRF*)mrf,startX,burningTime,samplingInterval,num_samples);

      delete[] startX;
      startX = 0;
      
      break;

    case AT_SWENDSEN_WANG:

      algorithm = new SwendsenWang((PottsMRF*)mrf,startX,burningTime,samplingInterval,num_samples);

      delete[] startX;
      startX = 0;
      
      break;

    case AT_METROPOLIS:

      algorithm = new Metropolis(mrf,startX,burningTime,samplingInterval,num_samples);

      delete[] startX;
      startX = 0;
      
      break;

    case AT_MEAN_FIELD:

      if (logspace) {
	algorithm = new LogMeanField(mrf,maxIter,logBels,threshold);
      }
      else {
	algorithm = new MeanField(mrf,maxIter,threshold);
      }

      break;
      
    default:

      mexErrMsgTxt("invalid algorithm type. possible values are: 0-loopy, 1-gbp, 2-gibbs, 3-wolff, 4-swendswen-wang, 5-metropolis, 6-mean-field");
      break;
  }
  

  // **************************************************************************
  // make inference
  // **************************************************************************
  int converged;
  double** beliefs = algorithm->inference(&converged);

  double** singleBeliefs = 0;
  double**** pairBeliefs = 0;
  

  switch (algo_type) {
    
    case AT_LOOPY:
      
      if (nlhs > 2) {
	if (countingNode != 0) {
	  pairBeliefs = ((PairsGBP*)algorithm)->calcPairBeliefs();
	}
	else {
	  pairBeliefs = ((Loopy*)algorithm)->calcPairBeliefs();
	}
      }
      
      break;
      
    case AT_GBP:

      bool marg;
      if (sumOrMax==SUM) {
	marg = ((GBP*)algorithm)->isSumMarg(.0001);
      }
      else {
	marg = ((GBP*)algorithm)->isMaxMarg(.0001);
      }
      if (!marg) {
	converged = -2;
	mexWarnMsgTxt("resulted beliefs are not marginalizable\n");
      }
      if (!regBeliefs || nlhs > 4) {
	
	singleBeliefs = new double*[num_nodes];
	for (int i=0; i<num_nodes; i++) {
	  singleBeliefs[i] = new double[mrf->V[i]];      
	}
	processor->extractSingle(beliefs,singleBeliefs,sumOrMax);
      
	if ((!regBeliefs && nlhs > 2) || (regBeliefs && nlhs > 5)) {
	  pairBeliefs = new double***[num_nodes];
	  for (int i=0; i<num_nodes; i++) {
	    pairBeliefs[i] = new double**[mrf->neighbNum(i)];
	    for (int n=0; n<mrf->neighbNum(i); n++) {
	      pairBeliefs[i][n] = 0;
	      int j = mrf->adjMat[i][n];
	      if (i<j) {
		pairBeliefs[i][n] = new double*[mrf->V[i]];
		for (int xi=0; xi<mrf->V[i]; xi++) {
		  pairBeliefs[i][n][xi] = new double[mrf->V[j]];
		}
	      }
	    }
	  }
	  processor->extractPairs(beliefs,pairBeliefs,sumOrMax);

	}
	if (!regBeliefs) {
	  beliefs = singleBeliefs;
	}
      }
      break;
      
    default:
      
      break;
  }
  
  // **************************************************************************
  // assign results to output argument (if given)
  // **************************************************************************

  if (regBeliefs) {
    int num_regs = reg_mrf->N;
    int regs_dims[2] = {1,num_regs};

    Region** all_regions = processor->getAllRegions();

    // assign: 1. regions 2. regions' adj-matrix 3. region beliefs 4. convergence flag
    plhs[0] = mxCreateCellArray(2,regs_dims);
    plhs[1] = mxCreateCellArray(2,regs_dims);
    plhs[2] = mxCreateCellArray(2,regs_dims);
    plhs[3] = mxCreateDoubleScalar(converged);

    for (int i=0; i<num_regs; i++) {

      // regions
      Region* region = all_regions[i];
      int reg_i_size = (int)(region->size());
      int reg_i_dims[2] = {1,reg_i_size};
      mxArray* reg_i = mxCreateNumericArray(2,reg_i_dims,mxDOUBLE_CLASS, mxREAL);
      double* reg_i_ptr = mxGetPr(reg_i);
      for (int n=0; n<reg_i_size; n++) {
	reg_i_ptr[n] = (double)((*region)[n] + 1);
      }
      mxSetCell(plhs[0],i,reg_i);
      
      // adj-matrix
      int adj_dims[2] = {1,reg_mrf->neighbNum(i)};
      mxArray* adj_i = mxCreateNumericArray(2,adj_dims,mxDOUBLE_CLASS, mxREAL);
      double* adj_i_ptr = mxGetPr(adj_i);
      for (int n=0; n<reg_mrf->neighbNum(i); n++) {
	adj_i_ptr[n] = (double)(reg_mrf->adjMat[i][n] + 1);
      }
      mxSetCell(plhs[1],i,adj_i);

      // region beliefs
      int val_dims[2] = {reg_mrf->V[i],1};
      mxArray* bel_i = mxCreateNumericArray(2,val_dims,mxDOUBLE_CLASS, mxREAL);
      double* resBelPtr = mxGetPr(bel_i);
      for (int xi=0; xi<reg_mrf->V[i]; xi++) {
	resBelPtr[xi] = beliefs[i][xi];
      }
      mxSetCell(plhs[2],i,bel_i);

    }

    if (nlhs > 4) {
      int bel_dims[2] = {1,num_nodes};

      // assign: 5. single beliefs 6. pairwise beliefs (if required)
      plhs[4] = mxCreateCellArray(2,bel_dims);
      if (nlhs > 5) {
	plhs[5] = mxCreateCellArray(2,bel_dims);
      }

      for (int i=0; i<num_nodes; i++) {

	// single beliefs
	int val_dims[2] = {mrf->V[i],1};
	mxArray* bel_i = mxCreateNumericArray(2,val_dims,mxDOUBLE_CLASS, mxREAL);
	double* resBelPtr = mxGetPr(bel_i);
	for (int xi=0; xi<mrf->V[i]; xi++) {
	  resBelPtr[xi] = singleBeliefs[i][xi];
	}
	mxSetCell(plhs[4],i,bel_i);

	// pairwise beliefs
	if (nlhs > 5) {
	  int pair_i_dims[2] = {1, mrf->neighbNum(i)};
	  mxArray* pbel_i = mxCreateCellArray(2,pair_i_dims);
	  
	  for (int n=0; n<mrf->neighbNum(i); n++) {
	    int j = mrf->adjMat[i][n];
	    if (i<j) {
	      int pval_dims[2] = {mrf->V[i], mrf->V[j]};
	      mxArray* pbel_ij = mxCreateNumericArray(2,pval_dims,mxDOUBLE_CLASS,mxREAL);
	      
	      double* resPBelPtr = mxGetPr(pbel_ij);
	      for (int xi=0; xi<mrf->V[i]; xi++) {
		for (int xj=0; xj<mrf->V[j]; xj++) {
		  resPBelPtr[xi + xj*mrf->V[i]] = pairBeliefs[i][n][xi][xj];
		}
	      }
	      mxSetCell(pbel_i, n, pbel_ij);	      
	    }
	  }
	  mxSetCell(plhs[5], i, pbel_i);
	}
      }
    }
  }
  else {
    if (nlhs > 0) {
      int bel_dims[2] = {1,num_nodes};
      plhs[0] = mxCreateCellArray(2,bel_dims);
      for (int i=0; i<num_nodes; i++) {
	int val_dims[2] = {mrf->V[i],1};
	mxArray* bel_i = mxCreateNumericArray(2,val_dims,mxDOUBLE_CLASS, mxREAL);
	double* resBelPtr = mxGetPr(bel_i);
	for (int xi=0; xi<mrf->V[i]; xi++) {
	  resBelPtr[xi] = beliefs[i][xi];
	}
	mxSetCell(plhs[0],i,bel_i);
      }
      if (nlhs > 1) {
	plhs[1] = mxCreateDoubleScalar(converged); // For matlab6.5
	//plhs[1] = mxCreateScalarDouble(converged);
	if (nlhs > 2) {
	  int pair_dims[2] = {1,num_nodes};
	  plhs[2] = mxCreateCellArray(2,pair_dims);

	  for (int i=0; i<num_nodes; i++) {
	    int pair_i_dims[2] = {1, mrf->neighbNum(i)};
	    mxArray* bel_i = mxCreateCellArray(2,pair_i_dims);
	  
	    for (int n=0; n<mrf->neighbNum(i); n++) {
	      int j = mrf->adjMat[i][n];
	      if (i<j) {
		int pval_dims[2] = {mrf->V[i], mrf->V[j]};
		mxArray* bel_ij = mxCreateNumericArray(2,pval_dims,mxDOUBLE_CLASS,mxREAL);
	      
		double* resBelPtr = mxGetPr(bel_ij);
		for (int xi=0; xi<mrf->V[i]; xi++) {
		  for (int xj=0; xj<mrf->V[j]; xj++) {
		    resBelPtr[xi + xj*mrf->V[i]] = pairBeliefs[i][n][xi][xj];
		  }
		}
		mxSetCell(bel_i, n, bel_ij);	      
	      }
	    }
	    mxSetCell(plhs[2], i, bel_i);
	  }

	  if (nlhs > 3) {

	    double*** msg = 0;
	    int msg_dims[2];
	  
	    switch (algo_type) {
    
	      case AT_LOOPY:
      
		if (countingNode != 0) {
		  msg = ((PairsGBP*)algorithm)->getMessages();
		}
		else {
		  msg = ((Loopy*)algorithm)->getMessages();
		}
	    
		msg_dims[0] = 1;
		msg_dims[1] = num_nodes;
	      
		plhs[3] = mxCreateCellArray(2,msg_dims);
		for (int i=0; i<num_nodes; i++) {
		  int Ni = mrf->neighbNum(i);
		  int msg_i_dims[2];
		  msg_i_dims[0] = 1;
		  msg_i_dims[1] = (saveTime ? num_nodes : Ni);
		  mxArray* msg_i = mxCreateCellArray(2,msg_i_dims);
		  for (int n=0; n<Ni; n++) {
		    int j = mrf->adjMat[i][n];
		    int nei = (saveTime ? j : n);
		    int msg_ij_dims[2] = {1, mrf->V[j]};
		    mxArray* msg_ij = mxCreateNumericArray(2,msg_ij_dims,mxDOUBLE_CLASS, mxREAL);
		    double* msg_ij_ptr = mxGetPr(msg_ij);
		    for (int xj=0; xj<mrf->V[j]; xj++) {
		      msg_ij_ptr[xj] = msg[i][nei][xj];
		    }
		    mxSetCell(msg_i,nei,msg_ij);
		  }
		  mxSetCell(plhs[3],i,msg_i);
		}
		

		break;
      
	      case AT_GBP:

		if (!trw) {
		  msg = ((GBP*)algorithm)->getMessages();

		  msg_dims[0] = 1;
		  msg_dims[1] = reg_mrf->N;
		  plhs[3] = mxCreateCellArray(2,msg_dims);
		  for (int i=0; i<reg_mrf->N; i++) {
		    int Ni = reg_mrf->neighbNum(i);
		    int msg_i_dims[2] = {1,Ni};
		    mxArray* msg_i = mxCreateCellArray(2,msg_i_dims);
		    for (int n=0; n<Ni; n++) {
		      int j = reg_mrf->adjMat[i][n];
		      int numStates = reg_mrf->V[max(i,j)];
		      int msg_ij_dims[2] = {1, numStates};
		      mxArray* msg_ij = mxCreateNumericArray(2,msg_ij_dims,mxDOUBLE_CLASS, mxREAL);
		      double* msg_ij_ptr = mxGetPr(msg_ij);
		      for (int xs=0; xs<numStates; xs++) {
			msg_ij_ptr[xs] = msg[i][n][xs];
		      }
		      mxSetCell(msg_i,n,msg_ij);
		    }
		    mxSetCell(plhs[3],i,msg_i);
		  }
		}
		break;

	      default:
	      
		break;
	    
	    }
	  
	  }
	}
      }
    }
  }
  // **************************************************************************
  // free memory
  // **************************************************************************
  delete algorithm;
  algorithm = 0;
  
  if (singleBeliefs != 0) {
    for (int i=0; i<num_nodes; i++) {
      delete[] singleBeliefs[i];
    }
    delete[] singleBeliefs;    
    singleBeliefs = 0;
  }
  if (pairBeliefs != 0 && algo_type == AT_GBP) {
    for (int i=0; i<num_nodes; i++) {
      for (int n=0; n<mrf->neighbNum(i); n++) {
	if (pairBeliefs[i][n] != 0) {
	  for (int xi=0; xi<mrf->V[i]; xi++) {
	    delete[] pairBeliefs[i][n][xi];
	  }
	  delete[] pairBeliefs[i][n];
	}
      }
      delete[] pairBeliefs[i];
    }
    delete[] pairBeliefs;
    pairBeliefs = 0;
  }
  if (processor != 0) {
    delete processor;
    processor = 0;
  }
  if (rho != 0) {
    for (int i=0; i<num_nodes; i++) {
      delete[] rho[i];
      rho[i] = 0;
    }
    delete[] rho;
    rho = 0;
  }
  if (countingNode != 0) {
    delete[] countingNode;
    countingNode = 0;
  }
  if (bigRegsPot != 0) {
    for (int i=0; i<num_regs; i++) {
      delete[] bigRegsPot[i];
    }
    delete[] bigRegsPot;
    bigRegsPot = 0;
  }
  
  delete mrf;
  mrf = 0;
  delete adjMat;
  adjMat = 0;
  
}