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.

dlarrj.f 11 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. *> \brief \b DLARRJ performs refinement of the initial estimates of the eigenvalues of the matrix T.
  2. *
  3. * =========== DOCUMENTATION ===========
  4. *
  5. * Online html documentation available at
  6. * http://www.netlib.org/lapack/explore-html/
  7. *
  8. *> \htmlonly
  9. *> Download DLARRJ + dependencies
  10. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarrj.f">
  11. *> [TGZ]</a>
  12. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarrj.f">
  13. *> [ZIP]</a>
  14. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarrj.f">
  15. *> [TXT]</a>
  16. *> \endhtmlonly
  17. *
  18. * Definition:
  19. * ===========
  20. *
  21. * SUBROUTINE DLARRJ( N, D, E2, IFIRST, ILAST,
  22. * RTOL, OFFSET, W, WERR, WORK, IWORK,
  23. * PIVMIN, SPDIAM, INFO )
  24. *
  25. * .. Scalar Arguments ..
  26. * INTEGER IFIRST, ILAST, INFO, N, OFFSET
  27. * DOUBLE PRECISION PIVMIN, RTOL, SPDIAM
  28. * ..
  29. * .. Array Arguments ..
  30. * INTEGER IWORK( * )
  31. * DOUBLE PRECISION D( * ), E2( * ), W( * ),
  32. * $ WERR( * ), WORK( * )
  33. * ..
  34. *
  35. *
  36. *> \par Purpose:
  37. * =============
  38. *>
  39. *> \verbatim
  40. *>
  41. *> Given the initial eigenvalue approximations of T, DLARRJ
  42. *> does bisection to refine the eigenvalues of T,
  43. *> W( IFIRST-OFFSET ) through W( ILAST-OFFSET ), to more accuracy. Initial
  44. *> guesses for these eigenvalues are input in W, the corresponding estimate
  45. *> of the error in these guesses in WERR. During bisection, intervals
  46. *> [left, right] are maintained by storing their mid-points and
  47. *> semi-widths in the arrays W and WERR respectively.
  48. *> \endverbatim
  49. *
  50. * Arguments:
  51. * ==========
  52. *
  53. *> \param[in] N
  54. *> \verbatim
  55. *> N is INTEGER
  56. *> The order of the matrix.
  57. *> \endverbatim
  58. *>
  59. *> \param[in] D
  60. *> \verbatim
  61. *> D is DOUBLE PRECISION array, dimension (N)
  62. *> The N diagonal elements of T.
  63. *> \endverbatim
  64. *>
  65. *> \param[in] E2
  66. *> \verbatim
  67. *> E2 is DOUBLE PRECISION array, dimension (N-1)
  68. *> The Squares of the (N-1) subdiagonal elements of T.
  69. *> \endverbatim
  70. *>
  71. *> \param[in] IFIRST
  72. *> \verbatim
  73. *> IFIRST is INTEGER
  74. *> The index of the first eigenvalue to be computed.
  75. *> \endverbatim
  76. *>
  77. *> \param[in] ILAST
  78. *> \verbatim
  79. *> ILAST is INTEGER
  80. *> The index of the last eigenvalue to be computed.
  81. *> \endverbatim
  82. *>
  83. *> \param[in] RTOL
  84. *> \verbatim
  85. *> RTOL is DOUBLE PRECISION
  86. *> Tolerance for the convergence of the bisection intervals.
  87. *> An interval [LEFT,RIGHT] has converged if
  88. *> RIGHT-LEFT.LT.RTOL*MAX(|LEFT|,|RIGHT|).
  89. *> \endverbatim
  90. *>
  91. *> \param[in] OFFSET
  92. *> \verbatim
  93. *> OFFSET is INTEGER
  94. *> Offset for the arrays W and WERR, i.e., the IFIRST-OFFSET
  95. *> through ILAST-OFFSET elements of these arrays are to be used.
  96. *> \endverbatim
  97. *>
  98. *> \param[in,out] W
  99. *> \verbatim
  100. *> W is DOUBLE PRECISION array, dimension (N)
  101. *> On input, W( IFIRST-OFFSET ) through W( ILAST-OFFSET ) are
  102. *> estimates of the eigenvalues of L D L^T indexed IFIRST through
  103. *> ILAST.
  104. *> On output, these estimates are refined.
  105. *> \endverbatim
  106. *>
  107. *> \param[in,out] WERR
  108. *> \verbatim
  109. *> WERR is DOUBLE PRECISION array, dimension (N)
  110. *> On input, WERR( IFIRST-OFFSET ) through WERR( ILAST-OFFSET ) are
  111. *> the errors in the estimates of the corresponding elements in W.
  112. *> On output, these errors are refined.
  113. *> \endverbatim
  114. *>
  115. *> \param[out] WORK
  116. *> \verbatim
  117. *> WORK is DOUBLE PRECISION array, dimension (2*N)
  118. *> Workspace.
  119. *> \endverbatim
  120. *>
  121. *> \param[out] IWORK
  122. *> \verbatim
  123. *> IWORK is INTEGER array, dimension (2*N)
  124. *> Workspace.
  125. *> \endverbatim
  126. *>
  127. *> \param[in] PIVMIN
  128. *> \verbatim
  129. *> PIVMIN is DOUBLE PRECISION
  130. *> The minimum pivot in the Sturm sequence for T.
  131. *> \endverbatim
  132. *>
  133. *> \param[in] SPDIAM
  134. *> \verbatim
  135. *> SPDIAM is DOUBLE PRECISION
  136. *> The spectral diameter of T.
  137. *> \endverbatim
  138. *>
  139. *> \param[out] INFO
  140. *> \verbatim
  141. *> INFO is INTEGER
  142. *> Error flag.
  143. *> \endverbatim
  144. *
  145. * Authors:
  146. * ========
  147. *
  148. *> \author Univ. of Tennessee
  149. *> \author Univ. of California Berkeley
  150. *> \author Univ. of Colorado Denver
  151. *> \author NAG Ltd.
  152. *
  153. *> \date June 2017
  154. *
  155. *> \ingroup OTHERauxiliary
  156. *
  157. *> \par Contributors:
  158. * ==================
  159. *>
  160. *> Beresford Parlett, University of California, Berkeley, USA \n
  161. *> Jim Demmel, University of California, Berkeley, USA \n
  162. *> Inderjit Dhillon, University of Texas, Austin, USA \n
  163. *> Osni Marques, LBNL/NERSC, USA \n
  164. *> Christof Voemel, University of California, Berkeley, USA
  165. *
  166. * =====================================================================
  167. SUBROUTINE DLARRJ( N, D, E2, IFIRST, ILAST,
  168. $ RTOL, OFFSET, W, WERR, WORK, IWORK,
  169. $ PIVMIN, SPDIAM, INFO )
  170. *
  171. * -- LAPACK auxiliary routine (version 3.7.1) --
  172. * -- LAPACK is a software package provided by Univ. of Tennessee, --
  173. * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  174. * June 2017
  175. *
  176. * .. Scalar Arguments ..
  177. INTEGER IFIRST, ILAST, INFO, N, OFFSET
  178. DOUBLE PRECISION PIVMIN, RTOL, SPDIAM
  179. * ..
  180. * .. Array Arguments ..
  181. INTEGER IWORK( * )
  182. DOUBLE PRECISION D( * ), E2( * ), W( * ),
  183. $ WERR( * ), WORK( * )
  184. * ..
  185. *
  186. * =====================================================================
  187. *
  188. * .. Parameters ..
  189. DOUBLE PRECISION ZERO, ONE, TWO, HALF
  190. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,
  191. $ HALF = 0.5D0 )
  192. INTEGER MAXITR
  193. * ..
  194. * .. Local Scalars ..
  195. INTEGER CNT, I, I1, I2, II, ITER, J, K, NEXT, NINT,
  196. $ OLNINT, P, PREV, SAVI1
  197. DOUBLE PRECISION DPLUS, FAC, LEFT, MID, RIGHT, S, TMP, WIDTH
  198. *
  199. * ..
  200. * .. Intrinsic Functions ..
  201. INTRINSIC ABS, MAX
  202. * ..
  203. * .. Executable Statements ..
  204. *
  205. INFO = 0
  206. *
  207. * Quick return if possible
  208. *
  209. IF( N.LE.0 ) THEN
  210. RETURN
  211. END IF
  212. *
  213. MAXITR = INT( ( LOG( SPDIAM+PIVMIN )-LOG( PIVMIN ) ) /
  214. $ LOG( TWO ) ) + 2
  215. *
  216. * Initialize unconverged intervals in [ WORK(2*I-1), WORK(2*I) ].
  217. * The Sturm Count, Count( WORK(2*I-1) ) is arranged to be I-1, while
  218. * Count( WORK(2*I) ) is stored in IWORK( 2*I ). The integer IWORK( 2*I-1 )
  219. * for an unconverged interval is set to the index of the next unconverged
  220. * interval, and is -1 or 0 for a converged interval. Thus a linked
  221. * list of unconverged intervals is set up.
  222. *
  223. I1 = IFIRST
  224. I2 = ILAST
  225. * The number of unconverged intervals
  226. NINT = 0
  227. * The last unconverged interval found
  228. PREV = 0
  229. DO 75 I = I1, I2
  230. K = 2*I
  231. II = I - OFFSET
  232. LEFT = W( II ) - WERR( II )
  233. MID = W(II)
  234. RIGHT = W( II ) + WERR( II )
  235. WIDTH = RIGHT - MID
  236. TMP = MAX( ABS( LEFT ), ABS( RIGHT ) )
  237. * The following test prevents the test of converged intervals
  238. IF( WIDTH.LT.RTOL*TMP ) THEN
  239. * This interval has already converged and does not need refinement.
  240. * (Note that the gaps might change through refining the
  241. * eigenvalues, however, they can only get bigger.)
  242. * Remove it from the list.
  243. IWORK( K-1 ) = -1
  244. * Make sure that I1 always points to the first unconverged interval
  245. IF((I.EQ.I1).AND.(I.LT.I2)) I1 = I + 1
  246. IF((PREV.GE.I1).AND.(I.LE.I2)) IWORK( 2*PREV-1 ) = I + 1
  247. ELSE
  248. * unconverged interval found
  249. PREV = I
  250. * Make sure that [LEFT,RIGHT] contains the desired eigenvalue
  251. *
  252. * Do while( CNT(LEFT).GT.I-1 )
  253. *
  254. FAC = ONE
  255. 20 CONTINUE
  256. CNT = 0
  257. S = LEFT
  258. DPLUS = D( 1 ) - S
  259. IF( DPLUS.LT.ZERO ) CNT = CNT + 1
  260. DO 30 J = 2, N
  261. DPLUS = D( J ) - S - E2( J-1 )/DPLUS
  262. IF( DPLUS.LT.ZERO ) CNT = CNT + 1
  263. 30 CONTINUE
  264. IF( CNT.GT.I-1 ) THEN
  265. LEFT = LEFT - WERR( II )*FAC
  266. FAC = TWO*FAC
  267. GO TO 20
  268. END IF
  269. *
  270. * Do while( CNT(RIGHT).LT.I )
  271. *
  272. FAC = ONE
  273. 50 CONTINUE
  274. CNT = 0
  275. S = RIGHT
  276. DPLUS = D( 1 ) - S
  277. IF( DPLUS.LT.ZERO ) CNT = CNT + 1
  278. DO 60 J = 2, N
  279. DPLUS = D( J ) - S - E2( J-1 )/DPLUS
  280. IF( DPLUS.LT.ZERO ) CNT = CNT + 1
  281. 60 CONTINUE
  282. IF( CNT.LT.I ) THEN
  283. RIGHT = RIGHT + WERR( II )*FAC
  284. FAC = TWO*FAC
  285. GO TO 50
  286. END IF
  287. NINT = NINT + 1
  288. IWORK( K-1 ) = I + 1
  289. IWORK( K ) = CNT
  290. END IF
  291. WORK( K-1 ) = LEFT
  292. WORK( K ) = RIGHT
  293. 75 CONTINUE
  294. SAVI1 = I1
  295. *
  296. * Do while( NINT.GT.0 ), i.e. there are still unconverged intervals
  297. * and while (ITER.LT.MAXITR)
  298. *
  299. ITER = 0
  300. 80 CONTINUE
  301. PREV = I1 - 1
  302. I = I1
  303. OLNINT = NINT
  304. DO 100 P = 1, OLNINT
  305. K = 2*I
  306. II = I - OFFSET
  307. NEXT = IWORK( K-1 )
  308. LEFT = WORK( K-1 )
  309. RIGHT = WORK( K )
  310. MID = HALF*( LEFT + RIGHT )
  311. * semiwidth of interval
  312. WIDTH = RIGHT - MID
  313. TMP = MAX( ABS( LEFT ), ABS( RIGHT ) )
  314. IF( ( WIDTH.LT.RTOL*TMP ) .OR.
  315. $ (ITER.EQ.MAXITR) )THEN
  316. * reduce number of unconverged intervals
  317. NINT = NINT - 1
  318. * Mark interval as converged.
  319. IWORK( K-1 ) = 0
  320. IF( I1.EQ.I ) THEN
  321. I1 = NEXT
  322. ELSE
  323. * Prev holds the last unconverged interval previously examined
  324. IF(PREV.GE.I1) IWORK( 2*PREV-1 ) = NEXT
  325. END IF
  326. I = NEXT
  327. GO TO 100
  328. END IF
  329. PREV = I
  330. *
  331. * Perform one bisection step
  332. *
  333. CNT = 0
  334. S = MID
  335. DPLUS = D( 1 ) - S
  336. IF( DPLUS.LT.ZERO ) CNT = CNT + 1
  337. DO 90 J = 2, N
  338. DPLUS = D( J ) - S - E2( J-1 )/DPLUS
  339. IF( DPLUS.LT.ZERO ) CNT = CNT + 1
  340. 90 CONTINUE
  341. IF( CNT.LE.I-1 ) THEN
  342. WORK( K-1 ) = MID
  343. ELSE
  344. WORK( K ) = MID
  345. END IF
  346. I = NEXT
  347. 100 CONTINUE
  348. ITER = ITER + 1
  349. * do another loop if there are still unconverged intervals
  350. * However, in the last iteration, all intervals are accepted
  351. * since this is the best we can do.
  352. IF( ( NINT.GT.0 ).AND.(ITER.LE.MAXITR) ) GO TO 80
  353. *
  354. *
  355. * At this point, all the intervals have converged
  356. DO 110 I = SAVI1, ILAST
  357. K = 2*I
  358. II = I - OFFSET
  359. * All intervals marked by '0' have been refined.
  360. IF( IWORK( K-1 ).EQ.0 ) THEN
  361. W( II ) = HALF*( WORK( K-1 )+WORK( K ) )
  362. WERR( II ) = WORK( K ) - W( II )
  363. END IF
  364. 110 CONTINUE
  365. *
  366. RETURN
  367. *
  368. * End of DLARRJ
  369. *
  370. END