la05cs.f 12 KB

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