dspdi.f 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. *DECK DSPDI
  2. SUBROUTINE DSPDI (AP, N, KPVT, DET, INERT, WORK, JOB)
  3. C***BEGIN PROLOGUE DSPDI
  4. C***PURPOSE Compute the determinant, inertia, inverse of a real
  5. C symmetric matrix stored in packed form using the factors
  6. C from DSPFA.
  7. C***LIBRARY SLATEC (LINPACK)
  8. C***CATEGORY D2B1A, D3B1A
  9. C***TYPE DOUBLE PRECISION (SSPDI-S, DSPDI-D, CHPDI-C, CSPDI-C)
  10. C***KEYWORDS DETERMINANT, INVERSE, LINEAR ALGEBRA, LINPACK, MATRIX,
  11. C PACKED, SYMMETRIC
  12. C***AUTHOR Bunch, J., (UCSD)
  13. C***DESCRIPTION
  14. C
  15. C DSPDI computes the determinant, inertia and inverse
  16. C of a double precision symmetric matrix using the factors from
  17. C DSPFA, where the matrix is stored in packed form.
  18. C
  19. C On Entry
  20. C
  21. C AP DOUBLE PRECISION (N*(N+1)/2)
  22. C the output from DSPFA.
  23. C
  24. C N INTEGER
  25. C the order of the matrix A.
  26. C
  27. C KPVT INTEGER(N)
  28. C the pivot vector from DSPFA.
  29. C
  30. C WORK DOUBLE PRECISION(N)
  31. C work vector. Contents ignored.
  32. C
  33. C JOB INTEGER
  34. C JOB has the decimal expansion ABC where
  35. C if C .NE. 0, the inverse is computed,
  36. C if B .NE. 0, the determinant is computed,
  37. C if A .NE. 0, the inertia is computed.
  38. C
  39. C For example, JOB = 111 gives all three.
  40. C
  41. C On Return
  42. C
  43. C Variables not requested by JOB are not used.
  44. C
  45. C AP contains the upper triangle of the inverse of
  46. C the original matrix, stored in packed form.
  47. C The columns of the upper triangle are stored
  48. C sequentially in a one-dimensional array.
  49. C
  50. C DET DOUBLE PRECISION(2)
  51. C determinant of original matrix.
  52. C DETERMINANT = DET(1) * 10.0**DET(2)
  53. C with 1.0 .LE. ABS(DET(1)) .LT. 10.0
  54. C or DET(1) = 0.0.
  55. C
  56. C INERT INTEGER(3)
  57. C the inertia of the original matrix.
  58. C INERT(1) = number of positive eigenvalues.
  59. C INERT(2) = number of negative eigenvalues.
  60. C INERT(3) = number of zero eigenvalues.
  61. C
  62. C Error Condition
  63. C
  64. C A division by zero will occur if the inverse is requested
  65. C and DSPCO has set RCOND .EQ. 0.0
  66. C or DSPFA has set INFO .NE. 0 .
  67. C
  68. C***REFERENCES J. J. Dongarra, J. R. Bunch, C. B. Moler, and G. W.
  69. C Stewart, LINPACK Users' Guide, SIAM, 1979.
  70. C***ROUTINES CALLED DAXPY, DCOPY, DDOT, DSWAP
  71. C***REVISION HISTORY (YYMMDD)
  72. C 780814 DATE WRITTEN
  73. C 890531 Changed all specific intrinsics to generic. (WRB)
  74. C 890831 Modified array declarations. (WRB)
  75. C 891107 Modified routine equivalence list. (WRB)
  76. C 891107 REVISION DATE from Version 3.2
  77. C 891214 Prologue converted to Version 4.0 format. (BAB)
  78. C 900326 Removed duplicate information from DESCRIPTION section.
  79. C (WRB)
  80. C 920501 Reformatted the REFERENCES section. (WRB)
  81. C***END PROLOGUE DSPDI
  82. INTEGER N,JOB
  83. DOUBLE PRECISION AP(*),WORK(*)
  84. DOUBLE PRECISION DET(2)
  85. INTEGER KPVT(*),INERT(3)
  86. C
  87. DOUBLE PRECISION AKKP1,DDOT,TEMP
  88. DOUBLE PRECISION TEN,D,T,AK,AKP1
  89. INTEGER IJ,IK,IKP1,IKS,J,JB,JK,JKP1
  90. INTEGER K,KK,KKP1,KM1,KS,KSJ,KSKP1,KSTEP
  91. LOGICAL NOINV,NODET,NOERT
  92. C***FIRST EXECUTABLE STATEMENT DSPDI
  93. NOINV = MOD(JOB,10) .EQ. 0
  94. NODET = MOD(JOB,100)/10 .EQ. 0
  95. NOERT = MOD(JOB,1000)/100 .EQ. 0
  96. C
  97. IF (NODET .AND. NOERT) GO TO 140
  98. IF (NOERT) GO TO 10
  99. INERT(1) = 0
  100. INERT(2) = 0
  101. INERT(3) = 0
  102. 10 CONTINUE
  103. IF (NODET) GO TO 20
  104. DET(1) = 1.0D0
  105. DET(2) = 0.0D0
  106. TEN = 10.0D0
  107. 20 CONTINUE
  108. T = 0.0D0
  109. IK = 0
  110. DO 130 K = 1, N
  111. KK = IK + K
  112. D = AP(KK)
  113. C
  114. C CHECK IF 1 BY 1
  115. C
  116. IF (KPVT(K) .GT. 0) GO TO 50
  117. C
  118. C 2 BY 2 BLOCK
  119. C USE DET (D S) = (D/T * C - T) * T , T = ABS(S)
  120. C (S C)
  121. C TO AVOID UNDERFLOW/OVERFLOW TROUBLES.
  122. C TAKE TWO PASSES THROUGH SCALING. USE T FOR FLAG.
  123. C
  124. IF (T .NE. 0.0D0) GO TO 30
  125. IKP1 = IK + K
  126. KKP1 = IKP1 + K
  127. T = ABS(AP(KKP1))
  128. D = (D/T)*AP(KKP1+1) - T
  129. GO TO 40
  130. 30 CONTINUE
  131. D = T
  132. T = 0.0D0
  133. 40 CONTINUE
  134. 50 CONTINUE
  135. C
  136. IF (NOERT) GO TO 60
  137. IF (D .GT. 0.0D0) INERT(1) = INERT(1) + 1
  138. IF (D .LT. 0.0D0) INERT(2) = INERT(2) + 1
  139. IF (D .EQ. 0.0D0) INERT(3) = INERT(3) + 1
  140. 60 CONTINUE
  141. C
  142. IF (NODET) GO TO 120
  143. DET(1) = D*DET(1)
  144. IF (DET(1) .EQ. 0.0D0) GO TO 110
  145. 70 IF (ABS(DET(1)) .GE. 1.0D0) GO TO 80
  146. DET(1) = TEN*DET(1)
  147. DET(2) = DET(2) - 1.0D0
  148. GO TO 70
  149. 80 CONTINUE
  150. 90 IF (ABS(DET(1)) .LT. TEN) GO TO 100
  151. DET(1) = DET(1)/TEN
  152. DET(2) = DET(2) + 1.0D0
  153. GO TO 90
  154. 100 CONTINUE
  155. 110 CONTINUE
  156. 120 CONTINUE
  157. IK = IK + K
  158. 130 CONTINUE
  159. 140 CONTINUE
  160. C
  161. C COMPUTE INVERSE(A)
  162. C
  163. IF (NOINV) GO TO 270
  164. K = 1
  165. IK = 0
  166. 150 IF (K .GT. N) GO TO 260
  167. KM1 = K - 1
  168. KK = IK + K
  169. IKP1 = IK + K
  170. KKP1 = IKP1 + K
  171. IF (KPVT(K) .LT. 0) GO TO 180
  172. C
  173. C 1 BY 1
  174. C
  175. AP(KK) = 1.0D0/AP(KK)
  176. IF (KM1 .LT. 1) GO TO 170
  177. CALL DCOPY(KM1,AP(IK+1),1,WORK,1)
  178. IJ = 0
  179. DO 160 J = 1, KM1
  180. JK = IK + J
  181. AP(JK) = DDOT(J,AP(IJ+1),1,WORK,1)
  182. CALL DAXPY(J-1,WORK(J),AP(IJ+1),1,AP(IK+1),1)
  183. IJ = IJ + J
  184. 160 CONTINUE
  185. AP(KK) = AP(KK) + DDOT(KM1,WORK,1,AP(IK+1),1)
  186. 170 CONTINUE
  187. KSTEP = 1
  188. GO TO 220
  189. 180 CONTINUE
  190. C
  191. C 2 BY 2
  192. C
  193. T = ABS(AP(KKP1))
  194. AK = AP(KK)/T
  195. AKP1 = AP(KKP1+1)/T
  196. AKKP1 = AP(KKP1)/T
  197. D = T*(AK*AKP1 - 1.0D0)
  198. AP(KK) = AKP1/D
  199. AP(KKP1+1) = AK/D
  200. AP(KKP1) = -AKKP1/D
  201. IF (KM1 .LT. 1) GO TO 210
  202. CALL DCOPY(KM1,AP(IKP1+1),1,WORK,1)
  203. IJ = 0
  204. DO 190 J = 1, KM1
  205. JKP1 = IKP1 + J
  206. AP(JKP1) = DDOT(J,AP(IJ+1),1,WORK,1)
  207. CALL DAXPY(J-1,WORK(J),AP(IJ+1),1,AP(IKP1+1),1)
  208. IJ = IJ + J
  209. 190 CONTINUE
  210. AP(KKP1+1) = AP(KKP1+1)
  211. 1 + DDOT(KM1,WORK,1,AP(IKP1+1),1)
  212. AP(KKP1) = AP(KKP1)
  213. 1 + DDOT(KM1,AP(IK+1),1,AP(IKP1+1),1)
  214. CALL DCOPY(KM1,AP(IK+1),1,WORK,1)
  215. IJ = 0
  216. DO 200 J = 1, KM1
  217. JK = IK + J
  218. AP(JK) = DDOT(J,AP(IJ+1),1,WORK,1)
  219. CALL DAXPY(J-1,WORK(J),AP(IJ+1),1,AP(IK+1),1)
  220. IJ = IJ + J
  221. 200 CONTINUE
  222. AP(KK) = AP(KK) + DDOT(KM1,WORK,1,AP(IK+1),1)
  223. 210 CONTINUE
  224. KSTEP = 2
  225. 220 CONTINUE
  226. C
  227. C SWAP
  228. C
  229. KS = ABS(KPVT(K))
  230. IF (KS .EQ. K) GO TO 250
  231. IKS = (KS*(KS - 1))/2
  232. CALL DSWAP(KS,AP(IKS+1),1,AP(IK+1),1)
  233. KSJ = IK + KS
  234. DO 230 JB = KS, K
  235. J = K + KS - JB
  236. JK = IK + J
  237. TEMP = AP(JK)
  238. AP(JK) = AP(KSJ)
  239. AP(KSJ) = TEMP
  240. KSJ = KSJ - (J - 1)
  241. 230 CONTINUE
  242. IF (KSTEP .EQ. 1) GO TO 240
  243. KSKP1 = IKP1 + KS
  244. TEMP = AP(KSKP1)
  245. AP(KSKP1) = AP(KKP1)
  246. AP(KKP1) = TEMP
  247. 240 CONTINUE
  248. 250 CONTINUE
  249. IK = IK + K
  250. IF (KSTEP .EQ. 2) IK = IK + K + 1
  251. K = K + KSTEP
  252. GO TO 150
  253. 260 CONTINUE
  254. 270 CONTINUE
  255. RETURN
  256. END