
        SUBROUTINE  ODRV
     *     (N, IA,JA,A, P,IP, NSP,ISP, PATH, FLAG)                        OD   6
C                                                                         OD   7
C  DESCRIPTION                                                            OD   8
C                                                                         OD   9
C    ODRV FINDS A MINIMUM DEGREE ORDERING OF THE ROWS AND COLUMNS OF A    OD  10
C    SYMMETRIC MATRIX M STORED IN (IA,JA,A) FORMAT (SEE BELOW).  FOR THE  OD  11
C    REORDERED MATRIX, THE WORK AND STORAGE REQUIRED TO PERFORM GAUSSIAN  OD  12
C    ELIMINATION IS (USUALLY) SIGNIFICANTLY LESS.                         OD  13
C                                                                         OD  14
C    IF ONLY THE NONZERO ENTRIES IN THE UPPER TRIANGLE OF M ARE BEING     OD  15
C    STORED, THEN ODRV SYMMETRICALLY REORDERS (IA,JA,A), (OPTIONALLY)     OD  16
C    WITH THE DIAGONAL ENTRIES PLACED FIRST IN EACH ROW.  THIS IS TO      OD  17
C    ENSURE THAT IF M(I,J) WILL BE IN THE UPPER TRIANGLE OF M WITH        OD  18
C    RESPECT TO THE NEW ORDERING, THEN M(I,J) IS STORED IN ROW I (AND     OD  19
C    THUS M(J,I) IS NOT STORED);  WHEREAS IF M(I,J) WILL BE IN THE        OD  20
C    STRICT LOWER TRIANGLE OF M, THEN M(J,I) IS STORED IN ROW J (AND      OD  21
C    THUS M(I,J) IS NOT STORED).                                          OD  22
C                                                                         OD  23
C                                                                         OD  24
C  STORAGE OF SPARSE MATRICES                                             OD  25
C                                                                         OD  26
C    THE NONZERO ENTRIES OF THE MATRIX M ARE STORED ROW-BY-ROW IN THE     OD  27
C    ARRAY A.  TO IDENTIFY THE INDIVIDUAL NONZERO ENTRIES IN EACH ROW,    OD  28
C    WE NEED TO KNOW IN WHICH COLUMN EACH ENTRY LIES.  THESE COLUMN       OD  29
C    INDICES ARE STORED IN THE ARRAY JA;  I.E., IF  A(K) = M(I,J),  THEN  OD  30
C    JA(K) = J.  TO IDENTIFY THE INDIVIDUAL ROWS, WE NEED TO KNOW WHERE   OD  31
C    EACH ROW STARTS.  THESE ROW POINTERS ARE STORED IN THE ARRAY IA;     OD  32
C    I.E., IF M(I,J) IS THE FIRST NONZERO ENTRY (STORED) IN THE I-TH ROW  OD  33
C    AND  A(K) = M(I,J),  THEN  IA(I) = K.  MOREOVER, IA(N+1) POINTS TO   OD  34
C    THE FIRST LOCATION FOLLOWING THE LAST ELEMENT IN THE LAST ROW.       OD  35
C    THUS, THE NUMBER OF ENTRIES IN THE I-TH ROW IS  IA(I+1) - IA(I),     OD  36
C    THE NONZERO ENTRIES IN THE I-TH ROW ARE STORED CONSECUTIVELY IN      OD  37
C                                                                         OD  38
C            A(IA(I)),  A(IA(I)+1),  ..., A(IA(I+1)-1),                   OD  39
C                                                                         OD  40
C    AND THE CORRESPONDING COLUMN INDICES ARE STORED CONSECUTIVELY IN     OD  41
C                                                                         OD  42
C            JA(IA(I)), JA(IA(I)+1), ..., JA(IA(I+1)-1).                  OD  43
C                                                                         OD  44
C    SINCE THE COEFFICIENT MATRIX IS SYMMETRIC, ONLY THE NONZERO ENTRIES  OD  45
C    IN THE UPPER TRIANGLE NEED BE STORED.  FOR EXAMPLE, THE MATRIX       OD  46
C                                                                         OD  47
C             ( 1  0  2  3  0 )                                           OD  48
C             ( 0  4  0  0  0 )                                           OD  49
C         M = ( 2  0  5  6  0 )                                           OD  50
C             ( 3  0  6  7  8 )                                           OD  51
C             ( 0  0  0  8  9 )                                           OD  52
C                                                                         OD  53
C    COULD BE STORED AS                                                   OD  54
C                                                                         OD  55
C            \ 1  2  3  4  5  6  7  8  9 10 11 12 13                      OD  56
C         ---+--------------------------------------                      OD  57
C         IA \ 1  4  5  8 12 14                                           OD  58
C         JA \ 1  3  4  2  1  3  4  1  3  4  5  4  5                      OD  59
C          A \ 1  2  3  4  2  5  6  3  6  7  8  8  9                      OD  60
C                                                                         OD  61
C    OR (SYMMETRICALLY) AS                                                OD  62
C                                                                         OD  63
C            \ 1  2  3  4  5  6  7  8  9                                  OD  64
C         ---+--------------------------                                  OD  65
C         IA \ 1  4  5  7  9 10                                           OD  66
C         JA \ 1  3  4  2  3  4  4  5  5                                  OD  67
C          A \ 1  2  3  4  5  6  7  8  9          .                       OD  68
C                                                                         OD  69
C                                                                         OD  70
C  PARAMETERS                                                             OD  71
C                                                                         OD  72
C    N    - ORDER OF THE MATRIX                                           OD  73
C                                                                         OD  74
C    IA   - INTEGER ONE-DIMENSIONAL ARRAY CONTAINING POINTERS TO DELIMIT  OD  75
C           ROWS IN JA AND A;  DIMENSION = N+1                            OD  76
C                                                                         OD  77
C    JA   - INTEGER ONE-DIMENSIONAL ARRAY CONTAINING THE COLUMN INDICES   OD  78
C           CORRESPONDING TO THE ELEMENTS OF A;  DIMENSION = NUMBER OF    OD  79
C           NONZERO ENTRIES IN (THE UPPER TRIANGLE OF) M                  OD  80
C                                                                         OD  81
C    A    - REAL ONE-DIMENSIONAL ARRAY CONTAINING THE NONZERO ENTRIES IN  OD  82
C           (THE UPPER TRIANGLE OF) M, STORED BY ROWS;  DIMENSION =       OD  83
C           NUMBER OF NONZERO ENTRIES IN (THE UPPER TRIANGLE OF) M        OD  84
C                                                                         OD  85
C    P    - INTEGER ONE-DIMENSIONAL ARRAY USED TO RETURN THE PERMUTATION  OD  86
C           OF THE ROWS AND COLUMNS OF M CORRESPONDING TO THE MINIMUM     OD  87
C           DEGREE ORDERING;  DIMENSION = N                               OD  88
C                                                                         OD  89
C    IP   - INTEGER ONE-DIMENSIONAL ARRAY USED TO RETURN THE INVERSE OF   OD  90
C           THE PERMUTATION RETURNED IN P;  DIMENSION = N                 OD  91
C                                                                         OD  92
C    NSP  - DECLARED DIMENSION OF THE ONE-DIMENSIONAL ARRAY ISP;  NSP     OD  93
C           MUST BE AT LEAST  3N+4K,  WHERE K IS THE NUMBER OF NONZEROES  OD  94
C           IN THE STRICT UPPER TRIANGLE OF M                             OD  95
C                                                                         OD  96
C    ISP  - INTEGER ONE-DIMENSIONAL ARRAY USED FOR WORKING STORAGE;       OD  97
C           DIMENSION = NSP                                               OD  98
C                                                                         OD  99
C    PATH - INTEGER PATH SPECIFICATION;  VALUES AND THEIR MEANINGS ARE -  OD 100
C             1  FIND MINIMUM DEGREE ORDERING ONLY                        OD 101
C             2  FIND MINIMUM DEGREE ORDERING AND REORDER SYMMETRICALLY   OD 102
C                  STORED MATRIX (USED WHEN ONLY THE NONZERO ENTRIES IN   OD 103
C                  THE UPPER TRIANGLE OF M ARE BEING STORED)              OD 104
C             3  REORDER SYMMETRICALLY STORED MATRIX AS SPECIFIED BY      OD 105
C                  INPUT PERMUTATION (USED WHEN AN ORDERING HAS ALREADY   OD 106
C                  BEEN DETERMINED AND ONLY THE NONZERO ENTRIES IN THE    OD 107
C                  UPPER TRIANGLE OF M ARE BEING STORED)                  OD 108
C             4  SAME AS 2 BUT PUT DIAGONAL ENTRIES AT START OF EACH ROW  OD 109
C             5  SAME AS 3 BUT PUT DIAGONAL ENTRIES AT START OF EACH ROW  OD 110
C                                                                         OD 111
C    FLAG - INTEGER ERROR FLAG;  VALUES AND THEIR MEANINGS ARE -          OD 112
C               0    NO ERRORS DETECTED                                   OD 113
C              9N+K  INSUFFICIENT STORAGE IN MD                           OD 114
C             10N+1  INSUFFICIENT STORAGE IN ODRV                         OD 115
C             11N+1  ILLEGAL PATH SPECIFICATION                           OD 116
C                                                                         OD 117
C                                                                         OD 118
C  CONVERSION FROM REAL TO DOUBLE PRECISION                               OD 119
C                                                                         OD 120
C    CHANGE THE REAL DECLARATIONS IN ODRV AND SRO TO DOUBLE PRECISION     OD 121
C    DECLARATIONS.                                                        OD 122
C                                                                         OD 123
C-----------------------------------------------------------------------  OD 124
C                                                                         OD 125
        INTEGER  IA(1), JA(1),  P(1), IP(1),  ISP(1),  PATH,  FLAG,       OD 126
     *     V, L, HEAD,  TMP, Q                                            OD 127
        REAL  A(1)                                                        OD 128
