Télécharger dseupd.eso

Retour à la liste

Numérotation des lignes :

dseupd
  1. C DSEUPD SOURCE FANDEUR 22/05/02 21:15:15 11359
  2. c\BeginDoc
  3. c
  4. c\Name: dseupd
  5. c
  6. c\Description:
  7. c
  8. c This subroutine returns the converged approximations to eigenvalues
  9. c of A*z = lambda*B*z and (optionally):
  10. c
  11. c (1) the corresponding approximate eigenvectors,
  12. c
  13. c (2) an orthonormal (Lanczos) basis for the associated approximate
  14. c invariant subspace,
  15. c
  16. c (3) Both.
  17. c
  18. c There is negligible additional cost to obtain eigenvectors. An orthonormal
  19. c (Lanczos) basis is always computed. There is an additional storage cost
  20. c of n*nev if both are requested (in this case a separate array Z must be
  21. c supplied).
  22. c
  23. c These quantities are obtained from the Lanczos factorization computed
  24. c by DSAUPD for the linear operator OP prescribed by the MODE selection
  25. c (see IPARAM(7) in DSAUPD documentation.) DSAUPD must be called before
  26. c this routine is called. These approximate eigenvalues and vectors are
  27. c commonly called Ritz values and Ritz vectors respectively. They are
  28. c referred to as such in the comments that follow. The computed orthonormal
  29. c basis for the invariant subspace corresponding to these Ritz values is
  30. c referred to as a Lanczos basis.
  31. c
  32. c See documentation in the header of the subroutine DSAUPD for a definition
  33. c of OP as well as other terms and the relation of computed Ritz values
  34. c and vectors of OP with respect to the given problem A*z = lambda*B*z.
  35. c
  36. c The approximate eigenvalues of the original problem are returned in
  37. c ascending algebraic order. The user may elect to call this routine
  38. c once for each desired Ritz vector and store it peripherally if desired.
  39. c There is also the option of computing a selected set of these vectors
  40. c with a single call.
  41. c
  42. c\Usage:
  43. c call dseupd
  44. c ( RVEC, HOWMNY, SELECT, D, Z, LDZ, SIGMA, BMAT, N, WHICH, NEV, TOL,
  45. c RESID, NCV, V, LDV, IPARAM, IPNTR, WORKD, WORKL, LWORKL, INFO )
  46. c
  47. c RVEC LOGICAL (INPUT)
  48. c Specifies whether Ritz vectors corresponding to the Ritz value
  49. c approximations to the eigenproblem A*z = lambda*B*z are computed.
  50. c
  51. c RVEC = .FALSE. Compute Ritz values only.
  52. c
  53. c RVEC = .TRUE. Compute Ritz vectors.
  54. c
  55. c HOWMNY Character*1 (INPUT)
  56. c Specifies how many Ritz vectors are wanted and the form of Z
  57. c the matrix of Ritz vectors. See remark 1 below.
  58. c = 'A': compute NEV Ritz vectors;
  59. c = 'S': compute some of the Ritz vectors, specified
  60. c by the logical array SELECT.
  61. c
  62. c SELECT Logical array of dimension NCV. (INPUT/WORKSPACE)
  63. c If HOWMNY = 'S', SELECT specifies the Ritz vectors to be
  64. c computed. To select the Ritz vector corresponding to a
  65. c Ritz value D(j), SELECT(j) must be set to .TRUE..
  66. c If HOWMNY = 'A' , SELECT is used as a workspace for
  67. c reordering the Ritz values.
  68. c
  69. c D REAL*8 array of dimension NEV. (OUTPUT)
  70. c On exit, D contains the Ritz value approximations to the
  71. c eigenvalues of A*z = lambda*B*z. The values are returned
  72. c in ascending order. If IPARAM(7) = 3,4,5 then D represents
  73. c the Ritz values of OP computed by dsaupd transformed to
  74. c those of the original eigensystem A*z = lambda*B*z. If
  75. c IPARAM(7) = 1,2 then the Ritz values of OP are the same
  76. c as the those of A*z = lambda*B*z.
  77. c
  78. c Z REAL*8 N by NEV array if HOWMNY = 'A'. (OUTPUT)
  79. c On exit, Z contains the B-orthonormal Ritz vectors of the
  80. c eigensystem A*z = lambda*B*z corresponding to the Ritz
  81. c value approximations.
  82. c If RVEC = .FALSE. then Z is not referenced.
  83. c NOTE: The array Z may be set equal to first NEV columns of the
  84. c Arnoldi/Lanczos basis array V computed by DSAUPD .
  85. c
  86. c LDZ Integer. (INPUT)
  87. c The leading dimension of the array Z. If Ritz vectors are
  88. c desired, then LDZ .ge. max( 1, N ). In any case, LDZ .ge. 1.
  89. c
  90. c SIGMA Double precision (INPUT)
  91. c If IPARAM(7) = 3,4,5 represents the shift. Not referenced if
  92. c IPARAM(7) = 1 or 2.
  93. c
  94. c
  95. c **** The remaining arguments MUST be the same as for the ****
  96. c **** call to DSAUPD that was just completed. ****
  97. c
  98. c NOTE: The remaining arguments
  99. c
  100. c BMAT, N, WHICH, NEV, TOL, RESID, NCV, V, LDV, IPARAM, IPNTR,
  101. c WORKD, WORKL, LWORKL, INFO
  102. c
  103. c must be passed directly to DSEUPD following the last call
  104. c to DSAUPD . These arguments MUST NOT BE MODIFIED between
  105. c the the last call to DSAUPD and the call to DSEUPD .
  106. c
  107. c Two of these parameters (WORKL, INFO) are also output parameters:
  108. c
  109. c WORKL Double precision work array of length LWORKL. (OUTPUT/WORKSPACE)
  110. c WORKL(1:4*ncv) contains information obtained in
  111. c dsaupd . They are not changed by dseupd .
  112. c WORKL(4*ncv+1:ncv*ncv+8*ncv) holds the
  113. c untransformed Ritz values, the computed error estimates,
  114. c and the associated eigenvector matrix of H.
  115. c
  116. c Note: IPNTR(8:10) contains the pointer into WORKL for addresses
  117. c of the above information computed by dseupd .
  118. c -------------------------------------------------------------
  119. c IPNTR(8): pointer to the NCV RITZ values of the original system.
  120. c IPNTR(9): pointer to the NCV corresponding error bounds.
  121. c IPNTR(10): pointer to the NCV by NCV matrix of eigenvectors
  122. c of the tridiagonal matrix T. Only referenced by
  123. c dseupd if RVEC = .TRUE. See Remarks.
  124. c -------------------------------------------------------------
  125. c
  126. c INFO Integer. (OUTPUT)
  127. c Error flag on output.
  128. c = 0: Normal exit.
  129. c = -1: N must be positive.
  130. c = -2: NEV must be positive.
  131. c = -3: NCV must be greater than NEV and less than or equal to N.
  132. c = -5: WHICH must be one of 'LM', 'SM', 'LA', 'SA' or 'BE'.
  133. c = -6: BMAT must be one of 'I' or 'G'.
  134. c = -7: Length of private work WORKL array is not sufficient.
  135. c = -8: Error return from trid. eigenvalue calculation;
  136. c Information error from LAPACK routine dsteqr .
  137. c = -9: Starting vector is zero.
  138. c = -10: IPARAM(7) must be 1,2,3,4,5.
  139. c = -11: IPARAM(7) = 1 and BMAT = 'G' are incompatible.
  140. c = -12: NEV and WHICH = 'BE' are incompatible.
  141. c = -14: DSAUPD did not find any eigenvalues to sufficient
  142. c accuracy.
  143. c = -15: HOWMNY must be one of 'A' or 'S' if RVEC = .true.
  144. c = -16: HOWMNY = 'S' not yet implemented
  145. c = -17: DSEUPD got a different count of the number of converged
  146. c Ritz values than DSAUPD got. This indicates the user
  147. c probably made an error in passing data from DSAUPD to
  148. c DSEUPD or that the data was modified before entering
  149. c DSEUPD .
  150. c
  151. c\BeginLib
  152. c
  153. c\References:
  154. c 1. D.C. Sorensen, "Implicit Application of Polynomial Filters in
  155. c a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992),
  156. c pp 357-385.
  157. c 2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly
  158. c Restarted Arnoldi Iteration", Rice University Technical Report
  159. c TR95-13, Department of Computational and Applied Mathematics.
  160. c 3. B.N. Parlett, "The Symmetric Eigenvalue Problem". Prentice-Hall,
  161. c 1980.
  162. c 4. B.N. Parlett, B. Nour-Omid, "Towards a Black Box Lanczos Program",
  163. c Computer Physics Communications, 53 (1989), pp 169-179.
  164. c 5. B. Nour-Omid, B.N. Parlett, T. Ericson, P.S. Jensen, "How to
  165. c Implement the Spectral Transformation", Math. Comp., 48 (1987),
  166. c pp 663-673.
  167. c 6. R.G. Grimes, J.G. Lewis and H.D. Simon, "A Shifted Block Lanczos
  168. c Algorithm for Solving Sparse Symmetric Generalized Eigenproblems",
  169. c SIAM J. Matr. Anal. Apps., January (1993).
  170. c 7. L. Reichel, W.B. Gragg, "Algorithm 686: FORTRAN Subroutines
  171. c for Updating the QR decomposition", ACM TOMS, December 1990,
  172. c Volume 16 Number 4, pp 369-377.
  173. c
  174. c\Remarks
  175. c 1. The converged Ritz values are always returned in increasing
  176. c (algebraic) order.
  177. c
  178. c 2. Currently only HOWMNY = 'A' is implemented. It is included at this
  179. c stage for the user who wants to incorporate it.
  180. c
  181. c\Routines called:
  182. c dsesrt ARPACK routine that sorts an array X, and applies the
  183. c corresponding permutation to a matrix A.
  184. c dsortr dsortr ARPACK sorting routine.
  185. c ivout ARPACK utility routine that prints integers.
  186. c dvout ARPACK utility routine that prints vectors.
  187. c dgeqr2 LAPACK routine that computes the QR factorization of
  188. c a matrix.
  189. c dlacpy LAPACK matrix copy routine.
  190. c dlamch LAPACK routine that determines machine constants.
  191. c dorm2r LAPACK routine that applies an orthogonal matrix in
  192. c factored form.
  193. c dsteqr LAPACK routine that computes eigenvalues and eigenvectors
  194. c of a tridiagonal matrix.
  195. c dger Level 2 BLAS rank one update to a matrix.
  196. c dcopy Level 1 BLAS that copies one vector to another .
  197. c dnrm2 Level 1 BLAS that computes the norm of a vector.
  198. c dscal Level 1 BLAS that scales a vector.
  199. c dswap Level 1 BLAS that swaps the contents of two vectors.
  200.  
  201. c\Authors
  202. c Danny Sorensen Phuong Vu
  203. c Richard Lehoucq CRPC / Rice University
  204. c Chao Yang Houston, Texas
  205. c Dept. of Computational &
  206. c Applied Mathematics
  207. c Rice University
  208. c Houston, Texas
  209. c
  210. c\Revision history:
  211. c 12/15/93: Version ' 2.1'
  212. c
  213. c\SCCS Information: @(#)
  214. c FILE: seupd.F SID: 2.11 DATE OF SID: 04/10/01 RELEASE: 2
  215. c
  216. c\EndLib
  217. c
  218. c-----------------------------------------------------------------------
  219. subroutine dseupd (rvec , howmny, select, d ,
  220. & z , ldz , sigma , bmat ,
  221. & n , which , nev , tol ,
  222. & resid , ncv , v , ldv ,
  223. & iparam, ipntr , workd , workl,
  224. & lworkl, info )
  225.  
  226. implicit real*8(a-h,o-z)
  227. c
  228. c %----------------------------------------------------%
  229. c | Include files for debugging and timing information |
  230. c -INC TARTRAK
  231. c %----------------------------------------------------%
  232. c
  233. c
  234. c %------------------%
  235. c | Scalar Arguments |
  236. c %------------------%
  237. c
  238. character bmat, howmny, which*2
  239. logical rvec
  240. integer info, ldz, ldv, lworkl, n, ncv, nev
  241. REAL*8
  242. & sigma, tol
  243. c
  244. c %-----------------%
  245. c | Array Arguments |
  246. c %-----------------%
  247. c
  248. cbp integer iparam(7), ipntr(11)
  249. integer iparam(11), ipntr(11)
  250. logical select(ncv)
  251. REAL*8
  252. & d(nev) , resid(n) , v(ldv,ncv),
  253. & z(ldz, nev), workd(2*n), workl(lworkl)
  254. c
  255. c %------------%
  256. c | Parameters |
  257. c %------------%
  258. c
  259. REAL*8
  260. & one, zero
  261. parameter (one = 1.0D+0 , zero = 0.0D+0 )
  262. c
  263. c %---------------%
  264. c | Local Scalars |
  265. c %---------------%
  266. c
  267. character type*6
  268. integer bounds , ierr , ih , ihb , ihd ,
  269. & iq , iw , j , k , ldh ,
  270. & ldq , mode , msglvl, nconv , next ,
  271. & ritz , irz , ibd , np , ishift,
  272. & leftptr, rghtptr, numcnv, jj
  273. parameter (msglvl=0)
  274. REAL*8
  275. & bnorm2 , rnorm, temp(1), temp1, eps23
  276. logical reord
  277. c
  278. c %----------------------%
  279. c | External Subroutines |
  280. c %----------------------%
  281. c
  282. external dcopy , dger , dgeqr2 , dlacpy ,
  283. c
  284. c %--------------------%
  285. c | External Functions |
  286. c %--------------------%
  287. c
  288. REAL*8
  289. external dnrm2 , dlamch
  290. c
  291. c %---------------------%
  292. **c | Intrinsic Functions |
  293. **c %---------------------%
  294. **c
  295. ** intrinsic min
  296. **c
  297. **c %-----------------------%
  298. **c | Executable Statements |
  299. c %-----------------------%
  300. c
  301. c %------------------------%
  302. c | Set default parameters |
  303. c %------------------------%
  304. c
  305. c msglvl = mseupd
  306. mode = iparam(7)
  307. nconv = iparam(5)
  308. info = 0
  309. c
  310. c %--------------%
  311. c | Quick return |
  312. c %--------------%
  313. c
  314. if (nconv .eq. 0) go to 9000
  315. ierr = 0
  316. c
  317. if (nconv .le. 0) ierr = -14
  318. if (n .le. 0) ierr = -1
  319. if (nev .le. 0) ierr = -2
  320. if (ncv .le. nev .or. ncv .gt. n) ierr = -3
  321. if (which .ne. 'LM' .and.
  322. & which .ne. 'SM' .and.
  323. & which .ne. 'LA' .and.
  324. & which .ne. 'SA' .and.
  325. & which .ne. 'BE') ierr = -5
  326. if (bmat .ne. 'I' .and. bmat .ne. 'G') ierr = -6
  327. if ( (howmny .ne. 'A' .and.
  328. & howmny .ne. 'P' .and.
  329. & howmny .ne. 'S') .and. rvec )
  330. & ierr = -15
  331. if (rvec .and. howmny .eq. 'S') ierr = -16
  332. c
  333. if (rvec .and. lworkl .lt. ncv**2+8*ncv) ierr = -7
  334. c
  335. if (mode .eq. 1 .or. mode .eq. 2) then
  336. type = 'REGULR'
  337. else if (mode .eq. 3 ) then
  338. type = 'SHIFTI'
  339. else if (mode .eq. 4 ) then
  340. type = 'BUCKLE'
  341. else if (mode .eq. 5 ) then
  342. type = 'CAYLEY'
  343. else
  344. ierr = -10
  345. end if
  346. if (mode .eq. 1 .and. bmat .eq. 'G') ierr = -11
  347. if (nev .eq. 1 .and. which .eq. 'BE') ierr = -12
  348. c
  349. c %------------%
  350. c | Error Exit |
  351. c %------------%
  352. c
  353. if (ierr .ne. 0) then
  354. info = ierr
  355. go to 9000
  356. end if
  357. c
  358. c %-------------------------------------------------------%
  359. c | Pointer into WORKL for address of H, RITZ, BOUNDS, Q |
  360. c | etc... and the remaining workspace. |
  361. c | Also update pointer to be used on output. |
  362. c | Memory is laid out as follows: |
  363. c | workl(1:2*ncv) := generated tridiagonal matrix H |
  364. c | The subdiagonal is stored in workl(2:ncv). |
  365. c | The dead spot is workl(1) but upon exiting |
  366. c | dsaupd stores the B-norm of the last residual |
  367. c | vector in workl(1). We use this !!! |
  368. c | workl(2*ncv+1:2*ncv+ncv) := ritz values |
  369. c | The wanted values are in the first NCONV spots. |
  370. c | workl(3*ncv+1:3*ncv+ncv) := computed Ritz estimates |
  371. c | The wanted values are in the first NCONV spots. |
  372. c | NOTE: workl(1:4*ncv) is set by dsaupd and is not |
  373. c | modified by dseupd . |
  374. c %-------------------------------------------------------%
  375. c
  376. c %-------------------------------------------------------%
  377. c | The following is used and set by dseupd . |
  378. c | workl(4*ncv+1:4*ncv+ncv) := used as workspace during |
  379. c | computation of the eigenvectors of H. Stores |
  380. c | the diagonal of H. Upon EXIT contains the NCV |
  381. c | Ritz values of the original system. The first |
  382. c | NCONV spots have the wanted values. If MODE = |
  383. c | 1 or 2 then will equal workl(2*ncv+1:3*ncv). |
  384. c | workl(5*ncv+1:5*ncv+ncv) := used as workspace during |
  385. c | computation of the eigenvectors of H. Stores |
  386. c | the subdiagonal of H. Upon EXIT contains the |
  387. c | NCV corresponding Ritz estimates of the |
  388. c | original system. The first NCONV spots have the |
  389. c | wanted values. If MODE = 1,2 then will equal |
  390. c | workl(3*ncv+1:4*ncv). |
  391. c | workl(6*ncv+1:6*ncv+ncv*ncv) := orthogonal Q that is |
  392. c | the eigenvector matrix for H as returned by |
  393. c | dsteqr . Not referenced if RVEC = .False. |
  394. c | Ordering follows that of workl(4*ncv+1:5*ncv) |
  395. c | workl(6*ncv+ncv*ncv+1:6*ncv+ncv*ncv+2*ncv) := |
  396. c | Workspace. Needed by dsteqr and by dseupd . |
  397. c | GRAND total of NCV*(NCV+8) locations. |
  398. c %-------------------------------------------------------%
  399. c
  400. c
  401. ih = ipntr(5)
  402. ritz = ipntr(6)
  403. bounds = ipntr(7)
  404. ldh = ncv
  405. ldq = ncv
  406. ihd = bounds + ldh
  407. ihb = ihd + ldh
  408. iq = ihb + ldh
  409. iw = iq + ldh*ncv
  410. next = iw + 2*ncv
  411. ipntr(4) = next
  412. ipntr(8) = ihd
  413. ipntr(9) = ihb
  414. ipntr(10) = iq
  415. c
  416. c %----------------------------------------%
  417. c | irz points to the Ritz values computed |
  418. c | by _seigt before exiting _saup2. |
  419. c | ibd points to the Ritz estimates |
  420. c | computed by _seigt before exiting |
  421. c | _saup2. |
  422. c %----------------------------------------%
  423. c
  424. irz = ipntr(11)+ncv
  425. ibd = irz+ncv
  426. c
  427. c
  428. c %---------------------------------%
  429. c | Set machine dependent constant. |
  430. c %---------------------------------%
  431. c
  432. eps23 = dlamch ('Epsilon-Machine')
  433. eps23 = eps23**(2.0D+0 / 3.0D+0 )
  434. c
  435. c %---------------------------------------%
  436. c | RNORM is B-norm of the RESID(1:N). |
  437. c | BNORM2 is the 2 norm of B*RESID(1:N). |
  438. c | Upon exit of dsaupd WORKD(1:N) has |
  439. c | B*RESID(1:N). |
  440. c %---------------------------------------%
  441. c
  442. rnorm = workl(ih)
  443. if (bmat .eq. 'I') then
  444. bnorm2 = rnorm
  445. else if (bmat .eq. 'G') then
  446. bnorm2 = dnrm2 (n, workd, 1)
  447. end if
  448. c
  449. c if (msglvl .gt. 2) then
  450. c call dvout ( ncv, workl(irz), ndigit,
  451. c & '_seupd: Ritz values passed in from _SAUPD.')
  452. c call dvout ( ncv, workl(ibd), ndigit,
  453. c & '_seupd: Ritz estimates passed in from _SAUPD.')
  454. c end if
  455. c
  456. if (rvec) then
  457. c
  458. reord = .false.
  459. c
  460. c %---------------------------------------------------%
  461. c | Use the temporary bounds array to store indices |
  462. c | These will be used to mark the select array later |
  463. c %---------------------------------------------------%
  464. c
  465. do 10 j = 1,ncv
  466. workl(bounds+j-1) = j
  467. select(j) = .false.
  468. 10 continue
  469. c
  470. c %-------------------------------------%
  471. c | Select the wanted Ritz values. |
  472. c | Sort the Ritz values so that the |
  473. c | wanted ones appear at the tailing |
  474. c | NEV positions of workl(irr) and |
  475. c | workl(iri). Move the corresponding |
  476. c | error estimates in workl(bound) |
  477. c | accordingly. |
  478. c %-------------------------------------%
  479. c
  480. np = ncv - nev
  481. ishift = 0
  482. call dsgets (ishift, which , nev ,
  483. & np , workl(irz) , workl(bounds),
  484. & workl)
  485. c
  486. c if (msglvl .gt. 2) then
  487. c call dvout ( ncv, workl(irz), ndigit,
  488. c & '_seupd: Ritz values after calling _SGETS.')
  489. c call dvout ( ncv, workl(bounds), ndigit,
  490. c & '_seupd: Ritz value indices after calling _SGETS.')
  491. c end if
  492. c
  493. c %-----------------------------------------------------%
  494. c | Record indices of the converged wanted Ritz values |
  495. c | Mark the select array for possible reordering |
  496. c %-----------------------------------------------------%
  497. c
  498. numcnv = 0
  499. do 11 j = 1,ncv
  500. temp1 = max(eps23, abs(workl(irz+ncv-j)) )
  501. jj = int(workl(bounds + ncv - j))
  502. if (numcnv .lt. nconv .and.
  503. & workl(ibd+jj-1) .le. tol*temp1) then
  504. select(jj) = .true.
  505. numcnv = numcnv + 1
  506. if (jj .gt. nconv) reord = .true.
  507. endif
  508. 11 continue
  509. c
  510. c %-----------------------------------------------------------%
  511. c | Check the count (numcnv) of converged Ritz values with |
  512. c | the number (nconv) reported by _saupd. If these two |
  513. c | are different then there has probably been an error |
  514. c | caused by incorrect passing of the _saupd data. |
  515. c %-----------------------------------------------------------%
  516. c
  517. c if (msglvl .gt. 2) then
  518. c call ivout ( 1, numcnv, ndigit,
  519. c & '_seupd: Number of specified eigenvalues')
  520. c call ivout ( 1, nconv, ndigit,
  521. c & '_seupd: Number of "converged" eigenvalues')
  522. c end if
  523. c
  524. if (numcnv .ne. nconv) then
  525. info = -17
  526. go to 9000
  527. end if
  528. c
  529. c %-----------------------------------------------------------%
  530. c | Call LAPACK routine _steqr to compute the eigenvalues and |
  531. c | eigenvectors of the final symmetric tridiagonal matrix H. |
  532. c | Initialize the eigenvector matrix Q to the identity. |
  533. c %-----------------------------------------------------------%
  534. c
  535. call dcopy (ncv-1, workl(ih+1), 1, workl(ihb), 1)
  536. call dcopy (ncv, workl(ih+ldh), 1, workl(ihd), 1)
  537. c
  538. call dsteqr ('Identity', ncv, workl(ihd), workl(ihb),
  539. & workl(iq) , ldq, workl(iw), ierr)
  540. c
  541. if (ierr .ne. 0) then
  542. info = -8
  543. go to 9000
  544. end if
  545. c
  546. c if (msglvl .gt. 1) then
  547. c call dcopy (ncv, workl(iq+ncv-1), ldq, workl(iw), 1)
  548. c call dvout ( ncv, workl(ihd), ndigit,
  549. c & '_seupd: NCV Ritz values of the final H matrix')
  550. c call dvout ( ncv, workl(iw), ndigit,
  551. c & '_seupd: last row of the eigenvector matrix for H')
  552. c end if
  553. c
  554. if (reord) then
  555. c
  556. c %---------------------------------------------%
  557. c | Reordered the eigenvalues and eigenvectors |
  558. c | computed by _steqr so that the "converged" |
  559. c | eigenvalues appear in the first NCONV |
  560. c | positions of workl(ihd), and the associated |
  561. c | eigenvectors appear in the first NCONV |
  562. c | columns. |
  563. c %---------------------------------------------%
  564. c
  565. leftptr = 1
  566. rghtptr = ncv
  567. c
  568. if (ncv .eq. 1) go to 30
  569. c
  570. 20 if (select(leftptr)) then
  571. c
  572. c %-------------------------------------------%
  573. c | Search, from the left, for the first Ritz |
  574. c | value that has not converged. |
  575. c %-------------------------------------------%
  576. c
  577. leftptr = leftptr + 1
  578. c
  579. else if ( .not. select(rghtptr)) then
  580. c
  581. c %----------------------------------------------%
  582. c | Search, from the right, the first Ritz value |
  583. c | that has converged. |
  584. c %----------------------------------------------%
  585. c
  586. rghtptr = rghtptr - 1
  587. c
  588. else
  589. c
  590. c %----------------------------------------------%
  591. c | Swap the Ritz value on the left that has not |
  592. c | converged with the Ritz value on the right |
  593. c | that has converged. Swap the associated |
  594. c | eigenvector of the tridiagonal matrix H as |
  595. c | well. |
  596. c %----------------------------------------------%
  597. c
  598. temp(1) = workl(ihd+leftptr-1)
  599. workl(ihd+leftptr-1) = workl(ihd+rghtptr-1)
  600. workl(ihd+rghtptr-1) = temp(1)
  601. call dcopy (ncv, workl(iq+ncv*(leftptr-1)), 1,
  602. & workl(iw), 1)
  603. call dcopy (ncv, workl(iq+ncv*(rghtptr-1)), 1,
  604. & workl(iq+ncv*(leftptr-1)), 1)
  605. call dcopy (ncv, workl(iw), 1,
  606. & workl(iq+ncv*(rghtptr-1)), 1)
  607. leftptr = leftptr + 1
  608. rghtptr = rghtptr - 1
  609. c
  610. end if
  611. c
  612. if (leftptr .lt. rghtptr) go to 20
  613. c
  614. end if
  615. c
  616. 30 continue
  617. c if (msglvl .gt. 2) then
  618. c call dvout ( ncv, workl(ihd), ndigit,
  619. c & '_seupd: The eigenvalues of H--reordered')
  620. c end if
  621. c
  622. c %----------------------------------------%
  623. c | Load the converged Ritz values into D. |
  624. c %----------------------------------------%
  625. c
  626. call dcopy (nconv, workl(ihd), 1, d, 1)
  627. c
  628. else
  629. c
  630. c %-----------------------------------------------------%
  631. c | Ritz vectors not required. Load Ritz values into D. |
  632. c %-----------------------------------------------------%
  633. c
  634. call dcopy (nconv, workl(ritz), 1, d, 1)
  635. call dcopy (ncv, workl(ritz), 1, workl(ihd), 1)
  636. c
  637. end if
  638. c
  639. c %------------------------------------------------------------------%
  640. c | Transform the Ritz values and possibly vectors and corresponding |
  641. c | Ritz estimates of OP to those of A*x=lambda*B*x. The Ritz values |
  642. c | (and corresponding data) are returned in ascending order. |
  643. c %------------------------------------------------------------------%
  644. c
  645. if (type .eq. 'REGULR') then
  646. c
  647. c %---------------------------------------------------------%
  648. c | Ascending sort of wanted Ritz values, vectors and error |
  649. c | bounds. Not necessary if only Ritz values are desired. |
  650. c %---------------------------------------------------------%
  651. c
  652. if (rvec) then
  653. call dsesrt ('LA', rvec , nconv, d, ncv, workl(iq), ldq)
  654. else
  655. call dcopy (ncv, workl(bounds), 1, workl(ihb), 1)
  656. end if
  657. c
  658. else
  659. c
  660. c %-------------------------------------------------------------%
  661. c | * Make a copy of all the Ritz values. |
  662. c | * Transform the Ritz values back to the original system. |
  663. c | For TYPE = 'SHIFTI' the transformation is |
  664. c | lambda = 1/theta + sigma |
  665. c | For TYPE = 'BUCKLE' the transformation is |
  666. c | lambda = sigma * theta / ( theta - 1 ) |
  667. c | For TYPE = 'CAYLEY' the transformation is |
  668. c | lambda = sigma * (theta + 1) / (theta - 1 ) |
  669. c | where the theta are the Ritz values returned by dsaupd . |
  670. c | NOTES: |
  671. c | *The Ritz vectors are not affected by the transformation. |
  672. c | They are only reordered. |
  673. c %-------------------------------------------------------------%
  674. c
  675. call dcopy (ncv, workl(ihd), 1, workl(iw), 1)
  676. if (type .eq. 'SHIFTI') then
  677. do 40 k=1, ncv
  678. workl(ihd+k-1) = one / workl(ihd+k-1) + sigma
  679. 40 continue
  680. else if (type .eq. 'BUCKLE') then
  681. do 50 k=1, ncv
  682. workl(ihd+k-1) = sigma * workl(ihd+k-1) /
  683. & (workl(ihd+k-1) - one)
  684. 50 continue
  685. else if (type .eq. 'CAYLEY') then
  686. do 60 k=1, ncv
  687. workl(ihd+k-1) = sigma * (workl(ihd+k-1) + one) /
  688. & (workl(ihd+k-1) - one)
  689. 60 continue
  690. end if
  691. c
  692. c %-------------------------------------------------------------%
  693. c | * Store the wanted NCONV lambda values into D. |
  694. c | * Sort the NCONV wanted lambda in WORKL(IHD:IHD+NCONV-1) |
  695. c | into ascending order and apply sort to the NCONV theta |
  696. c | values in the transformed system. We will need this to |
  697. c | compute Ritz estimates in the original system. |
  698. c | * Finally sort the lambda`s into ascending order and apply |
  699. c | to Ritz vectors if wanted. Else just sort lambda`s into |
  700. c | ascending order. |
  701. c | NOTES: |
  702. c | *workl(iw:iw+ncv-1) contain the theta ordered so that they |
  703. c | match the ordering of the lambda. We`ll use them again for |
  704. c | Ritz vector purification. |
  705. c %-------------------------------------------------------------%
  706. c
  707. call dcopy (nconv, workl(ihd), 1, d, 1)
  708. call dsortr ('LA', .true., nconv, workl(ihd), workl(iw))
  709. if (rvec) then
  710. call dsesrt ('LA', rvec , nconv, d, ncv, workl(iq), ldq)
  711. else
  712. call dcopy (ncv, workl(bounds), 1, workl(ihb), 1)
  713. call dscal (ncv, bnorm2/rnorm, workl(ihb), 1)
  714. call dsortr ('LA', .true., nconv, d, workl(ihb))
  715. end if
  716. c
  717. end if
  718. c
  719. c %------------------------------------------------%
  720. c | Compute the Ritz vectors. Transform the wanted |
  721. c | eigenvectors of the symmetric tridiagonal H by |
  722. c | the Lanczos basis matrix V. |
  723. c %------------------------------------------------%
  724. c
  725. if (rvec .and. howmny .eq. 'A') then
  726. c
  727. c %----------------------------------------------------------%
  728. c | Compute the QR factorization of the matrix representing |
  729. c | the wanted invariant subspace located in the first NCONV |
  730. c | columns of workl(iq,ldq). |
  731. c %----------------------------------------------------------%
  732. c
  733. call dgeqr2 (ncv, nconv , workl(iq) ,
  734. & ldq, workl(iw+ncv), workl(ihb),
  735. & ierr)
  736. c
  737. c %--------------------------------------------------------%
  738. c | * Postmultiply V by Q. |
  739. c | * Copy the first NCONV columns of VQ into Z. |
  740. c | The N by NCONV matrix Z is now a matrix representation |
  741. c | of the approximate invariant subspace associated with |
  742. c | the Ritz values in workl(ihd). |
  743. c %--------------------------------------------------------%
  744. c
  745. call dorm2r ('Right', 'Notranspose', n ,
  746. & ncv , nconv , workl(iq),
  747. & ldq , workl(iw+ncv), v ,
  748. & ldv , workd(n+1) , ierr)
  749. call dlacpy ('All', n, nconv, v, ldv, z, ldz)
  750. c
  751. c %-----------------------------------------------------%
  752. c | In order to compute the Ritz estimates for the Ritz |
  753. c | values in both systems, need the last row of the |
  754. c | eigenvector matrix. Remember, it`s in factored form |
  755. c %-----------------------------------------------------%
  756. c
  757. do 65 j = 1, ncv-1
  758. workl(ihb+j-1) = zero
  759. 65 continue
  760. workl(ihb+ncv-1) = one
  761. call dorm2r ('Left', 'Transpose' , ncv ,
  762. & 1 , nconv , workl(iq) ,
  763. & ldq , workl(iw+ncv), workl(ihb),
  764. & ncv , temp(1) , ierr)
  765. c
  766. c %-----------------------------------------------------%
  767. c | Make a copy of the last row into |
  768. c | workl(iw+ncv:iw+2*ncv), as it is needed again in |
  769. c | the Ritz vector purification step below |
  770. c %-----------------------------------------------------%
  771. c
  772. do 67 j = 1, nconv
  773. workl(iw+ncv+j-1) = workl(ihb+j-1)
  774. 67 continue
  775.  
  776. else if (rvec .and. howmny .eq. 'S') then
  777. c
  778. c Not yet implemented. See remark 2 above.
  779. c
  780. end if
  781. c
  782. if (type .eq. 'REGULR' .and. rvec) then
  783. c
  784. do 70 j=1, ncv
  785. workl(ihb+j-1) = rnorm * abs( workl(ihb+j-1) )
  786. 70 continue
  787. c
  788. else if (type .ne. 'REGULR' .and. rvec) then
  789. c
  790. c %-------------------------------------------------%
  791. c | * Determine Ritz estimates of the theta. |
  792. c | If RVEC = .true. then compute Ritz estimates |
  793. c | of the theta. |
  794. c | If RVEC = .false. then copy Ritz estimates |
  795. c | as computed by dsaupd . |
  796. c | * Determine Ritz estimates of the lambda. |
  797. c %-------------------------------------------------%
  798. c
  799. call dscal (ncv, bnorm2, workl(ihb), 1)
  800. if (type .eq. 'SHIFTI') then
  801. c
  802. do 80 k=1, ncv
  803. workl(ihb+k-1) = abs( workl(ihb+k-1) )
  804. & / workl(iw+k-1)**2
  805. 80 continue
  806. c
  807. else if (type .eq. 'BUCKLE') then
  808. c
  809. do 90 k=1, ncv
  810. workl(ihb+k-1) = sigma * abs( workl(ihb+k-1) )
  811. & / (workl(iw+k-1)-one )**2
  812. 90 continue
  813. c
  814. else if (type .eq. 'CAYLEY') then
  815. c
  816. do 100 k=1, ncv
  817. workl(ihb+k-1) = abs( workl(ihb+k-1)
  818. & / workl(iw+k-1)*(workl(iw+k-1)-one) )
  819. 100 continue
  820. c
  821. end if
  822. c
  823. end if
  824. c
  825. c if (type .ne. 'REGULR' .and. msglvl .gt. 1) then
  826. c call dvout ( nconv, d, ndigit,
  827. c & '_seupd: Untransformed converged Ritz values')
  828. c call dvout ( nconv, workl(ihb), ndigit,
  829. c & '_seupd: Ritz estimates of the untransformed Ritz values')
  830. c else if (msglvl .gt. 1) then
  831. c call dvout ( nconv, d, ndigit,
  832. c & '_seupd: Converged Ritz values')
  833. c call dvout ( nconv, workl(ihb), ndigit,
  834. c & '_seupd: Associated Ritz estimates')
  835. c end if
  836. c
  837. c %-------------------------------------------------%
  838. c | Ritz vector purification step. Formally perform |
  839. c | one of inverse subspace iteration. Only used |
  840. c | for MODE = 3,4,5. See reference 7 |
  841. c %-------------------------------------------------%
  842. c
  843. if (rvec .and. (type .eq. 'SHIFTI' .or. type .eq. 'CAYLEY')) then
  844. c
  845. do 110 k=0, nconv-1
  846. workl(iw+k) = workl(iw+ncv+k)
  847. & / workl(iw+k)
  848. 110 continue
  849. c
  850. else if (rvec .and. type .eq. 'BUCKLE') then
  851. c
  852. do 120 k=0, nconv-1
  853. workl(iw+k) = workl(iw+ncv+k)
  854. & / (workl(iw+k)-one)
  855. 120 continue
  856. c
  857. end if
  858. c
  859. if (rvec .and. type .ne. 'REGULR')
  860. & call dger (n, nconv, one, resid, 1, workl(iw), 1, z, ldz)
  861. c
  862. 9000 continue
  863. c
  864. c return
  865. c
  866. c %---------------%
  867. c | End of dseupd |
  868. c %---------------%
  869. c
  870. end
  871.  
  872.  
  873.  
  874.  
  875.  

© Cast3M 2003 - Tous droits réservés.
Mentions légales