dspfa.f 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. *DECK DSPFA
  2. SUBROUTINE DSPFA (AP, N, KPVT, INFO)
  3. C***BEGIN PROLOGUE DSPFA
  4. C***PURPOSE Factor a real symmetric matrix stored in packed form by
  5. C elimination with symmetric pivoting.
  6. C***LIBRARY SLATEC (LINPACK)
  7. C***CATEGORY D2B1A
  8. C***TYPE DOUBLE PRECISION (SSPFA-S, DSPFA-D, CHPFA-C, CSPFA-C)
  9. C***KEYWORDS LINEAR ALGEBRA, LINPACK, MATRIX FACTORIZATION, PACKED,
  10. C SYMMETRIC
  11. C***AUTHOR Bunch, J., (UCSD)
  12. C***DESCRIPTION
  13. C
  14. C DSPFA factors a double precision symmetric matrix stored in
  15. C packed form by elimination with symmetric pivoting.
  16. C
  17. C To solve A*X = B , follow DSPFA by DSPSL.
  18. C To compute INVERSE(A)*C , follow DSPFA by DSPSL.
  19. C To compute DETERMINANT(A) , follow DSPFA by DSPDI.
  20. C To compute INERTIA(A) , follow DSPFA by DSPDI.
  21. C To compute INVERSE(A) , follow DSPFA by DSPDI.
  22. C
  23. C On Entry
  24. C
  25. C AP DOUBLE PRECISION (N*(N+1)/2)
  26. C the packed form of a symmetric matrix A . The
  27. C columns of the upper triangle are stored sequentially
  28. C in a one-dimensional array of length N*(N+1)/2 .
  29. C See comments below for details.
  30. C
  31. C N INTEGER
  32. C the order of the matrix A .
  33. C
  34. C Output
  35. C
  36. C AP a block diagonal matrix and the multipliers which
  37. C were used to obtain it stored in packed form.
  38. C The factorization can be written A = U*D*TRANS(U)
  39. C where U is a product of permutation and unit
  40. C upper triangular matrices, TRANS(U) is the
  41. C transpose of U , and D is block diagonal
  42. C with 1 by 1 and 2 by 2 blocks.
  43. C
  44. C KPVT INTEGER(N)
  45. C an integer vector of pivot indices.
  46. C
  47. C INFO INTEGER
  48. C = 0 normal value.
  49. C = K if the K-th pivot block is singular. This is
  50. C not an error condition for this subroutine,
  51. C but it does indicate that DSPSL or DSPDI may
  52. C divide by zero if called.
  53. C
  54. C Packed Storage
  55. C
  56. C The following program segment will pack the upper
  57. C triangle of a symmetric matrix.
  58. C
  59. C K = 0
  60. C DO 20 J = 1, N
  61. C DO 10 I = 1, J
  62. C K = K + 1
  63. C AP(K) = A(I,J)
  64. C 10 CONTINUE
  65. C 20 CONTINUE
  66. C
  67. C***REFERENCES J. J. Dongarra, J. R. Bunch, C. B. Moler, and G. W.
  68. C Stewart, LINPACK Users' Guide, SIAM, 1979.
  69. C***ROUTINES CALLED DAXPY, DSWAP, IDAMAX
  70. C***REVISION HISTORY (YYMMDD)
  71. C 780814 DATE WRITTEN
  72. C 890531 Changed all specific intrinsics to generic. (WRB)
  73. C 890831 Modified array declarations. (WRB)
  74. C 891107 Modified routine equivalence list. (WRB)
  75. C 891107 REVISION DATE from Version 3.2
  76. C 891214 Prologue converted to Version 4.0 format. (BAB)
  77. C 900326 Removed duplicate information from DESCRIPTION section.
  78. C (WRB)
  79. C 920501 Reformatted the REFERENCES section. (WRB)
  80. C***END PROLOGUE DSPFA
  81. INTEGER N,KPVT(*),INFO
  82. DOUBLE PRECISION AP(*)
  83. C
  84. DOUBLE PRECISION AK,AKM1,BK,BKM1,DENOM,MULK,MULKM1,T
  85. DOUBLE PRECISION ABSAKK,ALPHA,COLMAX,ROWMAX
  86. INTEGER IDAMAX,IJ,IK,IKM1,IM,IMAX,IMAXP1,IMIM,IMJ,IMK
  87. INTEGER J,JJ,JK,JKM1,JMAX,JMIM,K,KK,KM1,KM1K,KM1KM1,KM2,KSTEP
  88. LOGICAL SWAP
  89. C***FIRST EXECUTABLE STATEMENT DSPFA
  90. C
  91. C INITIALIZE
  92. C
  93. C ALPHA IS USED IN CHOOSING PIVOT BLOCK SIZE.
  94. C
  95. ALPHA = (1.0D0 + SQRT(17.0D0))/8.0D0
  96. C
  97. INFO = 0
  98. C
  99. C MAIN LOOP ON K, WHICH GOES FROM N TO 1.
  100. C
  101. K = N
  102. IK = (N*(N - 1))/2
  103. 10 CONTINUE
  104. C
  105. C LEAVE THE LOOP IF K=0 OR K=1.
  106. C
  107. IF (K .EQ. 0) GO TO 200
  108. IF (K .GT. 1) GO TO 20
  109. KPVT(1) = 1
  110. IF (AP(1) .EQ. 0.0D0) INFO = 1
  111. GO TO 200
  112. 20 CONTINUE
  113. C
  114. C THIS SECTION OF CODE DETERMINES THE KIND OF
  115. C ELIMINATION TO BE PERFORMED. WHEN IT IS COMPLETED,
  116. C KSTEP WILL BE SET TO THE SIZE OF THE PIVOT BLOCK, AND
  117. C SWAP WILL BE SET TO .TRUE. IF AN INTERCHANGE IS
  118. C REQUIRED.
  119. C
  120. KM1 = K - 1
  121. KK = IK + K
  122. ABSAKK = ABS(AP(KK))
  123. C
  124. C DETERMINE THE LARGEST OFF-DIAGONAL ELEMENT IN
  125. C COLUMN K.
  126. C
  127. IMAX = IDAMAX(K-1,AP(IK+1),1)
  128. IMK = IK + IMAX
  129. COLMAX = ABS(AP(IMK))
  130. IF (ABSAKK .LT. ALPHA*COLMAX) GO TO 30
  131. KSTEP = 1
  132. SWAP = .FALSE.
  133. GO TO 90
  134. 30 CONTINUE
  135. C
  136. C DETERMINE THE LARGEST OFF-DIAGONAL ELEMENT IN
  137. C ROW IMAX.
  138. C
  139. ROWMAX = 0.0D0
  140. IMAXP1 = IMAX + 1
  141. IM = IMAX*(IMAX - 1)/2
  142. IMJ = IM + 2*IMAX
  143. DO 40 J = IMAXP1, K
  144. ROWMAX = MAX(ROWMAX,ABS(AP(IMJ)))
  145. IMJ = IMJ + J
  146. 40 CONTINUE
  147. IF (IMAX .EQ. 1) GO TO 50
  148. JMAX = IDAMAX(IMAX-1,AP(IM+1),1)
  149. JMIM = JMAX + IM
  150. ROWMAX = MAX(ROWMAX,ABS(AP(JMIM)))
  151. 50 CONTINUE
  152. IMIM = IMAX + IM
  153. IF (ABS(AP(IMIM)) .LT. ALPHA*ROWMAX) GO TO 60
  154. KSTEP = 1
  155. SWAP = .TRUE.
  156. GO TO 80
  157. 60 CONTINUE
  158. IF (ABSAKK .LT. ALPHA*COLMAX*(COLMAX/ROWMAX)) GO TO 70
  159. KSTEP = 1
  160. SWAP = .FALSE.
  161. GO TO 80
  162. 70 CONTINUE
  163. KSTEP = 2
  164. SWAP = IMAX .NE. KM1
  165. 80 CONTINUE
  166. 90 CONTINUE
  167. IF (MAX(ABSAKK,COLMAX) .NE. 0.0D0) GO TO 100
  168. C
  169. C COLUMN K IS ZERO. SET INFO AND ITERATE THE LOOP.
  170. C
  171. KPVT(K) = K
  172. INFO = K
  173. GO TO 190
  174. 100 CONTINUE
  175. IF (KSTEP .EQ. 2) GO TO 140
  176. C
  177. C 1 X 1 PIVOT BLOCK.
  178. C
  179. IF (.NOT.SWAP) GO TO 120
  180. C
  181. C PERFORM AN INTERCHANGE.
  182. C
  183. CALL DSWAP(IMAX,AP(IM+1),1,AP(IK+1),1)
  184. IMJ = IK + IMAX
  185. DO 110 JJ = IMAX, K
  186. J = K + IMAX - JJ
  187. JK = IK + J
  188. T = AP(JK)
  189. AP(JK) = AP(IMJ)
  190. AP(IMJ) = T
  191. IMJ = IMJ - (J - 1)
  192. 110 CONTINUE
  193. 120 CONTINUE
  194. C
  195. C PERFORM THE ELIMINATION.
  196. C
  197. IJ = IK - (K - 1)
  198. DO 130 JJ = 1, KM1
  199. J = K - JJ
  200. JK = IK + J
  201. MULK = -AP(JK)/AP(KK)
  202. T = MULK
  203. CALL DAXPY(J,T,AP(IK+1),1,AP(IJ+1),1)
  204. AP(JK) = MULK
  205. IJ = IJ - (J - 1)
  206. 130 CONTINUE
  207. C
  208. C SET THE PIVOT ARRAY.
  209. C
  210. KPVT(K) = K
  211. IF (SWAP) KPVT(K) = IMAX
  212. GO TO 190
  213. 140 CONTINUE
  214. C
  215. C 2 X 2 PIVOT BLOCK.
  216. C
  217. KM1K = IK + K - 1
  218. IKM1 = IK - (K - 1)
  219. IF (.NOT.SWAP) GO TO 160
  220. C
  221. C PERFORM AN INTERCHANGE.
  222. C
  223. CALL DSWAP(IMAX,AP(IM+1),1,AP(IKM1+1),1)
  224. IMJ = IKM1 + IMAX
  225. DO 150 JJ = IMAX, KM1
  226. J = KM1 + IMAX - JJ
  227. JKM1 = IKM1 + J
  228. T = AP(JKM1)
  229. AP(JKM1) = AP(IMJ)
  230. AP(IMJ) = T
  231. IMJ = IMJ - (J - 1)
  232. 150 CONTINUE
  233. T = AP(KM1K)
  234. AP(KM1K) = AP(IMK)
  235. AP(IMK) = T
  236. 160 CONTINUE
  237. C
  238. C PERFORM THE ELIMINATION.
  239. C
  240. KM2 = K - 2
  241. IF (KM2 .EQ. 0) GO TO 180
  242. AK = AP(KK)/AP(KM1K)
  243. KM1KM1 = IKM1 + K - 1
  244. AKM1 = AP(KM1KM1)/AP(KM1K)
  245. DENOM = 1.0D0 - AK*AKM1
  246. IJ = IK - (K - 1) - (K - 2)
  247. DO 170 JJ = 1, KM2
  248. J = KM1 - JJ
  249. JK = IK + J
  250. BK = AP(JK)/AP(KM1K)
  251. JKM1 = IKM1 + J
  252. BKM1 = AP(JKM1)/AP(KM1K)
  253. MULK = (AKM1*BK - BKM1)/DENOM
  254. MULKM1 = (AK*BKM1 - BK)/DENOM
  255. T = MULK
  256. CALL DAXPY(J,T,AP(IK+1),1,AP(IJ+1),1)
  257. T = MULKM1
  258. CALL DAXPY(J,T,AP(IKM1+1),1,AP(IJ+1),1)
  259. AP(JK) = MULK
  260. AP(JKM1) = MULKM1
  261. IJ = IJ - (J - 1)
  262. 170 CONTINUE
  263. 180 CONTINUE
  264. C
  265. C SET THE PIVOT ARRAY.
  266. C
  267. KPVT(K) = 1 - K
  268. IF (SWAP) KPVT(K) = -IMAX
  269. KPVT(K-1) = KPVT(K)
  270. 190 CONTINUE
  271. IK = IK - (K - 1)
  272. IF (KSTEP .EQ. 2) IK = IK - (K - 2)
  273. K = K - KSTEP
  274. GO TO 10
  275. 200 CONTINUE
  276. RETURN
  277. END