You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

csytf2.f 19 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. *> \brief \b CSYTF2 computes the factorization of a real symmetric indefinite matrix, using the diagonal pivoting method (unblocked algorithm).
  2. *
  3. * =========== DOCUMENTATION ===========
  4. *
  5. * Online html documentation available at
  6. * http://www.netlib.org/lapack/explore-html/
  7. *
  8. *> \htmlonly
  9. *> Download CSYTF2 + dependencies
  10. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/csytf2.f">
  11. *> [TGZ]</a>
  12. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/csytf2.f">
  13. *> [ZIP]</a>
  14. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/csytf2.f">
  15. *> [TXT]</a>
  16. *> \endhtmlonly
  17. *
  18. * Definition:
  19. * ===========
  20. *
  21. * SUBROUTINE CSYTF2( UPLO, N, A, LDA, IPIV, INFO )
  22. *
  23. * .. Scalar Arguments ..
  24. * CHARACTER UPLO
  25. * INTEGER INFO, LDA, N
  26. * ..
  27. * .. Array Arguments ..
  28. * INTEGER IPIV( * )
  29. * COMPLEX A( LDA, * )
  30. * ..
  31. *
  32. *
  33. *> \par Purpose:
  34. * =============
  35. *>
  36. *> \verbatim
  37. *>
  38. *> CSYTF2 computes the factorization of a complex symmetric matrix A
  39. *> using the Bunch-Kaufman diagonal pivoting method:
  40. *>
  41. *> A = U*D*U**T or A = L*D*L**T
  42. *>
  43. *> where U (or L) is a product of permutation and unit upper (lower)
  44. *> triangular matrices, U**T is the transpose of U, and D is symmetric and
  45. *> block diagonal with 1-by-1 and 2-by-2 diagonal blocks.
  46. *>
  47. *> This is the unblocked version of the algorithm, calling Level 2 BLAS.
  48. *> \endverbatim
  49. *
  50. * Arguments:
  51. * ==========
  52. *
  53. *> \param[in] UPLO
  54. *> \verbatim
  55. *> UPLO is CHARACTER*1
  56. *> Specifies whether the upper or lower triangular part of the
  57. *> symmetric matrix A is stored:
  58. *> = 'U': Upper triangular
  59. *> = 'L': Lower triangular
  60. *> \endverbatim
  61. *>
  62. *> \param[in] N
  63. *> \verbatim
  64. *> N is INTEGER
  65. *> The order of the matrix A. N >= 0.
  66. *> \endverbatim
  67. *>
  68. *> \param[in,out] A
  69. *> \verbatim
  70. *> A is COMPLEX array, dimension (LDA,N)
  71. *> On entry, the symmetric matrix A. If UPLO = 'U', the leading
  72. *> n-by-n upper triangular part of A contains the upper
  73. *> triangular part of the matrix A, and the strictly lower
  74. *> triangular part of A is not referenced. If UPLO = 'L', the
  75. *> leading n-by-n lower triangular part of A contains the lower
  76. *> triangular part of the matrix A, and the strictly upper
  77. *> triangular part of A is not referenced.
  78. *>
  79. *> On exit, the block diagonal matrix D and the multipliers used
  80. *> to obtain the factor U or L (see below for further details).
  81. *> \endverbatim
  82. *>
  83. *> \param[in] LDA
  84. *> \verbatim
  85. *> LDA is INTEGER
  86. *> The leading dimension of the array A. LDA >= max(1,N).
  87. *> \endverbatim
  88. *>
  89. *> \param[out] IPIV
  90. *> \verbatim
  91. *> IPIV is INTEGER array, dimension (N)
  92. *> Details of the interchanges and the block structure of D.
  93. *>
  94. *> If UPLO = 'U':
  95. *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were
  96. *> interchanged and D(k,k) is a 1-by-1 diagonal block.
  97. *>
  98. *> If IPIV(k) = IPIV(k-1) < 0, then rows and columns
  99. *> k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k)
  100. *> is a 2-by-2 diagonal block.
  101. *>
  102. *> If UPLO = 'L':
  103. *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were
  104. *> interchanged and D(k,k) is a 1-by-1 diagonal block.
  105. *>
  106. *> If IPIV(k) = IPIV(k+1) < 0, then rows and columns
  107. *> k+1 and -IPIV(k) were interchanged and D(k:k+1,k:k+1)
  108. *> is a 2-by-2 diagonal block.
  109. *> \endverbatim
  110. *>
  111. *> \param[out] INFO
  112. *> \verbatim
  113. *> INFO is INTEGER
  114. *> = 0: successful exit
  115. *> < 0: if INFO = -k, the k-th argument had an illegal value
  116. *> > 0: if INFO = k, D(k,k) is exactly zero. The factorization
  117. *> has been completed, but the block diagonal matrix D is
  118. *> exactly singular, and division by zero will occur if it
  119. *> is used to solve a system of equations.
  120. *> \endverbatim
  121. *
  122. * Authors:
  123. * ========
  124. *
  125. *> \author Univ. of Tennessee
  126. *> \author Univ. of California Berkeley
  127. *> \author Univ. of Colorado Denver
  128. *> \author NAG Ltd.
  129. *
  130. *> \date November 2013
  131. *
  132. *> \ingroup complexSYcomputational
  133. *
  134. *> \par Further Details:
  135. * =====================
  136. *>
  137. *> \verbatim
  138. *>
  139. *> If UPLO = 'U', then A = U*D*U**T, where
  140. *> U = P(n)*U(n)* ... *P(k)U(k)* ...,
  141. *> i.e., U is a product of terms P(k)*U(k), where k decreases from n to
  142. *> 1 in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1
  143. *> and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as
  144. *> defined by IPIV(k), and U(k) is a unit upper triangular matrix, such
  145. *> that if the diagonal block D(k) is of order s (s = 1 or 2), then
  146. *>
  147. *> ( I v 0 ) k-s
  148. *> U(k) = ( 0 I 0 ) s
  149. *> ( 0 0 I ) n-k
  150. *> k-s s n-k
  151. *>
  152. *> If s = 1, D(k) overwrites A(k,k), and v overwrites A(1:k-1,k).
  153. *> If s = 2, the upper triangle of D(k) overwrites A(k-1,k-1), A(k-1,k),
  154. *> and A(k,k), and v overwrites A(1:k-2,k-1:k).
  155. *>
  156. *> If UPLO = 'L', then A = L*D*L**T, where
  157. *> L = P(1)*L(1)* ... *P(k)*L(k)* ...,
  158. *> i.e., L is a product of terms P(k)*L(k), where k increases from 1 to
  159. *> n in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1
  160. *> and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as
  161. *> defined by IPIV(k), and L(k) is a unit lower triangular matrix, such
  162. *> that if the diagonal block D(k) is of order s (s = 1 or 2), then
  163. *>
  164. *> ( I 0 0 ) k-1
  165. *> L(k) = ( 0 I 0 ) s
  166. *> ( 0 v I ) n-k-s+1
  167. *> k-1 s n-k-s+1
  168. *>
  169. *> If s = 1, D(k) overwrites A(k,k), and v overwrites A(k+1:n,k).
  170. *> If s = 2, the lower triangle of D(k) overwrites A(k,k), A(k+1,k),
  171. *> and A(k+1,k+1), and v overwrites A(k+2:n,k:k+1).
  172. *> \endverbatim
  173. *
  174. *> \par Contributors:
  175. * ==================
  176. *>
  177. *> \verbatim
  178. *>
  179. *> 09-29-06 - patch from
  180. *> Bobby Cheng, MathWorks
  181. *>
  182. *> Replace l.209 and l.377
  183. *> IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN
  184. *> by
  185. *> IF( (MAX( ABSAKK, COLMAX ).EQ.ZERO) .OR. SISNAN(ABSAKK) ) THEN
  186. *>
  187. *> 1-96 - Based on modifications by J. Lewis, Boeing Computer Services
  188. *> Company
  189. *> \endverbatim
  190. *
  191. * =====================================================================
  192. SUBROUTINE CSYTF2( UPLO, N, A, LDA, IPIV, INFO )
  193. *
  194. * -- LAPACK computational routine (version 3.5.0) --
  195. * -- LAPACK is a software package provided by Univ. of Tennessee, --
  196. * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  197. * November 2013
  198. *
  199. * .. Scalar Arguments ..
  200. CHARACTER UPLO
  201. INTEGER INFO, LDA, N
  202. * ..
  203. * .. Array Arguments ..
  204. INTEGER IPIV( * )
  205. COMPLEX A( LDA, * )
  206. * ..
  207. *
  208. * =====================================================================
  209. *
  210. * .. Parameters ..
  211. REAL ZERO, ONE
  212. PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 )
  213. REAL EIGHT, SEVTEN
  214. PARAMETER ( EIGHT = 8.0E+0, SEVTEN = 17.0E+0 )
  215. COMPLEX CONE
  216. PARAMETER ( CONE = ( 1.0E+0, 0.0E+0 ) )
  217. * ..
  218. * .. Local Scalars ..
  219. LOGICAL UPPER
  220. INTEGER I, IMAX, J, JMAX, K, KK, KP, KSTEP
  221. REAL ABSAKK, ALPHA, COLMAX, ROWMAX
  222. COMPLEX D11, D12, D21, D22, R1, T, WK, WKM1, WKP1, Z
  223. * ..
  224. * .. External Functions ..
  225. LOGICAL LSAME, SISNAN
  226. INTEGER ICAMAX
  227. EXTERNAL LSAME, ICAMAX, SISNAN
  228. * ..
  229. * .. External Subroutines ..
  230. EXTERNAL CSCAL, CSWAP, CSYR, XERBLA
  231. * ..
  232. * .. Intrinsic Functions ..
  233. INTRINSIC ABS, AIMAG, MAX, REAL, SQRT
  234. * ..
  235. * .. Statement Functions ..
  236. REAL CABS1
  237. * ..
  238. * .. Statement Function definitions ..
  239. CABS1( Z ) = ABS( REAL( Z ) ) + ABS( AIMAG( Z ) )
  240. * ..
  241. * .. Executable Statements ..
  242. *
  243. * Test the input parameters.
  244. *
  245. INFO = 0
  246. UPPER = LSAME( UPLO, 'U' )
  247. IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
  248. INFO = -1
  249. ELSE IF( N.LT.0 ) THEN
  250. INFO = -2
  251. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  252. INFO = -4
  253. END IF
  254. IF( INFO.NE.0 ) THEN
  255. CALL XERBLA( 'CSYTF2', -INFO )
  256. RETURN
  257. END IF
  258. *
  259. * Initialize ALPHA for use in choosing pivot block size.
  260. *
  261. ALPHA = ( ONE+SQRT( SEVTEN ) ) / EIGHT
  262. *
  263. IF( UPPER ) THEN
  264. *
  265. * Factorize A as U*D*U**T using the upper triangle of A
  266. *
  267. * K is the main loop index, decreasing from N to 1 in steps of
  268. * 1 or 2
  269. *
  270. K = N
  271. 10 CONTINUE
  272. *
  273. * If K < 1, exit from loop
  274. *
  275. IF( K.LT.1 )
  276. $ GO TO 70
  277. KSTEP = 1
  278. *
  279. * Determine rows and columns to be interchanged and whether
  280. * a 1-by-1 or 2-by-2 pivot block will be used
  281. *
  282. ABSAKK = CABS1( A( K, K ) )
  283. *
  284. * IMAX is the row-index of the largest off-diagonal element in
  285. * column K, and COLMAX is its absolute value.
  286. * Determine both COLMAX and IMAX.
  287. *
  288. IF( K.GT.1 ) THEN
  289. IMAX = ICAMAX( K-1, A( 1, K ), 1 )
  290. COLMAX = CABS1( A( IMAX, K ) )
  291. ELSE
  292. COLMAX = ZERO
  293. END IF
  294. *
  295. IF( MAX( ABSAKK, COLMAX ).EQ.ZERO .OR. SISNAN(ABSAKK) ) THEN
  296. *
  297. * Column K is zero or underflow, or contains a NaN:
  298. * set INFO and continue
  299. *
  300. IF( INFO.EQ.0 )
  301. $ INFO = K
  302. KP = K
  303. ELSE
  304. IF( ABSAKK.GE.ALPHA*COLMAX ) THEN
  305. *
  306. * no interchange, use 1-by-1 pivot block
  307. *
  308. KP = K
  309. ELSE
  310. *
  311. * JMAX is the column-index of the largest off-diagonal
  312. * element in row IMAX, and ROWMAX is its absolute value
  313. *
  314. JMAX = IMAX + ICAMAX( K-IMAX, A( IMAX, IMAX+1 ), LDA )
  315. ROWMAX = CABS1( A( IMAX, JMAX ) )
  316. IF( IMAX.GT.1 ) THEN
  317. JMAX = ICAMAX( IMAX-1, A( 1, IMAX ), 1 )
  318. ROWMAX = MAX( ROWMAX, CABS1( A( JMAX, IMAX ) ) )
  319. END IF
  320. *
  321. IF( ABSAKK.GE.ALPHA*COLMAX*( COLMAX / ROWMAX ) ) THEN
  322. *
  323. * no interchange, use 1-by-1 pivot block
  324. *
  325. KP = K
  326. ELSE IF( CABS1( A( IMAX, IMAX ) ).GE.ALPHA*ROWMAX ) THEN
  327. *
  328. * interchange rows and columns K and IMAX, use 1-by-1
  329. * pivot block
  330. *
  331. KP = IMAX
  332. ELSE
  333. *
  334. * interchange rows and columns K-1 and IMAX, use 2-by-2
  335. * pivot block
  336. *
  337. KP = IMAX
  338. KSTEP = 2
  339. END IF
  340. END IF
  341. *
  342. KK = K - KSTEP + 1
  343. IF( KP.NE.KK ) THEN
  344. *
  345. * Interchange rows and columns KK and KP in the leading
  346. * submatrix A(1:k,1:k)
  347. *
  348. CALL CSWAP( KP-1, A( 1, KK ), 1, A( 1, KP ), 1 )
  349. CALL CSWAP( KK-KP-1, A( KP+1, KK ), 1, A( KP, KP+1 ),
  350. $ LDA )
  351. T = A( KK, KK )
  352. A( KK, KK ) = A( KP, KP )
  353. A( KP, KP ) = T
  354. IF( KSTEP.EQ.2 ) THEN
  355. T = A( K-1, K )
  356. A( K-1, K ) = A( KP, K )
  357. A( KP, K ) = T
  358. END IF
  359. END IF
  360. *
  361. * Update the leading submatrix
  362. *
  363. IF( KSTEP.EQ.1 ) THEN
  364. *
  365. * 1-by-1 pivot block D(k): column k now holds
  366. *
  367. * W(k) = U(k)*D(k)
  368. *
  369. * where U(k) is the k-th column of U
  370. *
  371. * Perform a rank-1 update of A(1:k-1,1:k-1) as
  372. *
  373. * A := A - U(k)*D(k)*U(k)**T = A - W(k)*1/D(k)*W(k)**T
  374. *
  375. R1 = CONE / A( K, K )
  376. CALL CSYR( UPLO, K-1, -R1, A( 1, K ), 1, A, LDA )
  377. *
  378. * Store U(k) in column k
  379. *
  380. CALL CSCAL( K-1, R1, A( 1, K ), 1 )
  381. ELSE
  382. *
  383. * 2-by-2 pivot block D(k): columns k and k-1 now hold
  384. *
  385. * ( W(k-1) W(k) ) = ( U(k-1) U(k) )*D(k)
  386. *
  387. * where U(k) and U(k-1) are the k-th and (k-1)-th columns
  388. * of U
  389. *
  390. * Perform a rank-2 update of A(1:k-2,1:k-2) as
  391. *
  392. * A := A - ( U(k-1) U(k) )*D(k)*( U(k-1) U(k) )**T
  393. * = A - ( W(k-1) W(k) )*inv(D(k))*( W(k-1) W(k) )**T
  394. *
  395. IF( K.GT.2 ) THEN
  396. *
  397. D12 = A( K-1, K )
  398. D22 = A( K-1, K-1 ) / D12
  399. D11 = A( K, K ) / D12
  400. T = CONE / ( D11*D22-CONE )
  401. D12 = T / D12
  402. *
  403. DO 30 J = K - 2, 1, -1
  404. WKM1 = D12*( D11*A( J, K-1 )-A( J, K ) )
  405. WK = D12*( D22*A( J, K )-A( J, K-1 ) )
  406. DO 20 I = J, 1, -1
  407. A( I, J ) = A( I, J ) - A( I, K )*WK -
  408. $ A( I, K-1 )*WKM1
  409. 20 CONTINUE
  410. A( J, K ) = WK
  411. A( J, K-1 ) = WKM1
  412. 30 CONTINUE
  413. *
  414. END IF
  415. *
  416. END IF
  417. END IF
  418. *
  419. * Store details of the interchanges in IPIV
  420. *
  421. IF( KSTEP.EQ.1 ) THEN
  422. IPIV( K ) = KP
  423. ELSE
  424. IPIV( K ) = -KP
  425. IPIV( K-1 ) = -KP
  426. END IF
  427. *
  428. * Decrease K and return to the start of the main loop
  429. *
  430. K = K - KSTEP
  431. GO TO 10
  432. *
  433. ELSE
  434. *
  435. * Factorize A as L*D*L**T using the lower triangle of A
  436. *
  437. * K is the main loop index, increasing from 1 to N in steps of
  438. * 1 or 2
  439. *
  440. K = 1
  441. 40 CONTINUE
  442. *
  443. * If K > N, exit from loop
  444. *
  445. IF( K.GT.N )
  446. $ GO TO 70
  447. KSTEP = 1
  448. *
  449. * Determine rows and columns to be interchanged and whether
  450. * a 1-by-1 or 2-by-2 pivot block will be used
  451. *
  452. ABSAKK = CABS1( A( K, K ) )
  453. *
  454. * IMAX is the row-index of the largest off-diagonal element in
  455. * column K, and COLMAX is its absolute value.
  456. * Determine both COLMAX and IMAX.
  457. *
  458. IF( K.LT.N ) THEN
  459. IMAX = K + ICAMAX( N-K, A( K+1, K ), 1 )
  460. COLMAX = CABS1( A( IMAX, K ) )
  461. ELSE
  462. COLMAX = ZERO
  463. END IF
  464. *
  465. IF( MAX( ABSAKK, COLMAX ).EQ.ZERO .OR. SISNAN(ABSAKK) ) THEN
  466. *
  467. * Column K is zero or underflow, or contains a NaN:
  468. * set INFO and continue
  469. *
  470. IF( INFO.EQ.0 )
  471. $ INFO = K
  472. KP = K
  473. ELSE
  474. IF( ABSAKK.GE.ALPHA*COLMAX ) THEN
  475. *
  476. * no interchange, use 1-by-1 pivot block
  477. *
  478. KP = K
  479. ELSE
  480. *
  481. * JMAX is the column-index of the largest off-diagonal
  482. * element in row IMAX, and ROWMAX is its absolute value
  483. *
  484. JMAX = K - 1 + ICAMAX( IMAX-K, A( IMAX, K ), LDA )
  485. ROWMAX = CABS1( A( IMAX, JMAX ) )
  486. IF( IMAX.LT.N ) THEN
  487. JMAX = IMAX + ICAMAX( N-IMAX, A( IMAX+1, IMAX ), 1 )
  488. ROWMAX = MAX( ROWMAX, CABS1( A( JMAX, IMAX ) ) )
  489. END IF
  490. *
  491. IF( ABSAKK.GE.ALPHA*COLMAX*( COLMAX / ROWMAX ) ) THEN
  492. *
  493. * no interchange, use 1-by-1 pivot block
  494. *
  495. KP = K
  496. ELSE IF( CABS1( A( IMAX, IMAX ) ).GE.ALPHA*ROWMAX ) THEN
  497. *
  498. * interchange rows and columns K and IMAX, use 1-by-1
  499. * pivot block
  500. *
  501. KP = IMAX
  502. ELSE
  503. *
  504. * interchange rows and columns K+1 and IMAX, use 2-by-2
  505. * pivot block
  506. *
  507. KP = IMAX
  508. KSTEP = 2
  509. END IF
  510. END IF
  511. *
  512. KK = K + KSTEP - 1
  513. IF( KP.NE.KK ) THEN
  514. *
  515. * Interchange rows and columns KK and KP in the trailing
  516. * submatrix A(k:n,k:n)
  517. *
  518. IF( KP.LT.N )
  519. $ CALL CSWAP( N-KP, A( KP+1, KK ), 1, A( KP+1, KP ), 1 )
  520. CALL CSWAP( KP-KK-1, A( KK+1, KK ), 1, A( KP, KK+1 ),
  521. $ LDA )
  522. T = A( KK, KK )
  523. A( KK, KK ) = A( KP, KP )
  524. A( KP, KP ) = T
  525. IF( KSTEP.EQ.2 ) THEN
  526. T = A( K+1, K )
  527. A( K+1, K ) = A( KP, K )
  528. A( KP, K ) = T
  529. END IF
  530. END IF
  531. *
  532. * Update the trailing submatrix
  533. *
  534. IF( KSTEP.EQ.1 ) THEN
  535. *
  536. * 1-by-1 pivot block D(k): column k now holds
  537. *
  538. * W(k) = L(k)*D(k)
  539. *
  540. * where L(k) is the k-th column of L
  541. *
  542. IF( K.LT.N ) THEN
  543. *
  544. * Perform a rank-1 update of A(k+1:n,k+1:n) as
  545. *
  546. * A := A - L(k)*D(k)*L(k)**T = A - W(k)*(1/D(k))*W(k)**T
  547. *
  548. R1 = CONE / A( K, K )
  549. CALL CSYR( UPLO, N-K, -R1, A( K+1, K ), 1,
  550. $ A( K+1, K+1 ), LDA )
  551. *
  552. * Store L(k) in column K
  553. *
  554. CALL CSCAL( N-K, R1, A( K+1, K ), 1 )
  555. END IF
  556. ELSE
  557. *
  558. * 2-by-2 pivot block D(k)
  559. *
  560. IF( K.LT.N-1 ) THEN
  561. *
  562. * Perform a rank-2 update of A(k+2:n,k+2:n) as
  563. *
  564. * A := A - ( L(k) L(k+1) )*D(k)*( L(k) L(k+1) )**T
  565. * = A - ( W(k) W(k+1) )*inv(D(k))*( W(k) W(k+1) )**T
  566. *
  567. * where L(k) and L(k+1) are the k-th and (k+1)-th
  568. * columns of L
  569. *
  570. D21 = A( K+1, K )
  571. D11 = A( K+1, K+1 ) / D21
  572. D22 = A( K, K ) / D21
  573. T = CONE / ( D11*D22-CONE )
  574. D21 = T / D21
  575. *
  576. DO 60 J = K + 2, N
  577. WK = D21*( D11*A( J, K )-A( J, K+1 ) )
  578. WKP1 = D21*( D22*A( J, K+1 )-A( J, K ) )
  579. DO 50 I = J, N
  580. A( I, J ) = A( I, J ) - A( I, K )*WK -
  581. $ A( I, K+1 )*WKP1
  582. 50 CONTINUE
  583. A( J, K ) = WK
  584. A( J, K+1 ) = WKP1
  585. 60 CONTINUE
  586. END IF
  587. END IF
  588. END IF
  589. *
  590. * Store details of the interchanges in IPIV
  591. *
  592. IF( KSTEP.EQ.1 ) THEN
  593. IPIV( K ) = KP
  594. ELSE
  595. IPIV( K ) = -KP
  596. IPIV( K+1 ) = -KP
  597. END IF
  598. *
  599. * Increase K and return to the start of the main loop
  600. *
  601. K = K + KSTEP
  602. GO TO 40
  603. *
  604. END IF
  605. *
  606. 70 CONTINUE
  607. RETURN
  608. *
  609. * End of CSYTF2
  610. *
  611. END