kusano 7d535a
/*! @file ilu_relax_snode.c
kusano 7d535a
 * \brief Identify initial relaxed supernodes
kusano 7d535a
 *
kusano 7d535a
 * 
kusano 7d535a
 * -- SuperLU routine (version 4.0) --
kusano 7d535a
 * Lawrence Berkeley National Laboratory
kusano 7d535a
 * June 1, 2009
kusano 7d535a
 * 
kusano 7d535a
 */
kusano 7d535a
kusano 7d535a
#include "slu_ddefs.h"
kusano 7d535a
/*! \brief
kusano 7d535a
 *
kusano 7d535a
 * 
kusano 7d535a
 * Purpose
kusano 7d535a
 * =======
kusano 7d535a
 *    ilu_relax_snode() - Identify the initial relaxed supernodes, assuming
kusano 7d535a
 *    that the matrix has been reordered according to the postorder of the
kusano 7d535a
 *    etree.
kusano 7d535a
 * 
kusano 7d535a
 */
kusano 7d535a
void
kusano 7d535a
ilu_relax_snode (
kusano 7d535a
	      const	int n,
kusano 7d535a
	      int	*et,	       /* column elimination tree */
kusano 7d535a
	      const int relax_columns, /* max no of columns allowed in a
kusano 7d535a
					  relaxed snode */
kusano 7d535a
	      int	*descendants,  /* no of descendants of each node
kusano 7d535a
					 in the etree */
kusano 7d535a
	      int	*relax_end,    /* last column in a supernode
kusano 7d535a
					* if j-th column starts a relaxed
kusano 7d535a
					* supernode, relax_end[j] represents
kusano 7d535a
					* the last column of this supernode */
kusano 7d535a
	      int	*relax_fsupc   /* first column in a supernode
kusano 7d535a
					* relax_fsupc[j] represents the first
kusano 7d535a
					* column of j-th supernode */
kusano 7d535a
	     )
kusano 7d535a
{
kusano 7d535a
kusano 7d535a
    register int j, f, parent;
kusano 7d535a
    register int snode_start;	/* beginning of a snode */
kusano 7d535a
kusano 7d535a
    ifill (relax_end, n, EMPTY);
kusano 7d535a
    ifill (relax_fsupc, n, EMPTY);
kusano 7d535a
    for (j = 0; j < n; j++) descendants[j] = 0;
kusano 7d535a
kusano 7d535a
    /* Compute the number of descendants of each node in the etree */
kusano 7d535a
    for (j = 0; j < n; j++) {
kusano 7d535a
	parent = et[j];
kusano 7d535a
	if ( parent != n )  /* not the dummy root */
kusano 7d535a
	    descendants[parent] += descendants[j] + 1;
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    /* Identify the relaxed supernodes by postorder traversal of the etree. */
kusano 7d535a
    for (j = f = 0; j < n; ) {
kusano 7d535a
	parent = et[j];
kusano 7d535a
	snode_start = j;
kusano 7d535a
	while ( parent != n && descendants[parent] < relax_columns ) {
kusano 7d535a
	    j = parent;
kusano 7d535a
	    parent = et[j];
kusano 7d535a
	}
kusano 7d535a
	/* Found a supernode with j being the last column. */
kusano 7d535a
	relax_end[snode_start] = j;		/* Last column is recorded */
kusano 7d535a
	j++;
kusano 7d535a
	relax_fsupc[f++] = snode_start;
kusano 7d535a
	/* Search for a new leaf */
kusano 7d535a
	while ( descendants[j] != 0 && j < n ) j++;
kusano 7d535a
    }
kusano 7d535a
}