dpnnzr.f 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. *DECK DPNNZR
  2. SUBROUTINE DPNNZR (I, XVAL, IPLACE, SX, IX, IRCX)
  3. C***BEGIN PROLOGUE DPNNZR
  4. C***SUBSIDIARY
  5. C***PURPOSE Subsidiary to DSPLP
  6. C***LIBRARY SLATEC
  7. C***TYPE DOUBLE PRECISION (PNNZRS-S, DPNNZR-D)
  8. C***AUTHOR Hanson, R. J., (SNLA)
  9. C Wisniewski, J. A., (SNLA)
  10. C***DESCRIPTION
  11. C
  12. C DPNNZR LIMITS THE TYPE OF STORAGE TO A SEQUENTIAL SCHEME.
  13. C SPARSE MATRIX NON ZERO RETRIEVAL SUBROUTINE.
  14. C
  15. C SUBROUTINE DPNNZR() GETS THE NEXT NONZERO VALUE IN ROW OR COLUMN
  16. C +/- IRCX WITH AN INDEX GREATER THAN THE VALUE OF I.
  17. C
  18. C I ABSOLUTE VALUE OF THIS SUBSCRIPT IS TO BE EXCEEDED
  19. C IN THE SEARCH FOR THE NEXT NONZERO VALUE. A NEGATIVE
  20. C OR ZERO VALUE OF I CAUSES THE SEARCH TO START AT
  21. C THE BEGINNING OF THE VECTOR. A POSITIVE VALUE
  22. C OF I CAUSES THE SEARCH TO CONTINUE FROM THE LAST PLACE
  23. C ACCESSED. ON OUTPUT, THE ARGUMENT I
  24. C CONTAINS THE VALUE OF THE SUBSCRIPT FOUND. AN OUTPUT
  25. C VALUE OF I EQUAL TO ZERO INDICATES THAT ALL COMPONENTS
  26. C WITH AN INDEX GREATER THAN THE INPUT VALUE OF I ARE
  27. C ZERO.
  28. C XVAL VALUE OF THE NONZERO ELEMENT FOUND. ON OUTPUT,
  29. C XVAL=0. WHENEVER I=0.
  30. C IPLACE POINTER INFORMATION WHICH IS MAINTAINED BY THE PACKAGE.
  31. C SX(*),IX(*) THE WORK ARRAYS WHICH ARE USED TO STORE THE SPARSE
  32. C MATRIX. THESE ARRAY CONTENTS ARE AUTOMATICALLY
  33. C MAINTAINED BY THE PACKAGE FOR THE USER.
  34. C IRCX POINTS TO THE VECTOR OF THE MATRIX BEING SCANNED. A
  35. C NEGATIVE VALUE OF IRCX INDICATES THAT ROW -IRCX IS TO BE
  36. C SCANNED. A POSITIVE VALUE OF IRCX INDICATES THAT
  37. C COLUMN IRCX IS TO BE SCANNED. A ZERO VALUE OF IRCX IS
  38. C AN ERROR.
  39. C
  40. C THIS SUBROUTINE IS A MODIFICATION OF THE SUBROUTINE LNNZRS,
  41. C SANDIA LABS. REPT. SAND78-0785.
  42. C MODIFICATIONS BY K.L. HIEBERT AND R.J. HANSON
  43. C REVISED 811130-1000
  44. C REVISED YYMMDD-HHMM
  45. C
  46. C***SEE ALSO DSPLP
  47. C***ROUTINES CALLED IDLOC, XERMSG
  48. C***REVISION HISTORY (YYMMDD)
  49. C 811215 DATE WRITTEN
  50. C 890531 Changed all specific intrinsics to generic. (WRB)
  51. C 890605 Removed unreferenced labels. (WRB)
  52. C 890606 Changed references from IPLOC to IDLOC. (WRB)
  53. C 891214 Prologue converted to Version 4.0 format. (BAB)
  54. C 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ)
  55. C 900328 Added TYPE section. (WRB)
  56. C 910403 Updated AUTHOR and DESCRIPTION sections. (WRB)
  57. C***END PROLOGUE DPNNZR
  58. DIMENSION IX(*)
  59. DOUBLE PRECISION XVAL,SX(*),ZERO
  60. SAVE ZERO
  61. DATA ZERO /0.D0/
  62. C***FIRST EXECUTABLE STATEMENT DPNNZR
  63. IOPT=1
  64. C
  65. C CHECK VALIDITY OF ROW/COL. INDEX.
  66. C
  67. IF (.NOT.(IRCX .EQ.0)) GO TO 20002
  68. NERR=55
  69. CALL XERMSG ('SLATEC', 'DPNNZR', 'IRCX=0', NERR, IOPT)
  70. C
  71. C LMX IS THE LENGTH OF THE IN-MEMORY STORAGE AREA.
  72. C
  73. 20002 LMX = IX(1)
  74. IF (.NOT.(IRCX.LT.0)) GO TO 20005
  75. C
  76. C CHECK SUBSCRIPTS OF THE ROW. THE ROW NUMBER MUST BE .LE. M AND
  77. C THE INDEX MUST BE .LE. N.
  78. C
  79. IF (.NOT.(IX(2).LT.-IRCX .OR. IX(3).LT.ABS(I))) GO TO 20008
  80. NERR=55
  81. CALL XERMSG ('SLATEC', 'DPNNZR',
  82. + 'SUBSCRIPTS FOR ARRAY ELEMENT TO BE ACCESSED WERE OUT OF ' //
  83. + 'BOUNDS.', NERR, IOPT)
  84. 20008 L=IX(3)
  85. GO TO 20006
  86. C
  87. C CHECK SUBSCRIPTS OF THE COLUMN. THE COL. NUMBER MUST BE .LE. N AND
  88. C THE INDEX MUST BE .LE. M.
  89. C
  90. 20005 IF (.NOT.(IRCX.GT.IX(3) .OR. ABS(I).GT.IX(2))) GO TO 20011
  91. NERR=55
  92. CALL XERMSG ('SLATEC', 'DPNNZR',
  93. + 'SUBSCRIPTS FOR ARRAY ELEMENT TO BE ACCESSED WERE OUT OF ' //
  94. + 'BOUNDS', NERR, IOPT)
  95. 20011 L=IX(2)
  96. C
  97. C HERE L IS THE LARGEST POSSIBLE SUBSCRIPT WITHIN THE VECTOR.
  98. C
  99. 20006 J=ABS(IRCX)
  100. LL=IX(3)+4
  101. LPG = LMX - LL
  102. IF (.NOT.(IRCX.GT.0)) GO TO 20014
  103. C
  104. C SEARCHING FOR THE NEXT NONZERO IN A COLUMN.
  105. C
  106. C INITIALIZE STARTING LOCATIONS..
  107. IF (.NOT.(I.LE.0)) GO TO 20017
  108. IF (.NOT.(J.EQ.1)) GO TO 20020
  109. IPLACE=LL+1
  110. GO TO 20021
  111. 20020 IPLACE=IX(J+3)+1
  112. 20021 CONTINUE
  113. C
  114. C THE CASE I.LE.0 SIGNALS THAT THE SCAN FOR THE ENTRY
  115. C IS TO BEGIN AT THE START OF THE VECTOR.
  116. C
  117. 20017 I = ABS(I)
  118. IF (.NOT.(J.EQ.1)) GO TO 20023
  119. ISTART = LL+1
  120. GO TO 20024
  121. 20023 ISTART=IX(J+3)+1
  122. 20024 IEND = IX(J+4)
  123. C
  124. C VALIDATE IPLACE. SET TO START OF VECTOR IF OUT OF RANGE.
  125. C
  126. IF (.NOT.(ISTART.GT.IPLACE .OR. IPLACE.GT.IEND)) GO TO 20026
  127. IF (.NOT.(J.EQ.1)) GO TO 20029
  128. IPLACE=LL+1
  129. GO TO 20030
  130. 20029 IPLACE=IX(J+3)+1
  131. 20030 CONTINUE
  132. C
  133. C SCAN THROUGH SEVERAL PAGES, IF NECESSARY, TO FIND MATRIX ENTRY.
  134. C
  135. 20026 IPL = IDLOC(IPLACE,SX,IX)
  136. C
  137. C FIX UP IPLACE AND IPL IF THEY POINT TO PAGING DATA.
  138. C THIS IS NECESSARY BECAUSE THERE IS CONTROL INFORMATION AT THE
  139. C END OF EACH PAGE.
  140. C
  141. IDIFF = LMX - IPL
  142. IF (.NOT.(IDIFF.LE.1.AND.IX(LMX-1).GT.0)) GO TO 20032
  143. C
  144. C UPDATE THE RELATIVE ADDRESS IN A NEW PAGE.
  145. C
  146. IPLACE = IPLACE + IDIFF + 1
  147. IPL = IDLOC(IPLACE,SX,IX)
  148. 20032 NP = ABS(IX(LMX-1))
  149. GO TO 20036
  150. 20035 IF (ILAST.EQ.IEND) GO TO 20037
  151. 20036 ILAST = MIN(IEND,NP*LPG+LL-2)
  152. C
  153. C THE VIRTUAL END OF THE DATA FOR THIS PAGE IS ILAST.
  154. C
  155. IL = IDLOC(ILAST,SX,IX)
  156. IL = MIN(IL,LMX-2)
  157. C
  158. C THE RELATIVE END OF DATA FOR THIS PAGE IS IL.
  159. C SEARCH FOR A NONZERO VALUE WITH AN INDEX .GT. I ON THE PRESENT
  160. C PAGE.
  161. C
  162. 20038 IF (.NOT.(.NOT.(IPL.GE.IL.OR.(IX(IPL).GT.I.AND.SX(IPL).NE.ZERO))))
  163. * GO TO 20039
  164. IPL=IPL+1
  165. GO TO 20038
  166. C
  167. C TEST IF WE HAVE FOUND THE NEXT NONZERO.
  168. C
  169. 20039 IF (.NOT.(IX(IPL).GT.I .AND. SX(IPL).NE.ZERO .AND. IPL.LE.IL)) GO
  170. *TO 20040
  171. I = IX(IPL)
  172. XVAL = SX(IPL)
  173. IPLACE = (NP-1)*LPG + IPL
  174. RETURN
  175. C
  176. C UPDATE TO SCAN THE NEXT PAGE.
  177. 20040 IPL = LL + 1
  178. NP = NP + 1
  179. GO TO 20035
  180. C
  181. C NO DATA WAS FOUND. END OF VECTOR ENCOUNTERED.
  182. C
  183. 20037 I = 0
  184. XVAL = ZERO
  185. IL = IL + 1
  186. IF(IL.EQ.LMX-1) IL = IL + 2
  187. C
  188. C IF A NEW ITEM WOULD BE INSERTED, IPLACE POINTS TO THE PLACE
  189. C TO PUT IT.
  190. C
  191. IPLACE = (NP-1)*LPG + IL
  192. RETURN
  193. C
  194. C SEARCH A ROW FOR THE NEXT NONZERO.
  195. C FIND ELEMENT J=ABS(IRCX) IN ROWS ABS(I)+1,...,L.
  196. C
  197. 20014 I=ABS(I)
  198. C
  199. C CHECK FOR END OF VECTOR.
  200. C
  201. IF (.NOT.(I.EQ.L)) GO TO 20043
  202. I=0
  203. XVAL=ZERO
  204. RETURN
  205. 20043 I1 = I+1
  206. II=I1
  207. N20046=L
  208. GO TO 20047
  209. 20046 II=II+1
  210. 20047 IF ((N20046-II).LT.0) GO TO 20048
  211. C
  212. C INITIALIZE IPPLOC FOR ORTHOGONAL SCAN.
  213. C LOOK FOR J AS A SUBSCRIPT IN ROWS II, II=I+1,...,L.
  214. C
  215. IF (.NOT.(II.EQ.1)) GO TO 20050
  216. IPPLOC = LL + 1
  217. GO TO 20051
  218. 20050 IPPLOC = IX(II+3) + 1
  219. 20051 IEND = IX(II+4)
  220. C
  221. C SCAN THROUGH SEVERAL PAGES, IF NECESSARY, TO FIND MATRIX ENTRY.
  222. C
  223. IPL = IDLOC(IPPLOC,SX,IX)
  224. C
  225. C FIX UP IPPLOC AND IPL TO POINT TO MATRIX DATA.
  226. C
  227. IDIFF = LMX - IPL
  228. IF (.NOT.(IDIFF.LE.1.AND.IX(LMX-1).GT.0)) GO TO 20053
  229. IPPLOC = IPPLOC + IDIFF + 1
  230. IPL = IDLOC(IPPLOC,SX,IX)
  231. 20053 NP = ABS(IX(LMX-1))
  232. GO TO 20057
  233. 20056 IF (ILAST.EQ.IEND) GO TO 20058
  234. 20057 ILAST = MIN(IEND,NP*LPG+LL-2)
  235. IL = IDLOC(ILAST,SX,IX)
  236. IL = MIN(IL,LMX-2)
  237. 20059 IF (.NOT.(.NOT.(IPL.GE.IL .OR. IX(IPL).GE.J))) GO TO 20060
  238. IPL=IPL+1
  239. GO TO 20059
  240. C
  241. C TEST IF WE HAVE FOUND THE NEXT NONZERO.
  242. C
  243. 20060 IF (.NOT.(IX(IPL).EQ.J .AND. SX(IPL).NE.ZERO .AND. IPL.LE.IL)) GO
  244. *TO 20061
  245. I = II
  246. XVAL = SX(IPL)
  247. RETURN
  248. 20061 IF(IX(IPL).GE.J) ILAST = IEND
  249. IPL = LL + 1
  250. NP = NP + 1
  251. GO TO 20056
  252. 20058 GO TO 20046
  253. C
  254. C ORTHOGONAL SCAN FAILED. THE VALUE J WAS NOT A SUBSCRIPT
  255. C IN ANY ROW.
  256. C
  257. 20048 I=0
  258. XVAL=ZERO
  259. RETURN
  260. END