|
kusano |
7d535a |
|
|
kusano |
7d535a |
typedef int shortint;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
/* **** GENMMD ..... MULTIPLE MINIMUM EXTERNAL DEGREE **** */
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* AUTHOR - JOSEPH W.H. LIU */
|
|
kusano |
7d535a |
/* DEPT OF COMPUTER SCIENCE, YORK UNIVERSITY. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* PURPOSE - THIS ROUTINE IMPLEMENTS THE MINIMUM DEGREE */
|
|
kusano |
7d535a |
/* ALGORITHM. IT MAKES USE OF THE IMPLICIT REPRESENTATION */
|
|
kusano |
7d535a |
/* OF ELIMINATION GRAPHS BY QUOTIENT GRAPHS, AND THE */
|
|
kusano |
7d535a |
/* NOTION OF INDISTINGUISHABLE NODES. IT ALSO IMPLEMENTS */
|
|
kusano |
7d535a |
/* THE MODIFICATIONS BY MULTIPLE ELIMINATION AND MINIMUM */
|
|
kusano |
7d535a |
/* EXTERNAL DEGREE. */
|
|
kusano |
7d535a |
/* --------------------------------------------- */
|
|
kusano |
7d535a |
/* CAUTION - THE ADJACENCY VECTOR ADJNCY WILL BE */
|
|
kusano |
7d535a |
/* DESTROYED. */
|
|
kusano |
7d535a |
/* --------------------------------------------- */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* INPUT PARAMETERS - */
|
|
kusano |
7d535a |
/* NEQNS - NUMBER OF EQUATIONS. */
|
|
kusano |
7d535a |
/* (XADJ,ADJNCY) - THE ADJACENCY STRUCTURE. */
|
|
kusano |
7d535a |
/* DELTA - TOLERANCE VALUE FOR MULTIPLE ELIMINATION. */
|
|
kusano |
7d535a |
/* MAXINT - MAXIMUM MACHINE REPRESENTABLE (SHORT) INTEGER */
|
|
kusano |
7d535a |
/* (ANY SMALLER ESTIMATE WILL DO) FOR MARKING */
|
|
kusano |
7d535a |
/* NODES. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* OUTPUT PARAMETERS - */
|
|
kusano |
7d535a |
/* PERM - THE MINIMUM DEGREE ORDERING. */
|
|
kusano |
7d535a |
/* INVP - THE INVERSE OF PERM. */
|
|
kusano |
7d535a |
/* NOFSUB - AN UPPER BOUND ON THE NUMBER OF NONZERO */
|
|
kusano |
7d535a |
/* SUBSCRIPTS FOR THE COMPRESSED STORAGE SCHEME. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* WORKING PARAMETERS - */
|
|
kusano |
7d535a |
/* DHEAD - VECTOR FOR HEAD OF DEGREE LISTS. */
|
|
kusano |
7d535a |
/* INVP - USED TEMPORARILY FOR DEGREE FORWARD LINK. */
|
|
kusano |
7d535a |
/* PERM - USED TEMPORARILY FOR DEGREE BACKWARD LINK. */
|
|
kusano |
7d535a |
/* QSIZE - VECTOR FOR SIZE OF SUPERNODES. */
|
|
kusano |
7d535a |
/* LLIST - VECTOR FOR TEMPORARY LINKED LISTS. */
|
|
kusano |
7d535a |
/* MARKER - A TEMPORARY MARKER VECTOR. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* PROGRAM SUBROUTINES - */
|
|
kusano |
7d535a |
/* MMDELM, MMDINT, MMDNUM, MMDUPD. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Subroutine */ int genmmd_(int *neqns, int *xadj, shortint *adjncy,
|
|
kusano |
7d535a |
shortint *invp, shortint *perm, int *delta, shortint *dhead,
|
|
kusano |
7d535a |
shortint *qsize, shortint *llist, shortint *marker, int *maxint,
|
|
kusano |
7d535a |
int *nofsub)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
/* System generated locals */
|
|
kusano |
7d535a |
int i__1;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Local variables */
|
|
kusano |
7d535a |
static int mdeg, ehead, i, mdlmt, mdnode;
|
|
kusano |
7d535a |
extern /* Subroutine */ int mmdelm_(int *, int *, shortint *,
|
|
kusano |
7d535a |
shortint *, shortint *, shortint *, shortint *, shortint *,
|
|
kusano |
7d535a |
shortint *, int *, int *), mmdupd_(int *, int *,
|
|
kusano |
7d535a |
int *, shortint *, int *, int *, shortint *, shortint
|
|
kusano |
7d535a |
*, shortint *, shortint *, shortint *, shortint *, int *,
|
|
kusano |
7d535a |
int *), mmdint_(int *, int *, shortint *, shortint *,
|
|
kusano |
7d535a |
shortint *, shortint *, shortint *, shortint *, shortint *),
|
|
kusano |
7d535a |
mmdnum_(int *, shortint *, shortint *, shortint *);
|
|
kusano |
7d535a |
static int nextmd, tag, num;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Parameter adjustments */
|
|
kusano |
7d535a |
--marker;
|
|
kusano |
7d535a |
--llist;
|
|
kusano |
7d535a |
--qsize;
|
|
kusano |
7d535a |
--dhead;
|
|
kusano |
7d535a |
--perm;
|
|
kusano |
7d535a |
--invp;
|
|
kusano |
7d535a |
--adjncy;
|
|
kusano |
7d535a |
--xadj;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Function Body */
|
|
kusano |
7d535a |
if (*neqns <= 0) {
|
|
kusano |
7d535a |
return 0;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ------------------------------------------------ */
|
|
kusano |
7d535a |
/* INITIALIZATION FOR THE MINIMUM DEGREE ALGORITHM. */
|
|
kusano |
7d535a |
/* ------------------------------------------------ */
|
|
kusano |
7d535a |
*nofsub = 0;
|
|
kusano |
7d535a |
mmdint_(neqns, &xadj[1], &adjncy[1], &dhead[1], &invp[1], &perm[1], &
|
|
kusano |
7d535a |
qsize[1], &llist[1], &marker[1]);
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ---------------------------------------------- */
|
|
kusano |
7d535a |
/* NUM COUNTS THE NUMBER OF ORDERED NODES PLUS 1. */
|
|
kusano |
7d535a |
/* ---------------------------------------------- */
|
|
kusano |
7d535a |
num = 1;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ----------------------------- */
|
|
kusano |
7d535a |
/* ELIMINATE ALL ISOLATED NODES. */
|
|
kusano |
7d535a |
/* ----------------------------- */
|
|
kusano |
7d535a |
nextmd = dhead[1];
|
|
kusano |
7d535a |
L100:
|
|
kusano |
7d535a |
if (nextmd <= 0) {
|
|
kusano |
7d535a |
goto L200;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
mdnode = nextmd;
|
|
kusano |
7d535a |
nextmd = invp[mdnode];
|
|
kusano |
7d535a |
marker[mdnode] = *maxint;
|
|
kusano |
7d535a |
invp[mdnode] = -num;
|
|
kusano |
7d535a |
++num;
|
|
kusano |
7d535a |
goto L100;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
L200:
|
|
kusano |
7d535a |
/* ---------------------------------------- */
|
|
kusano |
7d535a |
/* SEARCH FOR NODE OF THE MINIMUM DEGREE. */
|
|
kusano |
7d535a |
/* MDEG IS THE CURRENT MINIMUM DEGREE; */
|
|
kusano |
7d535a |
/* TAG IS USED TO FACILITATE MARKING NODES. */
|
|
kusano |
7d535a |
/* ---------------------------------------- */
|
|
kusano |
7d535a |
if (num > *neqns) {
|
|
kusano |
7d535a |
goto L1000;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
tag = 1;
|
|
kusano |
7d535a |
dhead[1] = 0;
|
|
kusano |
7d535a |
mdeg = 2;
|
|
kusano |
7d535a |
L300:
|
|
kusano |
7d535a |
if (dhead[mdeg] > 0) {
|
|
kusano |
7d535a |
goto L400;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
++mdeg;
|
|
kusano |
7d535a |
goto L300;
|
|
kusano |
7d535a |
L400:
|
|
kusano |
7d535a |
/* ------------------------------------------------- */
|
|
kusano |
7d535a |
/* USE VALUE OF DELTA TO SET UP MDLMT, WHICH GOVERNS */
|
|
kusano |
7d535a |
/* WHEN A DEGREE UPDATE IS TO BE PERFORMED. */
|
|
kusano |
7d535a |
/* ------------------------------------------------- */
|
|
kusano |
7d535a |
mdlmt = mdeg + *delta;
|
|
kusano |
7d535a |
ehead = 0;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
L500:
|
|
kusano |
7d535a |
mdnode = dhead[mdeg];
|
|
kusano |
7d535a |
if (mdnode > 0) {
|
|
kusano |
7d535a |
goto L600;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
++mdeg;
|
|
kusano |
7d535a |
if (mdeg > mdlmt) {
|
|
kusano |
7d535a |
goto L900;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
goto L500;
|
|
kusano |
7d535a |
L600:
|
|
kusano |
7d535a |
/* ---------------------------------------- */
|
|
kusano |
7d535a |
/* REMOVE MDNODE FROM THE DEGREE STRUCTURE. */
|
|
kusano |
7d535a |
/* ---------------------------------------- */
|
|
kusano |
7d535a |
nextmd = invp[mdnode];
|
|
kusano |
7d535a |
dhead[mdeg] = nextmd;
|
|
kusano |
7d535a |
if (nextmd > 0) {
|
|
kusano |
7d535a |
perm[nextmd] = -mdeg;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
invp[mdnode] = -num;
|
|
kusano |
7d535a |
*nofsub = *nofsub + mdeg + qsize[mdnode] - 2;
|
|
kusano |
7d535a |
if (num + qsize[mdnode] > *neqns) {
|
|
kusano |
7d535a |
goto L1000;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* ---------------------------------------------- */
|
|
kusano |
7d535a |
/* ELIMINATE MDNODE AND PERFORM QUOTIENT GRAPH */
|
|
kusano |
7d535a |
/* TRANSFORMATION. RESET TAG VALUE IF NECESSARY. */
|
|
kusano |
7d535a |
/* ---------------------------------------------- */
|
|
kusano |
7d535a |
++tag;
|
|
kusano |
7d535a |
if (tag < *maxint) {
|
|
kusano |
7d535a |
goto L800;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
tag = 1;
|
|
kusano |
7d535a |
i__1 = *neqns;
|
|
kusano |
7d535a |
for (i = 1; i <= i__1; ++i) {
|
|
kusano |
7d535a |
if (marker[i] < *maxint) {
|
|
kusano |
7d535a |
marker[i] = 0;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L700: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L800:
|
|
kusano |
7d535a |
mmdelm_(&mdnode, &xadj[1], &adjncy[1], &dhead[1], &invp[1], &perm[1], &
|
|
kusano |
7d535a |
qsize[1], &llist[1], &marker[1], maxint, &tag);
|
|
kusano |
7d535a |
num += qsize[mdnode];
|
|
kusano |
7d535a |
llist[mdnode] = ehead;
|
|
kusano |
7d535a |
ehead = mdnode;
|
|
kusano |
7d535a |
if (*delta >= 0) {
|
|
kusano |
7d535a |
goto L500;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L900:
|
|
kusano |
7d535a |
/* ------------------------------------------- */
|
|
kusano |
7d535a |
/* UPDATE DEGREES OF THE NODES INVOLVED IN THE */
|
|
kusano |
7d535a |
/* MINIMUM DEGREE NODES ELIMINATION. */
|
|
kusano |
7d535a |
/* ------------------------------------------- */
|
|
kusano |
7d535a |
if (num > *neqns) {
|
|
kusano |
7d535a |
goto L1000;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
mmdupd_(&ehead, neqns, &xadj[1], &adjncy[1], delta, &mdeg, &dhead[1], &
|
|
kusano |
7d535a |
invp[1], &perm[1], &qsize[1], &llist[1], &marker[1], maxint, &tag)
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
goto L300;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
L1000:
|
|
kusano |
7d535a |
mmdnum_(neqns, &perm[1], &invp[1], &qsize[1]);
|
|
kusano |
7d535a |
return 0;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
} /* genmmd_ */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
/* *** MMDINT ..... MULT MINIMUM DEGREE INITIALIZATION *** */
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* AUTHOR - JOSEPH W.H. LIU */
|
|
kusano |
7d535a |
/* DEPT OF COMPUTER SCIENCE, YORK UNIVERSITY. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* PURPOSE - THIS ROUTINE PERFORMS INITIALIZATION FOR THE */
|
|
kusano |
7d535a |
/* MULTIPLE ELIMINATION VERSION OF THE MINIMUM DEGREE */
|
|
kusano |
7d535a |
/* ALGORITHM. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* INPUT PARAMETERS - */
|
|
kusano |
7d535a |
/* NEQNS - NUMBER OF EQUATIONS. */
|
|
kusano |
7d535a |
/* (XADJ,ADJNCY) - ADJACENCY STRUCTURE. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* OUTPUT PARAMETERS - */
|
|
kusano |
7d535a |
/* (DHEAD,DFORW,DBAKW) - DEGREE DOUBLY LINKED STRUCTURE. */
|
|
kusano |
7d535a |
/* QSIZE - SIZE OF SUPERNODE (INITIALIZED TO ONE). */
|
|
kusano |
7d535a |
/* LLIST - LINKED LIST. */
|
|
kusano |
7d535a |
/* MARKER - MARKER VECTOR. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Subroutine */ int mmdint_(int *neqns, int *xadj, shortint *adjncy,
|
|
kusano |
7d535a |
shortint *dhead, shortint *dforw, shortint *dbakw, shortint *qsize,
|
|
kusano |
7d535a |
shortint *llist, shortint *marker)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
/* System generated locals */
|
|
kusano |
7d535a |
int i__1;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Local variables */
|
|
kusano |
7d535a |
static int ndeg, node, fnode;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Parameter adjustments */
|
|
kusano |
7d535a |
--marker;
|
|
kusano |
7d535a |
--llist;
|
|
kusano |
7d535a |
--qsize;
|
|
kusano |
7d535a |
--dbakw;
|
|
kusano |
7d535a |
--dforw;
|
|
kusano |
7d535a |
--dhead;
|
|
kusano |
7d535a |
--adjncy;
|
|
kusano |
7d535a |
--xadj;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Function Body */
|
|
kusano |
7d535a |
i__1 = *neqns;
|
|
kusano |
7d535a |
for (node = 1; node <= i__1; ++node) {
|
|
kusano |
7d535a |
dhead[node] = 0;
|
|
kusano |
7d535a |
qsize[node] = 1;
|
|
kusano |
7d535a |
marker[node] = 0;
|
|
kusano |
7d535a |
llist[node] = 0;
|
|
kusano |
7d535a |
/* L100: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* ------------------------------------------ */
|
|
kusano |
7d535a |
/* INITIALIZE THE DEGREE DOUBLY LINKED LISTS. */
|
|
kusano |
7d535a |
/* ------------------------------------------ */
|
|
kusano |
7d535a |
i__1 = *neqns;
|
|
kusano |
7d535a |
for (node = 1; node <= i__1; ++node) {
|
|
kusano |
7d535a |
ndeg = xadj[node + 1] - xadj[node] + 1;
|
|
kusano |
7d535a |
fnode = dhead[ndeg];
|
|
kusano |
7d535a |
dforw[node] = fnode;
|
|
kusano |
7d535a |
dhead[ndeg] = node;
|
|
kusano |
7d535a |
if (fnode > 0) {
|
|
kusano |
7d535a |
dbakw[fnode] = node;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
dbakw[node] = -ndeg;
|
|
kusano |
7d535a |
/* L200: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
return 0;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
} /* mmdint_ */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
/* ** MMDELM ..... MULTIPLE MINIMUM DEGREE ELIMINATION *** */
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* AUTHOR - JOSEPH W.H. LIU */
|
|
kusano |
7d535a |
/* DEPT OF COMPUTER SCIENCE, YORK UNIVERSITY. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* PURPOSE - THIS ROUTINE ELIMINATES THE NODE MDNODE OF */
|
|
kusano |
7d535a |
/* MINIMUM DEGREE FROM THE ADJACENCY STRUCTURE, WHICH */
|
|
kusano |
7d535a |
/* IS STORED IN THE QUOTIENT GRAPH FORMAT. IT ALSO */
|
|
kusano |
7d535a |
/* TRANSFORMS THE QUOTIENT GRAPH REPRESENTATION OF THE */
|
|
kusano |
7d535a |
/* ELIMINATION GRAPH. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* INPUT PARAMETERS - */
|
|
kusano |
7d535a |
/* MDNODE - NODE OF MINIMUM DEGREE. */
|
|
kusano |
7d535a |
/* MAXINT - ESTIMATE OF MAXIMUM REPRESENTABLE (SHORT) */
|
|
kusano |
7d535a |
/* INT. */
|
|
kusano |
7d535a |
/* TAG - TAG VALUE. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* UPDATED PARAMETERS - */
|
|
kusano |
7d535a |
/* (XADJ,ADJNCY) - UPDATED ADJACENCY STRUCTURE. */
|
|
kusano |
7d535a |
/* (DHEAD,DFORW,DBAKW) - DEGREE DOUBLY LINKED STRUCTURE. */
|
|
kusano |
7d535a |
/* QSIZE - SIZE OF SUPERNODE. */
|
|
kusano |
7d535a |
/* MARKER - MARKER VECTOR. */
|
|
kusano |
7d535a |
/* LLIST - TEMPORARY LINKED LIST OF ELIMINATED NABORS. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Subroutine */ int mmdelm_(int *mdnode, int *xadj, shortint *adjncy,
|
|
kusano |
7d535a |
shortint *dhead, shortint *dforw, shortint *dbakw, shortint *qsize,
|
|
kusano |
7d535a |
shortint *llist, shortint *marker, int *maxint, int *tag)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
/* System generated locals */
|
|
kusano |
7d535a |
int i__1, i__2;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Local variables */
|
|
kusano |
7d535a |
static int node, link, rloc, rlmt, i, j, nabor, rnode, elmnt, xqnbr,
|
|
kusano |
7d535a |
istop, jstop, istrt, jstrt, nxnode, pvnode, nqnbrs, npv;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ----------------------------------------------- */
|
|
kusano |
7d535a |
/* FIND REACHABLE SET AND PLACE IN DATA STRUCTURE. */
|
|
kusano |
7d535a |
/* ----------------------------------------------- */
|
|
kusano |
7d535a |
/* Parameter adjustments */
|
|
kusano |
7d535a |
--marker;
|
|
kusano |
7d535a |
--llist;
|
|
kusano |
7d535a |
--qsize;
|
|
kusano |
7d535a |
--dbakw;
|
|
kusano |
7d535a |
--dforw;
|
|
kusano |
7d535a |
--dhead;
|
|
kusano |
7d535a |
--adjncy;
|
|
kusano |
7d535a |
--xadj;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Function Body */
|
|
kusano |
7d535a |
marker[*mdnode] = *tag;
|
|
kusano |
7d535a |
istrt = xadj[*mdnode];
|
|
kusano |
7d535a |
istop = xadj[*mdnode + 1] - 1;
|
|
kusano |
7d535a |
/* ------------------------------------------------------- */
|
|
kusano |
7d535a |
/* ELMNT POINTS TO THE BEGINNING OF THE LIST OF ELIMINATED */
|
|
kusano |
7d535a |
/* NABORS OF MDNODE, AND RLOC GIVES THE STORAGE LOCATION */
|
|
kusano |
7d535a |
/* FOR THE NEXT REACHABLE NODE. */
|
|
kusano |
7d535a |
/* ------------------------------------------------------- */
|
|
kusano |
7d535a |
elmnt = 0;
|
|
kusano |
7d535a |
rloc = istrt;
|
|
kusano |
7d535a |
rlmt = istop;
|
|
kusano |
7d535a |
i__1 = istop;
|
|
kusano |
7d535a |
for (i = istrt; i <= i__1; ++i) {
|
|
kusano |
7d535a |
nabor = adjncy[i];
|
|
kusano |
7d535a |
if (nabor == 0) {
|
|
kusano |
7d535a |
goto L300;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (marker[nabor] >= *tag) {
|
|
kusano |
7d535a |
goto L200;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
marker[nabor] = *tag;
|
|
kusano |
7d535a |
if (dforw[nabor] < 0) {
|
|
kusano |
7d535a |
goto L100;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
adjncy[rloc] = nabor;
|
|
kusano |
7d535a |
++rloc;
|
|
kusano |
7d535a |
goto L200;
|
|
kusano |
7d535a |
L100:
|
|
kusano |
7d535a |
llist[nabor] = elmnt;
|
|
kusano |
7d535a |
elmnt = nabor;
|
|
kusano |
7d535a |
L200:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L300:
|
|
kusano |
7d535a |
/* ----------------------------------------------------- */
|
|
kusano |
7d535a |
/* MERGE WITH REACHABLE NODES FROM GENERALIZED ELEMENTS. */
|
|
kusano |
7d535a |
/* ----------------------------------------------------- */
|
|
kusano |
7d535a |
if (elmnt <= 0) {
|
|
kusano |
7d535a |
goto L1000;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
adjncy[rlmt] = -elmnt;
|
|
kusano |
7d535a |
link = elmnt;
|
|
kusano |
7d535a |
L400:
|
|
kusano |
7d535a |
jstrt = xadj[link];
|
|
kusano |
7d535a |
jstop = xadj[link + 1] - 1;
|
|
kusano |
7d535a |
i__1 = jstop;
|
|
kusano |
7d535a |
for (j = jstrt; j <= i__1; ++j) {
|
|
kusano |
7d535a |
node = adjncy[j];
|
|
kusano |
7d535a |
link = -node;
|
|
kusano |
7d535a |
if (node < 0) {
|
|
kusano |
7d535a |
goto L400;
|
|
kusano |
7d535a |
} else if (node == 0) {
|
|
kusano |
7d535a |
goto L900;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
goto L500;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L500:
|
|
kusano |
7d535a |
if (marker[node] >= *tag || dforw[node] < 0) {
|
|
kusano |
7d535a |
goto L800;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
marker[node] = *tag;
|
|
kusano |
7d535a |
/* --------------------------------- */
|
|
kusano |
7d535a |
/* USE STORAGE FROM ELIMINATED NODES */
|
|
kusano |
7d535a |
/* IF NECESSARY. */
|
|
kusano |
7d535a |
/* --------------------------------- */
|
|
kusano |
7d535a |
L600:
|
|
kusano |
7d535a |
if (rloc < rlmt) {
|
|
kusano |
7d535a |
goto L700;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
link = -adjncy[rlmt];
|
|
kusano |
7d535a |
rloc = xadj[link];
|
|
kusano |
7d535a |
rlmt = xadj[link + 1] - 1;
|
|
kusano |
7d535a |
goto L600;
|
|
kusano |
7d535a |
L700:
|
|
kusano |
7d535a |
adjncy[rloc] = node;
|
|
kusano |
7d535a |
++rloc;
|
|
kusano |
7d535a |
L800:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L900:
|
|
kusano |
7d535a |
elmnt = llist[elmnt];
|
|
kusano |
7d535a |
goto L300;
|
|
kusano |
7d535a |
L1000:
|
|
kusano |
7d535a |
if (rloc <= rlmt) {
|
|
kusano |
7d535a |
adjncy[rloc] = 0;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* -------------------------------------------------------- */
|
|
kusano |
7d535a |
/* FOR EACH NODE IN THE REACHABLE SET, DO THE FOLLOWING ... */
|
|
kusano |
7d535a |
/* -------------------------------------------------------- */
|
|
kusano |
7d535a |
link = *mdnode;
|
|
kusano |
7d535a |
L1100:
|
|
kusano |
7d535a |
istrt = xadj[link];
|
|
kusano |
7d535a |
istop = xadj[link + 1] - 1;
|
|
kusano |
7d535a |
i__1 = istop;
|
|
kusano |
7d535a |
for (i = istrt; i <= i__1; ++i) {
|
|
kusano |
7d535a |
rnode = adjncy[i];
|
|
kusano |
7d535a |
link = -rnode;
|
|
kusano |
7d535a |
if (rnode < 0) {
|
|
kusano |
7d535a |
goto L1100;
|
|
kusano |
7d535a |
} else if (rnode == 0) {
|
|
kusano |
7d535a |
goto L1800;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
goto L1200;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L1200:
|
|
kusano |
7d535a |
/* -------------------------------------------- */
|
|
kusano |
7d535a |
/* IF RNODE IS IN THE DEGREE LIST STRUCTURE ... */
|
|
kusano |
7d535a |
/* -------------------------------------------- */
|
|
kusano |
7d535a |
pvnode = dbakw[rnode];
|
|
kusano |
7d535a |
if (pvnode == 0 || pvnode == -(*maxint)) {
|
|
kusano |
7d535a |
goto L1300;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* ------------------------------------- */
|
|
kusano |
7d535a |
/* THEN REMOVE RNODE FROM THE STRUCTURE. */
|
|
kusano |
7d535a |
/* ------------------------------------- */
|
|
kusano |
7d535a |
nxnode = dforw[rnode];
|
|
kusano |
7d535a |
if (nxnode > 0) {
|
|
kusano |
7d535a |
dbakw[nxnode] = pvnode;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (pvnode > 0) {
|
|
kusano |
7d535a |
dforw[pvnode] = nxnode;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
npv = -pvnode;
|
|
kusano |
7d535a |
if (pvnode < 0) {
|
|
kusano |
7d535a |
dhead[npv] = nxnode;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L1300:
|
|
kusano |
7d535a |
/* ---------------------------------------- */
|
|
kusano |
7d535a |
/* PURGE INACTIVE QUOTIENT NABORS OF RNODE. */
|
|
kusano |
7d535a |
/* ---------------------------------------- */
|
|
kusano |
7d535a |
jstrt = xadj[rnode];
|
|
kusano |
7d535a |
jstop = xadj[rnode + 1] - 1;
|
|
kusano |
7d535a |
xqnbr = jstrt;
|
|
kusano |
7d535a |
i__2 = jstop;
|
|
kusano |
7d535a |
for (j = jstrt; j <= i__2; ++j) {
|
|
kusano |
7d535a |
nabor = adjncy[j];
|
|
kusano |
7d535a |
if (nabor == 0) {
|
|
kusano |
7d535a |
goto L1500;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (marker[nabor] >= *tag) {
|
|
kusano |
7d535a |
goto L1400;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
adjncy[xqnbr] = nabor;
|
|
kusano |
7d535a |
++xqnbr;
|
|
kusano |
7d535a |
L1400:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L1500:
|
|
kusano |
7d535a |
/* ---------------------------------------- */
|
|
kusano |
7d535a |
/* IF NO ACTIVE NABOR AFTER THE PURGING ... */
|
|
kusano |
7d535a |
/* ---------------------------------------- */
|
|
kusano |
7d535a |
nqnbrs = xqnbr - jstrt;
|
|
kusano |
7d535a |
if (nqnbrs > 0) {
|
|
kusano |
7d535a |
goto L1600;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* ----------------------------- */
|
|
kusano |
7d535a |
/* THEN MERGE RNODE WITH MDNODE. */
|
|
kusano |
7d535a |
/* ----------------------------- */
|
|
kusano |
7d535a |
qsize[*mdnode] += qsize[rnode];
|
|
kusano |
7d535a |
qsize[rnode] = 0;
|
|
kusano |
7d535a |
marker[rnode] = *maxint;
|
|
kusano |
7d535a |
dforw[rnode] = -(*mdnode);
|
|
kusano |
7d535a |
dbakw[rnode] = -(*maxint);
|
|
kusano |
7d535a |
goto L1700;
|
|
kusano |
7d535a |
L1600:
|
|
kusano |
7d535a |
/* -------------------------------------- */
|
|
kusano |
7d535a |
/* ELSE FLAG RNODE FOR DEGREE UPDATE, AND */
|
|
kusano |
7d535a |
/* ADD MDNODE AS A NABOR OF RNODE. */
|
|
kusano |
7d535a |
/* -------------------------------------- */
|
|
kusano |
7d535a |
dforw[rnode] = nqnbrs + 1;
|
|
kusano |
7d535a |
dbakw[rnode] = 0;
|
|
kusano |
7d535a |
adjncy[xqnbr] = *mdnode;
|
|
kusano |
7d535a |
++xqnbr;
|
|
kusano |
7d535a |
if (xqnbr <= jstop) {
|
|
kusano |
7d535a |
adjncy[xqnbr] = 0;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
L1700:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L1800:
|
|
kusano |
7d535a |
return 0;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
} /* mmdelm_ */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
/* ***** MMDUPD ..... MULTIPLE MINIMUM DEGREE UPDATE ***** */
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* AUTHOR - JOSEPH W.H. LIU */
|
|
kusano |
7d535a |
/* DEPT OF COMPUTER SCIENCE, YORK UNIVERSITY. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* PURPOSE - THIS ROUTINE UPDATES THE DEGREES OF NODES */
|
|
kusano |
7d535a |
/* AFTER A MULTIPLE ELIMINATION STEP. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* INPUT PARAMETERS - */
|
|
kusano |
7d535a |
/* EHEAD - THE BEGINNING OF THE LIST OF ELIMINATED */
|
|
kusano |
7d535a |
/* NODES (I.E., NEWLY FORMED ELEMENTS). */
|
|
kusano |
7d535a |
/* NEQNS - NUMBER OF EQUATIONS. */
|
|
kusano |
7d535a |
/* (XADJ,ADJNCY) - ADJACENCY STRUCTURE. */
|
|
kusano |
7d535a |
/* DELTA - TOLERANCE VALUE FOR MULTIPLE ELIMINATION. */
|
|
kusano |
7d535a |
/* MAXINT - MAXIMUM MACHINE REPRESENTABLE (SHORT) */
|
|
kusano |
7d535a |
/* INTEGER. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* UPDATED PARAMETERS - */
|
|
kusano |
7d535a |
/* MDEG - NEW MINIMUM DEGREE AFTER DEGREE UPDATE. */
|
|
kusano |
7d535a |
/* (DHEAD,DFORW,DBAKW) - DEGREE DOUBLY LINKED STRUCTURE. */
|
|
kusano |
7d535a |
/* QSIZE - SIZE OF SUPERNODE. */
|
|
kusano |
7d535a |
/* LLIST - WORKING LINKED LIST. */
|
|
kusano |
7d535a |
/* MARKER - MARKER VECTOR FOR DEGREE UPDATE. */
|
|
kusano |
7d535a |
/* TAG - TAG VALUE. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Subroutine */ int mmdupd_(int *ehead, int *neqns, int *xadj,
|
|
kusano |
7d535a |
shortint *adjncy, int *delta, int *mdeg, shortint *dhead,
|
|
kusano |
7d535a |
shortint *dforw, shortint *dbakw, shortint *qsize, shortint *llist,
|
|
kusano |
7d535a |
shortint *marker, int *maxint, int *tag)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
/* System generated locals */
|
|
kusano |
7d535a |
int i__1, i__2;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Local variables */
|
|
kusano |
7d535a |
static int node, mtag, link, mdeg0, i, j, enode, fnode, nabor, elmnt,
|
|
kusano |
7d535a |
istop, jstop, q2head, istrt, jstrt, qxhead, iq2, deg, deg0;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Parameter adjustments */
|
|
kusano |
7d535a |
--marker;
|
|
kusano |
7d535a |
--llist;
|
|
kusano |
7d535a |
--qsize;
|
|
kusano |
7d535a |
--dbakw;
|
|
kusano |
7d535a |
--dforw;
|
|
kusano |
7d535a |
--dhead;
|
|
kusano |
7d535a |
--adjncy;
|
|
kusano |
7d535a |
--xadj;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Function Body */
|
|
kusano |
7d535a |
mdeg0 = *mdeg + *delta;
|
|
kusano |
7d535a |
elmnt = *ehead;
|
|
kusano |
7d535a |
L100:
|
|
kusano |
7d535a |
/* ------------------------------------------------------- */
|
|
kusano |
7d535a |
/* FOR EACH OF THE NEWLY FORMED ELEMENT, DO THE FOLLOWING. */
|
|
kusano |
7d535a |
/* (RESET TAG VALUE IF NECESSARY.) */
|
|
kusano |
7d535a |
/* ------------------------------------------------------- */
|
|
kusano |
7d535a |
if (elmnt <= 0) {
|
|
kusano |
7d535a |
return 0;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
mtag = *tag + mdeg0;
|
|
kusano |
7d535a |
if (mtag < *maxint) {
|
|
kusano |
7d535a |
goto L300;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
*tag = 1;
|
|
kusano |
7d535a |
i__1 = *neqns;
|
|
kusano |
7d535a |
for (i = 1; i <= i__1; ++i) {
|
|
kusano |
7d535a |
if (marker[i] < *maxint) {
|
|
kusano |
7d535a |
marker[i] = 0;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L200: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
mtag = *tag + mdeg0;
|
|
kusano |
7d535a |
L300:
|
|
kusano |
7d535a |
/* --------------------------------------------- */
|
|
kusano |
7d535a |
/* CREATE TWO LINKED LISTS FROM NODES ASSOCIATED */
|
|
kusano |
7d535a |
/* WITH ELMNT: ONE WITH TWO NABORS (Q2HEAD) IN */
|
|
kusano |
7d535a |
/* ADJACENCY STRUCTURE, AND THE OTHER WITH MORE */
|
|
kusano |
7d535a |
/* THAN TWO NABORS (QXHEAD). ALSO COMPUTE DEG0, */
|
|
kusano |
7d535a |
/* NUMBER OF NODES IN THIS ELEMENT. */
|
|
kusano |
7d535a |
/* --------------------------------------------- */
|
|
kusano |
7d535a |
q2head = 0;
|
|
kusano |
7d535a |
qxhead = 0;
|
|
kusano |
7d535a |
deg0 = 0;
|
|
kusano |
7d535a |
link = elmnt;
|
|
kusano |
7d535a |
L400:
|
|
kusano |
7d535a |
istrt = xadj[link];
|
|
kusano |
7d535a |
istop = xadj[link + 1] - 1;
|
|
kusano |
7d535a |
i__1 = istop;
|
|
kusano |
7d535a |
for (i = istrt; i <= i__1; ++i) {
|
|
kusano |
7d535a |
enode = adjncy[i];
|
|
kusano |
7d535a |
link = -enode;
|
|
kusano |
7d535a |
if (enode < 0) {
|
|
kusano |
7d535a |
goto L400;
|
|
kusano |
7d535a |
} else if (enode == 0) {
|
|
kusano |
7d535a |
goto L800;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
goto L500;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
L500:
|
|
kusano |
7d535a |
if (qsize[enode] == 0) {
|
|
kusano |
7d535a |
goto L700;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
deg0 += qsize[enode];
|
|
kusano |
7d535a |
marker[enode] = mtag;
|
|
kusano |
7d535a |
/* ---------------------------------- */
|
|
kusano |
7d535a |
/* IF ENODE REQUIRES A DEGREE UPDATE, */
|
|
kusano |
7d535a |
/* THEN DO THE FOLLOWING. */
|
|
kusano |
7d535a |
/* ---------------------------------- */
|
|
kusano |
7d535a |
if (dbakw[enode] != 0) {
|
|
kusano |
7d535a |
goto L700;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* ---------------------------------------
|
|
kusano |
7d535a |
*/
|
|
kusano |
7d535a |
/* PLACE EITHER IN QXHEAD OR Q2HEAD LISTS.
|
|
kusano |
7d535a |
*/
|
|
kusano |
7d535a |
/* ---------------------------------------
|
|
kusano |
7d535a |
*/
|
|
kusano |
7d535a |
if (dforw[enode] == 2) {
|
|
kusano |
7d535a |
goto L600;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
llist[enode] = qxhead;
|
|
kusano |
7d535a |
qxhead = enode;
|
|
kusano |
7d535a |
goto L700;
|
|
kusano |
7d535a |
L600:
|
|
kusano |
7d535a |
llist[enode] = q2head;
|
|
kusano |
7d535a |
q2head = enode;
|
|
kusano |
7d535a |
L700:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L800:
|
|
kusano |
7d535a |
/* -------------------------------------------- */
|
|
kusano |
7d535a |
/* FOR EACH ENODE IN Q2 LIST, DO THE FOLLOWING. */
|
|
kusano |
7d535a |
/* -------------------------------------------- */
|
|
kusano |
7d535a |
enode = q2head;
|
|
kusano |
7d535a |
iq2 = 1;
|
|
kusano |
7d535a |
L900:
|
|
kusano |
7d535a |
if (enode <= 0) {
|
|
kusano |
7d535a |
goto L1500;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (dbakw[enode] != 0) {
|
|
kusano |
7d535a |
goto L2200;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
++(*tag);
|
|
kusano |
7d535a |
deg = deg0;
|
|
kusano |
7d535a |
/* ------------------------------------------ */
|
|
kusano |
7d535a |
/* IDENTIFY THE OTHER ADJACENT ELEMENT NABOR. */
|
|
kusano |
7d535a |
/* ------------------------------------------ */
|
|
kusano |
7d535a |
istrt = xadj[enode];
|
|
kusano |
7d535a |
nabor = adjncy[istrt];
|
|
kusano |
7d535a |
if (nabor == elmnt) {
|
|
kusano |
7d535a |
nabor = adjncy[istrt + 1];
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* ------------------------------------------------ */
|
|
kusano |
7d535a |
/* IF NABOR IS UNELIMINATED, INCREASE DEGREE COUNT. */
|
|
kusano |
7d535a |
/* ------------------------------------------------ */
|
|
kusano |
7d535a |
link = nabor;
|
|
kusano |
7d535a |
if (dforw[nabor] < 0) {
|
|
kusano |
7d535a |
goto L1000;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
deg += qsize[nabor];
|
|
kusano |
7d535a |
goto L2100;
|
|
kusano |
7d535a |
L1000:
|
|
kusano |
7d535a |
/* -------------------------------------------- */
|
|
kusano |
7d535a |
/* OTHERWISE, FOR EACH NODE IN THE 2ND ELEMENT, */
|
|
kusano |
7d535a |
/* DO THE FOLLOWING. */
|
|
kusano |
7d535a |
/* -------------------------------------------- */
|
|
kusano |
7d535a |
istrt = xadj[link];
|
|
kusano |
7d535a |
istop = xadj[link + 1] - 1;
|
|
kusano |
7d535a |
i__1 = istop;
|
|
kusano |
7d535a |
for (i = istrt; i <= i__1; ++i) {
|
|
kusano |
7d535a |
node = adjncy[i];
|
|
kusano |
7d535a |
link = -node;
|
|
kusano |
7d535a |
if (node == enode) {
|
|
kusano |
7d535a |
goto L1400;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (node < 0) {
|
|
kusano |
7d535a |
goto L1000;
|
|
kusano |
7d535a |
} else if (node == 0) {
|
|
kusano |
7d535a |
goto L2100;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
goto L1100;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
L1100:
|
|
kusano |
7d535a |
if (qsize[node] == 0) {
|
|
kusano |
7d535a |
goto L1400;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (marker[node] >= *tag) {
|
|
kusano |
7d535a |
goto L1200;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* -----------------------------------
|
|
kusano |
7d535a |
-- */
|
|
kusano |
7d535a |
/* CASE WHEN NODE IS NOT YET CONSIDERED
|
|
kusano |
7d535a |
. */
|
|
kusano |
7d535a |
/* -----------------------------------
|
|
kusano |
7d535a |
-- */
|
|
kusano |
7d535a |
marker[node] = *tag;
|
|
kusano |
7d535a |
deg += qsize[node];
|
|
kusano |
7d535a |
goto L1400;
|
|
kusano |
7d535a |
L1200:
|
|
kusano |
7d535a |
/* ----------------------------------------
|
|
kusano |
7d535a |
*/
|
|
kusano |
7d535a |
/* CASE WHEN NODE IS INDISTINGUISHABLE FROM
|
|
kusano |
7d535a |
*/
|
|
kusano |
7d535a |
/* ENODE. MERGE THEM INTO A NEW SUPERNODE.
|
|
kusano |
7d535a |
*/
|
|
kusano |
7d535a |
/* ----------------------------------------
|
|
kusano |
7d535a |
*/
|
|
kusano |
7d535a |
if (dbakw[node] != 0) {
|
|
kusano |
7d535a |
goto L1400;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (dforw[node] != 2) {
|
|
kusano |
7d535a |
goto L1300;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
qsize[enode] += qsize[node];
|
|
kusano |
7d535a |
qsize[node] = 0;
|
|
kusano |
7d535a |
marker[node] = *maxint;
|
|
kusano |
7d535a |
dforw[node] = -enode;
|
|
kusano |
7d535a |
dbakw[node] = -(*maxint);
|
|
kusano |
7d535a |
goto L1400;
|
|
kusano |
7d535a |
L1300:
|
|
kusano |
7d535a |
/* --------------------------------------
|
|
kusano |
7d535a |
*/
|
|
kusano |
7d535a |
/* CASE WHEN NODE IS OUTMATCHED BY ENODE.
|
|
kusano |
7d535a |
*/
|
|
kusano |
7d535a |
/* --------------------------------------
|
|
kusano |
7d535a |
*/
|
|
kusano |
7d535a |
if (dbakw[node] == 0) {
|
|
kusano |
7d535a |
dbakw[node] = -(*maxint);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L1400:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
goto L2100;
|
|
kusano |
7d535a |
L1500:
|
|
kusano |
7d535a |
/* ------------------------------------------------ */
|
|
kusano |
7d535a |
/* FOR EACH ENODE IN THE QX LIST, DO THE FOLLOWING. */
|
|
kusano |
7d535a |
/* ------------------------------------------------ */
|
|
kusano |
7d535a |
enode = qxhead;
|
|
kusano |
7d535a |
iq2 = 0;
|
|
kusano |
7d535a |
L1600:
|
|
kusano |
7d535a |
if (enode <= 0) {
|
|
kusano |
7d535a |
goto L2300;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (dbakw[enode] != 0) {
|
|
kusano |
7d535a |
goto L2200;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
++(*tag);
|
|
kusano |
7d535a |
deg = deg0;
|
|
kusano |
7d535a |
/* --------------------------------- */
|
|
kusano |
7d535a |
/* FOR EACH UNMARKED NABOR OF ENODE, */
|
|
kusano |
7d535a |
/* DO THE FOLLOWING. */
|
|
kusano |
7d535a |
/* --------------------------------- */
|
|
kusano |
7d535a |
istrt = xadj[enode];
|
|
kusano |
7d535a |
istop = xadj[enode + 1] - 1;
|
|
kusano |
7d535a |
i__1 = istop;
|
|
kusano |
7d535a |
for (i = istrt; i <= i__1; ++i) {
|
|
kusano |
7d535a |
nabor = adjncy[i];
|
|
kusano |
7d535a |
if (nabor == 0) {
|
|
kusano |
7d535a |
goto L2100;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (marker[nabor] >= *tag) {
|
|
kusano |
7d535a |
goto L2000;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
marker[nabor] = *tag;
|
|
kusano |
7d535a |
link = nabor;
|
|
kusano |
7d535a |
/* ------------------------------ */
|
|
kusano |
7d535a |
/* IF UNELIMINATED, INCLUDE IT IN */
|
|
kusano |
7d535a |
/* DEG COUNT. */
|
|
kusano |
7d535a |
/* ------------------------------ */
|
|
kusano |
7d535a |
if (dforw[nabor] < 0) {
|
|
kusano |
7d535a |
goto L1700;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
deg += qsize[nabor];
|
|
kusano |
7d535a |
goto L2000;
|
|
kusano |
7d535a |
L1700:
|
|
kusano |
7d535a |
/* -------------------------------
|
|
kusano |
7d535a |
*/
|
|
kusano |
7d535a |
/* IF ELIMINATED, INCLUDE UNMARKED
|
|
kusano |
7d535a |
*/
|
|
kusano |
7d535a |
/* NODES IN THIS ELEMENT INTO THE
|
|
kusano |
7d535a |
*/
|
|
kusano |
7d535a |
/* DEGREE COUNT. */
|
|
kusano |
7d535a |
/* -------------------------------
|
|
kusano |
7d535a |
*/
|
|
kusano |
7d535a |
jstrt = xadj[link];
|
|
kusano |
7d535a |
jstop = xadj[link + 1] - 1;
|
|
kusano |
7d535a |
i__2 = jstop;
|
|
kusano |
7d535a |
for (j = jstrt; j <= i__2; ++j) {
|
|
kusano |
7d535a |
node = adjncy[j];
|
|
kusano |
7d535a |
link = -node;
|
|
kusano |
7d535a |
if (node < 0) {
|
|
kusano |
7d535a |
goto L1700;
|
|
kusano |
7d535a |
} else if (node == 0) {
|
|
kusano |
7d535a |
goto L2000;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
goto L1800;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
L1800:
|
|
kusano |
7d535a |
if (marker[node] >= *tag) {
|
|
kusano |
7d535a |
goto L1900;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
marker[node] = *tag;
|
|
kusano |
7d535a |
deg += qsize[node];
|
|
kusano |
7d535a |
L1900:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L2000:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L2100:
|
|
kusano |
7d535a |
/* ------------------------------------------- */
|
|
kusano |
7d535a |
/* UPDATE EXTERNAL DEGREE OF ENODE IN DEGREE */
|
|
kusano |
7d535a |
/* STRUCTURE, AND MDEG (MIN DEG) IF NECESSARY. */
|
|
kusano |
7d535a |
/* ------------------------------------------- */
|
|
kusano |
7d535a |
deg = deg - qsize[enode] + 1;
|
|
kusano |
7d535a |
fnode = dhead[deg];
|
|
kusano |
7d535a |
dforw[enode] = fnode;
|
|
kusano |
7d535a |
dbakw[enode] = -deg;
|
|
kusano |
7d535a |
if (fnode > 0) {
|
|
kusano |
7d535a |
dbakw[fnode] = enode;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
dhead[deg] = enode;
|
|
kusano |
7d535a |
if (deg < *mdeg) {
|
|
kusano |
7d535a |
*mdeg = deg;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L2200:
|
|
kusano |
7d535a |
/* ---------------------------------- */
|
|
kusano |
7d535a |
/* GET NEXT ENODE IN CURRENT ELEMENT. */
|
|
kusano |
7d535a |
/* ---------------------------------- */
|
|
kusano |
7d535a |
enode = llist[enode];
|
|
kusano |
7d535a |
if (iq2 == 1) {
|
|
kusano |
7d535a |
goto L900;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
goto L1600;
|
|
kusano |
7d535a |
L2300:
|
|
kusano |
7d535a |
/* ----------------------------- */
|
|
kusano |
7d535a |
/* GET NEXT ELEMENT IN THE LIST. */
|
|
kusano |
7d535a |
/* ----------------------------- */
|
|
kusano |
7d535a |
*tag = mtag;
|
|
kusano |
7d535a |
elmnt = llist[elmnt];
|
|
kusano |
7d535a |
goto L100;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
} /* mmdupd_ */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
/* ***** MMDNUM ..... MULTI MINIMUM DEGREE NUMBERING ***** */
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* AUTHOR - JOSEPH W.H. LIU */
|
|
kusano |
7d535a |
/* DEPT OF COMPUTER SCIENCE, YORK UNIVERSITY. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* PURPOSE - THIS ROUTINE PERFORMS THE FINAL STEP IN */
|
|
kusano |
7d535a |
/* PRODUCING THE PERMUTATION AND INVERSE PERMUTATION */
|
|
kusano |
7d535a |
/* VECTORS IN THE MULTIPLE ELIMINATION VERSION OF THE */
|
|
kusano |
7d535a |
/* MINIMUM DEGREE ORDERING ALGORITHM. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* INPUT PARAMETERS - */
|
|
kusano |
7d535a |
/* NEQNS - NUMBER OF EQUATIONS. */
|
|
kusano |
7d535a |
/* QSIZE - SIZE OF SUPERNODES AT ELIMINATION. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* UPDATED PARAMETERS - */
|
|
kusano |
7d535a |
/* INVP - INVERSE PERMUTATION VECTOR. ON INPUT, */
|
|
kusano |
7d535a |
/* IF QSIZE(NODE)=0, THEN NODE HAS BEEN MERGED */
|
|
kusano |
7d535a |
/* INTO THE NODE -INVP(NODE); OTHERWISE, */
|
|
kusano |
7d535a |
/* -INVP(NODE) IS ITS INVERSE LABELLING. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* OUTPUT PARAMETERS - */
|
|
kusano |
7d535a |
/* PERM - THE PERMUTATION VECTOR. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Subroutine */ int mmdnum_(int *neqns, shortint *perm, shortint *invp,
|
|
kusano |
7d535a |
shortint *qsize)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
/* System generated locals */
|
|
kusano |
7d535a |
int i__1;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Local variables */
|
|
kusano |
7d535a |
static int node, root, nextf, father, nqsize, num;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *************************************************************** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Parameter adjustments */
|
|
kusano |
7d535a |
--qsize;
|
|
kusano |
7d535a |
--invp;
|
|
kusano |
7d535a |
--perm;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Function Body */
|
|
kusano |
7d535a |
i__1 = *neqns;
|
|
kusano |
7d535a |
for (node = 1; node <= i__1; ++node) {
|
|
kusano |
7d535a |
nqsize = qsize[node];
|
|
kusano |
7d535a |
if (nqsize <= 0) {
|
|
kusano |
7d535a |
perm[node] = invp[node];
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (nqsize > 0) {
|
|
kusano |
7d535a |
perm[node] = -invp[node];
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L100: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* ------------------------------------------------------ */
|
|
kusano |
7d535a |
/* FOR EACH NODE WHICH HAS BEEN MERGED, DO THE FOLLOWING. */
|
|
kusano |
7d535a |
/* ------------------------------------------------------ */
|
|
kusano |
7d535a |
i__1 = *neqns;
|
|
kusano |
7d535a |
for (node = 1; node <= i__1; ++node) {
|
|
kusano |
7d535a |
if (perm[node] > 0) {
|
|
kusano |
7d535a |
goto L500;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* ----------------------------------------- */
|
|
kusano |
7d535a |
/* TRACE THE MERGED TREE UNTIL ONE WHICH HAS */
|
|
kusano |
7d535a |
/* NOT BEEN MERGED, CALL IT ROOT. */
|
|
kusano |
7d535a |
/* ----------------------------------------- */
|
|
kusano |
7d535a |
father = node;
|
|
kusano |
7d535a |
L200:
|
|
kusano |
7d535a |
if (perm[father] > 0) {
|
|
kusano |
7d535a |
goto L300;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
father = -perm[father];
|
|
kusano |
7d535a |
goto L200;
|
|
kusano |
7d535a |
L300:
|
|
kusano |
7d535a |
/* ----------------------- */
|
|
kusano |
7d535a |
/* NUMBER NODE AFTER ROOT. */
|
|
kusano |
7d535a |
/* ----------------------- */
|
|
kusano |
7d535a |
root = father;
|
|
kusano |
7d535a |
num = perm[root] + 1;
|
|
kusano |
7d535a |
invp[node] = -num;
|
|
kusano |
7d535a |
perm[root] = num;
|
|
kusano |
7d535a |
/* ------------------------ */
|
|
kusano |
7d535a |
/* SHORTEN THE MERGED TREE. */
|
|
kusano |
7d535a |
/* ------------------------ */
|
|
kusano |
7d535a |
father = node;
|
|
kusano |
7d535a |
L400:
|
|
kusano |
7d535a |
nextf = -perm[father];
|
|
kusano |
7d535a |
if (nextf <= 0) {
|
|
kusano |
7d535a |
goto L500;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
perm[father] = -root;
|
|
kusano |
7d535a |
father = nextf;
|
|
kusano |
7d535a |
goto L400;
|
|
kusano |
7d535a |
L500:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* ---------------------- */
|
|
kusano |
7d535a |
/* READY TO COMPUTE PERM. */
|
|
kusano |
7d535a |
/* ---------------------- */
|
|
kusano |
7d535a |
i__1 = *neqns;
|
|
kusano |
7d535a |
for (node = 1; node <= i__1; ++node) {
|
|
kusano |
7d535a |
num = -invp[node];
|
|
kusano |
7d535a |
invp[node] = num;
|
|
kusano |
7d535a |
perm[num] = node;
|
|
kusano |
7d535a |
/* L600: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
return 0;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
} /* mmdnum_ */
|
|
kusano |
7d535a |
|