Beispiel #1
0
//--------------------------------------------------------------------------------------------------
//----------------------------------- Message Creators----------------------------------------------
//--------------------------------------------------------------------------------------------------
mvec *SumRowsOrCols(nodes *factornode, nodes *previousnode, char specify)
{ //Sums rows of columns of a matrix represented as a vector
  //Specify 'f' for forwardtraverse 'b' for backward traverse
  //Produces array
  //Vector is assumed to be Row Major

	hfactor* fnhfac = (hfactor *)factornode->ndata;
	hfactor* pnhfac = (hfactor *)previousnode->ndata;
	mvec *messagein;
	if(specify=='f')
	{
		messagein = fnhfac->messagesin[0];
	}
	else
	{
		messagein = fnhfac->bmessagesin[0];
	}
	mvec *message = (mvec *)imalloc(E,1*sizeof(mvec));
	int nrow = fnhfac->nrow;
	int ncol = fnhfac->ncol;
	double *matrix = fnhfac->probdist;
	double *result;

	int i,j;
	//Determine length of resulting vector
	if(fnhfac->columnlabel == previousnode->nhash) //If the previousnode is represented in column
	{
		//Then the length of vector = to number of rows
		result = (double *)imalloc(E,nrow*sizeof(double));
		message->length = nrow;

		//Multiply incoming message -- which should only be 1 message as its a factor node
		//Then sum
		i=0;
		for(i;i<nrow;i++)
		{
			result[i]=0;
			j=0;
			for(j;j<ncol;j++)
			{
				result[i]=result[i]+matrix[i*ncol+j]*(messagein->vector[j]);
			}
		}

	}
	else //If the previousnode is represented in the rows
	{
		//Then the length of vector = number of columns
		result = (double *)imalloc(E,ncol*sizeof(double));
		message->length = ncol;

		//Multiply incoming message -- which should only be 1 message as its a factor node
		//Then sum
		j=0;
		for(j;j<ncol;j++)
		{
			result[j]=0;
			i=0;
			for(i;i<nrow;i++)
			{
				result[j]=result[j]+matrix[i*ncol+j]*(messagein->vector[i]);
			}
		}

	}

	message->sender = factornode->nhash;
	message->vector = result;
	NormaliseMVEC(message);
	return message;

}
Beispiel #2
0
void backwardtraverse(nodes *currentnode,nodes *callingnode, hgph *graph)
{
//--------------------------Go down and update nodes

	int nbranches = currentnode->nedges;

	//When further down the tree, every edge except the calling edge is forward
	int nforwardbranches = nbranches - 1;

	//If root node, every edge is a forward edge
	if(currentnode==callingnode) nforwardbranches = nbranches;

	char type = ((hfactor*)currentnode->ndata)->type;
	char callingobs = ((hfactor*)callingnode->ndata)->observed;
	nodes *nextnode;

//-----------------------------Find forward branches-------------------------------------------------
	//Already computed in forward traverse

		unsigned *forwardedges = ((hfactor*)currentnode->ndata)->fedges;

//-----------------------------Calculate & send message first----------------------------------------------------
	if (currentnode==callingnode) //If this is the root node --- Message is 1 if only 1 branch, product of messages if not
	{
		int msgveclength;
		mvec *message;
		int k = 0;
		if(nforwardbranches == 1) //If only has 1 outgoing connection
		{
			message = (mvec *)imalloc(E,1*sizeof(mvec)); //Allocate memory for message
			nextnode= find_node(forwardedges[0],graph->nnodes,graph->nodelist);

			//Determine length of message vector
			if(((hfactor *)nextnode->ndata)->columnlabel == currentnode->nhash) //If prob dist column is for the current node,
			{
				msgveclength = ((hfactor *)nextnode->ndata)->ncol;
			}
			else
			{
				msgveclength = ((hfactor *)nextnode->ndata)->nrow;
			}

			//Allocate memory for vector and initialise value to 1 as per theory
			double *msgvec = (double *)imalloc(E,msgveclength*sizeof(double));
			int i;
			for(i=0;i<msgveclength;i++)
			{
				msgvec[i] = 1;
			}
			message->vector = msgvec;
			message->sender = currentnode->nhash;
			message->length = msgveclength;

			addmessagetonodeB(message, nextnode); //Attach full message to callingnode

		}
		else //If it has multiple outgoing connections
		{
			for(k;k<nforwardbranches;k++) // For each nextnode
			{
				nextnode = find_node(forwardedges[k],graph->nnodes,graph->nodelist);
				message = productofmessagesinB(currentnode, nextnode);
				addmessagetonodeB(message, nextnode);
			}
		}
	}
	else if (type == 'v') //If this is a variable node --- Product of messages in
	{
		mvec *message;
		int k = 0;
		for(k;k<nforwardbranches;k++) // For each nextnode
		{
			nextnode = find_node(forwardedges[k],graph->nnodes,graph->nodelist);
			message = productofmessagesinB(currentnode, nextnode);
			addmessagetonodeB(message, nextnode);
		}
	}
	else //If this is a factor node --- Sum of row/column multiplied by previous messages --- Factor node only connected to 2 nodes
	{
		if(((hfactor*)callingnode->ndata)->observed == 'f') //If it is unobserved
		{
			nextnode = find_node(forwardedges[0],graph->nnodes,graph->nodelist);
			mvec *message;
			if(((hfactor*)nextnode->ndata)->observed == 't') //If the nextnode is observed
			{
				message = MsgToObservedNode(currentnode, nextnode);
			}
			else //Else if calling node not observed
			{
				message = SumRowsOrCols(currentnode, callingnode,'b');
			}

			addmessagetonodeB(message, nextnode);

		}
		else //If it is observed
		{
			mvec *message;
			nextnode = find_node(forwardedges[0],graph->nnodes,graph->nodelist);
			if(((hfactor*)nextnode->ndata)->observed == 't') //If the nextnode is observed
			{
				message = MsgToObservedNode(currentnode, nextnode);
			}
			else
			{
				message = sumobservednode(currentnode, callingnode);
			}
			addmessagetonodeB(message, nextnode);
		}
	}


//-------------------------------Recurse Down-------------------------------------------------------

	int i=0;
	for(i; i<nforwardbranches; i++)
	{
		nextnode = find_node(forwardedges[i],graph->nnodes,graph->nodelist);
		backwardtraverse(nextnode,currentnode,graph);
	}
	//Return from Recursion

	return;
}
Beispiel #3
0
void calculatemarginals(hgph *graph)
{
//-----------------------Calculate marginals at all the variable nodes
//------Done by calculating product of messages

	nodes **nodelist = graph->nodelist;
	int nnodes = graph->nnodes;
	nodes *currentnode;
	hfactor *currenthfac;
	mvec *margvec;
	mvec *currentmessage;
	double *vec;
	int length,nmessages,nbmessages;

	int i = 0;
	int j,k,m;
	for(i;i<nnodes;i++) //for every node
	{
		margvec = (mvec *)imalloc(E,1*sizeof(mvec));
		currentnode = nodelist[i];
		currenthfac = (hfactor *)currentnode->ndata;
		nmessages = currenthfac->nmessages;
		nbmessages = currenthfac->nbmessages;

		//Does a check if it is a variable node
		if(currenthfac->type == 'f') continue;

		//Length of messages will all be same, must have 1 message either in or out
		if(nmessages!=0) length = currenthfac->messagesin[0]->length;
		else if(nbmessages!= 0) length = currenthfac->bmessagesin[0]->length;

		//Allocate memory
		vec = (double *)imalloc(E,length*sizeof(double));
		margvec->length = length;

		for(k=0;k<length;k++)//For every element in the vector initialise to 1
		{
			vec[k] = 1;
		}

		if(nmessages!=0) //If there is forward message
		{
			j = 0;
			for(j;j<nmessages;j++) //For every messagein (Forward)
			{
				currentmessage = currenthfac->messagesin[j];
				for(k=0;k<length;k++)//For every element in the vector
				{
					vec[k] = vec[k]*currentmessage->vector[k];
				}
			}
		}

		if(nbmessages!=0) //If there is backward message
		{
			j = 0;
			for(j;j<nbmessages;j++) //For every messagein (Backward)
			{
				currentmessage = currenthfac->bmessagesin[j];
				for(k=0;k<length;k++)//For every element in the vector
				{
					vec[k] = vec[k]*currentmessage->vector[k];
				}
			}
		}

		//Normalise
		//1. Sum
		double sumofelements= 0.0;
		for(m=0;m<length;m++) //For every element - find sum
		{
			sumofelements = sumofelements + vec[m];
		}
		//2. Divide by sum
		for(m=0;m<length;m++) //For every element - find sum
		{
			vec[m] = vec[m]/sumofelements;
		}

		//Append
		margvec->vector = vec;
		currenthfac->marginal = margvec;
	}

	return;
}
Beispiel #4
0
void forwardtraverse(nodes *currentnode,nodes *callingnode, hgph *graph)
{
//-----------------------Go down to leaf and come up

	int nbranches = currentnode->nedges;

	//When further down the tree, every edge except the calling edge is forward
	int nforwardbranches = nbranches - 1;

	//If root node, every edge is a forward edge
	if(currentnode==callingnode) nforwardbranches = nbranches;

	char type = ((hfactor*)currentnode->ndata)->type;

	nodes *nextnode;

	//----If at leaf go up-----
	//----Leaf is the terminal nodes of the tree, as far as can go.
	if(nforwardbranches==0)
	{
		mvec *message = (mvec *)imalloc(E,1*sizeof(mvec)); //Allocate memory for message

		//Determine length of message vector
		int msgveclength;

		if(((hfactor *)callingnode->ndata)->columnlabel == currentnode->nhash) //If prob dist column is for the current node,
		{
			msgveclength = ((hfactor *)callingnode->ndata)->ncol;
		}
		else
		{
			msgveclength = ((hfactor *)callingnode->ndata)->nrow;
		}

		//Allocate memory for vector and initialise value to 1 as per theory
		double *msgvec = (double *)imalloc(E,msgveclength*sizeof(double));
		int i = 0;
		for(i;i<msgveclength;i++)
		{
			msgvec[i] = 1;
		}
		message->vector = msgvec;
		message->sender = currentnode->nhash;
		message->length = msgveclength;
		addmessagetonode(message, callingnode); //Attach full message to callingnode
		return;
	}

	//----If not at leaf, go down & come up----------
	else
	{
	//Copy edge list & remove calling node from the list
		unsigned *forwardedges = (unsigned *)imalloc(E,nforwardbranches*sizeof(unsigned)); //list of edges to pursue
		int j = 0;
		char callingnodefound = 'f';
		for( j; j<nbranches; j++)
		{
			if(callingnodefound =='f')
			{
			  if(currentnode->edge[j]==callingnode->nhash)
			    { callingnodefound = 't'; continue; }
			  else forwardedges[j] = currentnode->edge[j];
			}
			else forwardedges[j-1] = currentnode->edge[j];
		}
		((hfactor *)currentnode->ndata)->fedges = forwardedges; //Saves the list to the structure

	//RECURSION DOWN
		int i=0;
		for(i; i<nforwardbranches; i++)
		{
			nextnode = find_node(forwardedges[i],graph->nnodes,graph->nodelist);
			forwardtraverse(nextnode,currentnode,graph);
		}
	//RETURNING FROM RECURSION

	//What happens on this level before going up
	//Results are appended to the calling node
		if(currentnode==callingnode) return; //If this is the root node, forward traverse ends

		if(type == 'v') //variable -- product of factor messages
		{
			mvec *message = productofmessagesin(currentnode,'f'); //Products all the factor messages
			addmessagetonode(message, callingnode);
			return;
		}

		else if(type == 'f') //factor --- sum marginals
		{
			//Previous node is next node and next node is calling node
			if(((hfactor*)nextnode->ndata)->observed == 'f') //If the previous node was unobserved
			{
				mvec *message;
				if(((hfactor*)callingnode->ndata)->observed == 't') //If the nextnode is observed
				{
					message = MsgToObservedNode(currentnode, callingnode);
				}
				else //Else if calling node not observed
				{
					message = SumRowsOrCols(currentnode, nextnode,'f');
				}
				addmessagetonode(message,callingnode);
			}
			else //If the previous node was observed - take only the associated row or column
			{
				mvec *message;
				if(((hfactor*)callingnode->ndata)->observed == 't') //If the next node is observed
				{
					message = MsgToObservedNode(currentnode, callingnode);
				}
				else
				{
					message = sumobservednode(currentnode, nextnode);
				}
				addmessagetonode(message,callingnode);
			}
			return;
		}
	}
}
Beispiel #5
0
void *sumproduct_setupproblem(void *arglist)
{
//--------------------------- Creates nodes and sets up model---------------------------------------
	void *argptr;
	nodes *x1, *fa, *x2, *fb, *x3, *fc, *x4;
	hgph *graph;

	//Get previous hgph struct
	if(dynamic_getarg(arglist,"hgph",&argptr)=='f') return NULL;
	if(!invalidptr(E,argptr)) graph=(hgph *) argptr;

	//Sets up nodes in their places
	x1 = createnode(1,5,"x1",graph,'v');
	fa = createnode(3,5,"fa",graph,'f');
	x2 = createnode(5,5,"x2",graph,'v');
	fb = createnode(7,5,"fb",graph,'f');
	x3 = createnode(9,5,"x3",graph,'v');
	fc = createnode(5,3,"fc",graph,'f');
	x4 = createnode(5,1,"x4",graph,'v');

	//Adds directed edge between mu and x
	add_edge(x1,fa);
	add_edge(fa,x2);
	add_edge(x2,fb);
	add_edge(fb,x3);
	add_edge(x4,fc);
	add_edge(fc,x2);

	//Create probability distribution table
	/*Row Major Ordering
	EG:
	{11 12 13
	 21 22 23
	 31 32 33}
	Becomes
	{11 12 13 21 22 23 31 32 33}
	*/

	double *probdist1; //fc
	probdist1 =(double *)imalloc(E,6*sizeof(double));

/*	probdist1[0] = 1.0;
	probdist1[1] = 0.1;
	probdist1[2] = 0.1;
	probdist1[3] = 1.0; */

//	probdist1[0] = 0.3;
//	probdist1[1] = 0.4;
//	probdist1[2] = 0.3;
//	probdist1[3] = 0.0;

	probdist1[0] = 0.3;
	probdist1[1] = 0.4;
	probdist1[2] = 0.5;
	probdist1[3] = 0.3;
	probdist1[4] = 0.1;
	probdist1[5] = 0.6;

	double *probdist2; //fa
	probdist2 =(double *)imalloc(E,6*sizeof(double));

/*	probdist2[0] = 1.0;
	probdist2[1] = 0.9;
	probdist2[2] = 0.9;
	probdist2[3] = 1.0; */

//	probdist2[0] = 0.5;
//	probdist2[1] = 0.2;
//	probdist2[2] = 0.3;
//	probdist2[3] = 0.5;

	probdist2[0] = 0.5;
	probdist2[1] = 0.2;
	probdist2[2] = 0.3;
	probdist2[3] = 0.5;
	probdist2[4] = 0.1;
	probdist2[5] = 0.2;

	double *probdist3; //fb
	probdist3 =(double *)imalloc(E,6*sizeof(double));

/*	probdist3[0] = 0.1;
	probdist3[1] = 1.0;
	probdist3[2] = 1.0;
	probdist3[3] = 0.1; */

//	probdist3[0] = 0.7;
//	probdist3[1] = 0.2;
//	probdist3[2] = 0.1;
//	probdist3[3] = 0.3;

	probdist3[0] = 0.7;
	probdist3[1] = 0.2;
	probdist3[2] = 0.3;
	probdist3[3] = 0.1;
	probdist3[4] = 0.3;
	probdist3[5] = 0.5;

	//Populate factor payloads with probability distribution
	double *discretevalue = (double *)imalloc(E,2*sizeof(double));
	discretevalue[0] = 0.0;
	discretevalue[1] = 1.0;

	double *disval = (double *)imalloc(E,3*sizeof(double));
	disval[0] = 0.0;
	disval[1] = 1.0;
	disval[2] = 2.0;

	((hfactor *)fa->ndata)->probdist = probdist2;
	((hfactor *)fa->ndata)->columndiscretevalues = discretevalue;
	((hfactor *)fa->ndata)->rowdiscretevalues = disval;
	((hfactor *)fa->ndata)->columnlabel = str_hash("x1");
	((hfactor *)fa->ndata)->rowlabel = str_hash("x2");
	((hfactor *)fa->ndata)->ncol = 2;
	((hfactor *)fa->ndata)->nrow = 3;


	((hfactor *)fb->ndata)->probdist = probdist3;
	((hfactor *)fb->ndata)->columndiscretevalues = disval;
	((hfactor *)fb->ndata)->rowdiscretevalues = discretevalue;
	((hfactor *)fb->ndata)->columnlabel = str_hash("x2");
	((hfactor *)fb->ndata)->rowlabel = str_hash("x3");
	((hfactor *)fb->ndata)->ncol = 3;
	((hfactor *)fb->ndata)->nrow = 2;


	((hfactor *)fc->ndata)->probdist = probdist1;
	((hfactor *)fc->ndata)->columndiscretevalues = disval;
	((hfactor *)fc->ndata)->rowdiscretevalues = discretevalue;
	((hfactor *)fc->ndata)->columnlabel = str_hash("x2");
	((hfactor *)fc->ndata)->rowlabel = str_hash("x4");
	((hfactor *)fc->ndata)->ncol = 3;
	((hfactor *)fc->ndata)->nrow = 2;

	//Test observed node
	((hfactor *)x1->ndata)->observed = 't';
	((hfactor *)x1->ndata)->observedvariable = 1.0;

	//Output to arglist
	arglist=NULL;
	dynamic_putarg("graph.hgph","hgph",(void *)graph,SZ,&arglist);

	return arglist;
}
Beispiel #6
0
static bool
ctl_grow(void)
{
	ctl_arena_stats_t *astats;
	arena_t **tarenas;

	/* Allocate extended arena stats and arenas arrays. */
	astats = (ctl_arena_stats_t *)imalloc((ctl_stats.narenas + 2) *
	    sizeof(ctl_arena_stats_t));
	if (astats == NULL)
		return (true);
	tarenas = (arena_t **)imalloc((ctl_stats.narenas + 1) *
	    sizeof(arena_t *));
	if (tarenas == NULL) {
		idalloc(astats);
		return (true);
	}

	/* Initialize the new astats element. */
	memcpy(astats, ctl_stats.arenas, (ctl_stats.narenas + 1) *
	    sizeof(ctl_arena_stats_t));
	memset(&astats[ctl_stats.narenas + 1], 0, sizeof(ctl_arena_stats_t));
	if (ctl_arena_init(&astats[ctl_stats.narenas + 1])) {
		idalloc(tarenas);
		idalloc(astats);
		return (true);
	}
	/* Swap merged stats to their new location. */
	{
		ctl_arena_stats_t tstats;
		memcpy(&tstats, &astats[ctl_stats.narenas],
		    sizeof(ctl_arena_stats_t));
		memcpy(&astats[ctl_stats.narenas],
		    &astats[ctl_stats.narenas + 1], sizeof(ctl_arena_stats_t));
		memcpy(&astats[ctl_stats.narenas + 1], &tstats,
		    sizeof(ctl_arena_stats_t));
	}
	/* Initialize the new arenas element. */
	tarenas[ctl_stats.narenas] = NULL;
	{
		arena_t **arenas_old = arenas;
		/*
		 * Swap extended arenas array into place.  Although ctl_mtx
		 * protects this function from other threads extending the
		 * array, it does not protect from other threads mutating it
		 * (i.e. initializing arenas and setting array elements to
		 * point to them).  Therefore, array copying must happen under
		 * the protection of arenas_lock.
		 */
		malloc_mutex_lock(&arenas_lock);
		arenas = tarenas;
		memcpy(arenas, arenas_old, ctl_stats.narenas *
		    sizeof(arena_t *));
		narenas_total++;
		arenas_extend(narenas_total - 1);
		malloc_mutex_unlock(&arenas_lock);
		/*
		 * Deallocate arenas_old only if it came from imalloc() (not
		 * base_alloc()).
		 */
		if (ctl_stats.narenas != narenas_auto)
			idalloc(arenas_old);
	}
	ctl_stats.arenas = astats;
	ctl_stats.narenas++;

	return (false);
}
Beispiel #7
0
/*************************************************************************
* This function returns the min-cover of a bipartite graph.
* The algorithm used is due to Hopcroft and Karp as modified by Duff etal
* adj: the adjacency list of the bipartite graph
*       asize: the number of vertices in the first part of the bipartite graph
* bsize-asize: the number of vertices in the second part
*        0..(asize-1) > A vertices
*        asize..bsize > B vertices
*
* Returns:
*  cover : the actual cover (array)
*  csize : the size of the cover
**************************************************************************/
void MinCover(idx_t *xadj, idx_t *adjncy, idx_t asize, idx_t bsize, idx_t *cover, idx_t *csize) {
    idx_t i, j;
    idx_t *mate, *queue, *flag, *level, *lst;
    idx_t fptr, rptr, lstptr;
    idx_t row, maxlevel, col;

    mate = ismalloc(bsize, -1, "MinCover: mate");
    flag = imalloc(bsize, "MinCover: flag");
    level = imalloc(bsize, "MinCover: level");
    queue = imalloc(bsize, "MinCover: queue");
    lst = imalloc(bsize, "MinCover: lst");

    /* Get a cheap matching */
    for (i = 0; i < asize; i++) {
        for (j = xadj[i]; j < xadj[i + 1]; j++) {
            if (mate[adjncy[j]] == -1) {
                mate[i] = adjncy[j];
                mate[adjncy[j]] = i;
                break;
            }
        }
    }

    /* Get into the main loop */
    while (1) {
        /* Initialization */
        fptr = rptr = 0;   /* Empty Queue */
        lstptr = 0;        /* Empty List */
        for (i = 0; i < bsize; i++) {
            level[i] = -1;
            flag[i] = 0;
        }
        maxlevel = bsize;

        /* Insert free nodes into the queue */
        for (i = 0; i < asize; i++) {
            if (mate[i] == -1) {
                queue[rptr++] = i;
                level[i] = 0;
            }
        }

        /* Perform the BFS */
        while (fptr != rptr) {
            row = queue[fptr++];
            if (level[row] < maxlevel) {
                flag[row] = 1;
                for (j = xadj[row]; j < xadj[row + 1]; j++) {
                    col = adjncy[j];
                    if (!flag[col]) {  /* If this column has not been accessed yet */
                        flag[col] = 1;
                        if (mate[col] == -1) { /* Free column node was found */
                            maxlevel = level[row];
                            lst[lstptr++] = col;
                        } else { /* This column node is matched */
                            if (flag[mate[col]]) {
                                printf("\nSomething wrong, flag[%"PRIDX"] is 1", mate[col]);
                            }
                            queue[rptr++] = mate[col];
                            level[mate[col]] = level[row] + 1;
                        }
                    }
                }
            }
        }

        if (lstptr == 0) {
            break;
        }   /* No free columns can be reached */

        /* Perform restricted DFS from the free column nodes */
        for (i = 0; i < lstptr; i++)
            MinCover_Augment(xadj, adjncy, lst[i], mate, flag, level, maxlevel);
    }

    MinCover_Decompose(xadj, adjncy, asize, bsize, mate, cover, csize);

    gk_free((void **) &mate, &flag, &level, &queue, &lst, LTERM);

}
Beispiel #8
0
void CreateGraphNodal(idx_t ne, idx_t nn, idx_t *eptr, idx_t *eind, 
          idx_t **r_xadj, idx_t **r_adjncy)
{
  idx_t i, j, nnbrs;
  idx_t *nptr, *nind;
  idx_t *xadj, *adjncy;
  idx_t *marker, *nbrs;


  /* construct the node-element list first */
  nptr = ismalloc(nn+1, 0, "CreateGraphNodal: nptr");
  nind = imalloc(eptr[ne], "CreateGraphNodal: nind");

  for (i=0; i<ne; i++) {
    for (j=eptr[i]; j<eptr[i+1]; j++)
      nptr[eind[j]]++;
  }
  MAKECSR(i, nn, nptr);

  for (i=0; i<ne; i++) {
    for (j=eptr[i]; j<eptr[i+1]; j++)
      nind[nptr[eind[j]]++] = i;
  }
  SHIFTCSR(i, nn, nptr);


  /* Allocate memory for xadj, since you know its size.
     These are done using standard malloc as they are returned
     to the calling function */
  if ((xadj = (idx_t *)malloc((nn+1)*sizeof(idx_t))) == NULL)
    gk_errexit(SIGMEM, "***Failed to allocate memory for xadj.\n");
  *r_xadj = xadj;
  iset(nn+1, 0, xadj);

  /* allocate memory for working arrays used by FindCommonElements */
  marker = ismalloc(nn, 0, "CreateGraphNodal: marker");
  nbrs   = imalloc(nn, "CreateGraphNodal: nbrs");

  for (i=0; i<nn; i++) {
    xadj[i] = FindCommonNodes(i, nptr[i+1]-nptr[i], nind+nptr[i], eptr, 
                  eind, marker, nbrs);
  }
  MAKECSR(i, nn, xadj);

  /* Allocate memory for adjncy, since you now know its size.
     These are done using standard malloc as they are returned
     to the calling function */
  if ((adjncy = (idx_t *)malloc(xadj[nn]*sizeof(idx_t))) == NULL) {
    free(xadj);
    *r_xadj = NULL;
    gk_errexit(SIGMEM, "***Failed to allocate memory for adjncy.\n");
  }
  *r_adjncy = adjncy;

  for (i=0; i<nn; i++) {
    nnbrs = FindCommonNodes(i, nptr[i+1]-nptr[i], nind+nptr[i], eptr, 
                eind, marker, nbrs);
    for (j=0; j<nnbrs; j++)
      adjncy[xadj[i]++] = nbrs[j];
  }
  SHIFTCSR(i, nn, xadj);
  
  gk_free((void **)&nptr, &nind, &marker, &nbrs, LTERM);
}
Beispiel #9
0
EXPORT void* IAmalloc( size_t size, UINT attr )
{
	return imalloc(size, SelIMACB(attr));
}
Beispiel #10
0
graph_t *FixGraph(graph_t *graph)
{
  idx_t i, j, k, l, nvtxs, nedges;
  idx_t *xadj, *adjncy, *adjwgt;
  idx_t *nxadj, *nadjncy, *nadjwgt;
  graph_t *ngraph;
  uvw_t *edges;


  nvtxs  = graph->nvtxs;
  xadj   = graph->xadj;
  adjncy = graph->adjncy;
  adjwgt = graph->adjwgt;
  ASSERT(adjwgt != NULL);

  ngraph = CreateGraph();

  ngraph->nvtxs = nvtxs;

  /* deal with vertex weights/sizes */
  ngraph->ncon  = graph->ncon;
  ngraph->vwgt  = icopy(nvtxs*graph->ncon, graph->vwgt, 
                        imalloc(nvtxs*graph->ncon, "FixGraph: vwgt"));

  ngraph->vsize = ismalloc(nvtxs, 1, "FixGraph: vsize");
  if (graph->vsize)
    icopy(nvtxs, graph->vsize, ngraph->vsize);

  /* fix graph by sorting the "superset" of edges */
  edges = (uvw_t *)gk_malloc(sizeof(uvw_t)*2*xadj[nvtxs], "FixGraph: edges");

  for (nedges=0, i=0; i<nvtxs; i++) {
    for (j=xadj[i]; j<xadj[i+1]; j++) {
      /* keep only the upper-trianglular part of the adjacency matrix */
      if (i < adjncy[j]) {
        edges[nedges].u = i;
        edges[nedges].v = adjncy[j];
        edges[nedges].w = adjwgt[j];
        nedges++;
      }
      else if (i > adjncy[j]) {
        edges[nedges].u = adjncy[j];
        edges[nedges].v = i;
        edges[nedges].w = adjwgt[j];
        nedges++;
      }
    }
  }

  uvwsorti(nedges, edges);


  /* keep the unique subset */
  for (k=0, i=1; i<nedges; i++) {
    if (edges[k].v != edges[i].v || edges[k].u != edges[i].u) {
      edges[++k] = edges[i];
    }
  }
  nedges = k+1;

  /* allocate memory for the fixed graph */
  nxadj   = ngraph->xadj   = ismalloc(nvtxs+1, 0, "FixGraph: nxadj");
  nadjncy = ngraph->adjncy = imalloc(2*nedges, "FixGraph: nadjncy");
  nadjwgt = ngraph->adjwgt = imalloc(2*nedges, "FixGraph: nadjwgt");

  /* create the adjacency list of the fixed graph from the upper-triangular
     part of the adjacency matrix */
  for (k=0; k<nedges; k++) {
    nxadj[edges[k].u]++;
    nxadj[edges[k].v]++;
  }
  MAKECSR(i, nvtxs, nxadj);

  for (k=0; k<nedges; k++) {
    nadjncy[nxadj[edges[k].u]] = edges[k].v;
    nadjncy[nxadj[edges[k].v]] = edges[k].u;
    nadjwgt[nxadj[edges[k].u]] = edges[k].w;
    nadjwgt[nxadj[edges[k].v]] = edges[k].w;
    nxadj[edges[k].u]++;
    nxadj[edges[k].v]++;
  }
  SHIFTCSR(i, nvtxs, nxadj);

  gk_free((void **)&edges, LTERM);

  return ngraph;
}