cspdi.f 7.6 KB

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