LCOV - code coverage report
Current view: top level - /builds/ug4-project/ugcore/ug4-new/plugins/SuperLU6/external/superlu/SRC - mmd.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 380 0
Test Date: 2026-06-01 23:54:59 Functions: 0.0 % 5 0

            Line data    Source code
       1              : /*
       2              : Copyright (c) 2003, The Regents of the University of California, through
       3              : Lawrence Berkeley National Laboratory (subject to receipt of any required 
       4              : approvals from U.S. Dept. of Energy) 
       5              : 
       6              : All rights reserved. 
       7              : 
       8              : The source code is distributed under BSD license, see the file License.txt
       9              : at the top-level directory.
      10              : */
      11              : /*! \file
      12              :  * \brief Minimum degree algorithm
      13              :  *
      14              :  * \ingroup Common
      15              :  */
      16              : #include "superlu_config.h"
      17              : 
      18              : typedef int_t shortint;
      19              : 
      20              : /* *************************************************************** */
      21              : /* *************************************************************** */
      22              : /* ****     GENMMD ..... MULTIPLE MINIMUM EXTERNAL DEGREE     **** */
      23              : /* *************************************************************** */
      24              : /* *************************************************************** */
      25              : 
      26              : /*     AUTHOR - JOSEPH W.H. LIU */
      27              : /*              DEPT OF COMPUTER SCIENCE, YORK UNIVERSITY. */
      28              : 
      29              : /*     PURPOSE - THIS ROUTINE IMPLEMENTS THE MINIMUM DEGREE */
      30              : /*        ALGORITHM.  IT MAKES USE OF THE IMPLICIT REPRESENTATION */
      31              : /*        OF ELIMINATION GRAPHS BY QUOTIENT GRAPHS, AND THE */
      32              : /*        NOTION OF INDISTINGUISHABLE NODES.  IT ALSO IMPLEMENTS */
      33              : /*        THE MODIFICATIONS BY MULTIPLE ELIMINATION AND MINIMUM */
      34              : /*        EXTERNAL DEGREE. */
      35              : /*        --------------------------------------------- */
      36              : /*        CAUTION - THE ADJACENCY VECTOR ADJNCY WILL BE */
      37              : /*        DESTROYED. */
      38              : /*        --------------------------------------------- */
      39              : 
      40              : /*     INPUT PARAMETERS - */
      41              : /*        NEQNS  - NUMBER OF EQUATIONS. */
      42              : /*        (XADJ,ADJNCY) - THE ADJACENCY STRUCTURE. */
      43              : /*        DELTA  - TOLERANCE VALUE FOR MULTIPLE ELIMINATION. */
      44              : /*        MAXINT - MAXIMUM MACHINE REPRESENTABLE (SHORT) INTEGER */
      45              : /*                 (ANY SMALLER ESTIMATE WILL DO) FOR MARKING */
      46              : /*                 NODES. */
      47              : 
      48              : /*     OUTPUT PARAMETERS - */
      49              : /*        PERM   - THE MINIMUM DEGREE ORDERING. */
      50              : /*        INVP   - THE INVERSE OF PERM. */
      51              : /*        NOFSUB - AN UPPER BOUND ON THE NUMBER OF NONZERO */
      52              : /*                 SUBSCRIPTS FOR THE COMPRESSED STORAGE SCHEME. */
      53              : 
      54              : /*     WORKING PARAMETERS - */
      55              : /*        DHEAD  - VECTOR FOR HEAD OF DEGREE LISTS. */
      56              : /*        INVP   - USED TEMPORARILY FOR DEGREE FORWARD LINK. */
      57              : /*        PERM   - USED TEMPORARILY FOR DEGREE BACKWARD LINK. */
      58              : /*        QSIZE  - VECTOR FOR SIZE OF SUPERNODES. */
      59              : /*        LLIST  - VECTOR FOR TEMPORARY LINKED LISTS. */
      60              : /*        MARKER - A TEMPORARY MARKER VECTOR. */
      61              : 
      62              : /*     PROGRAM SUBROUTINES - */
      63              : /*        MMDELM, MMDINT, MMDNUM, MMDUPD. */
      64              : 
      65              : /* *************************************************************** */
      66              : 
      67            0 : /* Subroutine */ int genmmd_(int *neqns, int_t *xadj, shortint *adjncy, 
      68              :         int *invp, int *perm, int_t *delta, shortint *dhead, 
      69              :         shortint *qsize, shortint *llist, shortint *marker, int_t *maxint, 
      70              :         int_t *nofsub)
      71              : {
      72              :     /* System generated locals */
      73              :     int i__1;
      74              : 
      75              :     /* Local variables */
      76              :     int_t mdeg, ehead, i, mdlmt, mdnode;
      77              :     extern /* Subroutine */
      78              :     int slu_mmdelm_(const int_t *mdnode, int_t *xadj, shortint *adjncy,
      79              :                     shortint *dhead, int *dforw, int *dbakw, shortint *qsize,
      80              :                     shortint *llist, shortint *marker, const int_t *maxint, const int_t *tag),
      81              :     slu_mmdupd_(const int_t *ehead, const int *neqns, int_t *xadj,
      82              :                 shortint *adjncy, const int_t *delta, int_t *mdeg, shortint *dhead,
      83              :                 int *dforw, int *dbakw, shortint *qsize, shortint *llist,
      84              :                 shortint *marker, const int_t *maxint, int_t *tag),
      85              :     slu_mmdint_(const int *neqns, int_t *xadj, shortint *adjncy,
      86              :                 shortint *dhead, int *dforw, int *dbakw, shortint *qsize,
      87              :                 shortint *llist, shortint *marker),
      88              :     slu_mmdnum_(const int *neqns, int *perm, int *invp, shortint *qsize);
      89              : 
      90              :     int_t nextmd, tag, num;
      91              : 
      92              : /* *************************************************************** */
      93              : 
      94              : 
      95              : /* *************************************************************** */
      96              : 
      97              :     /* Parameter adjustments */
      98            0 :     --marker;
      99              :     --llist;
     100            0 :     --qsize;
     101            0 :     --dhead;
     102              :     --perm;
     103            0 :     --invp;
     104              :     --adjncy;
     105              :     --xadj;
     106              : 
     107              :     /* Function Body */
     108            0 :     if (*neqns <= 0) {
     109              :         return 0;
     110              :     }
     111              : 
     112              : /*        ------------------------------------------------ */
     113              : /*        INITIALIZATION FOR THE MINIMUM DEGREE ALGORITHM. */
     114              : /*        ------------------------------------------------ */
     115            0 :     *nofsub = 0;
     116            0 :     slu_mmdint_(neqns, &xadj[1], &adjncy[1], &dhead[1], &invp[1], &perm[1], &
     117              :             qsize[1], &llist[1], &marker[1]);
     118              : 
     119              : /*        ---------------------------------------------- */
     120              : /*        NUM COUNTS THE NUMBER OF ORDERED NODES PLUS 1. */
     121              : /*        ---------------------------------------------- */
     122              :     num = 1;
     123              : 
     124              : /*        ----------------------------- */
     125              : /*        ELIMINATE ALL ISOLATED NODES. */
     126              : /*        ----------------------------- */
     127            0 :     nextmd = dhead[1];
     128            0 : L100:
     129            0 :     if (nextmd <= 0) {
     130            0 :         goto L200;
     131              :     }
     132            0 :     mdnode = nextmd;
     133            0 :     nextmd = invp[mdnode];
     134            0 :     marker[mdnode] = *maxint;
     135            0 :     invp[mdnode] = -num;
     136            0 :     ++num;
     137            0 :     goto L100;
     138              : 
     139              : L200:
     140              : /*        ---------------------------------------- */
     141              : /*        SEARCH FOR NODE OF THE MINIMUM DEGREE. */
     142              : /*        MDEG IS THE CURRENT MINIMUM DEGREE; */
     143              : /*        TAG IS USED TO FACILITATE MARKING NODES. */
     144              : /*        ---------------------------------------- */
     145            0 :     if (num > *neqns) {
     146            0 :         goto L1000;
     147              :     }
     148            0 :     tag = 1;
     149            0 :     dhead[1] = 0;
     150            0 :     mdeg = 2;
     151              : L300:
     152            0 :     if (dhead[mdeg] > 0) {
     153            0 :         goto L400;
     154              :     }
     155            0 :     ++mdeg;
     156            0 :     goto L300;
     157              : L400:
     158              : /*            ------------------------------------------------- */
     159              : /*            USE VALUE OF DELTA TO SET UP MDLMT, WHICH GOVERNS */
     160              : /*            WHEN A DEGREE UPDATE IS TO BE PERFORMED. */
     161              : /*            ------------------------------------------------- */
     162            0 :     mdlmt = mdeg + *delta;
     163            0 :     ehead = 0;
     164              : 
     165              : L500:
     166            0 :     mdnode = dhead[mdeg];
     167            0 :     if (mdnode > 0) {
     168            0 :         goto L600;
     169              :     }
     170            0 :     ++mdeg;
     171            0 :     if (mdeg > mdlmt) {
     172            0 :         goto L900;
     173              :     }
     174            0 :     goto L500;
     175              : L600:
     176              : /*                ---------------------------------------- */
     177              : /*                REMOVE MDNODE FROM THE DEGREE STRUCTURE. */
     178              : /*                ---------------------------------------- */
     179            0 :     nextmd = invp[mdnode];
     180            0 :     dhead[mdeg] = nextmd;
     181            0 :     if (nextmd > 0) {
     182            0 :         perm[nextmd] = -mdeg;
     183              :     }
     184            0 :     invp[mdnode] = -num;
     185            0 :     *nofsub = *nofsub + mdeg + qsize[mdnode] - 2;
     186            0 :     if (num + qsize[mdnode] > *neqns) {
     187            0 :         goto L1000;
     188              :     }
     189              : /*                ---------------------------------------------- */
     190              : /*                ELIMINATE MDNODE AND PERFORM QUOTIENT GRAPH */
     191              : /*                TRANSFORMATION.  RESET TAG VALUE IF NECESSARY. */
     192              : /*                ---------------------------------------------- */
     193            0 :     ++tag;
     194            0 :     if (tag < *maxint) {
     195            0 :         goto L800;
     196              :     }
     197            0 :     tag = 1;
     198              :     i__1 = *neqns;
     199            0 :     for (i = 1; i <= i__1; ++i) {
     200            0 :         if (marker[i] < *maxint) {
     201            0 :             marker[i] = 0;
     202              :         }
     203              : /* L700: */
     204              :     }
     205            0 : L800:
     206            0 :     slu_mmdelm_(&mdnode, &xadj[1], &adjncy[1], &dhead[1], &invp[1], &perm[1], &
     207              :             qsize[1], &llist[1], &marker[1], maxint, &tag);
     208            0 :     num += qsize[mdnode];
     209            0 :     llist[mdnode] = ehead;
     210            0 :     ehead = mdnode;
     211            0 :     if (*delta >= 0) {
     212            0 :         goto L500;
     213              :     }
     214            0 : L900:
     215              : /*            ------------------------------------------- */
     216              : /*            UPDATE DEGREES OF THE NODES INVOLVED IN THE */
     217              : /*            MINIMUM DEGREE NODES ELIMINATION. */
     218              : /*            ------------------------------------------- */
     219            0 :     if (num > *neqns) {
     220            0 :         goto L1000;
     221              :     }
     222            0 :     slu_mmdupd_(&ehead, neqns, &xadj[1], &adjncy[1], delta, &mdeg, &dhead[1], &
     223              :             invp[1], &perm[1], &qsize[1], &llist[1], &marker[1], maxint, &tag)
     224              :             ;
     225            0 :     goto L300;
     226              : 
     227            0 : L1000:
     228            0 :     slu_mmdnum_(neqns, &perm[1], &invp[1], &qsize[1]);
     229            0 :     return 0;
     230              : 
     231              : } /* genmmd_ */
     232              : 
     233              : /* *************************************************************** */
     234              : /* *************************************************************** */
     235              : /* ***     MMDINT ..... MULT MINIMUM DEGREE INITIALIZATION     *** */
     236              : /* *************************************************************** */
     237              : /* *************************************************************** */
     238              : 
     239              : /*     AUTHOR - JOSEPH W.H. LIU */
     240              : /*              DEPT OF COMPUTER SCIENCE, YORK UNIVERSITY. */
     241              : 
     242              : /*     PURPOSE - THIS ROUTINE PERFORMS INITIALIZATION FOR THE */
     243              : /*        MULTIPLE ELIMINATION VERSION OF THE MINIMUM DEGREE */
     244              : /*        ALGORITHM. */
     245              : 
     246              : /*     INPUT PARAMETERS - */
     247              : /*        NEQNS  - NUMBER OF EQUATIONS. */
     248              : /*        (XADJ,ADJNCY) - ADJACENCY STRUCTURE. */
     249              : 
     250              : /*     OUTPUT PARAMETERS - */
     251              : /*        (DHEAD,DFORW,DBAKW) - DEGREE DOUBLY LINKED STRUCTURE. */
     252              : /*        QSIZE  - SIZE OF SUPERNODE (INITIALIZED TO ONE). */
     253              : /*        LLIST  - LINKED LIST. */
     254              : /*        MARKER - MARKER VECTOR. */
     255              : 
     256              : /* *************************************************************** */
     257              : 
     258              : /* Subroutine */
     259            0 : int slu_mmdint_(const int *neqns, int_t *xadj, shortint *adjncy,
     260              :         shortint *dhead, int *dforw, int *dbakw, shortint *qsize, 
     261              :         shortint *llist, shortint *marker)
     262              : {
     263              :     /* System generated locals */
     264              :     int i__1;
     265              : 
     266              :     /* Local variables */
     267              :     int ndeg, node, fnode;
     268              : 
     269              : /* *************************************************************** */
     270              : 
     271              :     /* Parameter adjustments */
     272              :     --marker;
     273              :     --llist;
     274              :     --qsize;
     275            0 :     --dbakw;
     276              :     --dforw;
     277            0 :     --dhead;
     278              :     --adjncy;
     279            0 :     --xadj;
     280              : 
     281              :     /* Function Body */
     282            0 :     i__1 = *neqns;
     283            0 :     for (node = 1; node <= i__1; ++node) {
     284            0 :         dhead[node] = 0;
     285            0 :         qsize[node] = 1;
     286            0 :         marker[node] = 0;
     287            0 :         llist[node] = 0;
     288              : /* L100: */
     289              :     }
     290              : /*        ------------------------------------------ */
     291              : /*        INITIALIZE THE DEGREE DOUBLY LINKED LISTS. */
     292              : /*        ------------------------------------------ */
     293            0 :     i__1 = *neqns;
     294            0 :     for (node = 1; node <= i__1; ++node) {
     295            0 :         ndeg = xadj[node + 1] - xadj[node] + 1;
     296            0 :         fnode = dhead[ndeg];
     297            0 :         dforw[node] = fnode;
     298            0 :         dhead[ndeg] = node;
     299            0 :         if (fnode > 0) {
     300            0 :             dbakw[fnode] = node;
     301              :         }
     302            0 :         dbakw[node] = -ndeg;
     303              : /* L200: */
     304              :     }
     305            0 :     return 0;
     306              : 
     307              : } /* slu_mmdint_ */
     308              : 
     309              : /* *************************************************************** */
     310              : /* *************************************************************** */
     311              : /* **     MMDELM ..... MULTIPLE MINIMUM DEGREE ELIMINATION     *** */
     312              : /* *************************************************************** */
     313              : /* *************************************************************** */
     314              : 
     315              : /*     AUTHOR - JOSEPH W.H. LIU */
     316              : /*              DEPT OF COMPUTER SCIENCE, YORK UNIVERSITY. */
     317              : 
     318              : /*     PURPOSE - THIS ROUTINE ELIMINATES THE NODE MDNODE OF */
     319              : /*        MINIMUM DEGREE FROM THE ADJACENCY STRUCTURE, WHICH */
     320              : /*        IS STORED IN THE QUOTIENT GRAPH FORMAT.  IT ALSO */
     321              : /*        TRANSFORMS THE QUOTIENT GRAPH REPRESENTATION OF THE */
     322              : /*        ELIMINATION GRAPH. */
     323              : 
     324              : /*     INPUT PARAMETERS - */
     325              : /*        MDNODE - NODE OF MINIMUM DEGREE. */
     326              : /*        MAXINT - ESTIMATE OF MAXIMUM REPRESENTABLE (SHORT) */
     327              : /*                 INT. */
     328              : /*        TAG    - TAG VALUE. */
     329              : 
     330              : /*     UPDATED PARAMETERS - */
     331              : /*        (XADJ,ADJNCY) - UPDATED ADJACENCY STRUCTURE. */
     332              : /*        (DHEAD,DFORW,DBAKW) - DEGREE DOUBLY LINKED STRUCTURE. */
     333              : /*        QSIZE  - SIZE OF SUPERNODE. */
     334              : /*        MARKER - MARKER VECTOR. */
     335              : /*        LLIST  - TEMPORARY LINKED LIST OF ELIMINATED NABORS. */
     336              : 
     337              : /* *************************************************************** */
     338              : 
     339              : /* Subroutine */
     340            0 : int slu_mmdelm_(const int_t *mdnode, int_t *xadj, shortint *adjncy,
     341              :                 shortint *dhead, int *dforw, int *dbakw, shortint *qsize,
     342              :                 shortint *llist, shortint *marker, const int_t *maxint, const int_t *tag)
     343              : {
     344              :     /* System generated locals */
     345              :     int_t i__1, i__2;
     346              : 
     347              :     /* Local variables */
     348              :     int_t node, link, rloc, rlmt, i, j, nabor, rnode, elmnt, xqnbr, 
     349              :         istop, jstop, istrt, jstrt, nxnode, pvnode, nqnbrs, npv;
     350              : 
     351              : 
     352              : /* *************************************************************** */
     353              : 
     354              : 
     355              : /* *************************************************************** */
     356              : 
     357              : /*        ----------------------------------------------- */
     358              : /*        FIND REACHABLE SET AND PLACE IN DATA STRUCTURE. */
     359              : /*        ----------------------------------------------- */
     360              :     /* Parameter adjustments */
     361            0 :     --marker;
     362            0 :     --llist;
     363            0 :     --qsize;
     364            0 :     --dbakw;
     365            0 :     --dforw;
     366              :     --dhead;
     367            0 :     --adjncy;
     368            0 :     --xadj;
     369              : 
     370              :     /* Function Body */
     371            0 :     marker[*mdnode] = *tag;
     372            0 :     istrt = xadj[*mdnode];
     373            0 :     istop = xadj[*mdnode + 1] - 1;
     374              : /*        ------------------------------------------------------- */
     375              : /*        ELMNT POINTS TO THE BEGINNING OF THE LIST OF ELIMINATED */
     376              : /*        NABORS OF MDNODE, AND RLOC GIVES THE STORAGE LOCATION */
     377              : /*        FOR THE NEXT REACHABLE NODE. */
     378              : /*        ------------------------------------------------------- */
     379              :     elmnt = 0;
     380              :     rloc = istrt;
     381              :     rlmt = istop;
     382              :     i__1 = istop;
     383            0 :     for (i = istrt; i <= i__1; ++i) {
     384            0 :         nabor = adjncy[i];
     385            0 :         if (nabor == 0) {
     386            0 :             goto L300;
     387              :         }
     388            0 :         if (marker[nabor] >= *tag) {
     389            0 :             goto L200;
     390              :         }
     391            0 :         marker[nabor] = *tag;
     392            0 :         if (dforw[nabor] < 0) {
     393            0 :             goto L100;
     394              :         }
     395            0 :         adjncy[rloc] = nabor;
     396            0 :         ++rloc;
     397            0 :         goto L200;
     398              : L100:
     399            0 :         llist[nabor] = elmnt;
     400              :         elmnt = nabor;
     401            0 : L200:
     402              :         ;
     403              :     }
     404            0 : L300:
     405              : /*            ----------------------------------------------------- */
     406              : /*            MERGE WITH REACHABLE NODES FROM GENERALIZED ELEMENTS. */
     407              : /*            ----------------------------------------------------- */
     408            0 :     if (elmnt <= 0) {
     409            0 :         goto L1000;
     410              :     }
     411            0 :     adjncy[rlmt] = -elmnt;
     412              :     link = elmnt;
     413            0 : L400:
     414            0 :     jstrt = xadj[link];
     415            0 :     jstop = xadj[link + 1] - 1;
     416              :     i__1 = jstop;
     417            0 :     for (j = jstrt; j <= i__1; ++j) {
     418            0 :         node = adjncy[j];
     419            0 :         link = -node;
     420            0 :         if (node < 0) {
     421            0 :             goto L400;
     422            0 :         } else if (node == 0) {
     423            0 :             goto L900;
     424              :         } else {
     425            0 :             goto L500;
     426              :         }
     427              : L500:
     428            0 :         if (marker[node] >= *tag || dforw[node] < 0) {
     429            0 :             goto L800;
     430              :         }
     431            0 :         marker[node] = *tag;
     432              : /*                            --------------------------------- */
     433              : /*                            USE STORAGE FROM ELIMINATED NODES */
     434              : /*                            IF NECESSARY. */
     435              : /*                            --------------------------------- */
     436            0 : L600:
     437            0 :         if (rloc < rlmt) {
     438            0 :             goto L700;
     439              :         }
     440            0 :         link = -adjncy[rlmt];
     441            0 :         rloc = xadj[link];
     442            0 :         rlmt = xadj[link + 1] - 1;
     443            0 :         goto L600;
     444              : L700:
     445            0 :         adjncy[rloc] = node;
     446            0 :         ++rloc;
     447            0 : L800:
     448              :         ;
     449              :     }
     450            0 : L900:
     451            0 :     elmnt = llist[elmnt];
     452            0 :     goto L300;
     453              : L1000:
     454            0 :     if (rloc <= rlmt) {
     455            0 :         adjncy[rloc] = 0;
     456              :     }
     457              : /*        -------------------------------------------------------- */
     458              : /*        FOR EACH NODE IN THE REACHABLE SET, DO THE FOLLOWING ... */
     459              : /*        -------------------------------------------------------- */
     460            0 :     link = *mdnode;
     461            0 : L1100:
     462            0 :     istrt = xadj[link];
     463            0 :     istop = xadj[link + 1] - 1;
     464              :     i__1 = istop;
     465            0 :     for (i = istrt; i <= i__1; ++i) {
     466            0 :         rnode = adjncy[i];
     467            0 :         link = -rnode;
     468            0 :         if (rnode < 0) {
     469            0 :             goto L1100;
     470            0 :         } else if (rnode == 0) {
     471            0 :             goto L1800;
     472              :         } else {
     473            0 :             goto L1200;
     474              :         }
     475              : L1200:
     476              : /*                -------------------------------------------- */
     477              : /*                IF RNODE IS IN THE DEGREE LIST STRUCTURE ... */
     478              : /*                -------------------------------------------- */
     479            0 :         pvnode = dbakw[rnode];
     480            0 :         if (pvnode == 0 || pvnode == -(*maxint)) {
     481            0 :             goto L1300;
     482              :         }
     483              : /*                    ------------------------------------- */
     484              : /*                    THEN REMOVE RNODE FROM THE STRUCTURE. */
     485              : /*                    ------------------------------------- */
     486            0 :         nxnode = dforw[rnode];
     487            0 :         if (nxnode > 0) {
     488            0 :             dbakw[nxnode] = pvnode;
     489              :         }
     490            0 :         if (pvnode > 0) {
     491            0 :             dforw[pvnode] = nxnode;
     492              :         }
     493            0 :         npv = -pvnode;
     494            0 :         if (pvnode < 0) {
     495            0 :             dhead[npv] = nxnode;
     496              :         }
     497            0 : L1300:
     498              : /*                ---------------------------------------- */
     499              : /*                PURGE INACTIVE QUOTIENT NABORS OF RNODE. */
     500              : /*                ---------------------------------------- */
     501            0 :         jstrt = xadj[rnode];
     502            0 :         jstop = xadj[rnode + 1] - 1;
     503              :         xqnbr = jstrt;
     504              :         i__2 = jstop;
     505            0 :         for (j = jstrt; j <= i__2; ++j) {
     506            0 :             nabor = adjncy[j];
     507            0 :             if (nabor == 0) {
     508            0 :                 goto L1500;
     509              :             }
     510            0 :             if (marker[nabor] >= *tag) {
     511            0 :                 goto L1400;
     512              :             }
     513            0 :             adjncy[xqnbr] = nabor;
     514            0 :             ++xqnbr;
     515            0 : L1400:
     516              :             ;
     517              :         }
     518            0 : L1500:
     519              : /*                ---------------------------------------- */
     520              : /*                IF NO ACTIVE NABOR AFTER THE PURGING ... */
     521              : /*                ---------------------------------------- */
     522            0 :         nqnbrs = xqnbr - jstrt;
     523            0 :         if (nqnbrs > 0) {
     524            0 :             goto L1600;
     525              :         }
     526              : /*                    ----------------------------- */
     527              : /*                    THEN MERGE RNODE WITH MDNODE. */
     528              : /*                    ----------------------------- */
     529            0 :         qsize[*mdnode] += qsize[rnode];
     530            0 :         qsize[rnode] = 0;
     531            0 :         marker[rnode] = *maxint;
     532            0 :         dforw[rnode] = -(*mdnode);
     533            0 :         dbakw[rnode] = -(*maxint);
     534            0 :         goto L1700;
     535              : L1600:
     536              : /*                -------------------------------------- */
     537              : /*                ELSE FLAG RNODE FOR DEGREE UPDATE, AND */
     538              : /*                ADD MDNODE AS A NABOR OF RNODE. */
     539              : /*                -------------------------------------- */
     540            0 :         dforw[rnode] = nqnbrs + 1;
     541            0 :         dbakw[rnode] = 0;
     542            0 :         adjncy[xqnbr] = *mdnode;
     543            0 :         ++xqnbr;
     544            0 :         if (xqnbr <= jstop) {
     545            0 :             adjncy[xqnbr] = 0;
     546              :         }
     547              : 
     548            0 : L1700:
     549              :         ;
     550              :     }
     551            0 : L1800:
     552            0 :     return 0;
     553              : 
     554              : } /* slu_mmdelm_ */
     555              : 
     556              : /* *************************************************************** */
     557              : /* *************************************************************** */
     558              : /* *****     MMDUPD ..... MULTIPLE MINIMUM DEGREE UPDATE     ***** */
     559              : /* *************************************************************** */
     560              : /* *************************************************************** */
     561              : 
     562              : /*     AUTHOR - JOSEPH W.H. LIU */
     563              : /*              DEPT OF COMPUTER SCIENCE, YORK UNIVERSITY. */
     564              : 
     565              : /*     PURPOSE - THIS ROUTINE UPDATES THE DEGREES OF NODES */
     566              : /*        AFTER A MULTIPLE ELIMINATION STEP. */
     567              : 
     568              : /*     INPUT PARAMETERS - */
     569              : /*        EHEAD  - THE BEGINNING OF THE LIST OF ELIMINATED */
     570              : /*                 NODES (I.E., NEWLY FORMED ELEMENTS). */
     571              : /*        NEQNS  - NUMBER OF EQUATIONS. */
     572              : /*        (XADJ,ADJNCY) - ADJACENCY STRUCTURE. */
     573              : /*        DELTA  - TOLERANCE VALUE FOR MULTIPLE ELIMINATION. */
     574              : /*        MAXINT - MAXIMUM MACHINE REPRESENTABLE (SHORT) */
     575              : /*                 INTEGER. */
     576              : 
     577              : /*     UPDATED PARAMETERS - */
     578              : /*        MDEG   - NEW MINIMUM DEGREE AFTER DEGREE UPDATE. */
     579              : /*        (DHEAD,DFORW,DBAKW) - DEGREE DOUBLY LINKED STRUCTURE. */
     580              : /*        QSIZE  - SIZE OF SUPERNODE. */
     581              : /*        LLIST  - WORKING LINKED LIST. */
     582              : /*        MARKER - MARKER VECTOR FOR DEGREE UPDATE. */
     583              : /*        TAG    - TAG VALUE. */
     584              : 
     585              : /* *************************************************************** */
     586              : 
     587              : 
     588              : /* Subroutine */
     589            0 : int slu_mmdupd_(const int_t *ehead, const int *neqns, int_t *xadj,
     590              :                 shortint *adjncy, const int_t *delta, int_t *mdeg, shortint *dhead,
     591              :                 int *dforw, int *dbakw, shortint *qsize, shortint *llist,
     592              :                 shortint *marker, const int_t *maxint, int_t *tag)
     593              : {
     594              :     /* System generated locals */
     595              :     int_t i__1, i__2;
     596              : 
     597              :     /* Local variables */
     598              :     int_t node, mtag, link, mdeg0, i, j, enode, fnode, nabor, elmnt, 
     599              :             istop, jstop, q2head, istrt, jstrt, qxhead, iq2, deg, deg0;
     600              : 
     601              : 
     602              : /* *************************************************************** */
     603              : 
     604              : 
     605              : /* *************************************************************** */
     606              : 
     607              :     /* Parameter adjustments */
     608            0 :     --marker;
     609            0 :     --llist;
     610            0 :     --qsize;
     611            0 :     --dbakw;
     612            0 :     --dforw;
     613              :     --dhead;
     614            0 :     --adjncy;
     615            0 :     --xadj;
     616              : 
     617              :     /* Function Body */
     618            0 :     mdeg0 = *mdeg + *delta;
     619            0 :     elmnt = *ehead;
     620            0 : L100:
     621              : /*            ------------------------------------------------------- */
     622              : /*            FOR EACH OF THE NEWLY FORMED ELEMENT, DO THE FOLLOWING. */
     623              : /*            (RESET TAG VALUE IF NECESSARY.) */
     624              : /*            ------------------------------------------------------- */
     625            0 :     if (elmnt <= 0) {
     626            0 :         return 0;
     627              :     }
     628            0 :     mtag = *tag + mdeg0;
     629            0 :     if (mtag < *maxint) {
     630            0 :         goto L300;
     631              :     }
     632            0 :     *tag = 1;
     633            0 :     i__1 = *neqns;
     634            0 :     for (i = 1; i <= i__1; ++i) {
     635            0 :         if (marker[i] < *maxint) {
     636            0 :             marker[i] = 0;
     637              :         }
     638              : /* L200: */
     639              :     }
     640            0 :     mtag = *tag + mdeg0;
     641            0 : L300:
     642              : /*            --------------------------------------------- */
     643              : /*            CREATE TWO LINKED LISTS FROM NODES ASSOCIATED */
     644              : /*            WITH ELMNT: ONE WITH TWO NABORS (Q2HEAD) IN */
     645              : /*            ADJACENCY STRUCTURE, AND THE OTHER WITH MORE */
     646              : /*            THAN TWO NABORS (QXHEAD).  ALSO COMPUTE DEG0, */
     647              : /*            NUMBER OF NODES IN THIS ELEMENT. */
     648              : /*            --------------------------------------------- */
     649              :     q2head = 0;
     650              :     qxhead = 0;
     651              :     deg0 = 0;
     652              :     link = elmnt;
     653            0 : L400:
     654            0 :     istrt = xadj[link];
     655            0 :     istop = xadj[link + 1] - 1;
     656              :     i__1 = istop;
     657            0 :     for (i = istrt; i <= i__1; ++i) {
     658            0 :         enode = adjncy[i];
     659            0 :         link = -enode;
     660            0 :         if (enode < 0) {
     661            0 :             goto L400;
     662            0 :         } else if (enode == 0) {
     663            0 :             goto L800;
     664              :         } else {
     665            0 :             goto L500;
     666              :         }
     667              : 
     668              : L500:
     669            0 :         if (qsize[enode] == 0) {
     670            0 :             goto L700;
     671              :         }
     672            0 :         deg0 += qsize[enode];
     673            0 :         marker[enode] = mtag;
     674              : /*                        ---------------------------------- */
     675              : /*                        IF ENODE REQUIRES A DEGREE UPDATE, */
     676              : /*                        THEN DO THE FOLLOWING. */
     677              : /*                        ---------------------------------- */
     678            0 :         if (dbakw[enode] != 0) {
     679            0 :             goto L700;
     680              :         }
     681              : /*                            --------------------------------------- 
     682              : */
     683              : /*                            PLACE EITHER IN QXHEAD OR Q2HEAD LISTS. 
     684              : */
     685              : /*                            --------------------------------------- 
     686              : */
     687            0 :         if (dforw[enode] == 2) {
     688            0 :             goto L600;
     689              :         }
     690            0 :         llist[enode] = qxhead;
     691              :         qxhead = enode;
     692            0 :         goto L700;
     693              : L600:
     694            0 :         llist[enode] = q2head;
     695              :         q2head = enode;
     696            0 : L700:
     697              :         ;
     698              :     }
     699            0 : L800:
     700              : /*            -------------------------------------------- */
     701              : /*            FOR EACH ENODE IN Q2 LIST, DO THE FOLLOWING. */
     702              : /*            -------------------------------------------- */
     703              :     enode = q2head;
     704              :     iq2 = 1;
     705            0 : L900:
     706            0 :     if (enode <= 0) {
     707            0 :         goto L1500;
     708              :     }
     709            0 :     if (dbakw[enode] != 0) {
     710            0 :         goto L2200;
     711              :     }
     712            0 :     ++(*tag);
     713              :     deg = deg0;
     714              : /*                    ------------------------------------------ */
     715              : /*                    IDENTIFY THE OTHER ADJACENT ELEMENT NABOR. */
     716              : /*                    ------------------------------------------ */
     717            0 :     istrt = xadj[enode];
     718            0 :     nabor = adjncy[istrt];
     719            0 :     if (nabor == elmnt) {
     720            0 :         nabor = adjncy[istrt + 1];
     721              :     }
     722              : /*                    ------------------------------------------------ */
     723              : /*                    IF NABOR IS UNELIMINATED, INCREASE DEGREE COUNT. */
     724              : /*                    ------------------------------------------------ */
     725              :     link = nabor;
     726            0 :     if (dforw[nabor] < 0) {
     727            0 :         goto L1000;
     728              :     }
     729            0 :     deg += qsize[nabor];
     730            0 :     goto L2100;
     731            0 : L1000:
     732              : /*                        -------------------------------------------- */
     733              : /*                        OTHERWISE, FOR EACH NODE IN THE 2ND ELEMENT, */
     734              : /*                        DO THE FOLLOWING. */
     735              : /*                        -------------------------------------------- */
     736            0 :     istrt = xadj[link];
     737            0 :     istop = xadj[link + 1] - 1;
     738              :     i__1 = istop;
     739            0 :     for (i = istrt; i <= i__1; ++i) {
     740            0 :         node = adjncy[i];
     741            0 :         link = -node;
     742            0 :         if (node == enode) {
     743            0 :             goto L1400;
     744              :         }
     745            0 :         if (node < 0) {
     746            0 :             goto L1000;
     747            0 :         } else if (node == 0) {
     748            0 :             goto L2100;
     749              :         } else {
     750            0 :             goto L1100;
     751              :         }
     752              : 
     753              : L1100:
     754            0 :         if (qsize[node] == 0) {
     755            0 :             goto L1400;
     756              :         }
     757            0 :         if (marker[node] >= *tag) {
     758            0 :             goto L1200;
     759              :         }
     760              : /*                                -----------------------------------
     761              : -- */
     762              : /*                                CASE WHEN NODE IS NOT YET CONSIDERED
     763              : . */
     764              : /*                                -----------------------------------
     765              : -- */
     766            0 :         marker[node] = *tag;
     767            0 :         deg += qsize[node];
     768            0 :         goto L1400;
     769              : L1200:
     770              : /*                            ----------------------------------------
     771              :  */
     772              : /*                            CASE WHEN NODE IS INDISTINGUISHABLE FROM
     773              :  */
     774              : /*                            ENODE.  MERGE THEM INTO A NEW SUPERNODE.
     775              :  */
     776              : /*                            ----------------------------------------
     777              :  */
     778            0 :         if (dbakw[node] != 0) {
     779            0 :             goto L1400;
     780              :         }
     781            0 :         if (dforw[node] != 2) {
     782            0 :             goto L1300;
     783              :         }
     784            0 :         qsize[enode] += qsize[node];
     785            0 :         qsize[node] = 0;
     786            0 :         marker[node] = *maxint;
     787            0 :         dforw[node] = -enode;
     788            0 :         dbakw[node] = -(*maxint);
     789            0 :         goto L1400;
     790              : L1300:
     791              : /*                            -------------------------------------- 
     792              : */
     793              : /*                            CASE WHEN NODE IS OUTMATCHED BY ENODE. 
     794              : */
     795              : /*                            -------------------------------------- 
     796              : */
     797              :         if (dbakw[node] == 0) {
     798            0 :             dbakw[node] = -(*maxint);
     799              :         }
     800            0 : L1400:
     801              :         ;
     802              :     }
     803            0 :     goto L2100;
     804              : L1500:
     805              : /*                ------------------------------------------------ */
     806              : /*                FOR EACH ENODE IN THE QX LIST, DO THE FOLLOWING. */
     807              : /*                ------------------------------------------------ */
     808              :     enode = qxhead;
     809              :     iq2 = 0;
     810            0 : L1600:
     811            0 :     if (enode <= 0) {
     812            0 :         goto L2300;
     813              :     }
     814            0 :     if (dbakw[enode] != 0) {
     815            0 :         goto L2200;
     816              :     }
     817            0 :     ++(*tag);
     818              :     deg = deg0;
     819              : /*                        --------------------------------- */
     820              : /*                        FOR EACH UNMARKED NABOR OF ENODE, */
     821              : /*                        DO THE FOLLOWING. */
     822              : /*                        --------------------------------- */
     823            0 :     istrt = xadj[enode];
     824            0 :     istop = xadj[enode + 1] - 1;
     825              :     i__1 = istop;
     826            0 :     for (i = istrt; i <= i__1; ++i) {
     827            0 :         nabor = adjncy[i];
     828            0 :         if (nabor == 0) {
     829            0 :             goto L2100;
     830              :         }
     831            0 :         if (marker[nabor] >= *tag) {
     832            0 :             goto L2000;
     833              :         }
     834            0 :         marker[nabor] = *tag;
     835              :         link = nabor;
     836              : /*                                ------------------------------ */
     837              : /*                                IF UNELIMINATED, INCLUDE IT IN */
     838              : /*                                DEG COUNT. */
     839              : /*                                ------------------------------ */
     840            0 :         if (dforw[nabor] < 0) {
     841            0 :             goto L1700;
     842              :         }
     843            0 :         deg += qsize[nabor];
     844            0 :         goto L2000;
     845            0 : L1700:
     846              : /*                                    ------------------------------- 
     847              : */
     848              : /*                                    IF ELIMINATED, INCLUDE UNMARKED 
     849              : */
     850              : /*                                    NODES IN THIS ELEMENT INTO THE 
     851              : */
     852              : /*                                    DEGREE COUNT. */
     853              : /*                                    ------------------------------- 
     854              : */
     855            0 :         jstrt = xadj[link];
     856            0 :         jstop = xadj[link + 1] - 1;
     857              :         i__2 = jstop;
     858            0 :         for (j = jstrt; j <= i__2; ++j) {
     859            0 :             node = adjncy[j];
     860            0 :             link = -node;
     861            0 :             if (node < 0) {
     862            0 :                 goto L1700;
     863            0 :             } else if (node == 0) {
     864            0 :                 goto L2000;
     865              :             } else {
     866            0 :                 goto L1800;
     867              :             }
     868              : 
     869              : L1800:
     870            0 :             if (marker[node] >= *tag) {
     871            0 :                 goto L1900;
     872              :             }
     873            0 :             marker[node] = *tag;
     874            0 :             deg += qsize[node];
     875            0 : L1900:
     876              :             ;
     877              :         }
     878            0 : L2000:
     879              :         ;
     880              :     }
     881            0 : L2100:
     882              : /*                    ------------------------------------------- */
     883              : /*                    UPDATE EXTERNAL DEGREE OF ENODE IN DEGREE */
     884              : /*                    STRUCTURE, AND MDEG (MIN DEG) IF NECESSARY. */
     885              : /*                    ------------------------------------------- */
     886            0 :     deg = deg - qsize[enode] + 1;
     887            0 :     fnode = dhead[deg];
     888            0 :     dforw[enode] = fnode;
     889            0 :     dbakw[enode] = -deg;
     890            0 :     if (fnode > 0) {
     891            0 :         dbakw[fnode] = enode;
     892              :     }
     893            0 :     dhead[deg] = enode;
     894            0 :     if (deg < *mdeg) {
     895            0 :         *mdeg = deg;
     896              :     }
     897            0 : L2200:
     898              : /*                    ---------------------------------- */
     899              : /*                    GET NEXT ENODE IN CURRENT ELEMENT. */
     900              : /*                    ---------------------------------- */
     901            0 :     enode = llist[enode];
     902            0 :     if (iq2 == 1) {
     903            0 :         goto L900;
     904              :     }
     905            0 :     goto L1600;
     906              : L2300:
     907              : /*            ----------------------------- */
     908              : /*            GET NEXT ELEMENT IN THE LIST. */
     909              : /*            ----------------------------- */
     910            0 :     *tag = mtag;
     911            0 :     elmnt = llist[elmnt];
     912            0 :     goto L100;
     913              : 
     914              : } /* slu_mmdupd_ */
     915              : 
     916              : /* *************************************************************** */
     917              : /* *************************************************************** */
     918              : /* *****     MMDNUM ..... MULTI MINIMUM DEGREE NUMBERING     ***** */
     919              : /* *************************************************************** */
     920              : /* *************************************************************** */
     921              : 
     922              : /*     AUTHOR - JOSEPH W.H. LIU */
     923              : /*              DEPT OF COMPUTER SCIENCE, YORK UNIVERSITY. */
     924              : 
     925              : /*     PURPOSE - THIS ROUTINE PERFORMS THE FINAL STEP IN */
     926              : /*        PRODUCING THE PERMUTATION AND INVERSE PERMUTATION */
     927              : /*        VECTORS IN THE MULTIPLE ELIMINATION VERSION OF THE */
     928              : /*        MINIMUM DEGREE ORDERING ALGORITHM. */
     929              : 
     930              : /*     INPUT PARAMETERS - */
     931              : /*        NEQNS  - NUMBER OF EQUATIONS. */
     932              : /*        QSIZE  - SIZE OF SUPERNODES AT ELIMINATION. */
     933              : 
     934              : /*     UPDATED PARAMETERS - */
     935              : /*        INVP   - INVERSE PERMUTATION VECTOR.  ON INPUT, */
     936              : /*                 IF QSIZE(NODE)=0, THEN NODE HAS BEEN MERGED */
     937              : /*                 INTO THE NODE -INVP(NODE); OTHERWISE, */
     938              : /*                 -INVP(NODE) IS ITS INVERSE LABELLING. */
     939              : 
     940              : /*     OUTPUT PARAMETERS - */
     941              : /*        PERM   - THE PERMUTATION VECTOR. */
     942              : 
     943              : /* *************************************************************** */
     944              : 
     945              : /* Subroutine */
     946            0 : int slu_mmdnum_(const int *neqns, int *perm, int *invp, shortint *qsize)
     947              : {
     948              :     /* System generated locals */
     949              : 
     950              :     int i__1;
     951              : 
     952              :     /* Local variables */
     953              :     int_t node, root, nextf, father, nqsize, num;
     954              : 
     955              : 
     956              : /* *************************************************************** */
     957              : 
     958              : 
     959              : /* *************************************************************** */
     960              : 
     961              :     /* Parameter adjustments */
     962              :     --qsize;
     963            0 :     --invp;
     964            0 :     --perm;
     965              : 
     966              :     /* Function Body */
     967            0 :     i__1 = *neqns;
     968            0 :     for (node = 1; node <= i__1; ++node) {
     969            0 :         nqsize = qsize[node];
     970            0 :         if (nqsize <= 0) {
     971            0 :             perm[node] = invp[node];
     972              :         }
     973              :         if (nqsize > 0) {
     974            0 :             perm[node] = -invp[node];
     975              :         }
     976              : /* L100: */
     977              :     }
     978              : /*        ------------------------------------------------------ */
     979              : /*        FOR EACH NODE WHICH HAS BEEN MERGED, DO THE FOLLOWING. */
     980              : /*        ------------------------------------------------------ */
     981            0 :     i__1 = *neqns;
     982            0 :     for (node = 1; node <= i__1; ++node) {
     983            0 :         if (perm[node] > 0) {
     984            0 :             goto L500;
     985              :         }
     986              : /*                ----------------------------------------- */
     987              : /*                TRACE THE MERGED TREE UNTIL ONE WHICH HAS */
     988              : /*                NOT BEEN MERGED, CALL IT ROOT. */
     989              : /*                ----------------------------------------- */
     990              :         father = node;
     991            0 : L200:
     992            0 :         if (perm[father] > 0) {
     993            0 :             goto L300;
     994              :         }
     995            0 :         father = -perm[father];
     996            0 :         goto L200;
     997              : L300:
     998              : /*                ----------------------- */
     999              : /*                NUMBER NODE AFTER ROOT. */
    1000              : /*                ----------------------- */
    1001              :         root = father;
    1002            0 :         num = perm[root] + 1;
    1003            0 :         invp[node] = -num;
    1004            0 :         perm[root] = num;
    1005              : /*                ------------------------ */
    1006              : /*                SHORTEN THE MERGED TREE. */
    1007              : /*                ------------------------ */
    1008              :         father = node;
    1009            0 : L400:
    1010            0 :         nextf = -perm[father];
    1011            0 :         if (nextf <= 0) {
    1012            0 :             goto L500;
    1013              :         }
    1014            0 :         perm[father] = -root;
    1015              :         father = nextf;
    1016            0 :         goto L400;
    1017            0 : L500:
    1018              :         ;
    1019              :     }
    1020              : /*        ---------------------- */
    1021              : /*        READY TO COMPUTE PERM. */
    1022              : /*        ---------------------- */
    1023            0 :     i__1 = *neqns;
    1024            0 :     for (node = 1; node <= i__1; ++node) {
    1025            0 :         num = -invp[node];
    1026            0 :         invp[node] = num;
    1027            0 :         perm[num] = node;
    1028              : /* L600: */
    1029              :     }
    1030            0 :     return 0;
    1031              : 
    1032              : } /* slu_mmdnum_ */
    1033              : 
        

Generated by: LCOV version 2.0-1