Blender V2.61 - r43446
|
00001 00005 typedef int shortint; 00006 00007 00008 /* prototypes -------------------- */ 00009 int genmmd_(int *, int *, int *, int *, int *, int *, int *, 00010 int *, int *, int *, int *, int *); 00011 int mmdint_(int *, int *, shortint *, shortint *, shortint *, shortint *, shortint *, 00012 shortint *, shortint *); 00013 int mmdelm_(int *, int *, shortint *, shortint *, shortint *, shortint *, shortint *, 00014 shortint *, shortint *, int *, int *); 00015 int mmdupd_(int *, int *, int *, shortint *, int *, int *, shortint *, 00016 shortint *, shortint *, shortint *, shortint *, shortint *, int *, int *); 00017 int mmdnum_(int *, shortint *, shortint *, shortint *); 00018 00019 00020 /* *************************************************************** */ 00021 /* *************************************************************** */ 00022 /* **** GENMMD ..... MULTIPLE MINIMUM EXTERNAL DEGREE **** */ 00023 /* *************************************************************** */ 00024 /* *************************************************************** */ 00025 00026 /* AUTHOR - JOSEPH W.H. LIU */ 00027 /* DEPT OF COMPUTER SCIENCE, YORK UNIVERSITY. */ 00028 00029 /* PURPOSE - THIS ROUTINE IMPLEMENTS THE MINIMUM DEGREE */ 00030 /* ALGORITHM. IT MAKES USE OF THE IMPLICIT REPRESENTATION */ 00031 /* OF ELIMINATION GRAPHS BY QUOTIENT GRAPHS, AND THE */ 00032 /* NOTION OF INDISTINGUISHABLE NODES. IT ALSO IMPLEMENTS */ 00033 /* THE MODIFICATIONS BY MULTIPLE ELIMINATION AND MINIMUM */ 00034 /* EXTERNAL DEGREE. */ 00035 /* --------------------------------------------- */ 00036 /* CAUTION - THE ADJACENCY VECTOR ADJNCY WILL BE */ 00037 /* DESTROYED. */ 00038 /* --------------------------------------------- */ 00039 00040 /* INPUT PARAMETERS - */ 00041 /* NEQNS - NUMBER OF EQUATIONS. */ 00042 /* (XADJ,ADJNCY) - THE ADJACENCY STRUCTURE. */ 00043 /* DELTA - TOLERANCE VALUE FOR MULTIPLE ELIMINATION. */ 00044 /* MAXINT - MAXIMUM MACHINE REPRESENTABLE (SHORT) INTEGER */ 00045 /* (ANY SMALLER ESTIMATE WILL DO) FOR MARKING */ 00046 /* NODES. */ 00047 00048 /* OUTPUT PARAMETERS - */ 00049 /* PERM - THE MINIMUM DEGREE ORDERING. */ 00050 /* INVP - THE INVERSE OF PERM. */ 00051 /* NOFSUB - AN UPPER BOUND ON THE NUMBER OF NONZERO */ 00052 /* SUBSCRIPTS FOR THE COMPRESSED STORAGE SCHEME. */ 00053 00054 /* WORKING PARAMETERS - */ 00055 /* DHEAD - VECTOR FOR HEAD OF DEGREE LISTS. */ 00056 /* INVP - USED TEMPORARILY FOR DEGREE FORWARD LINK. */ 00057 /* PERM - USED TEMPORARILY FOR DEGREE BACKWARD LINK. */ 00058 /* QSIZE - VECTOR FOR SIZE OF SUPERNODES. */ 00059 /* LLIST - VECTOR FOR TEMPORARY LINKED LISTS. */ 00060 /* MARKER - A TEMPORARY MARKER VECTOR. */ 00061 00062 /* PROGRAM SUBROUTINES - */ 00063 /* MMDELM, MMDINT, MMDNUM, MMDUPD. */ 00064 00065 /* *************************************************************** */ 00066 00067 /* Subroutine */ int genmmd_(int *neqns, int *xadj, shortint *adjncy, 00068 shortint *invp, shortint *perm, int *delta, shortint *dhead, 00069 shortint *qsize, shortint *llist, shortint *marker, int *maxint, 00070 int *nofsub) 00071 { 00072 /* System generated locals */ 00073 int i__1; 00074 00075 /* Local variables */ 00076 static int mdeg, ehead, i, mdlmt, mdnode; 00077 extern /* Subroutine */ int mmdelm_(int *, int *, shortint *, 00078 shortint *, shortint *, shortint *, shortint *, shortint *, 00079 shortint *, int *, int *), mmdupd_(int *, int *, 00080 int *, shortint *, int *, int *, shortint *, shortint 00081 *, shortint *, shortint *, shortint *, shortint *, int *, 00082 int *), mmdint_(int *, int *, shortint *, shortint *, 00083 shortint *, shortint *, shortint *, shortint *, shortint *), 00084 mmdnum_(int *, shortint *, shortint *, shortint *); 00085 static int nextmd, tag, num; 00086 00087 00088 /* *************************************************************** */ 00089 00090 00091 /* *************************************************************** */ 00092 00093 /* Parameter adjustments */ 00094 --marker; 00095 --llist; 00096 --qsize; 00097 --dhead; 00098 --perm; 00099 --invp; 00100 --adjncy; 00101 --xadj; 00102 00103 /* Function Body */ 00104 if (*neqns <= 0) { 00105 return 0; 00106 } 00107 00108 /* ------------------------------------------------ */ 00109 /* INITIALIZATION FOR THE MINIMUM DEGREE ALGORITHM. */ 00110 /* ------------------------------------------------ */ 00111 *nofsub = 0; 00112 mmdint_(neqns, &xadj[1], &adjncy[1], &dhead[1], &invp[1], &perm[1], & 00113 qsize[1], &llist[1], &marker[1]); 00114 00115 /* ---------------------------------------------- */ 00116 /* NUM COUNTS THE NUMBER OF ORDERED NODES PLUS 1. */ 00117 /* ---------------------------------------------- */ 00118 num = 1; 00119 00120 /* ----------------------------- */ 00121 /* ELIMINATE ALL ISOLATED NODES. */ 00122 /* ----------------------------- */ 00123 nextmd = dhead[1]; 00124 L100: 00125 if (nextmd <= 0) { 00126 goto L200; 00127 } 00128 mdnode = nextmd; 00129 nextmd = invp[mdnode]; 00130 marker[mdnode] = *maxint; 00131 invp[mdnode] = -num; 00132 ++num; 00133 goto L100; 00134 00135 L200: 00136 /* ---------------------------------------- */ 00137 /* SEARCH FOR NODE OF THE MINIMUM DEGREE. */ 00138 /* MDEG IS THE CURRENT MINIMUM DEGREE; */ 00139 /* TAG IS USED TO FACILITATE MARKING NODES. */ 00140 /* ---------------------------------------- */ 00141 if (num > *neqns) { 00142 goto L1000; 00143 } 00144 tag = 1; 00145 dhead[1] = 0; 00146 mdeg = 2; 00147 L300: 00148 if (dhead[mdeg] > 0) { 00149 goto L400; 00150 } 00151 ++mdeg; 00152 goto L300; 00153 L400: 00154 /* ------------------------------------------------- */ 00155 /* USE VALUE OF DELTA TO SET UP MDLMT, WHICH GOVERNS */ 00156 /* WHEN A DEGREE UPDATE IS TO BE PERFORMED. */ 00157 /* ------------------------------------------------- */ 00158 mdlmt = mdeg + *delta; 00159 ehead = 0; 00160 00161 L500: 00162 mdnode = dhead[mdeg]; 00163 if (mdnode > 0) { 00164 goto L600; 00165 } 00166 ++mdeg; 00167 if (mdeg > mdlmt) { 00168 goto L900; 00169 } 00170 goto L500; 00171 L600: 00172 /* ---------------------------------------- */ 00173 /* REMOVE MDNODE FROM THE DEGREE STRUCTURE. */ 00174 /* ---------------------------------------- */ 00175 nextmd = invp[mdnode]; 00176 dhead[mdeg] = nextmd; 00177 if (nextmd > 0) { 00178 perm[nextmd] = -mdeg; 00179 } 00180 invp[mdnode] = -num; 00181 *nofsub = *nofsub + mdeg + qsize[mdnode] - 2; 00182 if (num + qsize[mdnode] > *neqns) { 00183 goto L1000; 00184 } 00185 /* ---------------------------------------------- */ 00186 /* ELIMINATE MDNODE AND PERFORM QUOTIENT GRAPH */ 00187 /* TRANSFORMATION. RESET TAG VALUE IF NECESSARY. */ 00188 /* ---------------------------------------------- */ 00189 ++tag; 00190 if (tag < *maxint) { 00191 goto L800; 00192 } 00193 tag = 1; 00194 i__1 = *neqns; 00195 for (i = 1; i <= i__1; ++i) { 00196 if (marker[i] < *maxint) { 00197 marker[i] = 0; 00198 } 00199 /* L700: */ 00200 } 00201 L800: 00202 mmdelm_(&mdnode, &xadj[1], &adjncy[1], &dhead[1], &invp[1], &perm[1], & 00203 qsize[1], &llist[1], &marker[1], maxint, &tag); 00204 num += qsize[mdnode]; 00205 llist[mdnode] = ehead; 00206 ehead = mdnode; 00207 if (*delta >= 0) { 00208 goto L500; 00209 } 00210 L900: 00211 /* ------------------------------------------- */ 00212 /* UPDATE DEGREES OF THE NODES INVOLVED IN THE */ 00213 /* MINIMUM DEGREE NODES ELIMINATION. */ 00214 /* ------------------------------------------- */ 00215 if (num > *neqns) { 00216 goto L1000; 00217 } 00218 mmdupd_(&ehead, neqns, &xadj[1], &adjncy[1], delta, &mdeg, &dhead[1], & 00219 invp[1], &perm[1], &qsize[1], &llist[1], &marker[1], maxint, &tag) 00220 ; 00221 goto L300; 00222 00223 L1000: 00224 mmdnum_(neqns, &perm[1], &invp[1], &qsize[1]); 00225 return 0; 00226 00227 } /* genmmd_ */ 00228 00229 /* *************************************************************** */ 00230 /* *************************************************************** */ 00231 /* *** MMDINT ..... MULT MINIMUM DEGREE INITIALIZATION *** */ 00232 /* *************************************************************** */ 00233 /* *************************************************************** */ 00234 00235 /* AUTHOR - JOSEPH W.H. LIU */ 00236 /* DEPT OF COMPUTER SCIENCE, YORK UNIVERSITY. */ 00237 00238 /* PURPOSE - THIS ROUTINE PERFORMS INITIALIZATION FOR THE */ 00239 /* MULTIPLE ELIMINATION VERSION OF THE MINIMUM DEGREE */ 00240 /* ALGORITHM. */ 00241 00242 /* INPUT PARAMETERS - */ 00243 /* NEQNS - NUMBER OF EQUATIONS. */ 00244 /* (XADJ,ADJNCY) - ADJACENCY STRUCTURE. */ 00245 00246 /* OUTPUT PARAMETERS - */ 00247 /* (DHEAD,DFORW,DBAKW) - DEGREE DOUBLY LINKED STRUCTURE. */ 00248 /* QSIZE - SIZE OF SUPERNODE (INITIALIZED TO ONE). */ 00249 /* LLIST - LINKED LIST. */ 00250 /* MARKER - MARKER VECTOR. */ 00251 00252 /* *************************************************************** */ 00253 00254 /* Subroutine */ int mmdint_(int *neqns, int *xadj, shortint *adjncy, 00255 shortint *dhead, shortint *dforw, shortint *dbakw, shortint *qsize, 00256 shortint *llist, shortint *marker) 00257 { 00258 /* System generated locals */ 00259 int i__1; 00260 00261 /* Local variables */ 00262 static int ndeg, node, fnode; 00263 00264 00265 /* *************************************************************** */ 00266 00267 00268 /* *************************************************************** */ 00269 00270 /* Parameter adjustments */ 00271 --marker; 00272 --llist; 00273 --qsize; 00274 --dbakw; 00275 --dforw; 00276 --dhead; 00277 --adjncy; 00278 --xadj; 00279 00280 /* Function Body */ 00281 i__1 = *neqns; 00282 for (node = 1; node <= i__1; ++node) { 00283 dhead[node] = 0; 00284 qsize[node] = 1; 00285 marker[node] = 0; 00286 llist[node] = 0; 00287 /* L100: */ 00288 } 00289 /* ------------------------------------------ */ 00290 /* INITIALIZE THE DEGREE DOUBLY LINKED LISTS. */ 00291 /* ------------------------------------------ */ 00292 i__1 = *neqns; 00293 for (node = 1; node <= i__1; ++node) { 00294 ndeg = xadj[node + 1] - xadj[node] + 1; 00295 fnode = dhead[ndeg]; 00296 dforw[node] = fnode; 00297 dhead[ndeg] = node; 00298 if (fnode > 0) { 00299 dbakw[fnode] = node; 00300 } 00301 dbakw[node] = -ndeg; 00302 /* L200: */ 00303 } 00304 return 0; 00305 00306 } /* mmdint_ */ 00307 00308 /* *************************************************************** */ 00309 /* *************************************************************** */ 00310 /* ** MMDELM ..... MULTIPLE MINIMUM DEGREE ELIMINATION *** */ 00311 /* *************************************************************** */ 00312 /* *************************************************************** */ 00313 00314 /* AUTHOR - JOSEPH W.H. LIU */ 00315 /* DEPT OF COMPUTER SCIENCE, YORK UNIVERSITY. */ 00316 00317 /* PURPOSE - THIS ROUTINE ELIMINATES THE NODE MDNODE OF */ 00318 /* MINIMUM DEGREE FROM THE ADJACENCY STRUCTURE, WHICH */ 00319 /* IS STORED IN THE QUOTIENT GRAPH FORMAT. IT ALSO */ 00320 /* TRANSFORMS THE QUOTIENT GRAPH REPRESENTATION OF THE */ 00321 /* ELIMINATION GRAPH. */ 00322 00323 /* INPUT PARAMETERS - */ 00324 /* MDNODE - NODE OF MINIMUM DEGREE. */ 00325 /* MAXINT - ESTIMATE OF MAXIMUM REPRESENTABLE (SHORT) */ 00326 /* INT. */ 00327 /* TAG - TAG VALUE. */ 00328 00329 /* UPDATED PARAMETERS - */ 00330 /* (XADJ,ADJNCY) - UPDATED ADJACENCY STRUCTURE. */ 00331 /* (DHEAD,DFORW,DBAKW) - DEGREE DOUBLY LINKED STRUCTURE. */ 00332 /* QSIZE - SIZE OF SUPERNODE. */ 00333 /* MARKER - MARKER VECTOR. */ 00334 /* LLIST - TEMPORARY LINKED LIST OF ELIMINATED NABORS. */ 00335 00336 /* *************************************************************** */ 00337 00338 /* Subroutine */ int mmdelm_(int *mdnode, int *xadj, shortint *adjncy, 00339 shortint *dhead, shortint *dforw, shortint *dbakw, shortint *qsize, 00340 shortint *llist, shortint *marker, int *maxint, int *tag) 00341 { 00342 /* System generated locals */ 00343 int i__1, i__2; 00344 00345 /* Local variables */ 00346 static int node, link, rloc, rlmt, i, j, nabor, rnode, elmnt, xqnbr, 00347 istop, jstop, istrt, jstrt, nxnode, pvnode, nqnbrs, npv; 00348 00349 00350 /* *************************************************************** */ 00351 00352 00353 /* *************************************************************** */ 00354 00355 /* ----------------------------------------------- */ 00356 /* FIND REACHABLE SET AND PLACE IN DATA STRUCTURE. */ 00357 /* ----------------------------------------------- */ 00358 /* Parameter adjustments */ 00359 --marker; 00360 --llist; 00361 --qsize; 00362 --dbakw; 00363 --dforw; 00364 --dhead; 00365 --adjncy; 00366 --xadj; 00367 00368 /* Function Body */ 00369 marker[*mdnode] = *tag; 00370 istrt = xadj[*mdnode]; 00371 istop = xadj[*mdnode + 1] - 1; 00372 /* ------------------------------------------------------- */ 00373 /* ELMNT POINTS TO THE BEGINNING OF THE LIST OF ELIMINATED */ 00374 /* NABORS OF MDNODE, AND RLOC GIVES THE STORAGE LOCATION */ 00375 /* FOR THE NEXT REACHABLE NODE. */ 00376 /* ------------------------------------------------------- */ 00377 elmnt = 0; 00378 rloc = istrt; 00379 rlmt = istop; 00380 i__1 = istop; 00381 for (i = istrt; i <= i__1; ++i) { 00382 nabor = adjncy[i]; 00383 if (nabor == 0) { 00384 goto L300; 00385 } 00386 if (marker[nabor] >= *tag) { 00387 goto L200; 00388 } 00389 marker[nabor] = *tag; 00390 if (dforw[nabor] < 0) { 00391 goto L100; 00392 } 00393 adjncy[rloc] = nabor; 00394 ++rloc; 00395 goto L200; 00396 L100: 00397 llist[nabor] = elmnt; 00398 elmnt = nabor; 00399 L200: 00400 ; 00401 } 00402 L300: 00403 /* ----------------------------------------------------- */ 00404 /* MERGE WITH REACHABLE NODES FROM GENERALIZED ELEMENTS. */ 00405 /* ----------------------------------------------------- */ 00406 if (elmnt <= 0) { 00407 goto L1000; 00408 } 00409 adjncy[rlmt] = -elmnt; 00410 link = elmnt; 00411 L400: 00412 jstrt = xadj[link]; 00413 jstop = xadj[link + 1] - 1; 00414 i__1 = jstop; 00415 for (j = jstrt; j <= i__1; ++j) { 00416 node = adjncy[j]; 00417 link = -node; 00418 if (node < 0) { 00419 goto L400; 00420 } else if (node == 0) { 00421 goto L900; 00422 } else { 00423 goto L500; 00424 } 00425 L500: 00426 if (marker[node] >= *tag || dforw[node] < 0) { 00427 goto L800; 00428 } 00429 marker[node] = *tag; 00430 /* --------------------------------- */ 00431 /* USE STORAGE FROM ELIMINATED NODES */ 00432 /* IF NECESSARY. */ 00433 /* --------------------------------- */ 00434 L600: 00435 if (rloc < rlmt) { 00436 goto L700; 00437 } 00438 link = -adjncy[rlmt]; 00439 rloc = xadj[link]; 00440 rlmt = xadj[link + 1] - 1; 00441 goto L600; 00442 L700: 00443 adjncy[rloc] = node; 00444 ++rloc; 00445 L800: 00446 ; 00447 } 00448 L900: 00449 elmnt = llist[elmnt]; 00450 goto L300; 00451 L1000: 00452 if (rloc <= rlmt) { 00453 adjncy[rloc] = 0; 00454 } 00455 /* -------------------------------------------------------- */ 00456 /* FOR EACH NODE IN THE REACHABLE SET, DO THE FOLLOWING ... */ 00457 /* -------------------------------------------------------- */ 00458 link = *mdnode; 00459 L1100: 00460 istrt = xadj[link]; 00461 istop = xadj[link + 1] - 1; 00462 i__1 = istop; 00463 for (i = istrt; i <= i__1; ++i) { 00464 rnode = adjncy[i]; 00465 link = -rnode; 00466 if (rnode < 0) { 00467 goto L1100; 00468 } else if (rnode == 0) { 00469 goto L1800; 00470 } else { 00471 goto L1200; 00472 } 00473 L1200: 00474 /* -------------------------------------------- */ 00475 /* IF RNODE IS IN THE DEGREE LIST STRUCTURE ... */ 00476 /* -------------------------------------------- */ 00477 pvnode = dbakw[rnode]; 00478 if (pvnode == 0 || pvnode == -(*maxint)) { 00479 goto L1300; 00480 } 00481 /* ------------------------------------- */ 00482 /* THEN REMOVE RNODE FROM THE STRUCTURE. */ 00483 /* ------------------------------------- */ 00484 nxnode = dforw[rnode]; 00485 if (nxnode > 0) { 00486 dbakw[nxnode] = pvnode; 00487 } 00488 if (pvnode > 0) { 00489 dforw[pvnode] = nxnode; 00490 } 00491 npv = -pvnode; 00492 if (pvnode < 0) { 00493 dhead[npv] = nxnode; 00494 } 00495 L1300: 00496 /* ---------------------------------------- */ 00497 /* PURGE INACTIVE QUOTIENT NABORS OF RNODE. */ 00498 /* ---------------------------------------- */ 00499 jstrt = xadj[rnode]; 00500 jstop = xadj[rnode + 1] - 1; 00501 xqnbr = jstrt; 00502 i__2 = jstop; 00503 for (j = jstrt; j <= i__2; ++j) { 00504 nabor = adjncy[j]; 00505 if (nabor == 0) { 00506 goto L1500; 00507 } 00508 if (marker[nabor] >= *tag) { 00509 goto L1400; 00510 } 00511 adjncy[xqnbr] = nabor; 00512 ++xqnbr; 00513 L1400: 00514 ; 00515 } 00516 L1500: 00517 /* ---------------------------------------- */ 00518 /* IF NO ACTIVE NABOR AFTER THE PURGING ... */ 00519 /* ---------------------------------------- */ 00520 nqnbrs = xqnbr - jstrt; 00521 if (nqnbrs > 0) { 00522 goto L1600; 00523 } 00524 /* ----------------------------- */ 00525 /* THEN MERGE RNODE WITH MDNODE. */ 00526 /* ----------------------------- */ 00527 qsize[*mdnode] += qsize[rnode]; 00528 qsize[rnode] = 0; 00529 marker[rnode] = *maxint; 00530 dforw[rnode] = -(*mdnode); 00531 dbakw[rnode] = -(*maxint); 00532 goto L1700; 00533 L1600: 00534 /* -------------------------------------- */ 00535 /* ELSE FLAG RNODE FOR DEGREE UPDATE, AND */ 00536 /* ADD MDNODE AS A NABOR OF RNODE. */ 00537 /* -------------------------------------- */ 00538 dforw[rnode] = nqnbrs + 1; 00539 dbakw[rnode] = 0; 00540 adjncy[xqnbr] = *mdnode; 00541 ++xqnbr; 00542 if (xqnbr <= jstop) { 00543 adjncy[xqnbr] = 0; 00544 } 00545 00546 L1700: 00547 ; 00548 } 00549 L1800: 00550 return 0; 00551 00552 } /* mmdelm_ */ 00553 00554 /* *************************************************************** */ 00555 /* *************************************************************** */ 00556 /* ***** MMDUPD ..... MULTIPLE MINIMUM DEGREE UPDATE ***** */ 00557 /* *************************************************************** */ 00558 /* *************************************************************** */ 00559 00560 /* AUTHOR - JOSEPH W.H. LIU */ 00561 /* DEPT OF COMPUTER SCIENCE, YORK UNIVERSITY. */ 00562 00563 /* PURPOSE - THIS ROUTINE UPDATES THE DEGREES OF NODES */ 00564 /* AFTER A MULTIPLE ELIMINATION STEP. */ 00565 00566 /* INPUT PARAMETERS - */ 00567 /* EHEAD - THE BEGINNING OF THE LIST OF ELIMINATED */ 00568 /* NODES (I.E., NEWLY FORMED ELEMENTS). */ 00569 /* NEQNS - NUMBER OF EQUATIONS. */ 00570 /* (XADJ,ADJNCY) - ADJACENCY STRUCTURE. */ 00571 /* DELTA - TOLERANCE VALUE FOR MULTIPLE ELIMINATION. */ 00572 /* MAXINT - MAXIMUM MACHINE REPRESENTABLE (SHORT) */ 00573 /* INTEGER. */ 00574 00575 /* UPDATED PARAMETERS - */ 00576 /* MDEG - NEW MINIMUM DEGREE AFTER DEGREE UPDATE. */ 00577 /* (DHEAD,DFORW,DBAKW) - DEGREE DOUBLY LINKED STRUCTURE. */ 00578 /* QSIZE - SIZE OF SUPERNODE. */ 00579 /* LLIST - WORKING LINKED LIST. */ 00580 /* MARKER - MARKER VECTOR FOR DEGREE UPDATE. */ 00581 /* TAG - TAG VALUE. */ 00582 00583 /* *************************************************************** */ 00584 00585 /* Subroutine */ int mmdupd_(int *ehead, int *neqns, int *xadj, 00586 shortint *adjncy, int *delta, int *mdeg, shortint *dhead, 00587 shortint *dforw, shortint *dbakw, shortint *qsize, shortint *llist, 00588 shortint *marker, int *maxint, int *tag) 00589 { 00590 /* System generated locals */ 00591 int i__1, i__2; 00592 00593 /* Local variables */ 00594 static int node, mtag, link, mdeg0, i, j, enode, fnode, nabor, elmnt, 00595 istop, jstop, q2head, istrt, jstrt, qxhead, iq2, deg, deg0; 00596 00597 00598 /* *************************************************************** */ 00599 00600 00601 /* *************************************************************** */ 00602 00603 /* Parameter adjustments */ 00604 --marker; 00605 --llist; 00606 --qsize; 00607 --dbakw; 00608 --dforw; 00609 --dhead; 00610 --adjncy; 00611 --xadj; 00612 00613 /* Function Body */ 00614 mdeg0 = *mdeg + *delta; 00615 elmnt = *ehead; 00616 L100: 00617 /* ------------------------------------------------------- */ 00618 /* FOR EACH OF THE NEWLY FORMED ELEMENT, DO THE FOLLOWING. */ 00619 /* (RESET TAG VALUE IF NECESSARY.) */ 00620 /* ------------------------------------------------------- */ 00621 if (elmnt <= 0) { 00622 return 0; 00623 } 00624 mtag = *tag + mdeg0; 00625 if (mtag < *maxint) { 00626 goto L300; 00627 } 00628 *tag = 1; 00629 i__1 = *neqns; 00630 for (i = 1; i <= i__1; ++i) { 00631 if (marker[i] < *maxint) { 00632 marker[i] = 0; 00633 } 00634 /* L200: */ 00635 } 00636 mtag = *tag + mdeg0; 00637 L300: 00638 /* --------------------------------------------- */ 00639 /* CREATE TWO LINKED LISTS FROM NODES ASSOCIATED */ 00640 /* WITH ELMNT: ONE WITH TWO NABORS (Q2HEAD) IN */ 00641 /* ADJACENCY STRUCTURE, AND THE OTHER WITH MORE */ 00642 /* THAN TWO NABORS (QXHEAD). ALSO COMPUTE DEG0, */ 00643 /* NUMBER OF NODES IN THIS ELEMENT. */ 00644 /* --------------------------------------------- */ 00645 q2head = 0; 00646 qxhead = 0; 00647 deg0 = 0; 00648 link = elmnt; 00649 L400: 00650 istrt = xadj[link]; 00651 istop = xadj[link + 1] - 1; 00652 i__1 = istop; 00653 for (i = istrt; i <= i__1; ++i) { 00654 enode = adjncy[i]; 00655 link = -enode; 00656 if (enode < 0) { 00657 goto L400; 00658 } else if (enode == 0) { 00659 goto L800; 00660 } else { 00661 goto L500; 00662 } 00663 00664 L500: 00665 if (qsize[enode] == 0) { 00666 goto L700; 00667 } 00668 deg0 += qsize[enode]; 00669 marker[enode] = mtag; 00670 /* ---------------------------------- */ 00671 /* IF ENODE REQUIRES A DEGREE UPDATE, */ 00672 /* THEN DO THE FOLLOWING. */ 00673 /* ---------------------------------- */ 00674 if (dbakw[enode] != 0) { 00675 goto L700; 00676 } 00677 /* --------------------------------------- 00678 */ 00679 /* PLACE EITHER IN QXHEAD OR Q2HEAD LISTS. 00680 */ 00681 /* --------------------------------------- 00682 */ 00683 if (dforw[enode] == 2) { 00684 goto L600; 00685 } 00686 llist[enode] = qxhead; 00687 qxhead = enode; 00688 goto L700; 00689 L600: 00690 llist[enode] = q2head; 00691 q2head = enode; 00692 L700: 00693 ; 00694 } 00695 L800: 00696 /* -------------------------------------------- */ 00697 /* FOR EACH ENODE IN Q2 LIST, DO THE FOLLOWING. */ 00698 /* -------------------------------------------- */ 00699 enode = q2head; 00700 iq2 = 1; 00701 L900: 00702 if (enode <= 0) { 00703 goto L1500; 00704 } 00705 if (dbakw[enode] != 0) { 00706 goto L2200; 00707 } 00708 ++(*tag); 00709 deg = deg0; 00710 /* ------------------------------------------ */ 00711 /* IDENTIFY THE OTHER ADJACENT ELEMENT NABOR. */ 00712 /* ------------------------------------------ */ 00713 istrt = xadj[enode]; 00714 nabor = adjncy[istrt]; 00715 if (nabor == elmnt) { 00716 nabor = adjncy[istrt + 1]; 00717 } 00718 /* ------------------------------------------------ */ 00719 /* IF NABOR IS UNELIMINATED, INCREASE DEGREE COUNT. */ 00720 /* ------------------------------------------------ */ 00721 link = nabor; 00722 if (dforw[nabor] < 0) { 00723 goto L1000; 00724 } 00725 deg += qsize[nabor]; 00726 goto L2100; 00727 L1000: 00728 /* -------------------------------------------- */ 00729 /* OTHERWISE, FOR EACH NODE IN THE 2ND ELEMENT, */ 00730 /* DO THE FOLLOWING. */ 00731 /* -------------------------------------------- */ 00732 istrt = xadj[link]; 00733 istop = xadj[link + 1] - 1; 00734 i__1 = istop; 00735 for (i = istrt; i <= i__1; ++i) { 00736 node = adjncy[i]; 00737 link = -node; 00738 if (node == enode) { 00739 goto L1400; 00740 } 00741 if (node < 0) { 00742 goto L1000; 00743 } else if (node == 0) { 00744 goto L2100; 00745 } else { 00746 goto L1100; 00747 } 00748 00749 L1100: 00750 if (qsize[node] == 0) { 00751 goto L1400; 00752 } 00753 if (marker[node] >= *tag) { 00754 goto L1200; 00755 } 00756 /* ----------------------------------- 00757 -- */ 00758 /* CASE WHEN NODE IS NOT YET CONSIDERED 00759 . */ 00760 /* ----------------------------------- 00761 -- */ 00762 marker[node] = *tag; 00763 deg += qsize[node]; 00764 goto L1400; 00765 L1200: 00766 /* ---------------------------------------- 00767 */ 00768 /* CASE WHEN NODE IS INDISTINGUISHABLE FROM 00769 */ 00770 /* ENODE. MERGE THEM INTO A NEW SUPERNODE. 00771 */ 00772 /* ---------------------------------------- 00773 */ 00774 if (dbakw[node] != 0) { 00775 goto L1400; 00776 } 00777 if (dforw[node] != 2) { 00778 goto L1300; 00779 } 00780 qsize[enode] += qsize[node]; 00781 qsize[node] = 0; 00782 marker[node] = *maxint; 00783 dforw[node] = -enode; 00784 dbakw[node] = -(*maxint); 00785 goto L1400; 00786 L1300: 00787 /* -------------------------------------- 00788 */ 00789 /* CASE WHEN NODE IS OUTMATCHED BY ENODE. 00790 */ 00791 /* -------------------------------------- 00792 */ 00793 if (dbakw[node] == 0) { 00794 dbakw[node] = -(*maxint); 00795 } 00796 L1400: 00797 ; 00798 } 00799 goto L2100; 00800 L1500: 00801 /* ------------------------------------------------ */ 00802 /* FOR EACH ENODE IN THE QX LIST, DO THE FOLLOWING. */ 00803 /* ------------------------------------------------ */ 00804 enode = qxhead; 00805 iq2 = 0; 00806 L1600: 00807 if (enode <= 0) { 00808 goto L2300; 00809 } 00810 if (dbakw[enode] != 0) { 00811 goto L2200; 00812 } 00813 ++(*tag); 00814 deg = deg0; 00815 /* --------------------------------- */ 00816 /* FOR EACH UNMARKED NABOR OF ENODE, */ 00817 /* DO THE FOLLOWING. */ 00818 /* --------------------------------- */ 00819 istrt = xadj[enode]; 00820 istop = xadj[enode + 1] - 1; 00821 i__1 = istop; 00822 for (i = istrt; i <= i__1; ++i) { 00823 nabor = adjncy[i]; 00824 if (nabor == 0) { 00825 goto L2100; 00826 } 00827 if (marker[nabor] >= *tag) { 00828 goto L2000; 00829 } 00830 marker[nabor] = *tag; 00831 link = nabor; 00832 /* ------------------------------ */ 00833 /* IF UNELIMINATED, INCLUDE IT IN */ 00834 /* DEG COUNT. */ 00835 /* ------------------------------ */ 00836 if (dforw[nabor] < 0) { 00837 goto L1700; 00838 } 00839 deg += qsize[nabor]; 00840 goto L2000; 00841 L1700: 00842 /* ------------------------------- 00843 */ 00844 /* IF ELIMINATED, INCLUDE UNMARKED 00845 */ 00846 /* NODES IN THIS ELEMENT INTO THE 00847 */ 00848 /* DEGREE COUNT. */ 00849 /* ------------------------------- 00850 */ 00851 jstrt = xadj[link]; 00852 jstop = xadj[link + 1] - 1; 00853 i__2 = jstop; 00854 for (j = jstrt; j <= i__2; ++j) { 00855 node = adjncy[j]; 00856 link = -node; 00857 if (node < 0) { 00858 goto L1700; 00859 } else if (node == 0) { 00860 goto L2000; 00861 } else { 00862 goto L1800; 00863 } 00864 00865 L1800: 00866 if (marker[node] >= *tag) { 00867 goto L1900; 00868 } 00869 marker[node] = *tag; 00870 deg += qsize[node]; 00871 L1900: 00872 ; 00873 } 00874 L2000: 00875 ; 00876 } 00877 L2100: 00878 /* ------------------------------------------- */ 00879 /* UPDATE EXTERNAL DEGREE OF ENODE IN DEGREE */ 00880 /* STRUCTURE, AND MDEG (MIN DEG) IF NECESSARY. */ 00881 /* ------------------------------------------- */ 00882 deg = deg - qsize[enode] + 1; 00883 fnode = dhead[deg]; 00884 dforw[enode] = fnode; 00885 dbakw[enode] = -deg; 00886 if (fnode > 0) { 00887 dbakw[fnode] = enode; 00888 } 00889 dhead[deg] = enode; 00890 if (deg < *mdeg) { 00891 *mdeg = deg; 00892 } 00893 L2200: 00894 /* ---------------------------------- */ 00895 /* GET NEXT ENODE IN CURRENT ELEMENT. */ 00896 /* ---------------------------------- */ 00897 enode = llist[enode]; 00898 if (iq2 == 1) { 00899 goto L900; 00900 } 00901 goto L1600; 00902 L2300: 00903 /* ----------------------------- */ 00904 /* GET NEXT ELEMENT IN THE LIST. */ 00905 /* ----------------------------- */ 00906 *tag = mtag; 00907 elmnt = llist[elmnt]; 00908 goto L100; 00909 00910 } /* mmdupd_ */ 00911 00912 /* *************************************************************** */ 00913 /* *************************************************************** */ 00914 /* ***** MMDNUM ..... MULTI MINIMUM DEGREE NUMBERING ***** */ 00915 /* *************************************************************** */ 00916 /* *************************************************************** */ 00917 00918 /* AUTHOR - JOSEPH W.H. LIU */ 00919 /* DEPT OF COMPUTER SCIENCE, YORK UNIVERSITY. */ 00920 00921 /* PURPOSE - THIS ROUTINE PERFORMS THE FINAL STEP IN */ 00922 /* PRODUCING THE PERMUTATION AND INVERSE PERMUTATION */ 00923 /* VECTORS IN THE MULTIPLE ELIMINATION VERSION OF THE */ 00924 /* MINIMUM DEGREE ORDERING ALGORITHM. */ 00925 00926 /* INPUT PARAMETERS - */ 00927 /* NEQNS - NUMBER OF EQUATIONS. */ 00928 /* QSIZE - SIZE OF SUPERNODES AT ELIMINATION. */ 00929 00930 /* UPDATED PARAMETERS - */ 00931 /* INVP - INVERSE PERMUTATION VECTOR. ON INPUT, */ 00932 /* IF QSIZE(NODE)=0, THEN NODE HAS BEEN MERGED */ 00933 /* INTO THE NODE -INVP(NODE); OTHERWISE, */ 00934 /* -INVP(NODE) IS ITS INVERSE LABELLING. */ 00935 00936 /* OUTPUT PARAMETERS - */ 00937 /* PERM - THE PERMUTATION VECTOR. */ 00938 00939 /* *************************************************************** */ 00940 00941 /* Subroutine */ int mmdnum_(int *neqns, shortint *perm, shortint *invp, 00942 shortint *qsize) 00943 { 00944 /* System generated locals */ 00945 int i__1; 00946 00947 /* Local variables */ 00948 static int node, root, nextf, father, nqsize, num; 00949 00950 00951 /* *************************************************************** */ 00952 00953 00954 /* *************************************************************** */ 00955 00956 /* Parameter adjustments */ 00957 --qsize; 00958 --invp; 00959 --perm; 00960 00961 /* Function Body */ 00962 i__1 = *neqns; 00963 for (node = 1; node <= i__1; ++node) { 00964 nqsize = qsize[node]; 00965 if (nqsize <= 0) { 00966 perm[node] = invp[node]; 00967 } 00968 if (nqsize > 0) { 00969 perm[node] = -invp[node]; 00970 } 00971 /* L100: */ 00972 } 00973 /* ------------------------------------------------------ */ 00974 /* FOR EACH NODE WHICH HAS BEEN MERGED, DO THE FOLLOWING. */ 00975 /* ------------------------------------------------------ */ 00976 i__1 = *neqns; 00977 for (node = 1; node <= i__1; ++node) { 00978 if (perm[node] > 0) { 00979 goto L500; 00980 } 00981 /* ----------------------------------------- */ 00982 /* TRACE THE MERGED TREE UNTIL ONE WHICH HAS */ 00983 /* NOT BEEN MERGED, CALL IT ROOT. */ 00984 /* ----------------------------------------- */ 00985 father = node; 00986 L200: 00987 if (perm[father] > 0) { 00988 goto L300; 00989 } 00990 father = -perm[father]; 00991 goto L200; 00992 L300: 00993 /* ----------------------- */ 00994 /* NUMBER NODE AFTER ROOT. */ 00995 /* ----------------------- */ 00996 root = father; 00997 num = perm[root] + 1; 00998 invp[node] = -num; 00999 perm[root] = num; 01000 /* ------------------------ */ 01001 /* SHORTEN THE MERGED TREE. */ 01002 /* ------------------------ */ 01003 father = node; 01004 L400: 01005 nextf = -perm[father]; 01006 if (nextf <= 0) { 01007 goto L500; 01008 } 01009 perm[father] = -root; 01010 father = nextf; 01011 goto L400; 01012 L500: 01013 ; 01014 } 01015 /* ---------------------- */ 01016 /* READY TO COMPUTE PERM. */ 01017 /* ---------------------- */ 01018 i__1 = *neqns; 01019 for (node = 1; node <= i__1; ++node) { 01020 num = -invp[node]; 01021 invp[node] = num; 01022 perm[num] = node; 01023 /* L600: */ 01024 } 01025 return 0; 01026 01027 } /* mmdnum_ */ 01028