ETS  \$Id: Doxyfile 2162 2020-02-26 14:16:09Z g2dpc $
 All Classes Files Functions Variables Pages
SPAR.f
Go to the documentation of this file.
1 C 1/15/81
2 
3 C***********************************************************************
4 
5 C ODRV -- DRIVER FOR SPARSE MATRIX REORDERING ROUTINES
6 
7 C***********************************************************************
8 
9  SUBROUTINE odrvd
10 
11  * (n, ia,ja,a, p,ip, nsp,isp, path, flag)
12 
13 C
14 
15 C DESCRIPTION
16 
17 C
18 
19 C ODRV FINDS A MINIMUM DEGREE ORDERING OF THE ROWS AND COLUMNS OF A
20 
21 C SYMMETRIC MATRIX M STORED IN (IA,JA,A) FORMAT (SEE BELOW). FOR THE
22 
23 C REORDERED MATRIX, THE WORK AND STORAGE REQUIRED TO PERFORM GAUSSIAN
24 
25 C ELIMINATION IS (USUALLY) SIGNIFICANTLY LESS.
26 
27 C
28 
29 C IF ONLY THE NONZERO ENTRIES IN THE UPPER TRIANGLE OF M ARE BEING
30 
31 C STORED, THEN ODRV SYMMETRICALLY REORDERS (IA,JA,A), (OPTIONALLY)
32 
33 C WITH THE DIAGONAL ENTRIES PLACED FIRST IN EACH ROW. THIS IS TO
34 
35 C ENSURE THAT IF M(I,J) WILL BE IN THE UPPER TRIANGLE OF M WITH
36 
37 C RESPECT TO THE NEW ORDERING, THEN M(I,J) IS STORED IN ROW I (AND
38 
39 C THUS M(J,I) IS NOT STORED); WHEREAS IF M(I,J) WILL BE IN THE
40 
41 C STRICT LOWER TRIANGLE OF M, THEN M(J,I) IS STORED IN ROW J (AND
42 
43 C THUS M(I,J) IS NOT STORED).
44 
45 C
46 
47 C
48 
49 C STORAGE OF SPARSE MATRICES
50 
51 C
52 
53 C THE NONZERO ENTRIES OF THE MATRIX M ARE STORED ROW-BY-ROW IN THE
54 
55 C ARRAY A. TO IDENTIFY THE INDIVIDUAL NONZERO ENTRIES IN EACH ROW,
56 
57 C WE NEED TO KNOW IN WHICH COLUMN EACH ENTRY LIES. THESE COLUMN
58 
59 C INDICES ARE STORED IN THE ARRAY JA; I.E., IF A(K) = M(I,J), THEN
60 
61 C JA(K) = J. TO IDENTIFY THE INDIVIDUAL ROWS, WE NEED TO KNOW WHERE
62 
63 C EACH ROW STARTS. THESE ROW POINTERS ARE STORED IN THE ARRAY IA;
64 
65 C I.E., IF M(I,J) IS THE FIRST NONZERO ENTRY (STORED) IN THE I-TH ROW
66 
67 C AND A(K) = M(I,J), THEN IA(I) = K. MOREOVER, IA(N+1) POINTS TO
68 
69 C THE FIRST LOCATION FOLLOWING THE LAST ELEMENT IN THE LAST ROW.
70 
71 C THUS, THE NUMBER OF ENTRIES IN THE I-TH ROW IS IA(I+1) - IA(I),
72 
73 C THE NONZERO ENTRIES IN THE I-TH ROW ARE STORED CONSECUTIVELY IN
74 
75 C
76 
77 C A(IA(I)), A(IA(I)+1), ..., A(IA(I+1)-1),
78 
79 C
80 
81 C AND THE CORRESPONDING COLUMN INDICES ARE STORED CONSECUTIVELY IN
82 
83 C
84 
85 C JA(IA(I)), JA(IA(I)+1), ..., JA(IA(I+1)-1).
86 
87 C
88 
89 C SINCE THE COEFFICIENT MATRIX IS SYMMETRIC, ONLY THE NONZERO ENTRIES
90 
91 C IN THE UPPER TRIANGLE NEED BE STORED. FOR EXAMPLE, THE MATRIX
92 
93 C
94 
95 C ( 1 0 2 3 0 )
96 
97 C ( 0 4 0 0 0 )
98 
99 C M = ( 2 0 5 6 0 )
100 
101 C ( 3 0 6 7 8 )
102 
103 C ( 0 0 0 8 9 )
104 
105 C
106 
107 C COULD BE STORED AS
108 
109 C
110 
111 C 1 2 3 4 5 6 7 8 9 10 11 12 13
112 
113 C ---+--------------------------------------
114 
115 C IA 1 4 5 8 12 14
116 
117 C JA 1 3 4 2 1 3 4 1 3 4 5 4 5
118 
119 C A 1 2 3 4 2 5 6 3 6 7 8 8 9
120 
121 C
122 
123 C OR (SYMMETRICALLY) AS
124 
125 C
126 
127 C 1 2 3 4 5 6 7 8 9
128 
129 C ---+--------------------------
130 
131 C IA 1 4 5 7 9 10
132 
133 C JA 1 3 4 2 3 4 4 5 5
134 
135 C A 1 2 3 4 5 6 7 8 9 .
136 
137 C
138 
139 C
140 
141 C PARAMETERS
142 
143 C
144 
145 C N - ORDER OF THE MATRIX
146 
147 C
148 
149 C IA - INTEGER ONE-DIMENSIONAL ARRAY CONTAINING POINTERS TO DELIMIT
150 
151 C ROWS IN JA AND A; DIMENSION = N+1
152 
153 C
154 
155 C JA - INTEGER ONE-DIMENSIONAL ARRAY CONTAINING THE COLUMN INDICES
156 
157 C CORRESPONDING TO THE ELEMENTS OF A; DIMENSION = NUMBER OF
158 
159 C NONZERO ENTRIES IN (THE UPPER TRIANGLE OF) M
160 
161 C
162 
163 C A - REAL ONE-DIMENSIONAL ARRAY CONTAINING THE NONZERO ENTRIES IN
164 
165 C (THE UPPER TRIANGLE OF) M, STORED BY ROWS; DIMENSION =
166 
167 C NUMBER OF NONZERO ENTRIES IN (THE UPPER TRIANGLE OF) M
168 
169 C
170 
171 C P - INTEGER ONE-DIMENSIONAL ARRAY USED TO RETURN THE PERMUTATION
172 
173 C OF THE ROWS AND COLUMNS OF M CORRESPONDING TO THE MINIMUM
174 
175 C DEGREE ORDERING; DIMENSION = N
176 
177 C
178 
179 C IP - INTEGER ONE-DIMENSIONAL ARRAY USED TO RETURN THE INVERSE OF
180 
181 C THE PERMUTATION RETURNED IN P; DIMENSION = N
182 
183 C
184 
185 C NSP - DECLARED DIMENSION OF THE ONE-DIMENSIONAL ARRAY ISP; NSP
186 
187 C MUST BE AT LEAST 3N+4K, WHERE K IS THE NUMBER OF NONZEROES
188 
189 C IN THE STRICT UPPER TRIANGLE OF M
190 
191 C
192 
193 C ISP - INTEGER ONE-DIMENSIONAL ARRAY USED FOR WORKING STORAGE;
194 
195 C DIMENSION = NSP
196 
197 C
198 
199 C PATH - INTEGER PATH SPECIFICATION; VALUES AND THEIR MEANINGS ARE -
200 
201 C 1 FIND MINIMUM DEGREE ORDERING ONLY
202 
203 C 2 FIND MINIMUM DEGREE ORDERING AND REORDER SYMMETRICALLY
204 
205 C STORED MATRIX (USED WHEN ONLY THE NONZERO ENTRIES IN
206 
207 C THE UPPER TRIANGLE OF M ARE BEING STORED)
208 
209 C 3 REORDER SYMMETRICALLY STORED MATRIX AS SPECIFIED BY
210 
211 C INPUT PERMUTATION (USED WHEN AN ORDERING HAS ALREADY
212 
213 C BEEN DETERMINED AND ONLY THE NONZERO ENTRIES IN THE
214 
215 C UPPER TRIANGLE OF M ARE BEING STORED)
216 
217 C 4 SAME AS 2 BUT PUT DIAGONAL ENTRIES AT START OF EACH ROW
218 
219 C 5 SAME AS 3 BUT PUT DIAGONAL ENTRIES AT START OF EACH ROW
220 
221 C
222 
223 C FLAG - INTEGER ERROR FLAG; VALUES AND THEIR MEANINGS ARE -
224 
225 C 0 NO ERRORS DETECTED
226 
227 C 9N+K INSUFFICIENT STORAGE IN MD
228 
229 C 10N+1 INSUFFICIENT STORAGE IN ODRV
230 
231 C 11N+1 ILLEGAL PATH SPECIFICATION
232 
233 C
234 
235 C
236 
237 C CONVERSION FROM REAL TO DOUBLE PRECISION
238 
239 C
240 
241 C CHANGE THE REAL DECLARATIONS IN ODRV AND SRO TO DOUBLE PRECISION
242 
243 C DECLARATIONS.
244 
245 C
246 
247 C-----------------------------------------------------------------------
248 
249 C
250 
251  INTEGER ia(n+1), ja(*), p(n), ip(n), isp(nsp), path, flag,
252 
253  * v, l, head, tmp, q
254 
255 C... REAL A(1)
256 
257  DOUBLE PRECISION a(*)
258 
259  LOGICAL dflag
260 
261 C
262 
263 C----INITIALIZE ERROR FLAG AND VALIDATE PATH SPECIFICATION
264 
265  flag = 0
266 
267  IF (path.LT.1 .OR. 5.LT.path) go to 111
268 
269 C
270 
271 C----ALLOCATE STORAGE AND FIND MINIMUM DEGREE ORDERING
272 
273  IF ((path-1) * (path-2) * (path-4) .NE. 0) go to 1
274 
275  max = (nsp-n)/2
276 
277  v = 1
278 
279  l = v + max
280 
281  head = l + max
282 
283  next = head + n
284 
285  IF (max.LT.n) go to 110
286 
287 C
288 
289  CALL md
290 
291  * (n, ia,ja, max,isp(v),isp(l), isp(head),p,ip, isp(v), flag)
292 
293  IF (flag.NE.0) go to 100
294 
295 C
296 
297 C----ALLOCATE STORAGE AND SYMMETRICALLY REORDER MATRIX
298 
299  1 IF ((path-2) * (path-3) * (path-4) * (path-5) .NE. 0) go to 2
300 
301  tmp = (nsp+1) - n
302 
303  q = tmp - (ia(n+1)-1)
304 
305  IF (q.LT.1) go to 110
306 
307 C
308 
309  dflag = path.EQ.4 .OR. path.EQ.5
310 
311  CALL sro
312 
313  * (n, ip, ia, ja, a, isp(tmp), isp(q), dflag)
314 
315 C
316 
317  2 RETURN
318 
319 C
320 
321 C ** ERROR -- ERROR DETECTED IN MD
322 
323  100 RETURN
324 
325 C ** ERROR -- INSUFFICIENT STORAGE
326 
327  110 flag = 10*n + 1
328 
329  RETURN
330 
331 C ** ERROR -- ILLEGAL PATH SPECIFIED
332 
333  111 flag = 11*n + 1
334 
335  RETURN
336 
337  END
338 
339 C***********************************************************************
340 
341 C***********************************************************************
342 
343 C MD -- MINIMUM DEGREE ALGORITHM (BASED ON ELEMENT MODEL)
344 
345 C***********************************************************************
346 
347  SUBROUTINE md
348 
349  * (n, ia,ja, max, v,l, head,last,next, mark, flag)
350 
351 C
352 
353 C DESCRIPTION
354 
355 C
356 
357 C MD FINDS A MINIMUM DEGREE ORDERING OF THE ROWS AND COLUMNS OF A
358 
359 C SYMMETRIC MATRIX M STORED IN (IA,JA,A) FORMAT.
360 
361 C
362 
363 C
364 
365 C ADDITIONAL PARAMETERS
366 
367 C
368 
369 C MAX - DECLARED DIMENSION OF THE ONE-DIMENSIONAL ARRAYS V AND L;
370 
371 C MAX MUST BE AT LEAST N+2K, WHERE K IS THE NUMBER OF
372 
373 C NONZEROES IN THE STRICT UPPER TRIANGLE OF M
374 
375 C
376 
377 C V - INTEGER ONE-DIMENSIONAL WORK ARRAY; DIMENSION = MAX
378 
379 C
380 
381 C L - INTEGER ONE-DIMENSIONAL WORK ARRAY; DIMENSION = MAX
382 
383 C
384 
385 C HEAD - INTEGER ONE-DIMENSIONAL WORK ARRAY; DIMENSION = N
386 
387 C
388 
389 C LAST - INTEGER ONE-DIMENSIONAL ARRAY USED TO RETURN THE PERMUTATION
390 
391 C OF THE ROWS AND COLUMNS OF M CORRESPONDING TO THE MINIMUM
392 
393 C DEGREE ORDERING; DIMENSION = N
394 
395 C
396 
397 C NEXT - INTEGER ONE-DIMENSIONAL ARRAY USED TO RETURN THE INVERSE OF
398 
399 C THE PERMUTATION RETURNED IN LAST; DIMENSION = N
400 
401 C
402 
403 C MARK - INTEGER ONE-DIMENSIONAL WORK ARRAY (MAY BE THE SAME AS V);
404 
405 C DIMENSION = N
406 
407 C
408 
409 C FLAG - INTEGER ERROR FLAG; VALUES AND THEIR MEANINGS ARE -
410 
411 C 0 NO ERRORS DETECTED
412 
413 C 11N+1 INSUFFICIENT STORAGE IN MD
414 
415 C
416 
417 C
418 
419 C DEFINITIONS OF INTERNAL PARAMETERS
420 
421 C
422 
423 C ---------+---------------------------------------------------------
424 
425 C V(S) VALUE FIELD OF LIST ENTRY
426 
427 C ---------+---------------------------------------------------------
428 
429 C L(S) LINK FIELD OF LIST ENTRY (0 => END OF LIST)
430 
431 C ---------+---------------------------------------------------------
432 
433 C L(VI) POINTER TO ELEMENT LIST OF UNELIMINATED VERTEX VI
434 
435 C ---------+---------------------------------------------------------
436 
437 C L(EJ) POINTER TO BOUNDARY LIST OF ACTIVE ELEMENT EJ
438 
439 C ---------+---------------------------------------------------------
440 
441 C HEAD(D) VJ => VJ HEAD OF D-LIST D
442 
443 C 0 => NO VERTEX IN D-LIST D
444 
445 C
446 
447 C
448 
449 C VI UNELIMINATED VERTEX
450 
451 C VI IN EK VI NOT IN EK
452 
453 C ---------+-----------------------------+---------------------------
454 
455 C NEXT(VI) UNDEFINED BUT NONNEGATIVE VJ => VJ NEXT IN D-LIST
456 
457 C 0 => VI TAIL OF D-LIST
458 
459 C ---------+-----------------------------+---------------------------
460 
461 C LAST(VI) (NOT SET UNTIL MDP) -D => VI HEAD OF D-LIST D
462 
463 C -VK => COMPUTE DEGREE VJ => VJ LAST IN D-LIST
464 
465 C EJ => VI PROTOTYPE OF EJ 0 => VI NOT IN ANY D-LIST
466 
467 C 0 => DO NOT COMPUTE DEGREE
468 
469 C ---------+-----------------------------+---------------------------
470 
471 C MARK(VI) MARK(VK) NONNEGATIVE TAG < MARK(VK)
472 
473 C
474 
475 C
476 
477 C VI ELIMINATED VERTEX
478 
479 C EI ACTIVE ELEMENT OTHERWISE
480 
481 C ---------+-----------------------------+---------------------------
482 
483 C NEXT(VI) -J => VI WAS J-TH VERTEX -J => VI WAS J-TH VERTEX
484 
485 C TO BE ELIMINATED TO BE ELIMINATED
486 
487 C ---------+-----------------------------+---------------------------
488 
489 C LAST(VI) M => SIZE OF EI = M UNDEFINED
490 
491 C ---------+-----------------------------+---------------------------
492 
493 C MARK(VI) -M => OVERLAP COUNT OF EI UNDEFINED
494 
495 C WITH EK = M
496 
497 C OTHERWISE NONNEGATIVE TAG
498 
499 C < MARK(VK)
500 
501 C
502 
503 C-----------------------------------------------------------------------
504 
505 C
506 
507  INTEGER ia(*), ja(*), v(*), l(*), head(*), last(*), next(*),
508 
509  * mark(*), flag, tag, dmin, vk,ek, tail
510 
511 C
512 
513 C----INITIALIZATION
514 
515  tag = 0
516 
517  CALL mdi
518 
519  * (n, ia,ja, max,v,l, head,last,next, mark,tag, flag)
520 
521  IF (flag.NE.0) RETURN
522 
523 C
524 
525  k = 0
526 
527  dmin = 1
528 
529 C
530 
531 C----WHILE K < N DO
532 
533  1 IF (k.GE.n) go to 4
534 
535 C
536 
537 C------SEARCH FOR VERTEX OF MINIMUM DEGREE
538 
539  2 IF (head(dmin).GT.0) go to 3
540 
541  dmin = dmin + 1
542 
543  go to 2
544 
545 C
546 
547 C------REMOVE VERTEX VK OF MINIMUM DEGREE FROM DEGREE LIST
548 
549  3 vk = head(dmin)
550 
551  head(dmin) = next(vk)
552 
553  IF (head(dmin).GT.0) last(head(dmin)) = -dmin
554 
555 C
556 
557 C------NUMBER VERTEX VK, ADJUST TAG, AND TAG VK
558 
559  k = k+1
560 
561  next(vk) = -k
562 
563  last(vk) = dmin - 1
564 
565  tag = tag + last(vk)
566 
567  mark(vk) = tag
568 
569 C
570 
571 C------FORM ELEMENT EK FROM UNELIMINATED NEIGHBORS OF VK
572 
573  CALL mdm
574 
575  * (vk,tail, v,l, last,next, mark)
576 
577 C
578 
579 C------PURGE INACTIVE ELEMENTS AND DO MASS ELIMINATION
580 
581  CALL mdp
582 
583  * (k,vk,tail, v,l, head,last,next, mark)
584 
585 C
586 
587 C------UPDATE DEGREES OF UNELIMINATED VERTICES IN EK
588 
589  CALL mdu
590 
591  * (vk,dmin, v,l, head,last,next, mark)
592 
593 C
594 
595  go to 1
596 
597 C
598 
599 C----GENERATE INVERSE PERMUTATION FROM PERMUTATION
600 
601  4 DO 5 k=1,n
602 
603  next(k) = -next(k)
604 
605  5 last(next(k)) = k
606 
607 C
608 
609  RETURN
610 
611  END
612 
613 C
614 
615 C***********************************************************************
616 
617 C MDI -- INITIALIZATION
618 
619 C***********************************************************************
620 
621  SUBROUTINE mdi
622 
623  * (n, ia,ja, max,v,l, head,last,next, mark,tag, flag)
624 
625  INTEGER ia(*), ja(*), v(*), l(*), head(*), last(*), next(*),
626 
627  * mark(*), tag, flag, sfs, vi,dvi, vj
628 
629 C
630 
631 C----INITIALIZE DEGREES, ELEMENT LISTS, AND DEGREE LISTS
632 
633  DO 1 vi=1,n
634 
635  mark(vi) = 1
636 
637  l(vi) = 0
638 
639  1 head(vi) = 0
640 
641  sfs = n+1
642 
643 C
644 
645 C----CREATE NONZERO STRUCTURE
646 
647 C----FOR EACH NONZERO ENTRY A(VI,VJ) IN STRICT UPPER TRIANGLE
648 
649  DO 3 vi=1,n
650 
651  jmin = ia(vi)
652 
653  jmax = ia(vi+1) - 1
654 
655  IF (jmin.GT.jmax) go to 3
656 
657  DO 2 j=jmin,jmax
658 
659  vj = ja(j)
660 
661  IF (vi.GE.vj) go to 2
662 
663  IF (sfs.GE.max) go to 101
664 
665 C
666 
667 C------ENTER VJ IN ELEMENT LIST FOR VI
668 
669  mark(vi) = mark(vi) + 1
670 
671  v(sfs) = vj
672 
673  l(sfs) = l(vi)
674 
675  l(vi) = sfs
676 
677  sfs = sfs+1
678 
679 C
680 
681 C------ENTER VI IN ELEMENT LIST FOR VJ
682 
683  mark(vj) = mark(vj) + 1
684 
685  v(sfs) = vi
686 
687  l(sfs) = l(vj)
688 
689  l(vj) = sfs
690 
691  sfs = sfs+1
692 
693  2 CONTINUE
694 
695  3 CONTINUE
696 
697 C
698 
699 C----CREATE DEGREE LISTS AND INITIALIZE MARK VECTOR
700 
701  DO 4 vi=1,n
702 
703  dvi = mark(vi)
704 
705  next(vi) = head(dvi)
706 
707  head(dvi) = vi
708 
709  last(vi) = -dvi
710 
711  IF (next(vi).GT.0) last(next(vi)) = vi
712 
713  4 mark(vi) = tag
714 
715 C
716 
717  RETURN
718 
719 C
720 
721 C ** ERROR -- INSUFFICIENT STORAGE
722 
723  101 flag = 9*n + vi
724 
725  RETURN
726 
727  END
728 
729 C
730 
731 C***********************************************************************
732 
733 C MDM -- FORM ELEMENT FROM UNELIMINATED NEIGHBORS OF VK
734 
735 C***********************************************************************
736 
737  SUBROUTINE mdm
738 
739  * (vk,tail, v,l, last,next, mark)
740 
741  INTEGER vk, tail, v(*), l(*), last(*), next(*), mark(*),
742 
743  * tag, s,ls,vs,es, b,lb,vb, blp,blpmax
744 
745 C
746 
747 C----INITIALIZE TAG AND LIST OF UNELIMINATED NEIGHBORS
748 
749  tag = mark(vk)
750 
751  tail = vk
752 
753 C
754 
755 C----FOR EACH VERTEX/ELEMENT VS/ES IN ELEMENT LIST OF VK
756 
757  ls = l(vk)
758 
759  1 s = ls
760 
761  IF (s.EQ.0) go to 5
762 
763  ls = l(s)
764 
765  vs = v(s)
766 
767  IF (next(vs).LT.0) go to 2
768 
769 C
770 
771 C------IF VS IS UNELIMINATED VERTEX, THEN TAG AND APPEND TO LIST OF
772 
773 C------UNELIMINATED NEIGHBORS
774 
775  mark(vs) = tag
776 
777  l(tail) = s
778 
779  tail = s
780 
781  go to 4
782 
783 C
784 
785 C------IF ES IS ACTIVE ELEMENT, THEN ...
786 
787 C--------FOR EACH VERTEX VB IN BOUNDARY LIST OF ELEMENT ES
788 
789  2 lb = l(vs)
790 
791  blpmax = last(vs)
792 
793  DO 3 blp=1,blpmax
794 
795  b = lb
796 
797  lb = l(b)
798 
799  vb = v(b)
800 
801 C
802 
803 C----------IF VB IS UNTAGGED VERTEX, THEN TAG AND APPEND TO LIST OF
804 
805 C----------UNELIMINATED NEIGHBORS
806 
807  IF (mark(vb).GE.tag) go to 3
808 
809  mark(vb) = tag
810 
811  l(tail) = b
812 
813  tail = b
814 
815  3 CONTINUE
816 
817 C
818 
819 C--------MARK ES INACTIVE
820 
821  mark(vs) = tag
822 
823 C
824 
825  4 go to 1
826 
827 C
828 
829 C----TERMINATE LIST OF UNELIMINATED NEIGHBORS
830 
831  5 l(tail) = 0
832 
833 C
834 
835  RETURN
836 
837  END
838 
839 C
840 
841 C***********************************************************************
842 
843 C MDP -- PURGE INACTIVE ELEMENTS AND DO MASS ELIMINATION
844 
845 C***********************************************************************
846 
847  SUBROUTINE mdp
848 
849  * (k,ek,tail, v,l, head,last,next, mark)
850 
851  INTEGER ek, tail, v(*), l(*), head(*), last(*), next(*),
852 
853  * mark(*), tag, free, li,vi,lvi,evi, s,ls,vs, ilp,ilpmax
854 
855 C
856 
857 C----INITIALIZE TAG
858 
859  tag = mark(ek)
860 
861 C
862 
863 C----FOR EACH VERTEX VI IN EK
864 
865  li = ek
866 
867  ilpmax = last(ek)
868 
869  IF (ilpmax.LE.0) go to 12
870 
871  DO 11 ilp=1,ilpmax
872 
873  i = li
874 
875  li = l(i)
876 
877  vi = v(li)
878 
879 C
880 
881 C------REMOVE VI FROM DEGREE LIST
882 
883  IF (last(vi).EQ.0) go to 3
884 
885  IF (last(vi).GT.0) go to 1
886 
887  head(-last(vi)) = next(vi)
888 
889  go to 2
890 
891  1 next(last(vi)) = next(vi)
892 
893  2 IF (next(vi).GT.0) last(next(vi)) = last(vi)
894 
895 C
896 
897 C------REMOVE INACTIVE ITEMS FROM ELEMENT LIST OF VI
898 
899  3 ls = vi
900 
901  4 s = ls
902 
903  ls = l(s)
904 
905  IF (ls.EQ.0) go to 6
906 
907  vs = v(ls)
908 
909  IF (mark(vs).LT.tag) go to 5
910 
911  free = ls
912 
913  l(s) = l(ls)
914 
915  ls = s
916 
917  5 go to 4
918 
919 C
920 
921 C------IF VI IS INTERIOR VERTEX, THEN REMOVE FROM LIST AND ELIMINATE
922 
923  6 lvi = l(vi)
924 
925  IF (lvi.NE.0) go to 7
926 
927  l(i) = l(li)
928 
929  li = i
930 
931 C
932 
933  k = k+1
934 
935  next(vi) = -k
936 
937  last(ek) = last(ek) - 1
938 
939  go to 11
940 
941 C
942 
943 C------ELSE ...
944 
945 C--------CLASSIFY VERTEX VI
946 
947  7 IF (l(lvi).NE.0) go to 9
948 
949  evi = v(lvi)
950 
951  IF (next(evi).GE.0) go to 9
952 
953  IF (mark(evi).LT.0) go to 8
954 
955 C
956 
957 C----------IF VI IS PROTOTYPE VERTEX, THEN MARK AS SUCH, INITIALIZE
958 
959 C----------OVERLAP COUNT FOR CORRESPONDING ELEMENT, AND MOVE VI TO END
960 
961 C----------OF BOUNDARY LIST
962 
963  last(vi) = evi
964 
965  mark(evi) = -1
966 
967  l(tail) = li
968 
969  tail = li
970 
971  l(i) = l(li)
972 
973  li = i
974 
975  go to 10
976 
977 C
978 
979 C----------ELSE IF VI IS DUPLICATE VERTEX, THEN MARK AS SUCH AND ADJUST
980 
981 C----------OVERLAP COUNT FOR CORRESPONDING ELEMENT
982 
983  8 last(vi) = 0
984 
985  mark(evi) = mark(evi) - 1
986 
987  go to 10
988 
989 C
990 
991 C----------ELSE MARK VI TO COMPUTE DEGREE
992 
993  9 last(vi) = -ek
994 
995 C
996 
997 C--------INSERT EK IN ELEMENT LIST OF VI
998 
999  10 v(free) = ek
1000 
1001  l(free) = l(vi)
1002 
1003  l(vi) = free
1004 
1005  11 CONTINUE
1006 
1007 C
1008 
1009 C----TERMINATE BOUNDARY LIST
1010 
1011  12 l(tail) = 0
1012 
1013 C
1014 
1015  RETURN
1016 
1017  END
1018 
1019 C
1020 
1021 C***********************************************************************
1022 
1023 C MDU -- UPDATE DEGREES OF UNELIMINATED VERTICES IN EK
1024 
1025 C***********************************************************************
1026 
1027  SUBROUTINE mdu
1028 
1029  * (ek,dmin, v,l, head,last,next, mark)
1030 
1031  INTEGER ek, dmin, v(*), l(*), head(*), last(*), next(*),
1032 
1033  * mark(*), tag, vi,evi,dvi, s,vs,es, b,vb, ilp,ilpmax,
1034 
1035  * blp,blpmax
1036 
1037 C
1038 
1039 C----INITIALIZE TAG
1040 
1041  tag = mark(ek) - last(ek)
1042 
1043 C
1044 
1045 C----FOR EACH VERTEX VI IN EK
1046 
1047  i = ek
1048 
1049  ilpmax = last(ek)
1050 
1051  IF (ilpmax.LE.0) go to 11
1052 
1053  DO 10 ilp=1,ilpmax
1054 
1055  i = l(i)
1056 
1057  vi = v(i)
1058 
1059  IF (last(vi)) 1, 10, 8
1060 
1061 C
1062 
1063 C------IF VI NEITHER PROTOTYPE NOR DUPLICATE VERTEX, THEN MERGE ELEMENTS
1064 
1065 C------TO COMPUTE DEGREE
1066 
1067  1 tag = tag + 1
1068 
1069  dvi = last(ek)
1070 
1071 C
1072 
1073 C--------FOR EACH VERTEX/ELEMENT VS/ES IN ELEMENT LIST OF VI
1074 
1075  s = l(vi)
1076 
1077  2 s = l(s)
1078 
1079  IF (s.EQ.0) go to 9
1080 
1081  vs = v(s)
1082 
1083  IF (next(vs).LT.0) go to 3
1084 
1085 C
1086 
1087 C----------IF VS IS UNELIMINATED VERTEX, THEN TAG AND ADJUST DEGREE
1088 
1089  mark(vs) = tag
1090 
1091  dvi = dvi + 1
1092 
1093  go to 5
1094 
1095 C
1096 
1097 C----------IF ES IS ACTIVE ELEMENT, THEN EXPAND
1098 
1099 C------------CHECK FOR OUTMATCHED VERTEX
1100 
1101  3 IF (mark(vs).LT.0) go to 6
1102 
1103 C
1104 
1105 C------------FOR EACH VERTEX VB IN ES
1106 
1107  b = vs
1108 
1109  blpmax = last(vs)
1110 
1111  DO 4 blp=1,blpmax
1112 
1113  b = l(b)
1114 
1115  vb = v(b)
1116 
1117 C
1118 
1119 C--------------IF VB IS UNTAGGED, THEN TAG AND ADJUST DEGREE
1120 
1121  IF (mark(vb).GE.tag) go to 4
1122 
1123  mark(vb) = tag
1124 
1125  dvi = dvi + 1
1126 
1127  4 CONTINUE
1128 
1129 C
1130 
1131  5 go to 2
1132 
1133 C
1134 
1135 C------ELSE IF VI IS OUTMATCHED VERTEX, THEN ADJUST OVERLAPS BUT DO NOT
1136 
1137 C------COMPUTE DEGREE
1138 
1139  6 last(vi) = 0
1140 
1141  mark(vs) = mark(vs) - 1
1142 
1143  7 s = l(s)
1144 
1145  IF (s.EQ.0) go to 10
1146 
1147  vs = v(s)
1148 
1149  IF (mark(vs).LT.0) mark(vs) = mark(vs) - 1
1150 
1151  go to 7
1152 
1153 C
1154 
1155 C------ELSE IF VI IS PROTOTYPE VERTEX, THEN CALCULATE DEGREE BY
1156 
1157 C------INCLUSION/EXCLUSION AND RESET OVERLAP COUNT
1158 
1159  8 evi = last(vi)
1160 
1161  dvi = last(ek) + last(evi) + mark(evi)
1162 
1163  mark(evi) = 0
1164 
1165 C
1166 
1167 C------INSERT VI IN APPROPRIATE DEGREE LIST
1168 
1169  9 next(vi) = head(dvi)
1170 
1171  head(dvi) = vi
1172 
1173  last(vi) = -dvi
1174 
1175  IF (next(vi).GT.0) last(next(vi)) = vi
1176 
1177  IF (dvi.LT.dmin) dmin = dvi
1178 
1179 C
1180 
1181  10 CONTINUE
1182 
1183 C
1184 
1185  11 RETURN
1186 
1187  END
1188 
1189 C***********************************************************************
1190 
1191 C***********************************************************************
1192 
1193 C SRO -- SYMMETRIC REORDERING OF SPARSE SYMMETRIC MATRIX
1194 
1195 C***********************************************************************
1196 
1197  SUBROUTINE sro
1198 
1199  * (n, ip, ia,ja,a, q, r, dflag)
1200 
1201 C
1202 
1203 C DESCRIPTION
1204 
1205 C
1206 
1207 C THE NONZERO ENTRIES OF THE MATRIX M ARE ASSUMED TO BE STORED
1208 
1209 C SYMMETRICALLY IN (IA,JA,A) FORMAT (I.E., NOT BOTH M(I,J) AND M(J,I)
1210 
1211 C ARE STORED IF I NE J).
1212 
1213 C
1214 
1215 C SRO DOES NOT REARRANGE THE ORDER OF THE ROWS, BUT DOES MOVE
1216 
1217 C NONZEROES FROM ONE ROW TO ANOTHER TO ENSURE THAT IF M(I,J) WILL BE
1218 
1219 C IN THE UPPER TRIANGLE OF M WITH RESPECT TO THE NEW ORDERING, THEN
1220 
1221 C M(I,J) IS STORED IN ROW I (AND THUS M(J,I) IS NOT STORED); WHEREAS
1222 
1223 C IF M(I,J) WILL BE IN THE STRICT LOWER TRIANGLE OF M, THEN M(J,I) IS
1224 
1225 C STORED IN ROW J (AND THUS M(I,J) IS NOT STORED).
1226 
1227 C
1228 
1229 C
1230 
1231 C ADDITIONAL PARAMETERS
1232 
1233 C
1234 
1235 C Q - INTEGER ONE-DIMENSIONAL WORK ARRAY; DIMENSION = N
1236 
1237 C
1238 
1239 C R - INTEGER ONE-DIMENSIONAL WORK ARRAY; DIMENSION = NUMBER OF
1240 
1241 C NONZERO ENTRIES IN THE UPPER TRIANGLE OF M
1242 
1243 C
1244 
1245 C DFLAG - LOGICAL VARIABLE; IF DFLAG = .TRUE., THEN STORE NONZERO
1246 
1247 C DIAGONAL ELEMENTS AT THE BEGINNING OF THE ROW
1248 
1249 C
1250 
1251 C-----------------------------------------------------------------------
1252 
1253 C
1254 
1255  INTEGER ip(*), ia(*), ja(*), q(*), r(*)
1256 
1257 C... REAL A(1), AK
1258 
1259  DOUBLE PRECISION a(*), ak
1260 
1261  LOGICAL dflag
1262 
1263 C
1264 
1265 C
1266 
1267 C--PHASE 1 -- FIND ROW IN WHICH TO STORE EACH NONZERO
1268 
1269 C----INITIALIZE COUNT OF NONZEROES TO BE STORED IN EACH ROW
1270 
1271  DO 1 i=1,n
1272 
1273  1 q(i) = 0
1274 
1275 C
1276 
1277 C----FOR EACH NONZERO ELEMENT A(J)
1278 
1279  DO 3 i=1,n
1280 
1281  jmin = ia(i)
1282 
1283  jmax = ia(i+1) - 1
1284 
1285  IF (jmin.GT.jmax) go to 3
1286 
1287  DO 2 j=jmin,jmax
1288 
1289 C
1290 
1291 C--------FIND ROW (=R(J)) AND COLUMN (=JA(J)) IN WHICH TO STORE A(J) ...
1292 
1293  k = ja(j)
1294 
1295  IF (ip(k).LT.ip(i)) ja(j) = i
1296 
1297  IF (ip(k).GE.ip(i)) k = i
1298 
1299  r(j) = k
1300 
1301 C
1302 
1303 C--------... AND INCREMENT COUNT OF NONZEROES (=Q(R(J)) IN THAT ROW
1304 
1305  2 q(k) = q(k) + 1
1306 
1307  3 CONTINUE
1308 
1309 C
1310 
1311 C
1312 
1313 C--PHASE 2 -- FIND NEW IA AND PERMUTATION TO APPLY TO (JA,A)
1314 
1315 C----DETERMINE POINTERS TO DELIMIT ROWS IN PERMUTED (JA,A)
1316 
1317  DO 4 i=1,n
1318 
1319  ia(i+1) = ia(i) + q(i)
1320 
1321  4 q(i) = ia(i+1)
1322 
1323 C
1324 
1325 C----DETERMINE WHERE EACH (JA(J),A(J)) IS STORED IN PERMUTED (JA,A)
1326 
1327 C----FOR EACH NONZERO ELEMENT (IN REVERSE ORDER)
1328 
1329  ilast = 0
1330 
1331  jmin = ia(1)
1332 
1333  jmax = ia(n+1) - 1
1334 
1335  j = jmax
1336 
1337  DO 6 jdummy=jmin,jmax
1338 
1339  i = r(j)
1340 
1341  IF (.NOT.dflag .OR. ja(j).NE.i .OR. i.EQ.ilast) go to 5
1342 
1343 C
1344 
1345 C------IF DFLAG, THEN PUT DIAGONAL NONZERO AT BEGINNING OF ROW
1346 
1347  r(j) = ia(i)
1348 
1349  ilast = i
1350 
1351  go to 6
1352 
1353 C
1354 
1355 C------PUT (OFF-DIAGONAL) NONZERO IN LAST UNUSED LOCATION IN ROW
1356 
1357  5 q(i) = q(i) - 1
1358 
1359  r(j) = q(i)
1360 
1361 C
1362 
1363  6 j = j-1
1364 
1365 C
1366 
1367 C
1368 
1369 C--PHASE 3 -- PERMUTE (JA,A) TO UPPER TRIANGULAR FORM (WRT NEW ORDERING)
1370 
1371  DO 8 j=jmin,jmax
1372 
1373  7 IF (r(j).EQ.j) go to 8
1374 
1375  k = r(j)
1376 
1377  r(j) = r(k)
1378 
1379  r(k) = k
1380 
1381  jak = ja(k)
1382 
1383  ja(k) = ja(j)
1384 
1385  ja(j) = jak
1386 
1387  ak = a(k)
1388 
1389  a(k) = a(j)
1390 
1391  a(j) = ak
1392 
1393  go to 7
1394 
1395  8 CONTINUE
1396 
1397 C
1398 
1399  RETURN
1400 
1401  END
1402 
1403 C 1/15/81
1404 
1405 C***********************************************************************
1406 
1407 C SDRV -- DRIVER FOR SPARSE SYMMETRIC POSITIVE DEFINITE MATRIX ROUTINES
1408 
1409 C***********************************************************************
1410 
1411  SUBROUTINE sdrvd
1412 
1413  * (n, p,ip, ia,ja,a, b, z, nsp,isp,rsp,esp, path, flag)
1414 
1415 C
1416 
1417 C DESCRIPTION
1418 
1419 C
1420 
1421 C SDRV SOLVES SPARSE SYMMETRIC POSITIVE DEFINITE SYSTEMS OF LINEAR
1422 
1423 C EQUATIONS. THE SOLUTION PROCESS IS DIVIDED INTO THREE STAGES --
1424 
1425 C
1426 
1427 C SSF - THE COEFFICIENT MATRIX M IS FACTORED SYMBOLICALLY TO
1428 
1429 C DETERMINE WHERE FILLIN WILL OCCUR DURING THE NUMERIC
1430 
1431 C FACTORIZATION.
1432 
1433 C
1434 
1435 C SNF - M IS FACTORED NUMERICALLY INTO THE PRODUCT UT-D-U, WHERE
1436 
1437 C D IS DIAGONAL AND U IS UNIT UPPER TRIANGULAR.
1438 
1439 C
1440 
1441 C SNS - THE LINEAR SYSTEM MX = B IS SOLVED USING THE UT-D-U
1442 
1443 C FACTORIZATION FROM SNF.
1444 
1445 C
1446 
1447 C FOR SEVERAL SYSTEMS WITH THE SAME COEFFICIENT MATRIX, SSF AND SNF
1448 
1449 C NEED BE DONE ONLY ONCE (FOR THE FIRST SYSTEM); THEN SNS IS DONE
1450 
1451 C ONCE FOR EACH ADDITIONAL RIGHT-HAND SIDE. FOR SEVERAL SYSTEMS
1452 
1453 C WHOSE COEFFICIENT MATRICES HAVE THE SAME NONZERO STRUCTURE, SSF
1454 
1455 C NEED BE DONE ONLY ONCE (FOR THE FIRST SYSTEM); THEN SNF AND SNS
1456 
1457 C ARE DONE ONCE FOR EACH ADDITIONAL SYSTEM.
1458 
1459 C
1460 
1461 C
1462 
1463 C STORAGE OF SPARSE MATRICES
1464 
1465 C
1466 
1467 C THE NONZERO ENTRIES OF THE MATRIX M ARE STORED ROW-BY-ROW IN THE
1468 
1469 C ARRAY A. TO IDENTIFY THE INDIVIDUAL NONZERO ENTRIES IN EACH ROW,
1470 
1471 C WE NEED TO KNOW IN WHICH COLUMN EACH ENTRY LIES. THESE COLUMN
1472 
1473 C INDICES ARE STORED IN THE ARRAY JA; I.E., IF A(K) = M(I,J), THEN
1474 
1475 C JA(K) = J. TO IDENTIFY THE INDIVIDUAL ROWS, WE NEED TO KNOW WHERE
1476 
1477 C EACH ROW STARTS. THESE ROW POINTERS ARE STORED IN THE ARRAY IA;
1478 
1479 C I.E., IF M(I,J) IS THE FIRST NONZERO ENTRY (STORED) IN THE I-TH ROW
1480 
1481 C AND A(K) = M(I,J), THEN IA(I) = K. MOREOVER, IA(N+1) POINTS TO
1482 
1483 C THE FIRST LOCATION FOLLOWING THE LAST ELEMENT IN THE LAST ROW.
1484 
1485 C THUS, THE NUMBER OF ENTRIES IN THE I-TH ROW IS IA(I+1) - IA(I),
1486 
1487 C THE NONZERO ENTRIES IN THE I-TH ROW ARE STORED CONSECUTIVELY IN
1488 
1489 C
1490 
1491 C A(IA(I)), A(IA(I)+1), ..., A(IA(I+1)-1),
1492 
1493 C
1494 
1495 C AND THE CORRESPONDING COLUMN INDICES ARE STORED CONSECUTIVELY IN
1496 
1497 C
1498 
1499 C JA(IA(I)), JA(IA(I)+1), ..., JA(IA(I+1)-1).
1500 
1501 C
1502 
1503 C SINCE THE COEFFICIENT MATRIX IS SYMMETRIC, ONLY THE NONZERO ENTRIES
1504 
1505 C IN THE UPPER TRIANGLE NEED BE STORED, FOR EXAMPLE, THE MATRIX
1506 
1507 C
1508 
1509 C ( 1 0 2 3 0 )
1510 
1511 C ( 0 4 0 0 0 )
1512 
1513 C M = ( 2 0 5 6 0 )
1514 
1515 C ( 3 0 6 7 8 )
1516 
1517 C ( 0 0 0 8 9 )
1518 
1519 C
1520 
1521 C COULD BE STORED AS
1522 
1523 C
1524 
1525 C 1 2 3 4 5 6 7 8 9 10 11 12 13
1526 
1527 C ---+--------------------------------------
1528 
1529 C IA 1 4 5 8 12 14
1530 
1531 C JA 1 3 4 2 1 3 4 1 3 4 5 4 5
1532 
1533 C A 1 2 3 4 2 5 6 3 6 7 8 8 9
1534 
1535 C
1536 
1537 C OR (SYMMETRICALLY) AS
1538 
1539 C
1540 
1541 C 1 2 3 4 5 6 7 8 9
1542 
1543 C ---+--------------------------
1544 
1545 C IA 1 4 5 7 9 10
1546 
1547 C JA 1 3 4 2 3 4 4 5 5
1548 
1549 C A 1 2 3 4 5 6 7 8 9 .
1550 
1551 C
1552 
1553 C
1554 
1555 C REORDERING THE ROWS AND COLUMNS OF M
1556 
1557 C
1558 
1559 C A SYMMETRIC PERMUTATION OF THE ROWS AND COLUMNS OF THE COEFFICIENT
1560 
1561 C MATRIX M (E.G., WHICH REDUCES FILLIN OR ENHANCES NUMERICAL
1562 
1563 C STABILITY) MUST BE SPECIFIED. THE SOLUTION Z IS RETURNED IN THE
1564 
1565 C ORIGINAL ORDER.
1566 
1567 C
1568 
1569 C TO SPECIFY THE TRIVIAL ORDERING (I.E., THE IDENTITY PERMUTATION),
1570 
1571 C SET P(I) = IP(I) = I, I=1,...,N. IN THIS CASE, P AND IP CAN BE
1572 
1573 C THE SAME ARRAY.
1574 
1575 C
1576 
1577 C IF A NONTRIVIAL ORDERING (I.E., NOT THE IDENTITY PERMUTATION) IS
1578 
1579 C SPECIFIED AND M IS STORED SYMMETRICALLY (I.E., NOT BOTH M(I,J) AND
1580 
1581 C M(J,I) ARE STORED FOR I NE J), THEN ODRV SHOULD BE CALLED (WITH
1582 
1583 C PATH = 3 OR 5) TO SYMMETRICALLY REORDER (IA,JA,A) BEFORE CALLING
1584 
1585 C SDRV. THIS IS TO ENSURE THAT IF M(I,J) WILL BE IN THE UPPER
1586 
1587 C TRIANGLE OF M WITH RESPECT TO THE NEW ORDERING, THEN M(I,J) IS
1588 
1589 C STORED IN ROW I (AND THUS M(J,I) IS NOT STORED); WHEREAS IF M(I,J)
1590 
1591 C WILL BE IN THE STRICT LOWER TRIANGLE OF M, THEN M(J,I) IS STORED IN
1592 
1593 C ROW J (AND THUS M(I,J) IS NOT STORED).
1594 
1595 C
1596 
1597 C
1598 
1599 C PARAMETERS
1600 
1601 C
1602 
1603 C N - NUMBER OF VARIABLES/EQUATIONS
1604 
1605 C
1606 
1607 C P - INTEGER ONE-DIMENSIONAL ARRAY SPECIFYING A PERMUTATION OF
1608 
1609 C THE ROWS AND COLUMNS OF M; DIMENSION = N
1610 
1611 C
1612 
1613 C IP - INTEGER ONE-DIMENSIONAL ARRAY CONTAINING THE INVERSE OF THE
1614 
1615 C PERMUTATION SPECIFIED IN P; I.E., IP(P(I)) = I, I=1,...,N;
1616 
1617 C DIMENSION = N
1618 
1619 C
1620 
1621 C IA - INTEGER ONE-DIMENSIONAL ARRAY CONTAINING POINTERS TO DELIMIT
1622 
1623 C ROWS IN JA AND A; DIMENSION = N+1
1624 
1625 C
1626 
1627 C JA - INTEGER ONE-DIMENSIONAL ARRAY CONTAINING THE COLUMN INDICES
1628 
1629 C CORRESPONDING TO THE ELEMENTS OF A; DIMENSION = NUMBER OF
1630 
1631 C NONZERO ENTRIES IN M STORED
1632 
1633 C
1634 
1635 C A - REAL ONE-DIMENSIONAL ARRAY CONTAINING THE NONZERO ENTRIES IN
1636 
1637 C THE COEFFICIENT MATRIX M, STORED BY ROWS; DIMENSION =
1638 
1639 C NUMBER OF NONZERO ENTRIES IN M STORED
1640 
1641 C
1642 
1643 C B - REAL ONE-DIMENSIONAL ARRAY CONTAINING THE RIGHT-HAND SIDE B;
1644 
1645 C B AND Z CAN BE THE SAME ARRAY; DIMENSION = N
1646 
1647 C
1648 
1649 C Z - REAL ONE-DIMENSIONAL ARRAY CONTAINING THE SOLUTION X; Z AND
1650 
1651 C B CAN BE THE SAME ARRAY; DIMENSION = N
1652 
1653 C
1654 
1655 C NSP - DECLARED DIMENSION OF THE ONE-DIMENSIONAL ARRAYS ISP AND
1656 
1657 C RSP; NSP MUST BE (SUBSTANTIALLY) LARGER THAN 3N+2K, WHERE
1658 
1659 C K = NUMBER OF NONZERO ENTRIES IN THE UPPER TRIANGLE OF M
1660 
1661 C
1662 
1663 C ISP - INTEGER ONE-DIMENSIONAL ARRAY USED FOR WORKING STORAGE; ISP
1664 
1665 C AND RSP SHOULD BE EQUIVALENCED; DIMENSION = NSP
1666 
1667 C
1668 
1669 C RSP - REAL ONE-DIMENSIONAL ARRAY USED FOR WORKING STORAGE; RSP
1670 
1671 C AND ISP SHOULD BE EQUIVALENCED; DIMENSION = NSP
1672 
1673 C
1674 
1675 C ESP - INTEGER VARIABLE; IF SUFFICIENT STORAGE WAS AVAILABLE TO
1676 
1677 C PERFORM THE SYMBOLIC FACTORIZATION (SSF), THEN ESP IS SET TO
1678 
1679 C THE AMOUNT OF EXCESS STORAGE PROVIDED (NEGATIVE IF
1680 
1681 C INSUFFICIENT STORAGE WAS AVAILABLE TO PERFORM THE NUMERIC
1682 
1683 C FACTORIZATION (SNF))
1684 
1685 C
1686 
1687 C PATH - INTEGER PATH SPECIFICATION; VALUES AND THEIR MEANINGS ARE -
1688 
1689 C 1 PERFORM SSF, SNF, AND SNS
1690 
1691 C 2 PERFORM SNF AND SNS (ISP/RSP IS ASSUMED TO HAVE BEEN
1692 
1693 C SET UP IN AN EARLIER CALL TO SDRV (FOR SSF))
1694 
1695 C 3 PERFORM SNS ONLY (ISP/RSP IS ASSUMED TO HAVE BEEN SET
1696 
1697 C UP IN AN EARLIER CALL TO SDRV (FOR SSF AND SNF))
1698 
1699 C 4 PERFORM SSF
1700 
1701 C 5 PERFORM SSF AND SNF
1702 
1703 C 6 PERFORM SNF ONLY (ISP/RSP IS ASSUMED TO HAVE BEEN SET
1704 
1705 C UP IN AN EARLIER CALL TO SDRV (FOR SSF))
1706 
1707 C
1708 
1709 C FLAG - INTEGER ERROR FLAG; VALUES AND THEIR MEANINGS ARE -
1710 
1711 C 0 NO ERRORS DETECTED
1712 
1713 C 2N+K DUPLICATE ENTRY IN A -- ROW = K
1714 
1715 C 6N+K INSUFFICIENT STORAGE IN SSF -- ROW = K
1716 
1717 C 7N+1 INSUFFICIENT STORAGE IN SNF
1718 
1719 C 8N+K ZERO PIVOT -- ROW = K
1720 
1721 C 10N+1 INSUFFICIENT STORAGE IN SDRV
1722 
1723 C 11N+1 ILLEGAL PATH SPECIFICATION
1724 
1725 C
1726 
1727 C
1728 
1729 C CONVERSION FROM REAL TO DOUBLE PRECISION
1730 
1731 C
1732 
1733 C CHANGE THE REAL DECLARATIONS IN SDRV, SNF, AND SNS TO DOUBLE
1734 
1735 C PRECISION DECLARATIONS; AND CHANGE THE VALUE IN THE DATA STATEMENT
1736 
1737 C FOR THE INTEGER VARIABLE RATIO (IN SDRV) FROM 1 TO 2.
1738 
1739 C
1740 
1741 C-----------------------------------------------------------------------
1742 
1743 C
1744 
1745  INTEGER p(*), ip(*), ia(*), ja(*), isp(*), esp, path, flag,
1746 
1747  * ratio, q, mark, d, u, tmp, umax
1748 
1749 C... REAL A(1), B(1), Z(1), RSP(1)
1750 
1751 C... DATA RATIO/1/
1752 
1753  DOUBLE PRECISION a(*), b(*), z(*), rsp(*)
1754 
1755  DATA ratio/1/
1756 
1757 C
1758 
1759 C----VALIDATE PATH SPECIFICATION
1760 
1761  IF (path.LT.1 .OR. 6.LT.path) go to 111
1762 
1763 C
1764 
1765 C----ALLOCATE STORAGE AND FACTOR M SYMBOLICALLY TO DETERMINE FILL-IN
1766 
1767  iju = 1
1768 
1769  iu = iju + n
1770 
1771  jl = iu + n+1
1772 
1773  ju = jl + n
1774 
1775  q = (nsp+1) - n
1776 
1777  mark = q - n
1778 
1779  jumax = mark - ju
1780 
1781 C
1782 
1783  IF ((path-1) * (path-4) * (path-5) .NE. 0) go to 1
1784 
1785  IF (jumax.LE.0) go to 110
1786 
1787  CALL ssf
1788 
1789  * (n, p, ip, ia, ja, isp(iju), isp(ju), isp(iu), jumax,
1790 
1791  * isp(q), isp(mark), isp(jl), flag)
1792 
1793  IF (flag.NE.0) go to 100
1794 
1795 C
1796 
1797 C----ALLOCATE STORAGE AND FACTOR M NUMERICALLY
1798 
1799  1 il = ju + isp(iju+(n-1))
1800 
1801  tmp = ((il-1)+(ratio-1)) / ratio + 1
1802 
1803  d = tmp + n
1804 
1805  u = d + n
1806 
1807  umax = (nsp+1) - u
1808 
1809  esp = umax - (isp(iu+n)-1)
1810 
1811 C
1812 
1813  IF ((path-1) * (path-2) * (path-5) * (path-6) .NE. 0) go to 2
1814 
1815  IF (umax.LE.0) go to 110
1816 
1817  CALL snf
1818 
1819  * (n, p, ip, ia, ja, a,
1820 
1821  * rsp(d), isp(iju), isp(ju), isp(iu), rsp(u), umax,
1822 
1823  * isp(il), isp(jl), flag)
1824 
1825  IF (flag.NE.0) go to 100
1826 
1827 C
1828 
1829 C----SOLVE SYSTEM OF LINEAR EQUATIONS MX = B
1830 
1831  2 IF ((path-1) * (path-2) * (path-3) .NE. 0) go to 3
1832 
1833  IF (umax.LE.0) go to 110
1834 
1835  CALL sns
1836 
1837  * (n, p, rsp(d), isp(iju), isp(ju), isp(iu), rsp(u), z, b,
1838 
1839  * rsp(tmp))
1840 
1841 C
1842 
1843  3 RETURN
1844 
1845 C
1846 
1847 C ** ERROR -- ERROR DETECTED IN SSF, SNF, OR SNS
1848 
1849  100 RETURN
1850 
1851 C ** ERROR -- INSUFFICIENT STORAGE
1852 
1853  110 flag = 10*n + 1
1854 
1855  RETURN
1856 
1857 C ** ERROR -- ILLEGAL PATH SPECIFICATION
1858 
1859  111 flag = 11*n + 1
1860 
1861  RETURN
1862 
1863  END
1864 
1865 C
1866 
1867 C
1868 
1869 C***********************************************************************
1870 
1871 C INTERNAL DOCUMENTATION FOR SSF, SNF, AND SNS
1872 
1873 C***********************************************************************
1874 
1875 C
1876 
1877 C COMPRESSED STORAGE OF SPARSE MATRICES
1878 
1879 C
1880 
1881 C THE STRICT UPPER TRIANGULAR PORTION OF THE MATRIX U IS STORED IN
1882 
1883 C (IA,JA,A) FORMAT USING THE ARRAYS IU, JU, AND U, EXCEPT THAT AN
1884 
1885 C ADDITIONAL ARRAY IJU IS USED TO REDUCE THE STORAGE REQUIRED FOR JU
1886 
1887 C BY ALLOWING SOME SEQUENCES OF COLUMN INDICES TO CORRESPOND TO MORE
1888 
1889 C THAN ONE ROW. FOR I < N, IJU(I) IS THE INDEX IN JU OF THE FIRST
1890 
1891 C ENTRY FOR THE I-TH ROW; IJU(N) IS THE NUMBER OF ENTRIES IN JU.
1892 
1893 C THUS, THE NUMBER OF ENTRIES IN THE I-TH ROW IS IU(I+1) - IU(I),
1894 
1895 C THE NONZERO ENTRIES OF THE I-TH ROW ARE STORED CONSECUTIVELY IN
1896 
1897 C
1898 
1899 C U(IU(I)), U(IU(I)+1), ..., U(IU(I+1)-1),
1900 
1901 C
1902 
1903 C AND THE CORRESPONDING COLUMN INDICES ARE STORED CONSECUTIVELY IN
1904 
1905 C
1906 
1907 C JU(IJU(I)), JU(IJU(I)+1), ..., JU(IJU(I)+IU(I+1)-IU(I)+1).
1908 
1909 C
1910 
1911 C COMPRESSION IN JU OCCURS IN TWO WAYS. FIRST, IF A ROW I WAS MERGED
1912 
1913 C INTO ROW K, AND THE NUMBER OF ELEMENTS MERGED IN FROM (THE TAIL
1914 
1915 C PORTION OF) ROW I IS THE SAME AS THE FINAL LENGTH OF ROW K, THEN
1916 
1917 C THE KTH ROW AND THE TAIL OF ROW I ARE IDENTICAL AND IJU(K) POINTS
1918 
1919 C TO THE START OF THE TAIL. SECOND, IF SOME TAIL PORTION OF THE
1920 
1921 C (K-1)ST ROW IS IDENTICAL TO THE HEAD OF THE KTH ROW, THEN IJU(K)
1922 
1923 C POINTS TO THE START OF THAT TAIL PORTION. FOR EXAMPLE, THE NONZERO
1924 
1925 C STRUCTURE OF THE STRICT UPPER TRIANGULAR PART OF THE MATRIX
1926 
1927 C
1928 
1929 C ( D 0 0 0 X X X )
1930 
1931 C ( 0 D 0 X X 0 0 )
1932 
1933 C ( 0 0 D 0 X X 0 )
1934 
1935 C U = ( 0 0 0 D X X 0 )
1936 
1937 C ( 0 0 0 0 D X X )
1938 
1939 C ( 0 0 0 0 0 D X )
1940 
1941 C ( 0 0 0 0 0 0 D )
1942 
1943 C
1944 
1945 C WOULD BE STORED AS
1946 
1947 C
1948 
1949 C 1 2 3 4 5 6 7 8
1950 
1951 C ----+------------------------
1952 
1953 C IU 1 4 6 8 10 12 12 12
1954 
1955 C JU 5 6 7 4 5 6
1956 
1957 C IJU 1 4 5 5 2 3 6 .
1958 
1959 C
1960 
1961 C THE DIAGONAL ENTRIES OF U ARE EQUAL TO ONE AND ARE NOT STORED.
1962 
1963 C
1964 
1965 C
1966 
1967 C ADDITIONAL PARAMETERS
1968 
1969 C
1970 
1971 C D - REAL ONE-DIMENSIONAL ARRAY CONTAINING THE RECIPROCALS OF
1972 
1973 C THE DIAGONAL ENTRIES OF THE MATRIX D; DIMENSION = N
1974 
1975 C
1976 
1977 C IJU - INTEGER ONE-DIMENSIONAL ARRAY CONTAINING POINTERS TO THE
1978 
1979 C START OF EACH ROW IN JU; DIMENSION = N
1980 
1981 C
1982 
1983 C IU - INTEGER ONE-DIMENSIONAL ARRAY CONTAINING POINTERS TO
1984 
1985 C DELIMIT ROWS IN U; DIMENSION = N+1
1986 
1987 C
1988 
1989 C JU - INTEGER ONE-DIMENSIONAL ARRAY CONTAINING THE COLUMN INDICES
1990 
1991 C CORRESPONDING TO THE ELEMENTS OF U; DIMENSION = JUMAX
1992 
1993 C
1994 
1995 C JUMAX - DECLARED DIMENSION OF THE ONE-DIMENSIONAL ARRAY JU; JUMAX
1996 
1997 C MUST BE AT LEAST THE SIZE OF U MINUS COMPRESSION (IJU(N)
1998 
1999 C AFTER THE CALL TO SSF)
2000 
2001 C
2002 
2003 C U - REAL ONE-DIMENSIONAL ARRAY CONTAINING THE NONZERO ENTRIES
2004 
2005 C IN THE STRICT UPPER TRIANGLE OF U, STORED BY ROWS;
2006 
2007 C DIMENSION = UMAX
2008 
2009 C
2010 
2011 C UMAX - DECLARED DIMENSION OF THE ONE-DIMENSIONAL ARRAY U; UMAX
2012 
2013 C MUST BE AT LEAST THE NUMBER OF NONZERO ENTRIES IN THE
2014 
2015 C STRICT UPPER TRIANGLE OF M PLUS FILLIN (IU(N+1)-1 AFTER THE
2016 
2017 C CALL TO SSF)
2018 
2019 C
2020 
2021 C
2022 
2023 C***********************************************************************
2024 
2025 C SSF -- SYMBOLIC UT-D-U FACTORIZATION OF SPARSE SYMMETRIC MATRIX
2026 
2027 C***********************************************************************
2028 
2029  SUBROUTINE ssf
2030 
2031  * (n, p,ip, ia,ja, iju,ju,iu,jumax, q, mark, jl, flag)
2032 
2033 C
2034 
2035 C ADDITIONAL PARAMETERS
2036 
2037 C
2038 
2039 C Q - INTEGER ONE-DIMENSIONAL WORK ARRAY; DIMENSION = N
2040 
2041 C
2042 
2043 C MARK - INTEGER ONE-DIMENSIONAL WORK ARRAY; DIMENSION = N
2044 
2045 C
2046 
2047 C JL - INTEGER ONE-DIMENSIONAL WORK ARRAY; DIMENSION = N
2048 
2049 C
2050 
2051 C
2052 
2053 C DEFINITIONS OF INTERNAL PARAMETERS (DURING K-TH STAGE OF ELIMINATION)
2054 
2055 C
2056 
2057 C Q CONTAINS AN ORDERED LINKED LIST REPRESENTATION OF THE NONZERO
2058 
2059 C STRUCTURE OF THE K-TH ROW OF U --
2060 
2061 C Q(K) IS THE FIRST COLUMN WITH A NONZERO ENTRY
2062 
2063 C Q(I) IS THE NEXT COLUMN WITH A NONZERO ENTRY AFTER COLUMN I
2064 
2065 C IN EITHER CASE, Q(I) = N+1 INDICATES THE END OF THE LIST
2066 
2067 C
2068 
2069 C JL CONTAINS LISTS OF ROWS TO BE MERGED INTO UNELIMINATED ROWS --
2070 
2071 C I GE K => JL(I) IS THE FIRST ROW TO BE MERGED INTO ROW I
2072 
2073 C I LT K => JL(I) IS THE ROW FOLLOWING ROW I IN SOME LIST OF ROWS
2074 
2075 C IN EITHER CASE, JL(I) = 0 INDICATES THE END OF A LIST
2076 
2077 C
2078 
2079 C MARK(I) IS THE LAST ROW STORED IN JU FOR WHICH U(MARK(I),I) NE 0
2080 
2081 C
2082 
2083 C JUMIN AND JUPTR ARE THE INDICES IN JU OF THE FIRST AND LAST
2084 
2085 C ELEMENTS IN THE LAST ROW SAVED IN JU
2086 
2087 C
2088 
2089 C LUK IS THE NUMBER OF NONZERO ENTRIES IN THE K-TH ROW
2090 
2091 C
2092 
2093 C-----------------------------------------------------------------------
2094 
2095 C
2096 
2097  INTEGER p(*), ip(*), ia(*), ja(*), iju(*), ju(*), iu(*),
2098 
2099  * q(*), mark(*), jl(*), flag, tag, vj, qm
2100 
2101  LOGICAL clique
2102 
2103 C
2104 
2105 C----INITIALIZATION
2106 
2107  jumin = 1
2108 
2109  juptr = 0
2110 
2111  iu(1) = 1
2112 
2113  DO 1 k=1,n
2114 
2115  mark(k) = 0
2116 
2117  1 jl(k) = 0
2118 
2119 C
2120 
2121 C----FOR EACH ROW K
2122 
2123  DO 18 k=1,n
2124 
2125  luk = 0
2126 
2127  q(k) = n+1
2128 
2129 C
2130 
2131  tag = mark(k)
2132 
2133  clique = .false.
2134 
2135  IF (jl(k).NE.0) clique = jl(jl(k)).EQ.0
2136 
2137 C
2138 
2139 C------INITIALIZE NONZERO STRUCTURE OF K-TH ROW TO ROW P(K) OF M
2140 
2141  jmin = ia(p(k))
2142 
2143  jmax = ia(p(k)+1) - 1
2144 
2145  IF (jmin.GT.jmax) go to 4
2146 
2147  DO 3 j=jmin,jmax
2148 
2149  vj = ip(ja(j))
2150 
2151  IF (vj.LE.k) go to 3
2152 
2153 C
2154 
2155  qm = k
2156 
2157  2 m = qm
2158 
2159  qm = q(m)
2160 
2161  IF (qm.LT.vj) go to 2
2162 
2163  IF (qm.EQ.vj) go to 102
2164 
2165  luk = luk+1
2166 
2167  q(m) = vj
2168 
2169  q(vj) = qm
2170 
2171  IF (mark(vj).NE.tag) clique = .false.
2172 
2173 C
2174 
2175  3 CONTINUE
2176 
2177 C
2178 
2179 C------IF EXACTLY ONE ROW IS TO BE MERGED INTO THE K-TH ROW AND THERE IS
2180 
2181 C------A NONZERO ENTRY IN EVERY COLUMN IN THAT ROW IN WHICH THERE IS A
2182 
2183 C------NONZERO ENTRY IN ROW P(K) OF M, THEN DO NOT COMPUTE FILL-IN, JUST
2184 
2185 C------USE THE COLUMN INDICES FOR THE ROW WHICH WAS TO HAVE BEEN MERGED
2186 
2187  4 IF (.NOT.clique) go to 5
2188 
2189  iju(k) = iju(jl(k)) + 1
2190 
2191  luk = iu(jl(k)+1) - (iu(jl(k))+1)
2192 
2193  go to 17
2194 
2195 C
2196 
2197 C------MODIFY NONZERO STRUCTURE OF K-TH ROW BY COMPUTING FILL-IN
2198 
2199 C------FOR EACH ROW I TO BE MERGED IN
2200 
2201  5 lmax = 0
2202 
2203  iju(k) = juptr
2204 
2205 C
2206 
2207  i = k
2208 
2209  6 i = jl(i)
2210 
2211  IF (i.EQ.0) go to 10
2212 
2213 C
2214 
2215 C--------MERGE ROW I INTO K-TH ROW
2216 
2217  lui = iu(i+1) - (iu(i)+1)
2218 
2219  jmin = iju(i) + 1
2220 
2221  jmax = iju(i) + lui
2222 
2223  qm = k
2224 
2225 C
2226 
2227  DO 8 j=jmin,jmax
2228 
2229  vj = ju(j)
2230 
2231  7 m = qm
2232 
2233  qm = q(m)
2234 
2235  IF (qm.LT.vj) go to 7
2236 
2237  IF (qm.EQ.vj) go to 8
2238 
2239  luk = luk+1
2240 
2241  q(m) = vj
2242 
2243  q(vj) = qm
2244 
2245  qm = vj
2246 
2247  8 CONTINUE
2248 
2249 C
2250 
2251 C--------REMEMBER LENGTH AND POSITION IN JU OF LONGEST ROW MERGED
2252 
2253  IF (lui.LE.lmax) go to 9
2254 
2255  lmax = lui
2256 
2257  iju(k) = jmin
2258 
2259 C
2260 
2261  9 go to 6
2262 
2263 C
2264 
2265 C------IF THE K-TH ROW IS THE SAME LENGTH AS THE LONGEST ROW MERGED,
2266 
2267 C------THEN USE THE COLUMN INDICES FOR THAT ROW
2268 
2269  10 IF (luk.EQ.lmax) go to 17
2270 
2271 C
2272 
2273 C------IF THE TAIL OF THE LAST ROW SAVED IN JU IS THE SAME AS THE HEAD
2274 
2275 C------OF THE K-TH ROW, THEN OVERLAP THE TWO SETS OF COLUMN INDICES --
2276 
2277 C--------SEARCH LAST ROW SAVED FOR FIRST NONZERO ENTRY IN K-TH ROW ...
2278 
2279  i = q(k)
2280 
2281  IF (jumin.GT.juptr) go to 12
2282 
2283  DO 11 jmin=jumin,juptr
2284 
2285  IF (ju(jmin)-i) 11, 13, 12
2286 
2287  11 CONTINUE
2288 
2289  12 go to 15
2290 
2291 C
2292 
2293 C--------... AND THEN TEST WHETHER TAIL MATCHES HEAD OF K-TH ROW
2294 
2295  13 iju(k) = jmin
2296 
2297  DO 14 j=jmin,juptr
2298 
2299  IF (ju(j).NE.i) go to 15
2300 
2301  i = q(i)
2302 
2303  IF (i.GT.n) go to 17
2304 
2305  14 CONTINUE
2306 
2307  juptr = jmin - 1
2308 
2309 C
2310 
2311 C------SAVE NONZERO STRUCTURE OF K-TH ROW IN JU
2312 
2313  15 i = k
2314 
2315  jumin = juptr + 1
2316 
2317  juptr = juptr + luk
2318 
2319  IF (juptr.GT.jumax) go to 106
2320 
2321  DO 16 j=jumin,juptr
2322 
2323  i = q(i)
2324 
2325  ju(j) = i
2326 
2327  16 mark(i) = k
2328 
2329  iju(k) = jumin
2330 
2331 C
2332 
2333 C------ADD K TO ROW LIST FOR FIRST NONZERO ELEMENT IN K-TH ROW
2334 
2335  17 IF (luk.LE.1) go to 18
2336 
2337  i = ju(iju(k))
2338 
2339  jl(k) = jl(i)
2340 
2341  jl(i) = k
2342 
2343 C
2344 
2345  18 iu(k+1) = iu(k) + luk
2346 
2347 C
2348 
2349  flag = 0
2350 
2351  RETURN
2352 
2353 C
2354 
2355 C ** ERROR -- DUPLICATE ENTRY IN A
2356 
2357  102 flag = 2*n + p(k)
2358 
2359  RETURN
2360 
2361 C ** ERROR -- INSUFFICIENT STORAGE FOR JU
2362 
2363  106 flag = 6*n + k
2364 
2365  RETURN
2366 
2367  END
2368 
2369 C
2370 
2371 C***********************************************************************
2372 
2373 C SNF -- NUMERICAL UT-D-U FACTORIZATION OF SPARSE SYMMETRIC POSITIVE
2374 
2375 C DEFINITE MATRIX
2376 
2377 C***********************************************************************
2378 
2379  SUBROUTINE snf
2380 
2381  * (n, p,ip, ia,ja,a, d, iju,ju,iu,u,umax, il, jl, flag)
2382 
2383 C
2384 
2385 C ADDITIONAL PARAMETERS
2386 
2387 C
2388 
2389 C IL - INTEGER ONE-DIMENSIONAL WORK ARRAY; DIMENSION = N
2390 
2391 C
2392 
2393 C JL - INTEGER ONE-DIMENSIONAL WORK ARRAY; DIMENSION = N
2394 
2395 C
2396 
2397 C
2398 
2399 C DEFINITIONS OF INTERNAL PARAMETERS (DURING K-TH STAGE OF ELIMINATION)
2400 
2401 C
2402 
2403 C (D(I),I=K,N) CONTAINS THE K-TH ROW OF U (EXPANDED)
2404 
2405 C
2406 
2407 C IL(I) POINTS TO THE FIRST NONZERO ELEMENT IN COLUMNS K,...,N OF
2408 
2409 C ROW I OF U
2410 
2411 C
2412 
2413 C JL CONTAINS LISTS OF ROWS TO BE ADDED TO UNELIMINATED ROWS --
2414 
2415 C I GE K => JL(I) IS THE FIRST ROW TO BE ADDED TO ROW I
2416 
2417 C I LT K => JL(I) IS THE ROW FOLLOWING ROW I IN SOME LIST OF ROWS
2418 
2419 C IN EITHER CASE, JL(I) = 0 INDICATES THE END OF A LIST
2420 
2421 C
2422 
2423 C-----------------------------------------------------------------------
2424 
2425 C
2426 
2427  INTEGER p(*), ip(*), ia(*), ja(*), iju(*), ju(*), iu(*),
2428 
2429  * umax, il(*), jl(*), flag, vj
2430 
2431 C... REAL A(1), D(1), U(1), DK, UKIDI
2432 
2433  DOUBLE PRECISION a(*), d(*), u(*), dk, ukidi
2434 
2435 C
2436 
2437 C----CHECK FOR SUFFICIENT STORAGE FOR U
2438 
2439  IF (iu(n+1)-1 .GT. umax) go to 107
2440 
2441 C
2442 
2443 C----INITIALIZATION
2444 
2445  DO 1 k=1,n
2446 
2447  kk=p(k)
2448 
2449  ip(kk)=k
2450 
2451  d(k) = 0
2452 
2453  1 jl(k) = 0
2454 
2455 C
2456 
2457 C----FOR EACH ROW K
2458 
2459  DO 11 k=1,n
2460 
2461 C
2462 
2463 C------INITIALIZE K-TH ROW WITH ELEMENTS NONZERO IN ROW P(K) OF M
2464 
2465  3 jmin = ia(p(k))
2466 
2467  jmax = ia(p(k)+1) - 1
2468 
2469  IF (jmin.GT.jmax) go to 5
2470 
2471  DO 4 j=jmin,jmax
2472 
2473  vj = ip(ja(j))
2474 
2475  IF (k.LE.vj) d(vj) = a(j)
2476 
2477  4 CONTINUE
2478 
2479 C
2480 
2481 C------MODIFY K-TH ROW BY ADDING IN THOSE ROWS I WITH U(I,K) NE 0
2482 
2483 C------FOR EACH ROW I TO BE ADDED IN
2484 
2485  5 dk = d(k)
2486 
2487  i = jl(k)
2488 
2489  6 IF (i.EQ.0) go to 9
2490 
2491  nexti = jl(i)
2492 
2493 C
2494 
2495 C--------COMPUTE MULTIPLIER AND UPDATE DIAGONAL ELEMENT
2496 
2497  ili = il(i)
2498 
2499  ukidi = - u(ili) * d(i)
2500 
2501  dk = dk + ukidi * u(ili)
2502 
2503  u(ili) = ukidi
2504 
2505 C
2506 
2507 C--------ADD MULTIPLE OF ROW I TO K-TH ROW ...
2508 
2509  jmin = ili + 1
2510 
2511  jmax = iu(i+1) - 1
2512 
2513  IF (jmin.GT.jmax) go to 8
2514 
2515  mu = iju(i) - iu(i)
2516 
2517  DO 7 j=jmin,jmax
2518 
2519  7 d(ju(mu+j)) = d(ju(mu+j)) + ukidi * u(j)
2520 
2521 C
2522 
2523 C--------... AND ADD I TO ROW LIST FOR NEXT NONZERO ENTRY
2524 
2525  il(i) = jmin
2526 
2527  j = ju(mu+jmin)
2528 
2529  jl(i) = jl(j)
2530 
2531  jl(j) = i
2532 
2533 C
2534 
2535  8 i = nexti
2536 
2537  go to 6
2538 
2539 C
2540 
2541 C------CHECK FOR ZERO PIVOT AND SAVE DIAGONAL ELEMENT
2542 
2543  9 IF (dk.EQ.0) go to 108
2544 
2545  d(k) = 1 / dk
2546 
2547 C
2548 
2549 C------SAVE NONZERO ENTRIES IN K-TH ROW OF U ...
2550 
2551  jmin = iu(k)
2552 
2553  jmax = iu(k+1) - 1
2554 
2555  IF (jmin.GT.jmax) go to 11
2556 
2557  mu = iju(k) - jmin
2558 
2559  DO 10 j=jmin,jmax
2560 
2561  jumuj = ju(mu+j)
2562 
2563  u(j) = d(jumuj)
2564 
2565  10 d(jumuj) = 0
2566 
2567 C
2568 
2569 C------... AND ADD K TO ROW LIST FOR FIRST NONZERO ENTRY IN K-TH ROW
2570 
2571  il(k) = jmin
2572 
2573  i = ju(mu+jmin)
2574 
2575  jl(k) = jl(i)
2576 
2577  jl(i) = k
2578 
2579  11 CONTINUE
2580 
2581 C
2582 
2583  flag = 0
2584 
2585  RETURN
2586 
2587 C
2588 
2589 C ** ERROR -- INSUFFICIENT STORAGE FOR U
2590 
2591  107 flag = 7*n + 1
2592 
2593  RETURN
2594 
2595 C ** ERROR -- ZERO PIVOT
2596 
2597  108 flag = 8*n + k
2598 
2599  RETURN
2600 
2601  END
2602 
2603 C
2604 
2605 C***********************************************************************
2606 
2607 C SNS -- SOLUTION OF SPARSE SYMMETRIC POSITIVE DEFINITE SYSTEM OF
2608 
2609 C LINEAR EQUATIONS MX = B GIVEN UT-D-U FACTORIZATION OF M
2610 
2611 C***********************************************************************
2612 
2613  SUBROUTINE sns
2614 
2615  * (n, p, d, iju,ju,iu,u, z, b, tmp)
2616 
2617  INTEGER p(*), iju(*), ju(*), iu(*)
2618 
2619 C... REAL D(1), U(1), Z(1), B(1), TMP(1), TMPK, SUM
2620 
2621  DOUBLE PRECISION d(*), u(*), z(*), b(*), tmp(*), tmpk, sum
2622 
2623 C
2624 
2625 C ADDITIONAL PARAMETERS
2626 
2627 C
2628 
2629 C TMP - REAL ONE-DIMENSIONAL WORK ARRAY; DIMENSION = N
2630 
2631 C
2632 
2633 C-----------------------------------------------------------------------
2634 
2635 C
2636 
2637 C----SET TMP TO PERMUTED B
2638 
2639  DO 1 k=1,n
2640 
2641  1 tmp(k) = b(p(k))
2642 
2643 C
2644 
2645 C----SOLVE UT D Y = B BY FORWARD SUBSTITUTION
2646 
2647  DO 3 k=1,n
2648 
2649  tmpk = tmp(k)
2650 
2651  jmin = iu(k)
2652 
2653  jmax = iu(k+1) - 1
2654 
2655  IF (jmin.GT.jmax) go to 3
2656 
2657  mu = iju(k) - jmin
2658 
2659  DO 2 j=jmin,jmax
2660 
2661  2 tmp(ju(mu+j)) = tmp(ju(mu+j)) + u(j) * tmpk
2662 
2663  3 tmp(k) = tmpk * d(k)
2664 
2665 C
2666 
2667 C----SOLVE U X = Y BY BACK SUBSTITUTION
2668 
2669  k = n
2670 
2671  DO 6 i=1,n
2672 
2673  sum = tmp(k)
2674 
2675  jmin = iu(k)
2676 
2677  jmax = iu(k+1) - 1
2678 
2679  IF (jmin.GT.jmax) go to 5
2680 
2681  mu = iju(k) - jmin
2682 
2683  DO 4 j=jmin,jmax
2684 
2685  4 sum = sum + u(j) * tmp(ju(mu+j))
2686 
2687  5 tmp(k) = sum
2688 
2689  z(p(k)) = sum
2690 
2691  6 k = k-1
2692 
2693 C
2694 
2695  RETURN
2696 
2697  END
2698 
2699  SUBROUTINE cdrvd
2700 
2701  * (n, r,c,ic, ia,ja,a, b, z, nsp,isp,rsp,esp, path, flag)
2702 
2703 C-----------------------------------------------------------------------
2704 
2705 C*** DRIVER FOR SUBROUTINES FOR SOLVING SPARSE NONSYMMETRIC SYSTEMS OF
2706 
2707 C LINEAR EQUATIONS (COMPRESSED POINTER STORAGE)
2708 
2709 C-----------------------------------------------------------------------
2710 
2711 C
2712 
2713 C
2714 
2715  INTEGER r(*), c(*), ic(*), ia(*), ja(*), isp(*), esp, path,
2716 
2717  * flag, d, u, q, row, tmp, ar, umax
2718 
2719  DOUBLE PRECISION a(*), b(*), z(*), rsp(*)
2720 
2721 C
2722 
2723 C
2724 
2725  DATA lratio/2/
2726 
2727 C
2728 
2729  IF (path.LT.1 .OR. 5.LT.path) go to 111
2730 
2731 C
2732 
2733  il = 1
2734 
2735  ijl = il + (n+1)
2736 
2737  iu = ijl + n
2738 
2739  iju = iu + (n+1)
2740 
2741  irl = iju + n
2742 
2743  jrl = irl + n
2744 
2745  jl = jrl + n
2746 
2747 C
2748 
2749 C
2750 
2751  IF ((path-1) * (path-5) .NE. 0) go to 5
2752 
2753  max = (lratio*nsp + 1 - jl) - (n+1) - 5*n
2754 
2755  jlmax = max/2
2756 
2757  q = jl + jlmax
2758 
2759  ira = q + (n+1)
2760 
2761  jra = ira + n
2762 
2763  irac = jra + n
2764 
2765  iru = irac + n
2766 
2767  jru = iru + n
2768 
2769  jutmp = jru + n
2770 
2771  jumax = lratio*nsp + 1 - jutmp
2772 
2773  esp = max/lratio
2774 
2775  IF (jlmax.LE.0 .OR. jumax.LE.0) go to 110
2776 
2777 C
2778 
2779  DO 1 i=1,n
2780 
2781  IF (c(i).NE.i) go to 2
2782 
2783  1 CONTINUE
2784 
2785  go to 3
2786 
2787  2 ar = nsp + 1 - n
2788 
2789  CALL nroc
2790 
2791  * (n, ic, ia,ja,a, isp(il), rsp(ar), isp(iu), flag)
2792 
2793  IF (flag.NE.0) go to 100
2794 
2795 C
2796 
2797  3 CALL nsfc
2798 
2799  * (n, r, ic, ia,ja,
2800 
2801  * jlmax, isp(il), isp(jl), isp(ijl),
2802 
2803  * jumax, isp(iu), isp(jutmp), isp(iju),
2804 
2805  * isp(q), isp(ira), isp(jra), isp(irac),
2806 
2807  * isp(irl), isp(jrl), isp(iru), isp(jru), flag)
2808 
2809  IF(flag .NE. 0) go to 100
2810 
2811 C
2812 
2813  jlmax = isp(ijl+n-1)
2814 
2815  ju = jl + jlmax
2816 
2817  jumax = isp(iju+n-1)
2818 
2819  IF (jumax.LE.0) go to 5
2820 
2821  DO 4 j=1,jumax
2822 
2823  4 isp(ju+j-1) = isp(jutmp+j-1)
2824 
2825 C
2826 
2827 C
2828 
2829  5 jlmax = isp(ijl+n-1)
2830 
2831  ju = jl + jlmax
2832 
2833  jumax = isp(iju+n-1)
2834 
2835  l = (ju + jumax - 2 + lratio) / lratio + 1
2836 
2837  lmax = isp(il+n) - 1
2838 
2839  d = l + lmax
2840 
2841  u = d + n
2842 
2843  row = nsp + 1 - n
2844 
2845  tmp = row - n
2846 
2847  umax = tmp - u
2848 
2849  esp = umax - (isp(iu+n) - 1)
2850 
2851 C
2852 
2853  IF ((path-1) * (path-2) .NE. 0) go to 6
2854 
2855  IF (umax.LE.0) go to 110
2856 
2857  CALL nnfc
2858 
2859  * (n, r, c, ic, ia, ja, a, z, b,
2860 
2861  * lmax, isp(il), isp(jl), isp(ijl), rsp(l), rsp(d),
2862 
2863  * umax, isp(iu), isp(ju), isp(iju), rsp(u),
2864 
2865  * rsp(row), rsp(tmp), isp(irl), isp(jrl), flag)
2866 
2867  IF(flag .NE. 0) go to 100
2868 
2869 C
2870 
2871  6 IF ((path-3) .NE. 0) go to 7
2872 
2873  CALL nnsc
2874 
2875  * (n, r, c, isp(il), isp(jl), isp(ijl), rsp(l),
2876 
2877  * rsp(d), isp(iu), isp(ju), isp(iju), rsp(u),
2878 
2879  * z, b, rsp(tmp))
2880 
2881 C
2882 
2883  7 IF ((path-4) .NE. 0) go to 8
2884 
2885  CALL nntc
2886 
2887  * (n, r, c, isp(il), isp(jl), isp(ijl), rsp(l),
2888 
2889  * rsp(d), isp(iu), isp(ju), isp(iju), rsp(u),
2890 
2891  * z, b, rsp(tmp))
2892 
2893  8 RETURN
2894 
2895 C
2896 
2897 C
2898 
2899  100 RETURN
2900 
2901 C
2902 
2903  110 flag = 10*n + 1
2904 
2905  RETURN
2906 
2907 C
2908 
2909  111 flag = 11*n + 1
2910 
2911  RETURN
2912 
2913  END
2914 
2915 C-----------------------------------------------------------------------
2916 
2917  SUBROUTINE nnfc
2918 
2919  * (n, r,c,ic, ia,ja,a, z, b,
2920 
2921  * lmax,il,jl,ijl,l, d, umax,iu,ju,iju,u,
2922 
2923  * row, tmp, irl,jrl, flag)
2924 
2925 C-----------------------------------------------------------------------
2926 
2927 C*** SUBROUTINE NNFC
2928 
2929 C*** NUMERICAL LDU-FACTORIZATION OF SPARSE NONSYMMETRIC MATRIX AND
2930 
2931 C SOLUTION OF SYSTEM OF LINEAR EQUATIONS (COMPRESSED POINTER
2932 
2933 C STORAGE)
2934 
2935 C-----------------------------------------------------------------------
2936 
2937 C
2938 
2939 C
2940 
2941  INTEGER rk,umax
2942 
2943  INTEGER r(*), c(*), ic(*), ia(*), ja(*), il(*), jl(*), ijl(*)
2944 
2945  INTEGER iu(*), ju(*), iju(*), irl(*), jrl(*), flag
2946 
2947  DOUBLE PRECISION a(*), l(*), d(*), u(*), z(*), b(*), row(*)
2948 
2949  DOUBLE PRECISION tmp(*), lki, sum, dk
2950 
2951 C
2952 
2953 C
2954 
2955  IF(il(n+1)-1 .GT. lmax) go to 104
2956 
2957  IF(iu(n+1)-1 .GT. umax) go to 107
2958 
2959  DO 1 k=1,n
2960 
2961  irl(k) = il(k)
2962 
2963  jrl(k) = 0
2964 
2965  1 CONTINUE
2966 
2967 C
2968 
2969 C
2970 
2971  DO 19 k=1,n
2972 
2973 C
2974 
2975  row(k) = 0
2976 
2977  i1 = 0
2978 
2979  IF (jrl(k) .EQ. 0) go to 3
2980 
2981  i = jrl(k)
2982 
2983  2 i2 = jrl(i)
2984 
2985  jrl(i) = i1
2986 
2987  i1 = i
2988 
2989  row(i) = 0
2990 
2991  i = i2
2992 
2993  IF (i .NE. 0) go to 2
2994 
2995 C
2996 
2997  3 jmin = iju(k)
2998 
2999  jmax = jmin + iu(k+1) - iu(k) - 1
3000 
3001  IF (jmin .GT. jmax) go to 5
3002 
3003  DO 4 j=jmin,jmax
3004 
3005  4 row(ju(j)) = 0
3006 
3007 C
3008 
3009  5 rk = r(k)
3010 
3011  jmin = ia(rk)
3012 
3013  jmax = ia(rk+1) - 1
3014 
3015  DO 6 j=jmin,jmax
3016 
3017  row(ic(ja(j))) = a(j)
3018 
3019  6 CONTINUE
3020 
3021 C
3022 
3023  sum = b(rk)
3024 
3025  i = i1
3026 
3027  IF (i .EQ. 0) go to 10
3028 
3029 C
3030 
3031  7 lki = -row(i)
3032 
3033 C
3034 
3035  l(irl(i)) = -lki
3036 
3037  sum = sum + lki * tmp(i)
3038 
3039  jmin = iu(i)
3040 
3041  jmax = iu(i+1) - 1
3042 
3043  IF (jmin .GT. jmax) go to 9
3044 
3045  mu = iju(i) - jmin
3046 
3047  DO 8 j=jmin,jmax
3048 
3049  8 row(ju(mu+j)) = row(ju(mu+j)) + lki * u(j)
3050 
3051  9 i = jrl(i)
3052 
3053  IF (i .NE. 0) go to 7
3054 
3055 C
3056 
3057 C
3058 
3059  10 IF (row(k) .EQ. 0.0d0) go to 108
3060 
3061  dk = 1.0d0 / row(k)
3062 
3063  d(k) = dk
3064 
3065  tmp(k) = sum * dk
3066 
3067  IF (k .EQ. n) go to 19
3068 
3069  jmin = iu(k)
3070 
3071  jmax = iu(k+1) - 1
3072 
3073  IF (jmin .GT. jmax) go to 12
3074 
3075  mu = iju(k) - jmin
3076 
3077  DO 11 j=jmin,jmax
3078 
3079  11 u(j) = row(ju(mu+j)) * dk
3080 
3081  12 CONTINUE
3082 
3083 C
3084 
3085 C
3086 
3087  i = i1
3088 
3089  IF (i .EQ. 0) go to 18
3090 
3091  14 irl(i) = irl(i) + 1
3092 
3093  i1 = jrl(i)
3094 
3095  IF (irl(i) .GE. il(i+1)) go to 17
3096 
3097  ijlb = irl(i) - il(i) + ijl(i)
3098 
3099  j = jl(ijlb)
3100 
3101  15 IF (i .GT. jrl(j)) go to 16
3102 
3103  j = jrl(j)
3104 
3105  go to 15
3106 
3107  16 jrl(i) = jrl(j)
3108 
3109  jrl(j) = i
3110 
3111  17 i = i1
3112 
3113  IF (i .NE. 0) go to 14
3114 
3115  18 IF (irl(k) .GE. il(k+1)) go to 19
3116 
3117  j = jl(ijl(k))
3118 
3119  jrl(k) =jrl(j)
3120 
3121  jrl(j) = k
3122 
3123  19 CONTINUE
3124 
3125 C
3126 
3127 C
3128 
3129  k = n
3130 
3131  DO 22 i=1,n
3132 
3133  sum = tmp(k)
3134 
3135  jmin = iu(k)
3136 
3137  jmax = iu(k+1) - 1
3138 
3139  IF (jmin .GT. jmax) go to 21
3140 
3141  mu = iju(k) - jmin
3142 
3143  DO 20 j=jmin,jmax
3144 
3145  20 sum = sum - u(j) * tmp(ju(mu+j))
3146 
3147  21 tmp(k) = sum
3148 
3149  z(c(k)) = sum
3150 
3151  22 k = k-1
3152 
3153  flag = 0
3154 
3155  RETURN
3156 
3157 C
3158 
3159 C
3160 
3161  104 flag = 4*n + 1
3162 
3163  RETURN
3164 
3165 C
3166 
3167  107 flag = 7*n + 1
3168 
3169  RETURN
3170 
3171 C
3172 
3173  108 flag = 8*n + k
3174 
3175  RETURN
3176 
3177  END
3178 
3179 C-----------------------------------------------------------------------
3180 
3181  SUBROUTINE nnsc
3182 
3183  * (n, r, c, il, jl, ijl, l, d, iu, ju, iju, u, z, b, tmp)
3184 
3185 C-----------------------------------------------------------------------
3186 
3187 C*** SUBROUTINE NNSC
3188 
3189 C*** NUMERICAL SOLUTION OF SPARSE NONSYMMETRIC SYSTEM OF LINEAR
3190 
3191 C EQUATIONS GIVEN LDU-FACTORIZATION (COMPRESSED POINTER STORAGE)
3192 
3193 C-----------------------------------------------------------------------
3194 
3195 C
3196 
3197 C
3198 
3199  INTEGER r(*), c(*), il(*), jl(*), ijl(*), iu(*), ju(*), iju(*)
3200 
3201  DOUBLE PRECISION l(*), d(*), u(*), b(*), z(*), tmp(*), tmpk,sum
3202 
3203 C
3204 
3205 C
3206 
3207  DO 1 k=1,n
3208 
3209  1 tmp(k) = b(r(k))
3210 
3211 C
3212 
3213  DO 3 k = 1,n
3214 
3215  jmin = il(k)
3216 
3217  jmax = il(k+1) - 1
3218 
3219  tmpk = -d(k) * tmp(k)
3220 
3221  tmp(k) = -tmpk
3222 
3223  IF (jmin .GT. jmax) go to 3
3224 
3225  ml = ijl(k) - jmin
3226 
3227  DO 2 j=jmin,jmax
3228 
3229  2 tmp(jl(ml+j)) = tmp(jl(ml+j)) + tmpk * l(j)
3230 
3231  3 CONTINUE
3232 
3233 C
3234 
3235  k = n
3236 
3237  DO 6 i=1,n
3238 
3239  sum = -tmp(k)
3240 
3241  jmin = iu(k)
3242 
3243  jmax = iu(k+1) - 1
3244 
3245  IF (jmin .GT. jmax) go to 5
3246 
3247  mu = iju(k) - jmin
3248 
3249  DO 4 j=jmin,jmax
3250 
3251  4 sum = sum + u(j) * tmp(ju(mu+j))
3252 
3253  5 tmp(k) = -sum
3254 
3255  z(c(k)) = -sum
3256 
3257  k = k - 1
3258 
3259  6 CONTINUE
3260 
3261  RETURN
3262 
3263  END
3264 
3265 C-----------------------------------------------------------------------
3266 
3267  SUBROUTINE nntc
3268 
3269  * (n, r, c, il, jl, ijl, l, d, iu, ju, iju, u, z, b, tmp)
3270 
3271 C-----------------------------------------------------------------------
3272 
3273 C*** SUBROUTINE NNTC
3274 
3275 C*** NUMERIC SOLUTION OF THE TRANSPOSE OF A SPARSE NONSYMMETRIC SYSTEM
3276 
3277 C OF LINEAR EQUATIONS GIVEN LU-FACTORIZATION (COMPRESSED POINTER
3278 
3279 C STORAGE)
3280 
3281 C-----------------------------------------------------------------------
3282 
3283 C
3284 
3285 C
3286 
3287  INTEGER r(*), c(*), il(*), jl(*), ijl(*), iu(*), ju(*), iju(*)
3288 
3289  DOUBLE PRECISION l(*), d(*), u(*), b(*), z(*), tmp(*), tmpk,sum
3290 
3291 C
3292 
3293 C
3294 
3295  DO 1 k=1,n
3296 
3297  1 tmp(k) = b(c(k))
3298 
3299 C
3300 
3301  DO 3 k=1,n
3302 
3303  jmin = iu(k)
3304 
3305  jmax = iu(k+1) - 1
3306 
3307  tmpk = -tmp(k)
3308 
3309  IF (jmin .GT. jmax) go to 3
3310 
3311  mu = iju(k) - jmin
3312 
3313  DO 2 j=jmin,jmax
3314 
3315  2 tmp(ju(mu+j)) = tmp(ju(mu+j)) + tmpk * u(j)
3316 
3317  3 CONTINUE
3318 
3319 C
3320 
3321  k = n
3322 
3323  DO 6 i=1,n
3324 
3325  sum = -tmp(k)
3326 
3327  jmin = il(k)
3328 
3329  jmax = il(k+1) - 1
3330 
3331  IF (jmin .GT. jmax) go to 5
3332 
3333  ml = ijl(k) - jmin
3334 
3335  DO 4 j=jmin,jmax
3336 
3337  4 sum = sum + l(j) * tmp(jl(ml+j))
3338 
3339  5 tmp(k) = -sum * d(k)
3340 
3341  z(r(k)) = tmp(k)
3342 
3343  k = k - 1
3344 
3345  6 CONTINUE
3346 
3347  RETURN
3348 
3349  END
3350 
3351 C-----------------------------------------------------------------------
3352 
3353  SUBROUTINE nroc (N, IC, IA, JA, A, JAR, AR, P, FLAG)
3354 
3355 C-----------------------------------------------------------------------
3356 
3357 C YALE SPARSE MATRIX PACKAGE - NONSYMMETRIC CODES
3358 
3359 C-----------------------------------------------------------------------
3360 
3361 C*** SUBROUTINE NROC
3362 
3363 C*** REORDERS ROWS OF A, LEAVING ROW ORDER UNCHANGED
3364 
3365 C-----------------------------------------------------------------------
3366 
3367 C
3368 
3369  INTEGER ic(*), ia(*), ja(*), jar(*), p(*), flag
3370 
3371  DOUBLE PRECISION a(*), ar(*)
3372 
3373 C
3374 
3375 C
3376 
3377  DO 5 k=1,n
3378 
3379  jmin = ia(k)
3380 
3381  jmax = ia(k+1) - 1
3382 
3383  IF(jmin .GT. jmax) go to 5
3384 
3385  p(n+1) = n + 1
3386 
3387 C
3388 
3389  DO 3 j=jmin,jmax
3390 
3391  newj = ic(ja(j))
3392 
3393  i = n + 1
3394 
3395  1 IF(p(i) .GE. newj) go to 2
3396 
3397  i = p(i)
3398 
3399  go to 1
3400 
3401  2 IF(p(i) .EQ. newj) go to 102
3402 
3403  p(newj) = p(i)
3404 
3405  p(i) = newj
3406 
3407  jar(newj) = ja(j)
3408 
3409  ar(newj) = a(j)
3410 
3411  3 CONTINUE
3412 
3413 C
3414 
3415  i = n + 1
3416 
3417  DO 4 j=jmin,jmax
3418 
3419  i = p(i)
3420 
3421  ja(j) = jar(i)
3422 
3423  4 a(j) = ar(i)
3424 
3425  5 CONTINUE
3426 
3427  flag = 0
3428 
3429  RETURN
3430 
3431 C
3432 
3433 C
3434 
3435  102 flag = n + k
3436 
3437  RETURN
3438 
3439  END
3440 
3441 C-----------------------------------------------------------------------
3442 
3443  SUBROUTINE nsfc
3444 
3445  * (n, r, ic, ia,ja, jlmax,il,jl,ijl, jumax,iu,ju,iju,
3446 
3447  * q, ira,jra, irac, irl,jrl, iru,jru, flag)
3448 
3449 C-----------------------------------------------------------------------
3450 
3451 C*** SUBROUTINE NSFC
3452 
3453 C*** SYMBOLIC LDU-FACTORIZATION OF NONSYMMETRIC SPARSE MATRIX
3454 
3455 C (COMPRESSED POINTER STORAGE)
3456 
3457 C-----------------------------------------------------------------------
3458 
3459 C
3460 
3461 C
3462 
3463  INTEGER cend, qm, rend, rk, vj
3464 
3465  INTEGER ia(*), ja(*), ira(*), jra(*), il(*), jl(*), ijl(*)
3466 
3467  INTEGER iu(*), ju(*), iju(*), irl(*), jrl(*), iru(*), jru(*)
3468 
3469  INTEGER r(*), ic(*), q(*), irac(*), flag
3470 
3471 C
3472 
3473 C
3474 
3475  np1 = n + 1
3476 
3477  jlmin = 1
3478 
3479  jlptr = 0
3480 
3481  il(1) = 1
3482 
3483  jumin = 1
3484 
3485  juptr = 0
3486 
3487  iu(1) = 1
3488 
3489  DO 1 k=1,n
3490 
3491  irac(k) = 0
3492 
3493  jra(k) = 0
3494 
3495  jrl(k) = 0
3496 
3497  1 jru(k) = 0
3498 
3499 C
3500 
3501  DO 2 k=1,n
3502 
3503  rk = r(k)
3504 
3505  iak = ia(rk)
3506 
3507  IF (iak .GE. ia(rk+1)) go to 101
3508 
3509  jaiak = ic(ja(iak))
3510 
3511  IF (jaiak .GT. k) go to 105
3512 
3513  jra(k) = irac(jaiak)
3514 
3515  irac(jaiak) = k
3516 
3517  2 ira(k) = iak
3518 
3519 C
3520 
3521 C
3522 
3523  DO 41 k=1,n
3524 
3525 C
3526 
3527 C
3528 
3529  q(np1) = np1
3530 
3531  luk = -1
3532 
3533 C
3534 
3535  vj = irac(k)
3536 
3537  IF (vj .EQ. 0) go to 5
3538 
3539  3 qm = np1
3540 
3541  4 m = qm
3542 
3543  qm = q(m)
3544 
3545  IF (qm .LT. vj) go to 4
3546 
3547  IF (qm .EQ. vj) go to 102
3548 
3549  luk = luk + 1
3550 
3551  q(m) = vj
3552 
3553  q(vj) = qm
3554 
3555  vj = jra(vj)
3556 
3557  IF (vj .NE. 0) go to 3
3558 
3559 C
3560 
3561  5 lastid = 0
3562 
3563  lasti = 0
3564 
3565  ijl(k) = jlptr
3566 
3567  i = k
3568 
3569  6 i = jru(i)
3570 
3571  IF (i .EQ. 0) go to 10
3572 
3573  qm = np1
3574 
3575  jmin = irl(i)
3576 
3577  jmax = ijl(i) + il(i+1) - il(i) - 1
3578 
3579  long = jmax - jmin
3580 
3581  IF (long .LT. 0) go to 6
3582 
3583  jtmp = jl(jmin)
3584 
3585  IF (jtmp .NE. k) long = long + 1
3586 
3587  IF (jtmp .EQ. k) r(i) = -r(i)
3588 
3589  IF (lastid .GE. long) go to 7
3590 
3591  lasti = i
3592 
3593  lastid = long
3594 
3595 C
3596 
3597  7 DO 9 j=jmin,jmax
3598 
3599  vj = jl(j)
3600 
3601  8 m = qm
3602 
3603  qm = q(m)
3604 
3605  IF (qm .LT. vj) go to 8
3606 
3607  IF (qm .EQ. vj) go to 9
3608 
3609  luk = luk + 1
3610 
3611  q(m) = vj
3612 
3613  q(vj) = qm
3614 
3615  qm = vj
3616 
3617  9 CONTINUE
3618 
3619  go to 6
3620 
3621 C
3622 
3623 C
3624 
3625  10 qm = q(np1)
3626 
3627  IF (qm .NE. k) go to 105
3628 
3629  IF (luk .EQ. 0) go to 17
3630 
3631  IF (lastid .NE. luk) go to 11
3632 
3633 C
3634 
3635  irll = irl(lasti)
3636 
3637  ijl(k) = irll + 1
3638 
3639  IF (jl(irll) .NE. k) ijl(k) = ijl(k) - 1
3640 
3641  go to 17
3642 
3643 C
3644 
3645  11 IF (jlmin .GT. jlptr) go to 15
3646 
3647  qm = q(qm)
3648 
3649  DO 12 j=jlmin,jlptr
3650 
3651  IF (jl(j) - qm) 12, 13, 15
3652 
3653  12 CONTINUE
3654 
3655  go to 15
3656 
3657  13 ijl(k) = j
3658 
3659  DO 14 i=j,jlptr
3660 
3661  IF (jl(i) .NE. qm) go to 15
3662 
3663  qm = q(qm)
3664 
3665  IF (qm .GT. n) go to 17
3666 
3667  14 CONTINUE
3668 
3669  jlptr = j - 1
3670 
3671 C
3672 
3673  15 jlmin = jlptr + 1
3674 
3675  ijl(k) = jlmin
3676 
3677  IF (luk .EQ. 0) go to 17
3678 
3679  jlptr = jlptr + luk
3680 
3681  IF (jlptr .GT. jlmax) go to 103
3682 
3683  qm = q(np1)
3684 
3685  DO 16 j=jlmin,jlptr
3686 
3687  qm = q(qm)
3688 
3689  16 jl(j) = qm
3690 
3691  17 irl(k) = ijl(k)
3692 
3693  il(k+1) = il(k) + luk
3694 
3695 C
3696 
3697 C
3698 
3699  q(np1) = np1
3700 
3701  luk = -1
3702 
3703 C
3704 
3705  rk = r(k)
3706 
3707  jmin = ira(k)
3708 
3709  jmax = ia(rk+1) - 1
3710 
3711  IF (jmin .GT. jmax) go to 20
3712 
3713  DO 19 j=jmin,jmax
3714 
3715  vj = ic(ja(j))
3716 
3717  qm = np1
3718 
3719  18 m = qm
3720 
3721  qm = q(m)
3722 
3723  IF (qm .LT. vj) go to 18
3724 
3725  IF (qm .EQ. vj) go to 102
3726 
3727  luk = luk + 1
3728 
3729  q(m) = vj
3730 
3731  q(vj) = qm
3732 
3733  19 CONTINUE
3734 
3735 C
3736 
3737  20 lastid = 0
3738 
3739  lasti = 0
3740 
3741  iju(k) = juptr
3742 
3743  i = k
3744 
3745  i1 = jrl(k)
3746 
3747  21 i = i1
3748 
3749  IF (i .EQ. 0) go to 26
3750 
3751  i1 = jrl(i)
3752 
3753  qm = np1
3754 
3755  jmin = iru(i)
3756 
3757  jmax = iju(i) + iu(i+1) - iu(i) - 1
3758 
3759  long = jmax - jmin
3760 
3761  IF (long .LT. 0) go to 21
3762 
3763  jtmp = ju(jmin)
3764 
3765  IF (jtmp .EQ. k) go to 22
3766 
3767 C
3768 
3769  long = long + 1
3770 
3771  cend = ijl(i) + il(i+1) - il(i)
3772 
3773  irl(i) = irl(i) + 1
3774 
3775  IF (irl(i) .GE. cend) go to 22
3776 
3777  j = jl(irl(i))
3778 
3779  jrl(i) = jrl(j)
3780 
3781  jrl(j) = i
3782 
3783  22 IF (lastid .GE. long) go to 23
3784 
3785  lasti = i
3786 
3787  lastid = long
3788 
3789 C
3790 
3791  23 DO 25 j=jmin,jmax
3792 
3793  vj = ju(j)
3794 
3795  24 m = qm
3796 
3797  qm = q(m)
3798 
3799  IF (qm .LT. vj) go to 24
3800 
3801  IF (qm .EQ. vj) go to 25
3802 
3803  luk = luk + 1
3804 
3805  q(m) = vj
3806 
3807  q(vj) = qm
3808 
3809  qm = vj
3810 
3811  25 CONTINUE
3812 
3813  go to 21
3814 
3815 C
3816 
3817  26 IF (il(k+1) .LE. il(k)) go to 27
3818 
3819  j = jl(irl(k))
3820 
3821  jrl(k) = jrl(j)
3822 
3823  jrl(j) = k
3824 
3825 C
3826 
3827 C
3828 
3829  27 qm = q(np1)
3830 
3831  IF (qm .NE. k) go to 105
3832 
3833  IF (luk .EQ. 0) go to 34
3834 
3835  IF (lastid .NE. luk) go to 28
3836 
3837 C
3838 
3839  irul = iru(lasti)
3840 
3841  iju(k) = irul + 1
3842 
3843  IF (ju(irul) .NE. k) iju(k) = iju(k) - 1
3844 
3845  go to 34
3846 
3847 C
3848 
3849  28 IF (jumin .GT. juptr) go to 32
3850 
3851  qm = q(qm)
3852 
3853  DO 29 j=jumin,juptr
3854 
3855  IF (ju(j) - qm) 29, 30, 32
3856 
3857  29 CONTINUE
3858 
3859  go to 32
3860 
3861  30 iju(k) = j
3862 
3863  DO 31 i=j,juptr
3864 
3865  IF (ju(i) .NE. qm) go to 32
3866 
3867  qm = q(qm)
3868 
3869  IF (qm .GT. n) go to 34
3870 
3871  31 CONTINUE
3872 
3873  juptr = j - 1
3874 
3875 C
3876 
3877  32 jumin = juptr + 1
3878 
3879  iju(k) = jumin
3880 
3881  IF (luk .EQ. 0) go to 34
3882 
3883  juptr = juptr + luk
3884 
3885  IF (juptr .GT. jumax) go to 106
3886 
3887  qm = q(np1)
3888 
3889  DO 33 j=jumin,juptr
3890 
3891  qm = q(qm)
3892 
3893  33 ju(j) = qm
3894 
3895  34 iru(k) = iju(k)
3896 
3897  iu(k+1) = iu(k) + luk
3898 
3899 C
3900 
3901 C
3902 
3903  i = k
3904 
3905  35 i1 = jru(i)
3906 
3907  IF (r(i) .LT. 0) go to 36
3908 
3909  rend = iju(i) + iu(i+1) - iu(i)
3910 
3911  IF (iru(i) .GE. rend) go to 37
3912 
3913  j = ju(iru(i))
3914 
3915  jru(i) = jru(j)
3916 
3917  jru(j) = i
3918 
3919  go to 37
3920 
3921  36 r(i) = -r(i)
3922 
3923  37 i = i1
3924 
3925  IF (i .EQ. 0) go to 38
3926 
3927  iru(i) = iru(i) + 1
3928 
3929  go to 35
3930 
3931 C
3932 
3933 C
3934 
3935  38 i = irac(k)
3936 
3937  IF (i .EQ. 0) go to 41
3938 
3939  39 i1 = jra(i)
3940 
3941  ira(i) = ira(i) + 1
3942 
3943  IF (ira(i) .GE. ia(r(i)+1)) go to 40
3944 
3945  irai = ira(i)
3946 
3947  jairai = ic(ja(irai))
3948 
3949  IF (jairai .GT. i) go to 40
3950 
3951  jra(i) = irac(jairai)
3952 
3953  irac(jairai) = i
3954 
3955  40 i = i1
3956 
3957  IF (i .NE. 0) go to 39
3958 
3959  41 CONTINUE
3960 
3961 C
3962 
3963  ijl(n) = jlptr
3964 
3965  iju(n) = juptr
3966 
3967  flag = 0
3968 
3969  RETURN
3970 
3971 C
3972 
3973 C
3974 
3975  101 flag = n + rk
3976 
3977  RETURN
3978 
3979 C
3980 
3981  102 flag = 2*n + rk
3982 
3983  RETURN
3984 
3985 C
3986 
3987  103 flag = 3*n + k
3988 
3989  RETURN
3990 
3991 C
3992 
3993  105 flag = 5*n + k
3994 
3995  RETURN
3996 
3997 C
3998 
3999  106 flag = 6*n + k
4000 
4001  RETURN
4002 
4003  END
4004 
4005 C-----------------------------------------------------------------------
4006 
4007  SUBROUTINE nnfcad
4008 
4009  * (n, r,c,ic, ia,ja,a, z, b,
4010 
4011  * lmax,il,jl,ijl, umax,iu,ju,iju,u,
4012 
4013  * row, tmp, irl,jrl, flag)
4014 
4015 C-----------------------------------------------------------------------
4016 
4017 C*** SUBROUTINE NNFC
4018 
4019 C*** NUMERICAL LDU-FACTORIZATION OF SPARSE NONSYMMETRIC MATRIX AND
4020 
4021 C SOLUTION OF SYSTEM OF LINEAR EQUATIONS (COMPRESSED POINTER
4022 
4023 C STORAGE)
4024 
4025 C-----------------------------------------------------------------------
4026 
4027 C
4028 
4029 C
4030 
4031  INTEGER rk,umax
4032 
4033  INTEGER r(*), c(*), ic(*), ia(*), ja(*), il(*), jl(*), ijl(*)
4034 
4035  INTEGER iu(*), ju(*), iju(*), irl(*), jrl(*), flag
4036 
4037  REAL*8 a(*), u(*), z(*), b(*), row(*)
4038 
4039  REAL*8 tmp(*), lki, sum, dk
4040 
4041 C
4042 
4043 C
4044 
4045  IF(il(n+1)-1 .GT. lmax) go to 104
4046 
4047  IF(iu(n+1)-1 .GT. umax) go to 107
4048 
4049  DO 1 k=1,n
4050 
4051  irl(k) = il(k)
4052 
4053  jrl(k) = 0
4054 
4055  1 CONTINUE
4056 
4057 C
4058 
4059 C
4060 
4061  DO 19 k=1,n
4062 
4063 C
4064 
4065  row(k) = 0
4066 
4067  i1 = 0
4068 
4069  IF (jrl(k) .EQ. 0) go to 3
4070 
4071  i = jrl(k)
4072 
4073  2 i2 = jrl(i)
4074 
4075  jrl(i) = i1
4076 
4077  i1 = i
4078 
4079  row(i) = 0
4080 
4081  i = i2
4082 
4083  IF (i .NE. 0) go to 2
4084 
4085 C
4086 
4087  3 jmin = iju(k)
4088 
4089  jmax = jmin + iu(k+1) - iu(k) - 1
4090 
4091  IF (jmin .GT. jmax) go to 5
4092 
4093  DO 4 j=jmin,jmax
4094 
4095  4 row(ju(j)) = 0
4096 
4097 C
4098 
4099  5 rk = r(k)
4100 
4101  jmin = ia(rk)
4102 
4103  jmax = ia(rk+1) - 1
4104 
4105  DO 6 j=jmin,jmax
4106 
4107  row(ic(ja(j))) = a(j)
4108 
4109  6 CONTINUE
4110 
4111 C
4112 
4113  sum = b(rk)
4114 
4115  i = i1
4116 
4117  IF (i .EQ. 0) go to 10
4118 
4119 C
4120 
4121  7 lki = -row(i)
4122 
4123 C
4124 
4125  sum = sum + lki * tmp(i)
4126 
4127  jmin = iu(i)
4128 
4129  jmax = iu(i+1) - 1
4130 
4131  IF (jmin .GT. jmax) go to 9
4132 
4133  mu = iju(i) - jmin
4134 
4135  DO 8 j=jmin,jmax
4136 
4137  8 row(ju(mu+j)) = row(ju(mu+j)) + lki * u(j)
4138 
4139  9 i = jrl(i)
4140 
4141  IF (i .NE. 0) go to 7
4142 
4143 C
4144 
4145 C
4146 
4147  10 IF (row(k) .EQ. 0.0d0) go to 108
4148 
4149  dk = 1.0d0 / row(k)
4150 
4151  tmp(k) = sum * dk
4152 
4153  IF (k .EQ. n) go to 19
4154 
4155  jmin = iu(k)
4156 
4157  jmax = iu(k+1) - 1
4158 
4159  IF (jmin .GT. jmax) go to 12
4160 
4161  mu = iju(k) - jmin
4162 
4163  DO 11 j=jmin,jmax
4164 
4165  11 u(j) = row(ju(mu+j)) * dk
4166 
4167  12 CONTINUE
4168 
4169 C
4170 
4171 C
4172 
4173  i = i1
4174 
4175  IF (i .EQ. 0) go to 18
4176 
4177  14 irl(i) = irl(i) + 1
4178 
4179  i1 = jrl(i)
4180 
4181  IF (irl(i) .GE. il(i+1)) go to 17
4182 
4183  ijlb = irl(i) - il(i) + ijl(i)
4184 
4185  j = jl(ijlb)
4186 
4187  15 IF (i .GT. jrl(j)) go to 16
4188 
4189  j = jrl(j)
4190 
4191  go to 15
4192 
4193  16 jrl(i) = jrl(j)
4194 
4195  jrl(j) = i
4196 
4197  17 i = i1
4198 
4199  IF (i .NE. 0) go to 14
4200 
4201  18 IF (irl(k) .GE. il(k+1)) go to 19
4202 
4203  j = jl(ijl(k))
4204 
4205  jrl(k) =jrl(j)
4206 
4207  jrl(j) = k
4208 
4209  19 CONTINUE
4210 
4211 C
4212 
4213 C
4214 
4215  k = n
4216 
4217  DO 22 i=1,n
4218 
4219  sum = tmp(k)
4220 
4221  jmin = iu(k)
4222 
4223  jmax = iu(k+1) - 1
4224 
4225  IF (jmin .GT. jmax) go to 21
4226 
4227  mu = iju(k) - jmin
4228 
4229  DO 20 j=jmin,jmax
4230 
4231  20 sum = sum - u(j) * tmp(ju(mu+j))
4232 
4233  21 tmp(k) = sum
4234 
4235  z(c(k)) = sum
4236 
4237  22 k = k-1
4238 
4239  flag = 0
4240 
4241  RETURN
4242 
4243 C
4244 
4245 C
4246 
4247  104 flag = 4*n + 1
4248 
4249  RETURN
4250 
4251 C
4252 
4253  107 flag = 7*n + 1
4254 
4255  RETURN
4256 
4257 C
4258 
4259  108 flag = 8*n + k
4260 
4261  RETURN
4262 
4263  END
4264 
4265  SUBROUTINE adrvd
4266 
4267  * (n, r,c,ic, ia,ja,a, b, z, nsp,isp,rsp,esp, path, flag)
4268 
4269 C-----------------------------------------------------------------------
4270 
4271 C*** DRIVER FOR SUBROUTINES FOR SOLVING SPARSE NONSYMMETRIC SYSTEMS OF
4272 
4273 C LINEAR EQUATIONS (COMPRESSED POINTER STORAGE)
4274 
4275 C-----------------------------------------------------------------------
4276 
4277 C
4278 
4279 C
4280 
4281  INTEGER r(*), c(*), ic(*), ia(*), ja(*), isp(*), esp, path,
4282 
4283  * flag, u, q, row, tmp, ar, umax
4284 
4285  REAL*8 a(*), b(*), z(*), rsp(*)
4286 
4287 C
4288 
4289 C
4290 
4291  DATA lratio/1/
4292 
4293 C
4294 
4295 C
4296 
4297  il = 1
4298 
4299  ijl = il + (n+1)
4300 
4301  iu = ijl + n
4302 
4303  iju = iu + (n+1)
4304 
4305  irl = iju + n
4306 
4307  jrl = irl + n
4308 
4309  jl = jrl + n
4310 
4311 C
4312 
4313 C
4314 
4315  max = (lratio*nsp + 1 - jl) - (n+1) - 5*n
4316 
4317  jlmax = max/2
4318 
4319  q = jl + jlmax
4320 
4321  ira = q + (n+1)
4322 
4323  jra = ira + n
4324 
4325  irac = jra + n
4326 
4327  iru = irac + n
4328 
4329  jru = iru + n
4330 
4331  jutmp = jru + n
4332 
4333  jumax = lratio*nsp + 1 - jutmp
4334 
4335  esp = max/lratio
4336 
4337  IF (jlmax.LE.0 .OR. jumax.LE.0) go to 110
4338 
4339 C
4340 
4341  DO 1 i=1,n
4342 
4343  IF (c(i).NE.i) go to 2
4344 
4345  1 CONTINUE
4346 
4347  go to 3
4348 
4349  2 ar = nsp + 1 - n
4350 
4351  CALL nroc
4352 
4353  * (n, ic, ia,ja,a, isp(il), rsp(ar), isp(iu), flag)
4354 
4355  IF (flag.NE.0) go to 100
4356 
4357 C
4358 
4359  3 CALL nsfc
4360 
4361  * (n, r, ic, ia,ja,
4362 
4363  * jlmax, isp(il), isp(jl), isp(ijl),
4364 
4365  * jumax, isp(iu), isp(jutmp), isp(iju),
4366 
4367  * isp(q), isp(ira), isp(jra), isp(irac),
4368 
4369  * isp(irl), isp(jrl), isp(iru), isp(jru), flag)
4370 
4371  IF(flag .NE. 0) go to 100
4372 
4373 C
4374 
4375  jlmax = isp(ijl+n-1)
4376 
4377  ju = jl + jlmax
4378 
4379  jumax = isp(iju+n-1)
4380 
4381  IF (jumax.LE.0) go to 5
4382 
4383  DO 4 j=1,jumax
4384 
4385  4 isp(ju+j-1) = isp(jutmp+j-1)
4386 
4387 C
4388 
4389 C
4390 
4391  5 jlmax = isp(ijl+n-1)
4392 
4393  ju = jl + jlmax
4394 
4395  jumax = isp(iju+n-1)
4396 
4397  lmax = isp(il+n) - 1
4398 
4399  u = (ju + jumax - 2 + lratio ) / lratio + 1
4400 
4401  umax = isp(iu+n) - 1
4402 
4403  row = u + umax
4404 
4405  tmp = row + n
4406 
4407  esp = nsp - (tmp + n)
4408 
4409  IF(esp.LT.0) goto 110
4410 
4411 C
4412 
4413  CALL nnfcad
4414 
4415  * (n, r, c, ic, ia, ja, a, z, b,
4416 
4417  * lmax, isp(il), isp(jl), isp(ijl),
4418 
4419  * umax, isp(iu), isp(ju), isp(iju), rsp(u),
4420 
4421  * rsp(row), rsp(tmp), isp(irl), isp(jrl), flag)
4422 
4423  IF(flag .NE. 0) go to 100
4424 
4425  8 RETURN
4426 
4427 C
4428 
4429 C
4430 
4431  100 RETURN
4432 
4433 C
4434 
4435  110 flag = 10*n + 1
4436 
4437  RETURN
4438 
4439 C
4440 
4441  END
4442 
4443  SUBROUTINE pdrvd
4444 
4445  * (n, ia,ja,a, p,ip, nsp,isp, path, flag)
4446 
4447 C-----------------------------------------------------------------------
4448 
4449 C ODRV -- DRIVER FOR SPARSE MATRIX REORDERING ROUTINES
4450 
4451 C-----------------------------------------------------------------------
4452 
4453  INTEGER ia(*), ja(*), p(*), ip(*), isp(*), path, flag,
4454 
4455  * v, l, head, tmp, q
4456 
4457  DOUBLE PRECISION a(*)
4458 
4459  LOGICAL dflag
4460 
4461 C
4462 
4463 C
4464 
4465  flag = 0
4466 
4467  IF (path.LT.1 .OR. 5.LT.path) go to 111
4468 
4469 C
4470 
4471 C
4472 
4473  IF ((path-1) * (path-2) * (path-4) .NE. 0) go to 1
4474 
4475  max = (nsp-n)/2
4476 
4477  v = 1
4478 
4479  l = v + max
4480 
4481  head = l + max
4482 
4483  next = head + n
4484 
4485  IF (max.LT.n) go to 110
4486 
4487 C
4488 
4489  CALL mdn
4490 
4491  * (n, ia,ja, max,isp(v),isp(l), isp(head),p,ip, isp(v), flag)
4492 
4493  IF (flag.NE.0) go to 100
4494 
4495 C
4496 
4497 C
4498 
4499  1 IF ((path-2) * (path-3) * (path-4) * (path-5) .NE. 0) go to 2
4500 
4501  tmp = (nsp+1) - n
4502 
4503  q = tmp - (ia(n+1)-1)
4504 
4505  IF (q.LT.1) go to 110
4506 
4507 C
4508 
4509  dflag = path.EQ.4 .OR. path.EQ.5
4510 
4511  CALL sro
4512 
4513  * (n, ip, ia, ja, a, isp(tmp), isp(q), dflag)
4514 
4515 C
4516 
4517  2 RETURN
4518 
4519 C
4520 
4521 C ** ERROR -- ERROR DETECTED IN MD
4522 
4523  100 RETURN
4524 
4525 C ** ERROR -- INSUFFICIENT STORAGE
4526 
4527  110 flag = 10*n + 1
4528 
4529  RETURN
4530 
4531 C ** ERROR -- ILLEGAL PATH SPECIFIED
4532 
4533  111 flag = 11*n + 1
4534 
4535  RETURN
4536 
4537  END
4538 
4539  SUBROUTINE mdn
4540 
4541  * (n, ia,ja, max, v,l, head,last,next, mark, flag)
4542 
4543 C-----------------------------------------------------------------------
4544 
4545 C MD -- MINIMUM DEGREE ALGORITHM (BASED ON ELEMENT MODEL)
4546 
4547 C-----------------------------------------------------------------------
4548 
4549  INTEGER ia(*), ja(*), v(*), l(*), head(*), last(*), next(*),
4550 
4551  * mark(*), flag, tag, dmin, vk,ek, tail
4552 
4553  equivalence(vk,ek)
4554 
4555 C
4556 
4557 C
4558 
4559  tag = 0
4560 
4561  CALL mdin
4562 
4563  * (n, ia,ja, max,v,l, head,last,next, mark,tag, flag)
4564 
4565  IF (flag.NE.0) RETURN
4566 
4567 C
4568 
4569  k = 0
4570 
4571  dmin = 1
4572 
4573 C
4574 
4575 C
4576 
4577  1 IF (k.GE.n) go to 4
4578 
4579 C
4580 
4581 C
4582 
4583  2 IF (head(dmin).GT.0) go to 3
4584 
4585  dmin = dmin + 1
4586 
4587  go to 2
4588 
4589 C
4590 
4591 C
4592 
4593  3 vk = head(dmin)
4594 
4595  head(dmin) = next(vk)
4596 
4597  IF (head(dmin).GT.0) last(head(dmin)) = -dmin
4598 
4599 C
4600 
4601 C
4602 
4603  k = k+1
4604 
4605  next(vk) = -k
4606 
4607  last(ek) = dmin - 1
4608 
4609  tag = tag + last(ek)
4610 
4611  mark(vk) = tag
4612 
4613 C
4614 
4615 C
4616 
4617  CALL mdm
4618 
4619  * (vk,tail, v,l, last,next, mark)
4620 
4621 C
4622 
4623 C
4624 
4625  CALL mdp
4626 
4627  * (k,ek,tail, v,l, head,last,next, mark)
4628 
4629 C
4630 
4631 C
4632 
4633  CALL mdu
4634 
4635  * (ek,dmin, v,l, head,last,next, mark)
4636 
4637 C
4638 
4639  go to 1
4640 
4641 C
4642 
4643 C
4644 
4645  4 DO 5 k=1,n
4646 
4647  next(k) = -next(k)
4648 
4649  5 last(next(k)) = k
4650 
4651 C
4652 
4653  RETURN
4654 
4655  END
4656 
4657 C-----------------------------------------------------------------------
4658 
4659  SUBROUTINE mdin
4660 
4661  * (n, ia,ja, max,v,l, head,last,next, mark,tag, flag)
4662 
4663 C-----------------------------------------------------------------------
4664 
4665 C MDI -- INITIALIZATION
4666 
4667 C-----------------------------------------------------------------------
4668 
4669  INTEGER ia(*), ja(*), v(*), l(*), head(*), last(*), next(*),
4670 
4671  * mark(*), tag, flag, sfs, vi,dvi, vj
4672 
4673 C
4674 
4675 C
4676 
4677  DO 1 vi=1,n
4678 
4679  mark(vi) = 1
4680 
4681  l(vi) = 0
4682 
4683  1 head(vi) = 0
4684 
4685  sfs = n+1
4686 
4687 C
4688 
4689 C
4690 
4691  DO 6 vi=1,n
4692 
4693  jmin = ia(vi)
4694 
4695  jmax = ia(vi+1) - 1
4696 
4697  IF (jmin.GT.jmax) go to 6
4698 
4699  DO 5 j=jmin,jmax
4700 
4701  vj = ja(j)
4702 
4703  IF (vj-vi) 2, 5, 4
4704 
4705 C
4706 
4707 C
4708 
4709  2 lvk = vi
4710 
4711  kmax = mark(vi) - 1
4712 
4713  IF (kmax .EQ. 0) go to 4
4714 
4715  DO 3 k=1,kmax
4716 
4717  lvk = l(lvk)
4718 
4719  IF (v(lvk).EQ.vj) go to 5
4720 
4721  3 CONTINUE
4722 
4723 C
4724 
4725  4 IF (sfs.GE.max) go to 101
4726 
4727 C
4728 
4729 C
4730 
4731  mark(vi) = mark(vi) + 1
4732 
4733  v(sfs) = vj
4734 
4735  l(sfs) =l(vi)
4736 
4737  l(vi) = sfs
4738 
4739  sfs = sfs+1
4740 
4741 C
4742 
4743 C
4744 
4745  mark(vj) = mark(vj) + 1
4746 
4747  v(sfs) = vi
4748 
4749  l(sfs) = l(vj)
4750 
4751  l(vj) = sfs
4752 
4753  sfs = sfs+1
4754 
4755  5 CONTINUE
4756 
4757  6 CONTINUE
4758 
4759 C
4760 
4761 C
4762 
4763  DO 7 vi=1,n
4764 
4765  dvi = mark(vi)
4766 
4767  next(vi) = head(dvi)
4768 
4769  head(dvi) =vi
4770 
4771  last(vi) = -dvi
4772 
4773  nextvi = next(vi)
4774 
4775  IF (nextvi.GT.0) last(nextvi) = vi
4776 
4777  7 mark(vi) = tag
4778 
4779 C
4780 
4781  RETURN
4782 
4783 C
4784 
4785 C
4786 
4787  101 flag = 9*n + vi
4788 
4789  RETURN
4790 
4791  END
4792 
4793 
4794 
4795 
4796 
4797 
4798 
4799 
4800 
4801 
4802 
4803 
4804 
4805 
4806 
4807 
4808 
4809 
4810 
subroutine md
Definition: SPAR.f:347
subroutine mdin
Definition: SPAR.f:4659
subroutine odrvd
Definition: SPAR.f:9
subroutine nntc
Definition: SPAR.f:3267
subroutine mdi
Definition: SPAR.f:621
subroutine nnfc
Definition: SPAR.f:2917
subroutine mdu
Definition: SPAR.f:1027
subroutine nsfc
Definition: SPAR.f:3443
subroutine mdm
Definition: SPAR.f:737
subroutine nnfcad
Definition: SPAR.f:4007
subroutine ssf
Definition: SPAR.f:2029
subroutine pdrvd
Definition: SPAR.f:4443
subroutine sns
Definition: SPAR.f:2613
subroutine mdn
Definition: SPAR.f:4539
subroutine sro
Definition: SPAR.f:1197
real(r8) function p(a, x, xr, xs, yr, ys, psi, psir, F_dia)
subroutine cdrvd
Definition: SPAR.f:2699
subroutine mdp
Definition: SPAR.f:847
subroutine adrvd
Definition: SPAR.f:4265
subroutine sdrvd
Definition: SPAR.f:1411
subroutine nnsc
Definition: SPAR.f:3181
subroutine snf
Definition: SPAR.f:2379
subroutine nroc(N, IC, IA, JA, A, JAR, AR, P, FLAG)
Definition: SPAR.f:3353