dsidi.f 7.3 KB

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