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.

clar1v.f 15 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. *> \brief \b CLAR1V computes the (scaled) r-th column of the inverse of the submatrix in rows b1 through bn of the tridiagonal matrix LDLT - λI.
  2. *
  3. * =========== DOCUMENTATION ===========
  4. *
  5. * Online html documentation available at
  6. * http://www.netlib.org/lapack/explore-html/
  7. *
  8. *> \htmlonly
  9. *> Download CLAR1V + dependencies
  10. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/clar1v.f">
  11. *> [TGZ]</a>
  12. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/clar1v.f">
  13. *> [ZIP]</a>
  14. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/clar1v.f">
  15. *> [TXT]</a>
  16. *> \endhtmlonly
  17. *
  18. * Definition:
  19. * ===========
  20. *
  21. * SUBROUTINE CLAR1V( N, B1, BN, LAMBDA, D, L, LD, LLD,
  22. * PIVMIN, GAPTOL, Z, WANTNC, NEGCNT, ZTZ, MINGMA,
  23. * R, ISUPPZ, NRMINV, RESID, RQCORR, WORK )
  24. *
  25. * .. Scalar Arguments ..
  26. * LOGICAL WANTNC
  27. * INTEGER B1, BN, N, NEGCNT, R
  28. * REAL GAPTOL, LAMBDA, MINGMA, NRMINV, PIVMIN, RESID,
  29. * $ RQCORR, ZTZ
  30. * ..
  31. * .. Array Arguments ..
  32. * INTEGER ISUPPZ( * )
  33. * REAL D( * ), L( * ), LD( * ), LLD( * ),
  34. * $ WORK( * )
  35. * COMPLEX Z( * )
  36. * ..
  37. *
  38. *
  39. *> \par Purpose:
  40. * =============
  41. *>
  42. *> \verbatim
  43. *>
  44. *> CLAR1V computes the (scaled) r-th column of the inverse of
  45. *> the sumbmatrix in rows B1 through BN of the tridiagonal matrix
  46. *> L D L**T - sigma I. When sigma is close to an eigenvalue, the
  47. *> computed vector is an accurate eigenvector. Usually, r corresponds
  48. *> to the index where the eigenvector is largest in magnitude.
  49. *> The following steps accomplish this computation :
  50. *> (a) Stationary qd transform, L D L**T - sigma I = L(+) D(+) L(+)**T,
  51. *> (b) Progressive qd transform, L D L**T - sigma I = U(-) D(-) U(-)**T,
  52. *> (c) Computation of the diagonal elements of the inverse of
  53. *> L D L**T - sigma I by combining the above transforms, and choosing
  54. *> r as the index where the diagonal of the inverse is (one of the)
  55. *> largest in magnitude.
  56. *> (d) Computation of the (scaled) r-th column of the inverse using the
  57. *> twisted factorization obtained by combining the top part of the
  58. *> the stationary and the bottom part of the progressive transform.
  59. *> \endverbatim
  60. *
  61. * Arguments:
  62. * ==========
  63. *
  64. *> \param[in] N
  65. *> \verbatim
  66. *> N is INTEGER
  67. *> The order of the matrix L D L**T.
  68. *> \endverbatim
  69. *>
  70. *> \param[in] B1
  71. *> \verbatim
  72. *> B1 is INTEGER
  73. *> First index of the submatrix of L D L**T.
  74. *> \endverbatim
  75. *>
  76. *> \param[in] BN
  77. *> \verbatim
  78. *> BN is INTEGER
  79. *> Last index of the submatrix of L D L**T.
  80. *> \endverbatim
  81. *>
  82. *> \param[in] LAMBDA
  83. *> \verbatim
  84. *> LAMBDA is REAL
  85. *> The shift. In order to compute an accurate eigenvector,
  86. *> LAMBDA should be a good approximation to an eigenvalue
  87. *> of L D L**T.
  88. *> \endverbatim
  89. *>
  90. *> \param[in] L
  91. *> \verbatim
  92. *> L is REAL array, dimension (N-1)
  93. *> The (n-1) subdiagonal elements of the unit bidiagonal matrix
  94. *> L, in elements 1 to N-1.
  95. *> \endverbatim
  96. *>
  97. *> \param[in] D
  98. *> \verbatim
  99. *> D is REAL array, dimension (N)
  100. *> The n diagonal elements of the diagonal matrix D.
  101. *> \endverbatim
  102. *>
  103. *> \param[in] LD
  104. *> \verbatim
  105. *> LD is REAL array, dimension (N-1)
  106. *> The n-1 elements L(i)*D(i).
  107. *> \endverbatim
  108. *>
  109. *> \param[in] LLD
  110. *> \verbatim
  111. *> LLD is REAL array, dimension (N-1)
  112. *> The n-1 elements L(i)*L(i)*D(i).
  113. *> \endverbatim
  114. *>
  115. *> \param[in] PIVMIN
  116. *> \verbatim
  117. *> PIVMIN is REAL
  118. *> The minimum pivot in the Sturm sequence.
  119. *> \endverbatim
  120. *>
  121. *> \param[in] GAPTOL
  122. *> \verbatim
  123. *> GAPTOL is REAL
  124. *> Tolerance that indicates when eigenvector entries are negligible
  125. *> w.r.t. their contribution to the residual.
  126. *> \endverbatim
  127. *>
  128. *> \param[in,out] Z
  129. *> \verbatim
  130. *> Z is COMPLEX array, dimension (N)
  131. *> On input, all entries of Z must be set to 0.
  132. *> On output, Z contains the (scaled) r-th column of the
  133. *> inverse. The scaling is such that Z(R) equals 1.
  134. *> \endverbatim
  135. *>
  136. *> \param[in] WANTNC
  137. *> \verbatim
  138. *> WANTNC is LOGICAL
  139. *> Specifies whether NEGCNT has to be computed.
  140. *> \endverbatim
  141. *>
  142. *> \param[out] NEGCNT
  143. *> \verbatim
  144. *> NEGCNT is INTEGER
  145. *> If WANTNC is .TRUE. then NEGCNT = the number of pivots < pivmin
  146. *> in the matrix factorization L D L**T, and NEGCNT = -1 otherwise.
  147. *> \endverbatim
  148. *>
  149. *> \param[out] ZTZ
  150. *> \verbatim
  151. *> ZTZ is REAL
  152. *> The square of the 2-norm of Z.
  153. *> \endverbatim
  154. *>
  155. *> \param[out] MINGMA
  156. *> \verbatim
  157. *> MINGMA is REAL
  158. *> The reciprocal of the largest (in magnitude) diagonal
  159. *> element of the inverse of L D L**T - sigma I.
  160. *> \endverbatim
  161. *>
  162. *> \param[in,out] R
  163. *> \verbatim
  164. *> R is INTEGER
  165. *> The twist index for the twisted factorization used to
  166. *> compute Z.
  167. *> On input, 0 <= R <= N. If R is input as 0, R is set to
  168. *> the index where (L D L**T - sigma I)^{-1} is largest
  169. *> in magnitude. If 1 <= R <= N, R is unchanged.
  170. *> On output, R contains the twist index used to compute Z.
  171. *> Ideally, R designates the position of the maximum entry in the
  172. *> eigenvector.
  173. *> \endverbatim
  174. *>
  175. *> \param[out] ISUPPZ
  176. *> \verbatim
  177. *> ISUPPZ is INTEGER array, dimension (2)
  178. *> The support of the vector in Z, i.e., the vector Z is
  179. *> nonzero only in elements ISUPPZ(1) through ISUPPZ( 2 ).
  180. *> \endverbatim
  181. *>
  182. *> \param[out] NRMINV
  183. *> \verbatim
  184. *> NRMINV is REAL
  185. *> NRMINV = 1/SQRT( ZTZ )
  186. *> \endverbatim
  187. *>
  188. *> \param[out] RESID
  189. *> \verbatim
  190. *> RESID is REAL
  191. *> The residual of the FP vector.
  192. *> RESID = ABS( MINGMA )/SQRT( ZTZ )
  193. *> \endverbatim
  194. *>
  195. *> \param[out] RQCORR
  196. *> \verbatim
  197. *> RQCORR is REAL
  198. *> The Rayleigh Quotient correction to LAMBDA.
  199. *> RQCORR = MINGMA*TMP
  200. *> \endverbatim
  201. *>
  202. *> \param[out] WORK
  203. *> \verbatim
  204. *> WORK is REAL array, dimension (4*N)
  205. *> \endverbatim
  206. *
  207. * Authors:
  208. * ========
  209. *
  210. *> \author Univ. of Tennessee
  211. *> \author Univ. of California Berkeley
  212. *> \author Univ. of Colorado Denver
  213. *> \author NAG Ltd.
  214. *
  215. *> \date September 2012
  216. *
  217. *> \ingroup complexOTHERauxiliary
  218. *
  219. *> \par Contributors:
  220. * ==================
  221. *>
  222. *> Beresford Parlett, University of California, Berkeley, USA \n
  223. *> Jim Demmel, University of California, Berkeley, USA \n
  224. *> Inderjit Dhillon, University of Texas, Austin, USA \n
  225. *> Osni Marques, LBNL/NERSC, USA \n
  226. *> Christof Voemel, University of California, Berkeley, USA
  227. *
  228. * =====================================================================
  229. SUBROUTINE CLAR1V( N, B1, BN, LAMBDA, D, L, LD, LLD,
  230. $ PIVMIN, GAPTOL, Z, WANTNC, NEGCNT, ZTZ, MINGMA,
  231. $ R, ISUPPZ, NRMINV, RESID, RQCORR, WORK )
  232. *
  233. * -- LAPACK auxiliary routine (version 3.4.2) --
  234. * -- LAPACK is a software package provided by Univ. of Tennessee, --
  235. * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  236. * September 2012
  237. *
  238. * .. Scalar Arguments ..
  239. LOGICAL WANTNC
  240. INTEGER B1, BN, N, NEGCNT, R
  241. REAL GAPTOL, LAMBDA, MINGMA, NRMINV, PIVMIN, RESID,
  242. $ RQCORR, ZTZ
  243. * ..
  244. * .. Array Arguments ..
  245. INTEGER ISUPPZ( * )
  246. REAL D( * ), L( * ), LD( * ), LLD( * ),
  247. $ WORK( * )
  248. COMPLEX Z( * )
  249. * ..
  250. *
  251. * =====================================================================
  252. *
  253. * .. Parameters ..
  254. REAL ZERO, ONE
  255. PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0 )
  256. COMPLEX CONE
  257. PARAMETER ( CONE = ( 1.0E0, 0.0E0 ) )
  258. * ..
  259. * .. Local Scalars ..
  260. LOGICAL SAWNAN1, SAWNAN2
  261. INTEGER I, INDLPL, INDP, INDS, INDUMN, NEG1, NEG2, R1,
  262. $ R2
  263. REAL DMINUS, DPLUS, EPS, S, TMP
  264. * ..
  265. * .. External Functions ..
  266. LOGICAL SISNAN
  267. REAL SLAMCH
  268. EXTERNAL SISNAN, SLAMCH
  269. * ..
  270. * .. Intrinsic Functions ..
  271. INTRINSIC ABS, REAL
  272. * ..
  273. * .. Executable Statements ..
  274. *
  275. EPS = SLAMCH( 'Precision' )
  276. IF( R.EQ.0 ) THEN
  277. R1 = B1
  278. R2 = BN
  279. ELSE
  280. R1 = R
  281. R2 = R
  282. END IF
  283. * Storage for LPLUS
  284. INDLPL = 0
  285. * Storage for UMINUS
  286. INDUMN = N
  287. INDS = 2*N + 1
  288. INDP = 3*N + 1
  289. IF( B1.EQ.1 ) THEN
  290. WORK( INDS ) = ZERO
  291. ELSE
  292. WORK( INDS+B1-1 ) = LLD( B1-1 )
  293. END IF
  294. *
  295. * Compute the stationary transform (using the differential form)
  296. * until the index R2.
  297. *
  298. SAWNAN1 = .FALSE.
  299. NEG1 = 0
  300. S = WORK( INDS+B1-1 ) - LAMBDA
  301. DO 50 I = B1, R1 - 1
  302. DPLUS = D( I ) + S
  303. WORK( INDLPL+I ) = LD( I ) / DPLUS
  304. IF(DPLUS.LT.ZERO) NEG1 = NEG1 + 1
  305. WORK( INDS+I ) = S*WORK( INDLPL+I )*L( I )
  306. S = WORK( INDS+I ) - LAMBDA
  307. 50 CONTINUE
  308. SAWNAN1 = SISNAN( S )
  309. IF( SAWNAN1 ) GOTO 60
  310. DO 51 I = R1, R2 - 1
  311. DPLUS = D( I ) + S
  312. WORK( INDLPL+I ) = LD( I ) / DPLUS
  313. WORK( INDS+I ) = S*WORK( INDLPL+I )*L( I )
  314. S = WORK( INDS+I ) - LAMBDA
  315. 51 CONTINUE
  316. SAWNAN1 = SISNAN( S )
  317. *
  318. 60 CONTINUE
  319. IF( SAWNAN1 ) THEN
  320. * Runs a slower version of the above loop if a NaN is detected
  321. NEG1 = 0
  322. S = WORK( INDS+B1-1 ) - LAMBDA
  323. DO 70 I = B1, R1 - 1
  324. DPLUS = D( I ) + S
  325. IF(ABS(DPLUS).LT.PIVMIN) DPLUS = -PIVMIN
  326. WORK( INDLPL+I ) = LD( I ) / DPLUS
  327. IF(DPLUS.LT.ZERO) NEG1 = NEG1 + 1
  328. WORK( INDS+I ) = S*WORK( INDLPL+I )*L( I )
  329. IF( WORK( INDLPL+I ).EQ.ZERO )
  330. $ WORK( INDS+I ) = LLD( I )
  331. S = WORK( INDS+I ) - LAMBDA
  332. 70 CONTINUE
  333. DO 71 I = R1, R2 - 1
  334. DPLUS = D( I ) + S
  335. IF(ABS(DPLUS).LT.PIVMIN) DPLUS = -PIVMIN
  336. WORK( INDLPL+I ) = LD( I ) / DPLUS
  337. WORK( INDS+I ) = S*WORK( INDLPL+I )*L( I )
  338. IF( WORK( INDLPL+I ).EQ.ZERO )
  339. $ WORK( INDS+I ) = LLD( I )
  340. S = WORK( INDS+I ) - LAMBDA
  341. 71 CONTINUE
  342. END IF
  343. *
  344. * Compute the progressive transform (using the differential form)
  345. * until the index R1
  346. *
  347. SAWNAN2 = .FALSE.
  348. NEG2 = 0
  349. WORK( INDP+BN-1 ) = D( BN ) - LAMBDA
  350. DO 80 I = BN - 1, R1, -1
  351. DMINUS = LLD( I ) + WORK( INDP+I )
  352. TMP = D( I ) / DMINUS
  353. IF(DMINUS.LT.ZERO) NEG2 = NEG2 + 1
  354. WORK( INDUMN+I ) = L( I )*TMP
  355. WORK( INDP+I-1 ) = WORK( INDP+I )*TMP - LAMBDA
  356. 80 CONTINUE
  357. TMP = WORK( INDP+R1-1 )
  358. SAWNAN2 = SISNAN( TMP )
  359. IF( SAWNAN2 ) THEN
  360. * Runs a slower version of the above loop if a NaN is detected
  361. NEG2 = 0
  362. DO 100 I = BN-1, R1, -1
  363. DMINUS = LLD( I ) + WORK( INDP+I )
  364. IF(ABS(DMINUS).LT.PIVMIN) DMINUS = -PIVMIN
  365. TMP = D( I ) / DMINUS
  366. IF(DMINUS.LT.ZERO) NEG2 = NEG2 + 1
  367. WORK( INDUMN+I ) = L( I )*TMP
  368. WORK( INDP+I-1 ) = WORK( INDP+I )*TMP - LAMBDA
  369. IF( TMP.EQ.ZERO )
  370. $ WORK( INDP+I-1 ) = D( I ) - LAMBDA
  371. 100 CONTINUE
  372. END IF
  373. *
  374. * Find the index (from R1 to R2) of the largest (in magnitude)
  375. * diagonal element of the inverse
  376. *
  377. MINGMA = WORK( INDS+R1-1 ) + WORK( INDP+R1-1 )
  378. IF( MINGMA.LT.ZERO ) NEG1 = NEG1 + 1
  379. IF( WANTNC ) THEN
  380. NEGCNT = NEG1 + NEG2
  381. ELSE
  382. NEGCNT = -1
  383. ENDIF
  384. IF( ABS(MINGMA).EQ.ZERO )
  385. $ MINGMA = EPS*WORK( INDS+R1-1 )
  386. R = R1
  387. DO 110 I = R1, R2 - 1
  388. TMP = WORK( INDS+I ) + WORK( INDP+I )
  389. IF( TMP.EQ.ZERO )
  390. $ TMP = EPS*WORK( INDS+I )
  391. IF( ABS( TMP ).LE.ABS( MINGMA ) ) THEN
  392. MINGMA = TMP
  393. R = I + 1
  394. END IF
  395. 110 CONTINUE
  396. *
  397. * Compute the FP vector: solve N^T v = e_r
  398. *
  399. ISUPPZ( 1 ) = B1
  400. ISUPPZ( 2 ) = BN
  401. Z( R ) = CONE
  402. ZTZ = ONE
  403. *
  404. * Compute the FP vector upwards from R
  405. *
  406. IF( .NOT.SAWNAN1 .AND. .NOT.SAWNAN2 ) THEN
  407. DO 210 I = R-1, B1, -1
  408. Z( I ) = -( WORK( INDLPL+I )*Z( I+1 ) )
  409. IF( (ABS(Z(I))+ABS(Z(I+1)))* ABS(LD(I)).LT.GAPTOL )
  410. $ THEN
  411. Z( I ) = ZERO
  412. ISUPPZ( 1 ) = I + 1
  413. GOTO 220
  414. ENDIF
  415. ZTZ = ZTZ + REAL( Z( I )*Z( I ) )
  416. 210 CONTINUE
  417. 220 CONTINUE
  418. ELSE
  419. * Run slower loop if NaN occurred.
  420. DO 230 I = R - 1, B1, -1
  421. IF( Z( I+1 ).EQ.ZERO ) THEN
  422. Z( I ) = -( LD( I+1 ) / LD( I ) )*Z( I+2 )
  423. ELSE
  424. Z( I ) = -( WORK( INDLPL+I )*Z( I+1 ) )
  425. END IF
  426. IF( (ABS(Z(I))+ABS(Z(I+1)))* ABS(LD(I)).LT.GAPTOL )
  427. $ THEN
  428. Z( I ) = ZERO
  429. ISUPPZ( 1 ) = I + 1
  430. GO TO 240
  431. END IF
  432. ZTZ = ZTZ + REAL( Z( I )*Z( I ) )
  433. 230 CONTINUE
  434. 240 CONTINUE
  435. ENDIF
  436. * Compute the FP vector downwards from R in blocks of size BLKSIZ
  437. IF( .NOT.SAWNAN1 .AND. .NOT.SAWNAN2 ) THEN
  438. DO 250 I = R, BN-1
  439. Z( I+1 ) = -( WORK( INDUMN+I )*Z( I ) )
  440. IF( (ABS(Z(I))+ABS(Z(I+1)))* ABS(LD(I)).LT.GAPTOL )
  441. $ THEN
  442. Z( I+1 ) = ZERO
  443. ISUPPZ( 2 ) = I
  444. GO TO 260
  445. END IF
  446. ZTZ = ZTZ + REAL( Z( I+1 )*Z( I+1 ) )
  447. 250 CONTINUE
  448. 260 CONTINUE
  449. ELSE
  450. * Run slower loop if NaN occurred.
  451. DO 270 I = R, BN - 1
  452. IF( Z( I ).EQ.ZERO ) THEN
  453. Z( I+1 ) = -( LD( I-1 ) / LD( I ) )*Z( I-1 )
  454. ELSE
  455. Z( I+1 ) = -( WORK( INDUMN+I )*Z( I ) )
  456. END IF
  457. IF( (ABS(Z(I))+ABS(Z(I+1)))* ABS(LD(I)).LT.GAPTOL )
  458. $ THEN
  459. Z( I+1 ) = ZERO
  460. ISUPPZ( 2 ) = I
  461. GO TO 280
  462. END IF
  463. ZTZ = ZTZ + REAL( Z( I+1 )*Z( I+1 ) )
  464. 270 CONTINUE
  465. 280 CONTINUE
  466. END IF
  467. *
  468. * Compute quantities for convergence test
  469. *
  470. TMP = ONE / ZTZ
  471. NRMINV = SQRT( TMP )
  472. RESID = ABS( MINGMA )*NRMINV
  473. RQCORR = MINGMA*TMP
  474. *
  475. *
  476. RETURN
  477. *
  478. * End of CLAR1V
  479. *
  480. END