C...    DOUBLE PRECISION  A(1)                                            OD 129
        LOGICAL  DFLAG                                                    OD 130
C                                                                         OD 131
C----INITIALIZE ERROR FLAG AND VALIDATE PATH SPECIFICATION                OD 132
        FLAG = 0                                                          OD 133
        IF (PATH.LT.1 .OR. 5.LT.PATH)  GO TO 111                          OD 134
C                                                                         OD 135
C----ALLOCATE STORAGE AND FIND MINIMUM DEGREE ORDERING                    OD 136
        IF ((PATH-1) * (PATH-2) * (PATH-4) .NE. 0)  GO TO 1               OD 137
          MAX = (NSP-N)/2                                                 OD 138
          V    = 1                                                        OD 139
          L    = V     +  MAX                                             OD 140
          HEAD = L     +  MAX                                             OD 141
          NEXT = HEAD  +  N                                               OD 142
          IF (MAX.LT.N)  GO TO 110                                        OD 143
C                                                                         OD 144
          CALL  MD                                                        OD 145
     *       (N, IA,JA, MAX,ISP(V),ISP(L), ISP(HEAD),P,IP, ISP(V), FLAG)  OD 146
          IF (FLAG.NE.0)  GO TO 100                                       OD 147
C                                                                         OD 148
C----ALLOCATE STORAGE AND SYMMETRICALLY REORDER MATRIX                    OD 149
   1    IF ((PATH-2) * (PATH-3) * (PATH-4) * (PATH-5) .NE. 0)  GO TO 2    OD 150
          TMP = (NSP+1) -      N                                          OD 151
          Q   = TMP     - (IA(N+1)-1)                                     OD 152
          IF (Q.LT.1)  GO TO 110                                          OD 153
C                                                                         OD 154
          DFLAG = PATH.EQ.4 .OR. PATH.EQ.5                                OD 155
          CALL SRO                                                        OD 156
     *       (N,  IP,  IA, JA, A,  ISP(TMP),  ISP(Q),  DFLAG)             OD 157
C                                                                         OD 158
   2    RETURN                                                            OD 159
C                                                                         OD 160
C ** ERROR -- ERROR DETECTED IN MD                                        OD 161
 100    RETURN                                                            OD 162
C ** ERROR -- INSUFFICIENT STORAGE                                        OD 163
 110    FLAG = 10*N + 1                                                   OD 164
        RETURN                                                            OD 165
C ** ERROR -- ILLEGAL PATH SPECIFIED                                      OD 166
 111    FLAG = 11*N + 1                                                   OD 167
        RETURN                                                            OD 168
        END                                                               OD 169
