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