123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- *DECK DPNNZR
- SUBROUTINE DPNNZR (I, XVAL, IPLACE, SX, IX, IRCX)
- C***BEGIN PROLOGUE DPNNZR
- C***SUBSIDIARY
- C***PURPOSE Subsidiary to DSPLP
- C***LIBRARY SLATEC
- C***TYPE DOUBLE PRECISION (PNNZRS-S, DPNNZR-D)
- C***AUTHOR Hanson, R. J., (SNLA)
- C Wisniewski, J. A., (SNLA)
- C***DESCRIPTION
- C
- C DPNNZR LIMITS THE TYPE OF STORAGE TO A SEQUENTIAL SCHEME.
- C SPARSE MATRIX NON ZERO RETRIEVAL SUBROUTINE.
- C
- C SUBROUTINE DPNNZR() GETS THE NEXT NONZERO VALUE IN ROW OR COLUMN
- C +/- IRCX WITH AN INDEX GREATER THAN THE VALUE OF I.
- C
- C I ABSOLUTE VALUE OF THIS SUBSCRIPT IS TO BE EXCEEDED
- C IN THE SEARCH FOR THE NEXT NONZERO VALUE. A NEGATIVE
- C OR ZERO VALUE OF I CAUSES THE SEARCH TO START AT
- C THE BEGINNING OF THE VECTOR. A POSITIVE VALUE
- C OF I CAUSES THE SEARCH TO CONTINUE FROM THE LAST PLACE
- C ACCESSED. ON OUTPUT, THE ARGUMENT I
- C CONTAINS THE VALUE OF THE SUBSCRIPT FOUND. AN OUTPUT
- C VALUE OF I EQUAL TO ZERO INDICATES THAT ALL COMPONENTS
- C WITH AN INDEX GREATER THAN THE INPUT VALUE OF I ARE
- C ZERO.
- C XVAL VALUE OF THE NONZERO ELEMENT FOUND. ON OUTPUT,
- C XVAL=0. WHENEVER I=0.
- C IPLACE POINTER INFORMATION WHICH IS MAINTAINED BY THE PACKAGE.
- C SX(*),IX(*) THE WORK ARRAYS WHICH ARE USED TO STORE THE SPARSE
- C MATRIX. THESE ARRAY CONTENTS ARE AUTOMATICALLY
- C MAINTAINED BY THE PACKAGE FOR THE USER.
- C IRCX POINTS TO THE VECTOR OF THE MATRIX BEING SCANNED. A
- C NEGATIVE VALUE OF IRCX INDICATES THAT ROW -IRCX IS TO BE
- C SCANNED. A POSITIVE VALUE OF IRCX INDICATES THAT
- C COLUMN IRCX IS TO BE SCANNED. A ZERO VALUE OF IRCX IS
- C AN ERROR.
- C
- C THIS SUBROUTINE IS A MODIFICATION OF THE SUBROUTINE LNNZRS,
- C SANDIA LABS. REPT. SAND78-0785.
- C MODIFICATIONS BY K.L. HIEBERT AND R.J. HANSON
- C REVISED 811130-1000
- C REVISED YYMMDD-HHMM
- C
- C***SEE ALSO DSPLP
- C***ROUTINES CALLED IDLOC, XERMSG
- C***REVISION HISTORY (YYMMDD)
- C 811215 DATE WRITTEN
- C 890531 Changed all specific intrinsics to generic. (WRB)
- C 890605 Removed unreferenced labels. (WRB)
- C 890606 Changed references from IPLOC to IDLOC. (WRB)
- C 891214 Prologue converted to Version 4.0 format. (BAB)
- C 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ)
- C 900328 Added TYPE section. (WRB)
- C 910403 Updated AUTHOR and DESCRIPTION sections. (WRB)
- C***END PROLOGUE DPNNZR
- DIMENSION IX(*)
- DOUBLE PRECISION XVAL,SX(*),ZERO
- SAVE ZERO
- DATA ZERO /0.D0/
- C***FIRST EXECUTABLE STATEMENT DPNNZR
- IOPT=1
- C
- C CHECK VALIDITY OF ROW/COL. INDEX.
- C
- IF (.NOT.(IRCX .EQ.0)) GO TO 20002
- NERR=55
- CALL XERMSG ('SLATEC', 'DPNNZR', 'IRCX=0', NERR, IOPT)
- C
- C LMX IS THE LENGTH OF THE IN-MEMORY STORAGE AREA.
- C
- 20002 LMX = IX(1)
- IF (.NOT.(IRCX.LT.0)) GO TO 20005
- C
- C CHECK SUBSCRIPTS OF THE ROW. THE ROW NUMBER MUST BE .LE. M AND
- C THE INDEX MUST BE .LE. N.
- C
- IF (.NOT.(IX(2).LT.-IRCX .OR. IX(3).LT.ABS(I))) GO TO 20008
- NERR=55
- CALL XERMSG ('SLATEC', 'DPNNZR',
- + 'SUBSCRIPTS FOR ARRAY ELEMENT TO BE ACCESSED WERE OUT OF ' //
- + 'BOUNDS.', NERR, IOPT)
- 20008 L=IX(3)
- GO TO 20006
- C
- C CHECK SUBSCRIPTS OF THE COLUMN. THE COL. NUMBER MUST BE .LE. N AND
- C THE INDEX MUST BE .LE. M.
- C
- 20005 IF (.NOT.(IRCX.GT.IX(3) .OR. ABS(I).GT.IX(2))) GO TO 20011
- NERR=55
- CALL XERMSG ('SLATEC', 'DPNNZR',
- + 'SUBSCRIPTS FOR ARRAY ELEMENT TO BE ACCESSED WERE OUT OF ' //
- + 'BOUNDS', NERR, IOPT)
- 20011 L=IX(2)
- C
- C HERE L IS THE LARGEST POSSIBLE SUBSCRIPT WITHIN THE VECTOR.
- C
- 20006 J=ABS(IRCX)
- LL=IX(3)+4
- LPG = LMX - LL
- IF (.NOT.(IRCX.GT.0)) GO TO 20014
- C
- C SEARCHING FOR THE NEXT NONZERO IN A COLUMN.
- C
- C INITIALIZE STARTING LOCATIONS..
- IF (.NOT.(I.LE.0)) GO TO 20017
- IF (.NOT.(J.EQ.1)) GO TO 20020
- IPLACE=LL+1
- GO TO 20021
- 20020 IPLACE=IX(J+3)+1
- 20021 CONTINUE
- C
- C THE CASE I.LE.0 SIGNALS THAT THE SCAN FOR THE ENTRY
- C IS TO BEGIN AT THE START OF THE VECTOR.
- C
- 20017 I = ABS(I)
- IF (.NOT.(J.EQ.1)) GO TO 20023
- ISTART = LL+1
- GO TO 20024
- 20023 ISTART=IX(J+3)+1
- 20024 IEND = IX(J+4)
- C
- C VALIDATE IPLACE. SET TO START OF VECTOR IF OUT OF RANGE.
- C
- IF (.NOT.(ISTART.GT.IPLACE .OR. IPLACE.GT.IEND)) GO TO 20026
- IF (.NOT.(J.EQ.1)) GO TO 20029
- IPLACE=LL+1
- GO TO 20030
- 20029 IPLACE=IX(J+3)+1
- 20030 CONTINUE
- C
- C SCAN THROUGH SEVERAL PAGES, IF NECESSARY, TO FIND MATRIX ENTRY.
- C
- 20026 IPL = IDLOC(IPLACE,SX,IX)
- C
- C FIX UP IPLACE AND IPL IF THEY POINT TO PAGING DATA.
- C THIS IS NECESSARY BECAUSE THERE IS CONTROL INFORMATION AT THE
- C END OF EACH PAGE.
- C
- IDIFF = LMX - IPL
- IF (.NOT.(IDIFF.LE.1.AND.IX(LMX-1).GT.0)) GO TO 20032
- C
- C UPDATE THE RELATIVE ADDRESS IN A NEW PAGE.
- C
- IPLACE = IPLACE + IDIFF + 1
- IPL = IDLOC(IPLACE,SX,IX)
- 20032 NP = ABS(IX(LMX-1))
- GO TO 20036
- 20035 IF (ILAST.EQ.IEND) GO TO 20037
- 20036 ILAST = MIN(IEND,NP*LPG+LL-2)
- C
- C THE VIRTUAL END OF THE DATA FOR THIS PAGE IS ILAST.
- C
- IL = IDLOC(ILAST,SX,IX)
- IL = MIN(IL,LMX-2)
- C
- C THE RELATIVE END OF DATA FOR THIS PAGE IS IL.
- C SEARCH FOR A NONZERO VALUE WITH AN INDEX .GT. I ON THE PRESENT
- C PAGE.
- C
- 20038 IF (.NOT.(.NOT.(IPL.GE.IL.OR.(IX(IPL).GT.I.AND.SX(IPL).NE.ZERO))))
- * GO TO 20039
- IPL=IPL+1
- GO TO 20038
- C
- C TEST IF WE HAVE FOUND THE NEXT NONZERO.
- C
- 20039 IF (.NOT.(IX(IPL).GT.I .AND. SX(IPL).NE.ZERO .AND. IPL.LE.IL)) GO
- *TO 20040
- I = IX(IPL)
- XVAL = SX(IPL)
- IPLACE = (NP-1)*LPG + IPL
- RETURN
- C
- C UPDATE TO SCAN THE NEXT PAGE.
- 20040 IPL = LL + 1
- NP = NP + 1
- GO TO 20035
- C
- C NO DATA WAS FOUND. END OF VECTOR ENCOUNTERED.
- C
- 20037 I = 0
- XVAL = ZERO
- IL = IL + 1
- IF(IL.EQ.LMX-1) IL = IL + 2
- C
- C IF A NEW ITEM WOULD BE INSERTED, IPLACE POINTS TO THE PLACE
- C TO PUT IT.
- C
- IPLACE = (NP-1)*LPG + IL
- RETURN
- C
- C SEARCH A ROW FOR THE NEXT NONZERO.
- C FIND ELEMENT J=ABS(IRCX) IN ROWS ABS(I)+1,...,L.
- C
- 20014 I=ABS(I)
- C
- C CHECK FOR END OF VECTOR.
- C
- IF (.NOT.(I.EQ.L)) GO TO 20043
- I=0
- XVAL=ZERO
- RETURN
- 20043 I1 = I+1
- II=I1
- N20046=L
- GO TO 20047
- 20046 II=II+1
- 20047 IF ((N20046-II).LT.0) GO TO 20048
- C
- C INITIALIZE IPPLOC FOR ORTHOGONAL SCAN.
- C LOOK FOR J AS A SUBSCRIPT IN ROWS II, II=I+1,...,L.
- C
- IF (.NOT.(II.EQ.1)) GO TO 20050
- IPPLOC = LL + 1
- GO TO 20051
- 20050 IPPLOC = IX(II+3) + 1
- 20051 IEND = IX(II+4)
- C
- C SCAN THROUGH SEVERAL PAGES, IF NECESSARY, TO FIND MATRIX ENTRY.
- C
- IPL = IDLOC(IPPLOC,SX,IX)
- C
- C FIX UP IPPLOC AND IPL TO POINT TO MATRIX DATA.
- C
- IDIFF = LMX - IPL
- IF (.NOT.(IDIFF.LE.1.AND.IX(LMX-1).GT.0)) GO TO 20053
- IPPLOC = IPPLOC + IDIFF + 1
- IPL = IDLOC(IPPLOC,SX,IX)
- 20053 NP = ABS(IX(LMX-1))
- GO TO 20057
- 20056 IF (ILAST.EQ.IEND) GO TO 20058
- 20057 ILAST = MIN(IEND,NP*LPG+LL-2)
- IL = IDLOC(ILAST,SX,IX)
- IL = MIN(IL,LMX-2)
- 20059 IF (.NOT.(.NOT.(IPL.GE.IL .OR. IX(IPL).GE.J))) GO TO 20060
- IPL=IPL+1
- GO TO 20059
- C
- C TEST IF WE HAVE FOUND THE NEXT NONZERO.
- C
- 20060 IF (.NOT.(IX(IPL).EQ.J .AND. SX(IPL).NE.ZERO .AND. IPL.LE.IL)) GO
- *TO 20061
- I = II
- XVAL = SX(IPL)
- RETURN
- 20061 IF(IX(IPL).GE.J) ILAST = IEND
- IPL = LL + 1
- NP = NP + 1
- GO TO 20056
- 20058 GO TO 20046
- C
- C ORTHOGONAL SCAN FAILED. THE VALUE J WAS NOT A SUBSCRIPT
- C IN ANY ROW.
- C
- 20048 I=0
- XVAL=ZERO
- RETURN
- END
|