la05cd.f 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. *DECK LA05CD
  2. SUBROUTINE LA05CD (A, IND, IA, N, IP, IW, W, G, U, MM)
  3. C***BEGIN PROLOGUE LA05CD
  4. C***SUBSIDIARY
  5. C***PURPOSE Subsidiary to DSPLP
  6. C***LIBRARY SLATEC
  7. C***TYPE DOUBLE PRECISION (LA05CS-D, LA05CD-D)
  8. C***AUTHOR (UNKNOWN)
  9. C***DESCRIPTION
  10. C
  11. C THIS SUBPROGRAM IS A SLIGHT MODIFICATION OF A SUBPROGRAM
  12. C FROM THE C. 1979 AERE HARWELL LIBRARY. THE NAME OF THE
  13. C CORRESPONDING HARWELL CODE CAN BE OBTAINED BY DELETING
  14. C THE FINAL LETTER =D= IN THE NAMES USED HERE.
  15. C REVISED SEP. 13, 1979.
  16. C
  17. C ROYALTIES HAVE BEEN PAID TO AERE-UK FOR USE OF THEIR CODES
  18. C IN THE PACKAGE GIVEN HERE. ANY PRIMARY USAGE OF THE HARWELL
  19. C SUBROUTINES REQUIRES A ROYALTY AGREEMENT AND PAYMENT BETWEEN
  20. C THE USER AND AERE-UK. ANY USAGE OF THE SANDIA WRITTEN CODES
  21. C DSPLP( ) (WHICH USES THE HARWELL SUBROUTINES) IS PERMITTED.
  22. C
  23. C***SEE ALSO DSPLP
  24. C***ROUTINES CALLED LA05ED, XERMSG, XSETUN
  25. C***COMMON BLOCKS LA05DD
  26. C***REVISION HISTORY (YYMMDD)
  27. C 811215 DATE WRITTEN
  28. C 890531 Changed all specific intrinsics to generic. (WRB)
  29. C 890831 Modified array declarations. (WRB)
  30. C 891214 Prologue converted to Version 4.0 format. (BAB)
  31. C 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ)
  32. C 900402 Added TYPE section. (WRB)
  33. C 900510 Convert XERRWV calls to XERMSG calls. (RWC)
  34. C 920410 Corrected second dimension on IW declaration. (WRB)
  35. C 920422 Changed upper limit on DO from LAST to LAST-1. (WRB)
  36. C***END PROLOGUE LA05CD
  37. DOUBLE PRECISION A(*), G, U, AM, W(*), SMALL, AU
  38. INTEGER IND(IA,2), IW(N,8)
  39. INTEGER IP(N,2)
  40. CHARACTER*8 XERN1
  41. C
  42. COMMON /LA05DD/ SMALL, LP, LENL, LENU, NCP, LROW, LCOL
  43. C***FIRST EXECUTABLE STATEMENT LA05CD
  44. CALL XSETUN(LP)
  45. IF (G.LT.0.0D0) GO TO 620
  46. JM = MM
  47. C MCP LIMITS THE VALUE OF NCP PERMITTED BEFORE AN ERROR RETURN RESULTS.
  48. MCP = NCP + 20
  49. C REMOVE OLD COLUMN
  50. LENU = LENU - IW(JM,2)
  51. KP = IP(JM,2)
  52. IM = IND(KP,1)
  53. KL = KP + IW(JM,2) - 1
  54. IW(JM,2) = 0
  55. DO 30 K=KP,KL
  56. I = IND(K,1)
  57. IND(K,1) = 0
  58. KR = IP(I,1)
  59. NZ = IW(I,1) - 1
  60. IW(I,1) = NZ
  61. KRL = KR + NZ
  62. DO 10 KM=KR,KRL
  63. IF (IND(KM,2).EQ.JM) GO TO 20
  64. 10 CONTINUE
  65. 20 A(KM) = A(KRL)
  66. IND(KM,2) = IND(KRL,2)
  67. IND(KRL,2) = 0
  68. 30 CONTINUE
  69. C
  70. C INSERT NEW COLUMN
  71. DO 110 II=1,N
  72. I = IW(II,3)
  73. IF (I.EQ.IM) M = II
  74. IF (ABS(W(I)).LE.SMALL) GO TO 100
  75. LENU = LENU + 1
  76. LAST = II
  77. IF (LCOL+LENL.LT.IA) GO TO 40
  78. C COMPRESS COLUMN FILE IF NECESSARY.
  79. IF (NCP.GE.MCP .OR. LENL+LENU.GE.IA) GO TO 610
  80. CALL LA05ED(A, IND, IP(1,2), N, IW(1,2), IA, .FALSE.)
  81. 40 LCOL = LCOL + 1
  82. NZ = IW(JM,2)
  83. IF (NZ.EQ.0) IP(JM,2) = LCOL
  84. IW(JM,2) = NZ + 1
  85. IND(LCOL,1) = I
  86. NZ = IW(I,1)
  87. KPL = IP(I,1) + NZ
  88. IF (KPL.GT.LROW) GO TO 50
  89. IF (IND(KPL,2).EQ.0) GO TO 90
  90. C NEW ENTRY HAS TO BE CREATED.
  91. 50 IF (LENL+LROW+NZ.LT.IA) GO TO 60
  92. IF (NCP.GE.MCP .OR. LENL+LENU+NZ.GE.IA) GO TO 610
  93. C COMPRESS ROW FILE IF NECESSARY.
  94. CALL LA05ED(A, IND(1,2), IP, N, IW, IA, .TRUE.)
  95. 60 KP = IP(I,1)
  96. IP(I,1) = LROW + 1
  97. IF (NZ.EQ.0) GO TO 80
  98. KPL = KP + NZ - 1
  99. DO 70 K=KP,KPL
  100. LROW = LROW + 1
  101. A(LROW) = A(K)
  102. IND(LROW,2) = IND(K,2)
  103. IND(K,2) = 0
  104. 70 CONTINUE
  105. 80 LROW = LROW + 1
  106. KPL = LROW
  107. C PLACE NEW ELEMENT AT END OF ROW.
  108. 90 IW(I,1) = NZ + 1
  109. A(KPL) = W(I)
  110. IND(KPL,2) = JM
  111. 100 W(I) = 0.0D0
  112. 110 CONTINUE
  113. IF (IW(IM,1).EQ.0 .OR. IW(JM,2).EQ.0 .OR. M.GT.LAST) GO TO 590
  114. C
  115. C FIND COLUMN SINGLETONS, OTHER THAN THE SPIKE. NON-SINGLETONS ARE
  116. C MARKED WITH W(J)=1. ONLY IW(.,3) IS REVISED AND IW(.,4) IS USED
  117. C FOR WORKSPACE.
  118. INS = M
  119. M1 = M
  120. W(JM) = 1.0D0
  121. DO 140 II=M,LAST
  122. I = IW(II,3)
  123. J = IW(II,4)
  124. IF (W(J).EQ.0.) GO TO 130
  125. KP = IP(I,1)
  126. KL = KP + IW(I,1) - 1
  127. DO 120 K=KP,KL
  128. J = IND(K,2)
  129. W(J) = 1.0D0
  130. 120 CONTINUE
  131. IW(INS,4) = I
  132. INS = INS + 1
  133. GO TO 140
  134. C PLACE SINGLETONS IN NEW POSITION.
  135. 130 IW(M1,3) = I
  136. M1 = M1 + 1
  137. 140 CONTINUE
  138. C PLACE NON-SINGLETONS IN NEW POSITION.
  139. IJ = M + 1
  140. DO 150 II=M1,LAST-1
  141. IW(II,3) = IW(IJ,4)
  142. IJ = IJ + 1
  143. 150 CONTINUE
  144. C PLACE SPIKE AT END.
  145. IW(LAST,3) = IM
  146. C
  147. C FIND ROW SINGLETONS, APART FROM SPIKE ROW. NON-SINGLETONS ARE MARKED
  148. C WITH W(I)=2. AGAIN ONLY IW(.,3) IS REVISED AND IW(.,4) IS USED
  149. C FOR WORKSPACE.
  150. LAST1 = LAST
  151. JNS = LAST
  152. W(IM) = 2.0D0
  153. J = JM
  154. DO 180 IJ=M1,LAST
  155. II = LAST + M1 - IJ
  156. I = IW(II,3)
  157. IF (W(I).NE.2.0D0) GO TO 170
  158. K = IP(I,1)
  159. IF (II.NE.LAST) J = IND(K,2)
  160. KP = IP(J,2)
  161. KL = KP + IW(J,2) - 1
  162. IW(JNS,4) = I
  163. JNS = JNS - 1
  164. DO 160 K=KP,KL
  165. I = IND(K,1)
  166. W(I) = 2.0D0
  167. 160 CONTINUE
  168. GO TO 180
  169. 170 IW(LAST1,3) = I
  170. LAST1 = LAST1 - 1
  171. 180 CONTINUE
  172. DO 190 II=M1,LAST1
  173. JNS = JNS + 1
  174. I = IW(JNS,4)
  175. W(I) = 3.0D0
  176. IW(II,3) = I
  177. 190 CONTINUE
  178. C
  179. C DEAL WITH SINGLETON SPIKE COLUMN. NOTE THAT BUMP ROWS ARE MARKED BY
  180. C W(I)=3.
  181. DO 230 II=M1,LAST1
  182. KP = IP(JM,2)
  183. KL = KP + IW(JM,2) - 1
  184. IS = 0
  185. DO 200 K=KP,KL
  186. L = IND(K,1)
  187. IF (W(L).NE.3.0D0) GO TO 200
  188. IF (IS.NE.0) GO TO 240
  189. I = L
  190. KNP = K
  191. IS = 1
  192. 200 CONTINUE
  193. IF (IS.EQ.0) GO TO 590
  194. C MAKE A(I,JM) A PIVOT.
  195. IND(KNP,1) = IND(KP,1)
  196. IND(KP,1) = I
  197. KP = IP(I,1)
  198. DO 210 K=KP,IA
  199. IF (IND(K,2).EQ.JM) GO TO 220
  200. 210 CONTINUE
  201. 220 AM = A(KP)
  202. A(KP) = A(K)
  203. A(K) = AM
  204. IND(K,2) = IND(KP,2)
  205. IND(KP,2) = JM
  206. JM = IND(K,2)
  207. IW(II,4) = I
  208. W(I) = 2.0D0
  209. 230 CONTINUE
  210. II = LAST1
  211. GO TO 260
  212. 240 IN = M1
  213. DO 250 IJ=II,LAST1
  214. IW(IJ,4) = IW(IN,3)
  215. IN = IN + 1
  216. 250 CONTINUE
  217. 260 LAST2 = LAST1 - 1
  218. IF (M1.EQ.LAST1) GO TO 570
  219. DO 270 I=M1,LAST2
  220. IW(I,3) = IW(I,4)
  221. 270 CONTINUE
  222. M1 = II
  223. IF (M1.EQ.LAST1) GO TO 570
  224. C
  225. C CLEAR W
  226. DO 280 I=1,N
  227. W(I) = 0.0D0
  228. 280 CONTINUE
  229. C
  230. C PERFORM ELIMINATION
  231. IR = IW(LAST1,3)
  232. DO 560 II=M1,LAST1
  233. IPP = IW(II,3)
  234. KP = IP(IPP,1)
  235. KR = IP(IR,1)
  236. JP = IND(KP,2)
  237. IF (II.EQ.LAST1) JP = JM
  238. C SEARCH NON-PIVOT ROW FOR ELEMENT TO BE ELIMINATED.
  239. C AND BRING IT TO FRONT OF ITS ROW
  240. KRL = KR + IW(IR,1) - 1
  241. DO 290 KNP=KR,KRL
  242. IF (JP.EQ.IND(KNP,2)) GO TO 300
  243. 290 CONTINUE
  244. IF (II-LAST1) 560, 590, 560
  245. C BRING ELEMENT TO BE ELIMINATED TO FRONT OF ITS ROW.
  246. 300 AM = A(KNP)
  247. A(KNP) = A(KR)
  248. A(KR) = AM
  249. IND(KNP,2) = IND(KR,2)
  250. IND(KR,2) = JP
  251. IF (II.EQ.LAST1) GO TO 310
  252. IF (ABS(A(KP)).LT.U*ABS(AM)) GO TO 310
  253. IF (ABS(AM).LT.U*ABS(A(KP))) GO TO 340
  254. IF (IW(IPP,1).LE.IW(IR,1)) GO TO 340
  255. C PERFORM INTERCHANGE
  256. 310 IW(LAST1,3) = IPP
  257. IW(II,3) = IR
  258. IR = IPP
  259. IPP = IW(II,3)
  260. K = KR
  261. KR = KP
  262. KP = K
  263. KJ = IP(JP,2)
  264. DO 320 K=KJ,IA
  265. IF (IND(K,1).EQ.IPP) GO TO 330
  266. 320 CONTINUE
  267. 330 IND(K,1) = IND(KJ,1)
  268. IND(KJ,1) = IPP
  269. 340 IF (A(KP).EQ.0.0D0) GO TO 590
  270. IF (II.EQ.LAST1) GO TO 560
  271. AM = -A(KR)/A(KP)
  272. C COMPRESS ROW FILE UNLESS IT IS CERTAIN THAT THERE IS ROOM FOR NEW ROW.
  273. IF (LROW+IW(IR,1)+IW(IPP,1)+LENL.LE.IA) GO TO 350
  274. IF (NCP.GE.MCP .OR. LENU+IW(IR,1)+IW(IPP,1)+LENL.GT.IA) GO TO
  275. * 610
  276. CALL LA05ED(A, IND(1,2), IP, N, IW, IA, .TRUE.)
  277. KP = IP(IPP,1)
  278. KR = IP(IR,1)
  279. 350 KRL = KR + IW(IR,1) - 1
  280. KQ = KP + 1
  281. KPL = KP + IW(IPP,1) - 1
  282. C PLACE PIVOT ROW (EXCLUDING PIVOT ITSELF) IN W.
  283. IF (KQ.GT.KPL) GO TO 370
  284. DO 360 K=KQ,KPL
  285. J = IND(K,2)
  286. W(J) = A(K)
  287. 360 CONTINUE
  288. 370 IP(IR,1) = LROW + 1
  289. C
  290. C TRANSFER MODIFIED ELEMENTS.
  291. IND(KR,2) = 0
  292. KR = KR + 1
  293. IF (KR.GT.KRL) GO TO 430
  294. DO 420 KS=KR,KRL
  295. J = IND(KS,2)
  296. AU = A(KS) + AM*W(J)
  297. IND(KS,2) = 0
  298. C IF ELEMENT IS VERY SMALL REMOVE IT FROM U.
  299. IF (ABS(AU).LE.SMALL) GO TO 380
  300. G = MAX(G,ABS(AU))
  301. LROW = LROW + 1
  302. A(LROW) = AU
  303. IND(LROW,2) = J
  304. GO TO 410
  305. 380 LENU = LENU - 1
  306. C REMOVE ELEMENT FROM COL FILE.
  307. K = IP(J,2)
  308. KL = K + IW(J,2) - 1
  309. IW(J,2) = KL - K
  310. DO 390 KK=K,KL
  311. IF (IND(KK,1).EQ.IR) GO TO 400
  312. 390 CONTINUE
  313. 400 IND(KK,1) = IND(KL,1)
  314. IND(KL,1) = 0
  315. 410 W(J) = 0.0D0
  316. 420 CONTINUE
  317. C
  318. C SCAN PIVOT ROW FOR FILLS.
  319. 430 IF (KQ.GT.KPL) GO TO 520
  320. DO 510 KS=KQ,KPL
  321. J = IND(KS,2)
  322. AU = AM*W(J)
  323. IF (ABS(AU).LE.SMALL) GO TO 500
  324. LROW = LROW + 1
  325. A(LROW) = AU
  326. IND(LROW,2) = J
  327. LENU = LENU + 1
  328. C
  329. C CREATE FILL IN COLUMN FILE.
  330. NZ = IW(J,2)
  331. K = IP(J,2)
  332. KL = K + NZ - 1
  333. C IF POSSIBLE PLACE NEW ELEMENT AT END OF PRESENT ENTRY.
  334. IF (KL.NE.LCOL) GO TO 440
  335. IF (LCOL+LENL.GE.IA) GO TO 460
  336. LCOL = LCOL + 1
  337. GO TO 450
  338. 440 IF (IND(KL+1,1).NE.0) GO TO 460
  339. 450 IND(KL+1,1) = IR
  340. GO TO 490
  341. C NEW ENTRY HAS TO BE CREATED.
  342. 460 IF (LCOL+LENL+NZ+1.LT.IA) GO TO 470
  343. C COMPRESS COLUMN FILE IF THERE IS NOT ROOM FOR NEW ENTRY.
  344. IF (NCP.GE.MCP .OR. LENU+LENL+NZ+1.GE.IA) GO TO 610
  345. CALL LA05ED(A, IND, IP(1,2), N, IW(1,2), IA, .FALSE.)
  346. K = IP(J,2)
  347. KL = K + NZ - 1
  348. C TRANSFER OLD ENTRY INTO NEW.
  349. 470 IP(J,2) = LCOL + 1
  350. DO 480 KK=K,KL
  351. LCOL = LCOL + 1
  352. IND(LCOL,1) = IND(KK,1)
  353. IND(KK,1) = 0
  354. 480 CONTINUE
  355. C ADD NEW ELEMENT.
  356. LCOL = LCOL + 1
  357. IND(LCOL,1) = IR
  358. 490 G = MAX(G,ABS(AU))
  359. IW(J,2) = NZ + 1
  360. 500 W(J) = 0.0D0
  361. 510 CONTINUE
  362. 520 IW(IR,1) = LROW + 1 - IP(IR,1)
  363. C
  364. C STORE MULTIPLIER
  365. IF (LENL+LCOL+1.LE.IA) GO TO 530
  366. C COMPRESS COL FILE IF NECESSARY.
  367. IF (NCP.GE.MCP) GO TO 610
  368. CALL LA05ED(A, IND, IP(1,2), N, IW(1,2), IA, .FALSE.)
  369. 530 K = IA - LENL
  370. LENL = LENL + 1
  371. A(K) = AM
  372. IND(K,1) = IPP
  373. IND(K,2) = IR
  374. C CREATE BLANK IN PIVOTAL COLUMN.
  375. KP = IP(JP,2)
  376. NZ = IW(JP,2) - 1
  377. KL = KP + NZ
  378. DO 540 K=KP,KL
  379. IF (IND(K,1).EQ.IR) GO TO 550
  380. 540 CONTINUE
  381. 550 IND(K,1) = IND(KL,1)
  382. IW(JP,2) = NZ
  383. IND(KL,1) = 0
  384. LENU = LENU - 1
  385. 560 CONTINUE
  386. C
  387. C CONSTRUCT COLUMN PERMUTATION AND STORE IT IN IW(.,4)
  388. 570 DO 580 II=M,LAST
  389. I = IW(II,3)
  390. K = IP(I,1)
  391. J = IND(K,2)
  392. IW(II,4) = J
  393. 580 CONTINUE
  394. RETURN
  395. C
  396. C THE FOLLOWING INSTRUCTIONS IMPLEMENT THE FAILURE EXITS.
  397. C
  398. 590 IF (LP.GT.0) THEN
  399. WRITE (XERN1, '(I8)') MM
  400. CALL XERMSG ('SLATEC', 'LA05CD', 'SINGULAR MATRIX AFTER ' //
  401. * 'REPLACEMENT OF COLUMN. INDEX = ' // XERN1, -6, 1)
  402. ENDIF
  403. G = -6.0D0
  404. RETURN
  405. C
  406. 610 IF (LP.GT.0) CALL XERMSG ('SLATEC', 'LA05CD',
  407. * 'LENGTHS OF ARRAYS A(*) AND IND(*,2) ARE TOO SMALL.', -7, 1)
  408. G = -7.0D0
  409. RETURN
  410. C
  411. 620 IF (LP.GT.0) CALL XERMSG ('SLATEC', 'LA05CD',
  412. * 'EARLIER ENTRY GAVE ERROR RETURN.', -8, 2)
  413. G = -8.0D0
  414. RETURN
  415. END