Télécharger dsaup2.eso

Retour à la liste

Numérotation des lignes :

dsaup2
  1. C DSAUP2 SOURCE FANDEUR 22/05/02 21:15:14 11359
  2. c-----------------------------------------------------------------------
  3. c\BeginDoc
  4. c
  5. c\Name: dsaup2
  6. c
  7. c\Description:
  8. c Intermediate level interface called by dsaupd.
  9. c
  10. c\Usage:
  11. c call dsaup2
  12. c ( IDO, BMAT, N, WHICH, NEV, NP, TOL, RESID, MODE, IUPD,
  13. c ISHIFT, MXITER, V, LDV, H, LDH, RITZ, BOUNDS, Q, LDQ, WORKL,
  14. c IPNTR, WORKD, INFO )
  15. c
  16. c\Arguments
  17. c
  18. c IDO, BMAT, N, WHICH, NEV, TOL, RESID: same as defined in dsaupd.
  19. c MODE, ISHIFT, MXITER: see the definition of IPARAM in dsaupd.
  20. c
  21. c NP Integer. (INPUT/OUTPUT)
  22. c Contains the number of implicit shifts to apply during
  23. c each Arnoldi/Lanczos iteration.
  24. c If ISHIFT=1, NP is adjusted dynamically at each iteration
  25. c to accelerate convergence and prevent stagnation.
  26. c This is also roughly equal to the number of matrix-vector
  27. c products (involving the operator OP) per Arnoldi iteration.
  28. c The logic for adjusting is contained within the current
  29. c subroutine.
  30. c If ISHIFT=0, NP is the number of shifts the user needs
  31. c to provide via reverse comunication. 0 < NP < NCV-NEV.
  32. c NP may be less than NCV-NEV since a leading block of the current
  33. c upper Tridiagonal matrix has split off and contains "unwanted"
  34. c Ritz values.
  35. c Upon termination of the IRA iteration, NP contains the number
  36. c of "converged" wanted Ritz values.
  37. c
  38. c IUPD Integer. (INPUT)
  39. c IUPD .EQ. 0: use explicit restart instead implicit update.
  40. c IUPD .NE. 0: use implicit update.
  41. c
  42. c V REAL*8 N by (NEV+NP) array. (INPUT/OUTPUT)
  43. c The Lanczos basis vectors.
  44. c
  45. c LDV Integer. (INPUT)
  46. c Leading dimension of V exactly as declared in the calling
  47. c program.
  48. c
  49. c H REAL*8 (NEV+NP) by 2 array. (OUTPUT)
  50. c H is used to store the generated symmetric tridiagonal matrix
  51. c The subdiagonal is stored in the first column of H starting
  52. c at H(2,1). The main diagonal is stored in the arscnd column
  53. c of H starting at H(1,2). If dsaup2 converges store the
  54. c B-norm of the final residual vector in H(1,1).
  55. c
  56. c LDH Integer. (INPUT)
  57. c Leading dimension of H exactly as declared in the calling
  58. c program.
  59. c
  60. c RITZ Double precision array of length NEV+NP. (OUTPUT)
  61. c RITZ(1:NEV) contains the computed Ritz values of OP.
  62. c
  63. c BOUNDS Double precision array of length NEV+NP. (OUTPUT)
  64. c BOUNDS(1:NEV) contain the error bounds corresponding to RITZ.
  65. c
  66. c Q REAL*8 (NEV+NP) by (NEV+NP) array. (WORKSPACE)
  67. c Private (replicated) work array used to accumulate the
  68. c rotation in the shift application step.
  69. c
  70. c LDQ Integer. (INPUT)
  71. c Leading dimension of Q exactly as declared in the calling
  72. c program.
  73. c
  74. c WORKL Double precision array of length at least 3*(NEV+NP). (INPUT/WORKSPACE)
  75. c Private (replicated) array on each PE or array allocated on
  76. c the front end. It is used in the computation of the
  77. c tridiagonal eigenvalue problem, the calculation and
  78. c application of the shifts and convergence checking.
  79. c If ISHIFT .EQ. O and IDO .EQ. 3, the first NP locations
  80. c of WORKL are used in reverse communication to hold the user
  81. c supplied shifts.
  82. c
  83. c IPNTR Integer array of length 3. (OUTPUT)
  84. c Pointer to mark the starting locations in the WORKD for
  85. c vectors used by the Lanczos iteration.
  86. c -------------------------------------------------------------
  87. c IPNTR(1): pointer to the current operand vector X.
  88. c IPNTR(2): pointer to the current result vector Y.
  89. c IPNTR(3): pointer to the vector B * X when used in one of
  90. c the spectral transformation modes. X is the current
  91. c operand.
  92. c -------------------------------------------------------------
  93. c
  94. c WORKD Double precision work array of length 3*N. (REVERSE COMMUNICATION)
  95. c Distributed array to be used in the basic Lanczos iteration
  96. c for reverse communication. The user should not use WORKD
  97. c as temporary workspace during the iteration !!!!!!!!!!
  98. c See Data Distribution Note in dsaupd.
  99. c
  100. c INFO Integer. (INPUT/OUTPUT)
  101. c If INFO .EQ. 0, a randomly initial residual vector is used.
  102. c If INFO .NE. 0, RESID contains the initial residual vector,
  103. c possibly from a previous run.
  104. c Error flag on output.
  105. c = 0: Normal return.
  106. c = 1: All possible eigenvalues of OP has been found.
  107. c NP returns the size of the invariant subspace
  108. c spanning the operator OP.
  109. c = 2: No shifts could be applied.
  110. c = -8: Error return from trid. eigenvalue calculation;
  111. c This should never happen.
  112. c = -9: Starting vector is zero.
  113. c = -9999: Could not build an Lanczos factorization.
  114. c Size that was built in returned in NP.
  115. c
  116. c\EndDoc
  117. c
  118. c-----------------------------------------------------------------------
  119. c
  120. c\BeginLib
  121. c
  122. c\References:
  123. c 1. D.C. Sorensen, "Implicit Application of Polynomial Filters in
  124. c a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992),
  125. c pp 357-385.
  126. c 2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly
  127. c Restarted Arnoldi Iteration", Rice University Technical Report
  128. c TR95-13, Department of Computational and Applied Mathematics.
  129. c 3. B.N. Parlett, "The Symmetric Eigenvalue Problem". Prentice-Hall,
  130. c 1980.
  131. c 4. B.N. Parlett, B. Nour-Omid, "Towards a Black Box Lanczos Program",
  132. c Computer Physics Communications, 53 (1989), pp 169-179.
  133. c 5. B. Nour-Omid, B.N. Parlett, T. Ericson, P.S. Jensen, "How to
  134. c Implement the Spectral Transformation", Math. Comp., 48 (1987),
  135. c pp 663-673.
  136. c 6. R.G. Grimes, J.G. Lewis and H.D. Simon, "A Shifted Block Lanczos
  137. c Algorithm for Solving Sparse Symmetric Generalized Eigenproblems",
  138. c SIAM J. Matr. Anal. Apps., January (1993).
  139. c 7. L. Reichel, W.B. Gragg, "Algorithm 686: FORTRAN Subroutines
  140. c for Updating the QR decomposition", ACM TOMS, December 1990,
  141. c Volume 16 Number 4, pp 369-377.
  142. c
  143. c\Routines called:
  144. c dgetv0 ARPACK initial vector generation routine.
  145. c dsaitr ARPACK Lanczos factorization routine.
  146. c dsapps ARPACK application of implicit shifts routine.
  147. c dsconv ARPACK convergence of Ritz values routine.
  148. c dseigt ARPACK compute Ritz values and error bounds routine.
  149. c dsgets ARPACK reorder Ritz values and error bounds routine.
  150. c dsortr ARPACK sorting routine.
  151. c ivout ARPACK utility routine that prints integers.
  152. c arscnd ARPACK utility routine for timing. -> deleted by BP in 2020
  153. c dvout ARPACK utility routine that prints vectors.
  154. c dlamch LAPACK routine that determines machine constants.
  155. c dcopy Level 1 BLAS that copies one vector to another.
  156. c ddot Level 1 BLAS that computes the scalar product of two vectors.
  157. c dnrm2 Level 1 BLAS that computes the norm of a vector.
  158. c dscal Level 1 BLAS that scales a vector.
  159. c dswap Level 1 BLAS that swaps two vectors.
  160. c
  161. c\Author
  162. c Danny Sorensen Phuong Vu
  163. c Richard Lehoucq CRPC / Rice University
  164. c Dept. of Computational & Houston, Texas
  165. c Applied Mathematics
  166. c Rice University
  167. c Houston, Texas
  168. c
  169. c\Revision history:
  170. c 12/15/93: Version ' 2.4'
  171. c xx/xx/95: Version ' 2.4'. (R.B. Lehoucq)
  172. c
  173. c\SCCS Information: @(#)
  174. c FILE: saup2.F SID: 2.7 DATE OF SID: 5/19/98 RELEASE: 2
  175. c
  176. c\EndLib
  177. c
  178. c-----------------------------------------------------------------------
  179. c
  180. subroutine dsaup2
  181. & ( ido, bmat, n, which, nev, np, tol, resid, mode, iupd,
  182. & ishift, mxiter, v, ldv, h, ldh, ritz, bounds,
  183. & q, ldq, workl, ipntr, workd, ITRAK, info )
  184. c
  185. c %----------------------------------------------------%
  186. c | Include files for debugging and timing information |
  187. c -INC TARTRAK
  188. c %----------------------------------------------------%
  189. c
  190. c
  191. c %------------------%
  192. c | Scalar Arguments |
  193. c %------------------%
  194. c
  195. character bmat*1, which*2
  196. integer ido, info, ishift, iupd, ldh, ldq, ldv, mxiter,
  197. & n, mode, nev, np
  198. REAL*8
  199. & tol
  200. c real*8 T0,T1,T2,T3
  201. c
  202. c %-----------------%
  203. c | Array Arguments |
  204. c %-----------------%
  205. c
  206. integer ipntr(3)
  207. INTEGER ITRAK(5)
  208. REAL*8
  209. & bounds(nev+np), h(ldh,2), q(ldq,nev+np), resid(n),
  210. & ritz(nev+np), v(ldv,nev+np), workd(3*n),
  211. & workl(3*(nev+np))
  212. c
  213. c %------------%
  214. c | Parameters |
  215. c %------------%
  216. c
  217. REAL*8
  218. & one, zero
  219. parameter (one = 1.0D+0, zero = 0.0D+0)
  220. c
  221. c %---------------%
  222. c | Local Scalars |
  223. c %---------------%
  224. c
  225. character wprime*2
  226. logical cnorm, getv0, initv, update, ushift
  227. integer ierr, iter, j, kplusp, msglvl, nconv, nevbef, nev0,
  228. c & np0, nptemp, nevd2, nevm2, kp(3)
  229. & np0, nptemp, nevd2, nevm2
  230. REAL*8
  231. & rnorm, temp, eps23
  232. save cnorm, getv0, initv, update, ushift,
  233. c & iter, kplusp, msglvl, nconv, nev0, np0,
  234. & iter, kplusp, nconv, nev0, np0,
  235. & rnorm, eps23
  236. parameter (msglvl=0)
  237. c
  238. c %----------------------%
  239. c | External Subroutines |
  240. c %----------------------%
  241. c
  242. external dcopy, dgetv0, dsaitr, dscal,
  243. c
  244. c %--------------------%
  245. c | External Functions |
  246. c %--------------------%
  247. c
  248. REAL*8
  249. external ddot, dnrm2, dlamch
  250. c
  251. c %---------------------%
  252. **c | Intrinsic Functions |
  253. **c %---------------------%
  254. **c
  255. ** intrinsic min
  256. **c
  257. **c %-----------------------%
  258. **c | Executable Statements |
  259. c %-----------------------%
  260. c T0=0.D0
  261. c T1=0.D0
  262. c T2=0.D0
  263. c T3=0.D0
  264. NOPX =ITRAK(1)
  265. NBX =ITRAK(2)
  266. NRORTH=ITRAK(3)
  267. NITREF=ITRAK(4)
  268. NRSTRT=ITRAK(5)
  269. c
  270. if (ido .eq. 0) then
  271. c
  272. c %-------------------------------%
  273. c | Initialize timing statistics |
  274. c | & message level for debugging |
  275. c %-------------------------------%
  276. c
  277. * call arscnd (t0)
  278. c msglvl = msaup2
  279. c
  280. c %---------------------------------%
  281. c | Set machine dependent constant. |
  282. c %---------------------------------%
  283. c
  284. eps23 = dlamch('Epsilon-Machine')
  285. eps23 = eps23**(2.0D+0/3.0D+0)
  286. c
  287. c %-------------------------------------%
  288. c | nev0 and np0 are integer variables |
  289. c | hold the initial values of NEV & NP |
  290. c %-------------------------------------%
  291. c
  292. nev0 = nev
  293. np0 = np
  294. c
  295. c %-------------------------------------%
  296. c | kplusp is the bound on the largest |
  297. c | Lanczos factorization built. |
  298. c | nconv is the current number of |
  299. c | "converged" eigenvlues. |
  300. c | iter is the counter on the current |
  301. c | iteration step. |
  302. c %-------------------------------------%
  303. c
  304. kplusp = nev0 + np0
  305. nconv = 0
  306. iter = 0
  307. c
  308. c %--------------------------------------------%
  309. c | Set flags for computing the first NEV steps |
  310. c | of the Lanczos factorization. |
  311. c %--------------------------------------------%
  312. c
  313. getv0 = .true.
  314. update = .false.
  315. ushift = .false.
  316. cnorm = .false.
  317. c
  318. if (info .ne. 0) then
  319. c
  320. c %--------------------------------------------%
  321. c | User provides the initial residual vector. |
  322. c %--------------------------------------------%
  323. c
  324. initv = .true.
  325. info = 0
  326. else
  327. initv = .false.
  328. end if
  329. end if
  330. c
  331. c %---------------------------------------------%
  332. c | Get a possibly random starting vector and |
  333. c | force it into the range of the operator OP. |
  334. c %---------------------------------------------%
  335. c
  336. 10 continue
  337. c
  338. if (getv0) then
  339. call dgetv0 (ido, bmat, 1, initv, n, 1, v, ldv, resid, rnorm,
  340. & ipntr, workd, nbx,nopx, info)
  341. c
  342. if (ido .ne. 99) go to 9000
  343. c
  344. if (rnorm .eq. zero) then
  345. c
  346. c %-----------------------------------------%
  347. c | The initial vector is zero. Error exit. |
  348. c %-----------------------------------------%
  349. c
  350. info = -9
  351. go to 1200
  352. end if
  353. getv0 = .false.
  354. ido = 0
  355. end if
  356. c
  357. c %------------------------------------------------------------%
  358. c | Back from reverse communication: continue with update step |
  359. c %------------------------------------------------------------%
  360. c
  361. if (update) go to 20
  362. c
  363. c %-------------------------------------------%
  364. c | Back from computing user specified shifts |
  365. c %-------------------------------------------%
  366. c
  367. if (ushift) go to 50
  368. c
  369. c %-------------------------------------%
  370. c | Back from computing residual norm |
  371. c | at the end of the current iteration |
  372. c %-------------------------------------%
  373. c
  374. if (cnorm) go to 100
  375. c
  376. c %----------------------------------------------------------%
  377. c | Compute the first NEV steps of the Lanczos factorization |
  378. c %----------------------------------------------------------%
  379. c
  380. call dsaitr (ido, bmat, n, 0, nev0, mode, resid, rnorm, v, ldv,
  381. & h, ldh, ipntr, workd, ITRAK, info)
  382. c
  383. c %---------------------------------------------------%
  384. c | ido .ne. 99 implies use of reverse communication |
  385. c | to compute operations involving OP and possibly B |
  386. c %---------------------------------------------------%
  387. c
  388. if (ido .ne. 99) go to 9000
  389. c
  390. if (info .gt. 0) then
  391. c
  392. c %-----------------------------------------------------%
  393. c | dsaitr was unable to build an Lanczos factorization |
  394. c | of length NEV0. INFO is returned with the size of |
  395. c | the factorization built. Exit main loop. |
  396. c %-----------------------------------------------------%
  397. c
  398. np = info
  399. mxiter = iter
  400. info = -9999
  401. go to 1200
  402. end if
  403. c
  404. c %--------------------------------------------------------------%
  405. c | |
  406. c | M A I N LANCZOS I T E R A T I O N L O O P |
  407. c | Each iteration implicitly restarts the Lanczos |
  408. c | factorization in place. |
  409. c | |
  410. c %--------------------------------------------------------------%
  411. c
  412. 1000 continue
  413. c
  414. iter = iter + 1
  415. c
  416. if (msglvl .gt. 0) then
  417. call ivout ( 1, iter, ndigit,
  418. & '_saup2: **** Start of major iteration number ****')
  419. end if
  420. c if (msglvl .gt. 1) then
  421. c call ivout ( 1, nev, ndigit,
  422. c & '_saup2: The length of the current Lanczos factorization')
  423. c call ivout ( 1, np, ndigit,
  424. c & '_saup2: Extend the Lanczos factorization by')
  425. c end if
  426. c c
  427. c %------------------------------------------------------------%
  428. c | Compute NP additional steps of the Lanczos factorization. |
  429. c %------------------------------------------------------------%
  430. c
  431. ido = 0
  432. 20 continue
  433. update = .true.
  434. c
  435. call dsaitr (ido, bmat, n, nev, np, mode, resid, rnorm, v,
  436. & ldv, h, ldh, ipntr, workd, ITRAK, info)
  437. c
  438. c %---------------------------------------------------%
  439. c | ido .ne. 99 implies use of reverse communication |
  440. c | to compute operations involving OP and possibly B |
  441. c %---------------------------------------------------%
  442. c
  443. if (ido .ne. 99) go to 9000
  444. c
  445. if (info .gt. 0) then
  446. c
  447. c %-----------------------------------------------------%
  448. c | dsaitr was unable to build an Lanczos factorization |
  449. c | of length NEV0+NP0. INFO is returned with the size |
  450. c | of the factorization built. Exit main loop. |
  451. c %-----------------------------------------------------%
  452. c
  453. np = info
  454. mxiter = iter
  455. info = -9999
  456. go to 1200
  457. end if
  458. update = .false.
  459. c
  460. c if (msglvl .gt. 1) then
  461. c call dvout ( 1, rnorm, ndigit,
  462. c & '_saup2: Current B-norm of residual for factorization')
  463. c end if
  464. c
  465. c %--------------------------------------------------------%
  466. c | Compute the eigenvalues and corresponding error bounds |
  467. c | of the current symmetric tridiagonal matrix. |
  468. c %--------------------------------------------------------%
  469. c
  470. call dseigt (rnorm, kplusp, h, ldh, ritz, bounds, workl, ierr)
  471. c
  472. if (ierr .ne. 0) then
  473. info = -8
  474. go to 1200
  475. end if
  476. c
  477. c %----------------------------------------------------%
  478. c | Make a copy of eigenvalues and corresponding error |
  479. c | bounds obtained from _seigt. |
  480. c %----------------------------------------------------%
  481. c
  482. call dcopy(kplusp, ritz, 1, workl(kplusp+1), 1)
  483. call dcopy(kplusp, bounds, 1, workl(2*kplusp+1), 1)
  484. c
  485. c %---------------------------------------------------%
  486. c | Select the wanted Ritz values and their bounds |
  487. c | to be used in the convergence test. |
  488. c | The selection is based on the requested number of |
  489. c | eigenvalues instead of the current NEV and NP to |
  490. c | prevent possible misconvergence. |
  491. c | * Wanted Ritz values := RITZ(NP+1:NEV+NP) |
  492. c | * Shifts := RITZ(1:NP) := WORKL(1:NP) |
  493. c %---------------------------------------------------%
  494. c
  495. nev = nev0
  496. np = np0
  497. call dsgets (ishift, which, nev, np, ritz, bounds, workl)
  498. c
  499. c %-------------------%
  500. c | Convergence test. |
  501. c %-------------------%
  502. c
  503. call dcopy (nev, bounds(np+1), 1, workl(np+1), 1)
  504. call dsconv (nev, ritz(np+1), workl(np+1), tol, nconv)
  505. c
  506. c if (msglvl .gt. 2) then
  507. c kp(1) = nev
  508. c kp(2) = np
  509. c kp(3) = nconv
  510. c call ivout ( 3, kp, ndigit,
  511. c & '_saup2: NEV, NP, NCONV are')
  512. c call dvout ( kplusp, ritz, ndigit,
  513. c & '_saup2: The eigenvalues of H')
  514. c call dvout ( kplusp, bounds, ndigit,
  515. c & '_saup2: Ritz estimates of the current NCV Ritz values')
  516. c end if
  517. c
  518. c %---------------------------------------------------------%
  519. c | Count the number of unwanted Ritz values that have zero |
  520. c | Ritz estimates. If any Ritz estimates are equal to zero |
  521. c | then a leading block of H of order equal to at least |
  522. c | the number of Ritz values with zero Ritz estimates has |
  523. c | split off. None of these Ritz values may be removed by |
  524. c | shifting. Decrease NP the number of shifts to apply. If |
  525. c | no shifts may be applied, then prepare to exit |
  526. c %---------------------------------------------------------%
  527. c
  528. nptemp = np
  529. do 30 j=1, nptemp
  530. if (bounds(j) .eq. zero) then
  531. np = np - 1
  532. nev = nev + 1
  533. end if
  534. 30 continue
  535. c
  536. if ( (nconv .ge. nev0) .or.
  537. & (iter .gt. mxiter) .or.
  538. & (np .eq. 0) ) then
  539. c
  540. c %------------------------------------------------%
  541. c | Prepare to exit. Put the converged Ritz values |
  542. c | and corresponding bounds in RITZ(1:NCONV) and |
  543. c | BOUNDS(1:NCONV) respectively. Then sort. Be |
  544. c | careful when NCONV > NP since we don't want to |
  545. c | swap overlapping locations. |
  546. c %------------------------------------------------%
  547. c
  548. if (which .eq. 'BE') then
  549. c
  550. c %-----------------------------------------------------%
  551. c | Both ends of the spectrum are requested. |
  552. c | Sort the eigenvalues into algebraically decreasing |
  553. c | order first then swap low end of the spectrum next |
  554. c | to high end in appropriate locations. |
  555. c | NOTE: when np < floor(nev/2) be careful not to swap |
  556. c | overlapping locations. |
  557. c %-----------------------------------------------------%
  558. c
  559. wprime = 'SA'
  560. call dsortr (wprime, .true., kplusp, ritz, bounds)
  561. nevd2 = nev0 / 2
  562. nevm2 = nev0 - nevd2
  563. if ( nev .gt. 1 ) then
  564. np = kplusp - nev0
  565. call dswap ( min(nevd2,np), ritz(nevm2+1), 1,
  566. & ritz( max(kplusp-nevd2+1,kplusp-np+1) ), 1)
  567. call dswap ( min(nevd2,np), bounds(nevm2+1), 1,
  568. & bounds( max(kplusp-nevd2+1,kplusp-np+1)), 1)
  569. end if
  570. c
  571. else
  572. c
  573. c %--------------------------------------------------%
  574. c | LM, SM, LA, SA case. |
  575. c | Sort the eigenvalues of H into the an order that |
  576. c | is opposite to WHICH, and apply the resulting |
  577. c | order to BOUNDS. The eigenvalues are sorted so |
  578. c | that the wanted part are always within the first |
  579. c | NEV locations. |
  580. c %--------------------------------------------------%
  581. c
  582. if (which .eq. 'LM') wprime = 'SM'
  583. if (which .eq. 'SM') wprime = 'LM'
  584. if (which .eq. 'LA') wprime = 'SA'
  585. if (which .eq. 'SA') wprime = 'LA'
  586. c
  587. call dsortr (wprime, .true., kplusp, ritz, bounds)
  588. c
  589. end if
  590. c
  591. c %--------------------------------------------------%
  592. c | Scale the Ritz estimate of each Ritz value |
  593. c | by 1 / max(eps23,magnitude of the Ritz value). |
  594. c %--------------------------------------------------%
  595. c
  596. do 35 j = 1, nev0
  597. temp = max( eps23, abs(ritz(j)) )
  598. bounds(j) = bounds(j)/temp
  599. 35 continue
  600. c
  601. c %----------------------------------------------------%
  602. c | Sort the Ritz values according to the scaled Ritz |
  603. c | esitmates. This will push all the converged ones |
  604. c | towards the front of ritzr, ritzi, bounds |
  605. c | (in the case when NCONV < NEV.) |
  606. c %----------------------------------------------------%
  607. c
  608. wprime = 'LA'
  609. call dsortr(wprime, .true., nev0, bounds, ritz)
  610. c
  611. c %----------------------------------------------%
  612. c | Scale the Ritz estimate back to its original |
  613. c | value. |
  614. c %----------------------------------------------%
  615. c
  616. do 40 j = 1, nev0
  617. temp = max( eps23, abs(ritz(j)) )
  618. bounds(j) = bounds(j)*temp
  619. 40 continue
  620. c
  621. c %--------------------------------------------------%
  622. c | Sort the "converged" Ritz values again so that |
  623. c | the "threshold" values and their associated Ritz |
  624. c | estimates appear at the appropriate position in |
  625. c | ritz and bound. |
  626. c %--------------------------------------------------%
  627. c
  628. if (which .eq. 'BE') then
  629. c
  630. c %------------------------------------------------%
  631. c | Sort the "converged" Ritz values in increasing |
  632. c | order. The "threshold" values are in the |
  633. c | middle. |
  634. c %------------------------------------------------%
  635. c
  636. wprime = 'LA'
  637. call dsortr(wprime, .true., nconv, ritz, bounds)
  638. c
  639. else
  640. c
  641. c %----------------------------------------------%
  642. c | In LM, SM, LA, SA case, sort the "converged" |
  643. c | Ritz values according to WHICH so that the |
  644. c | "threshold" value appears at the front of |
  645. c | ritz. |
  646. c %----------------------------------------------%
  647.  
  648. call dsortr(which, .true., nconv, ritz, bounds)
  649. c
  650. end if
  651. c
  652. c %------------------------------------------%
  653. c | Use h( 1,1 ) as storage to communicate |
  654. c | rnorm to _seupd if needed |
  655. c %------------------------------------------%
  656. c
  657. h(1,1) = rnorm
  658. c
  659. c if (msglvl .gt. 1) then
  660. c call dvout ( kplusp, ritz, ndigit,
  661. c & '_saup2: Sorted Ritz values.')
  662. c call dvout ( kplusp, bounds, ndigit,
  663. c & '_saup2: Sorted ritz estimates.')
  664. c end if
  665. c c
  666. c %------------------------------------%
  667. c | Max iterations have been exceeded. |
  668. c %------------------------------------%
  669. c
  670. if (iter .gt. mxiter .and. nconv .lt. nev) info = 1
  671. c
  672. c %---------------------%
  673. c | No shifts to apply. |
  674. c %---------------------%
  675. c
  676. if (np .eq. 0 .and. nconv .lt. nev0) info = 2
  677. c
  678. np = nconv
  679. go to 1100
  680. c
  681. else if (nconv .lt. nev .and. ishift .eq. 1) then
  682. c
  683. c %---------------------------------------------------%
  684. c | Do not have all the requested eigenvalues yet. |
  685. c | To prevent possible stagnation, adjust the number |
  686. c | of Ritz values and the shifts. |
  687. c %---------------------------------------------------%
  688. c
  689. nevbef = nev
  690. nev = nev + min (nconv, np/2)
  691. if (nev .eq. 1 .and. kplusp .ge. 6) then
  692. nev = kplusp / 2
  693. else if (nev .eq. 1 .and. kplusp .gt. 2) then
  694. nev = 2
  695. end if
  696. np = kplusp - nev
  697. c
  698. c %---------------------------------------%
  699. c | If the size of NEV was just increased |
  700. c | resort the eigenvalues. |
  701. c %---------------------------------------%
  702. c
  703. if (nevbef .lt. nev)
  704. & call dsgets (ishift, which, nev, np, ritz, bounds,
  705. & workl)
  706. c
  707. end if
  708. c
  709. if (msglvl .gt. 0) then
  710. call ivout ( 1, nconv, ndigit,
  711. & '_saup2: no. of "converged" Ritz values at this iter.')
  712. c if (msglvl .gt. 1) then
  713. c kp(1) = nev
  714. c kp(2) = np
  715. c call ivout ( 2, kp, ndigit,
  716. c & '_saup2: NEV and NP are')
  717. c call dvout ( nev, ritz(np+1), ndigit,
  718. c & '_saup2: "wanted" Ritz values.')
  719. c call dvout ( nev, bounds(np+1), ndigit,
  720. c & '_saup2: Ritz estimates of the "wanted" values ')
  721. c end if
  722. end if
  723.  
  724. c
  725. if (ishift .eq. 0) then
  726. c
  727. c %-----------------------------------------------------%
  728. c | User specified shifts: reverse communication to |
  729. c | compute the shifts. They are returned in the first |
  730. c | NP locations of WORKL. |
  731. c %-----------------------------------------------------%
  732. c
  733. ushift = .true.
  734. ido = 3
  735. go to 9000
  736. end if
  737. c
  738. 50 continue
  739. c
  740. c %------------------------------------%
  741. c | Back from reverse communication; |
  742. c | User specified shifts are returned |
  743. c | in WORKL(1:*NP) |
  744. c %------------------------------------%
  745. c
  746. ushift = .false.
  747. c
  748. c
  749. c %---------------------------------------------------------%
  750. c | Move the NP shifts to the first NP locations of RITZ to |
  751. c | free up WORKL. This is for the non-exact shift case; |
  752. c | in the exact shift case, dsgets already handles this. |
  753. c %---------------------------------------------------------%
  754. c
  755. if (ishift .eq. 0) call dcopy (np, workl, 1, ritz, 1)
  756. c
  757. c if (msglvl .gt. 2) then
  758. c call ivout ( 1, np, ndigit,
  759. c & '_saup2: The number of shifts to apply ')
  760. c call dvout ( np, workl, ndigit,
  761. c & '_saup2: shifts selected')
  762. c if (ishift .eq. 1) then
  763. c call dvout ( np, bounds, ndigit,
  764. c & '_saup2: corresponding Ritz estimates')
  765. c end if
  766. c end if
  767. c
  768. c %---------------------------------------------------------%
  769. c | Apply the NP0 implicit shifts by QR bulge chasing. |
  770. c | Each shift is applied to the entire tridiagonal matrix. |
  771. c | The first 2*N locations of WORKD are used as workspace. |
  772. c | After dsapps is done, we have a Lanczos |
  773. c | factorization of length NEV. |
  774. c %---------------------------------------------------------%
  775. c
  776. call dsapps (n, nev, np, ritz, v, ldv, h, ldh, resid, q, ldq,
  777. & workd)
  778. c
  779. c %---------------------------------------------%
  780. c | Compute the B-norm of the updated residual. |
  781. c | Keep B*RESID in WORKD(1:N) to be used in |
  782. c | the first step of the next call to dsaitr. |
  783. c %---------------------------------------------%
  784. c
  785. cnorm = .true.
  786. * call arscnd (t2)
  787. if (bmat .eq. 'G') then
  788. nbx = nbx + 1
  789. call dcopy (n, resid, 1, workd(n+1), 1)
  790. ipntr(1) = n + 1
  791. ipntr(2) = 1
  792. ido = 2
  793. c
  794. c %----------------------------------%
  795. c | Exit in order to compute B*RESID |
  796. c %----------------------------------%
  797. c
  798. go to 9000
  799. else if (bmat .eq. 'I') then
  800. call dcopy (n, resid, 1, workd, 1)
  801. end if
  802. c
  803. 100 continue
  804. c
  805. c %----------------------------------%
  806. c | Back from reverse communication; |
  807. c | WORKD(1:N) := B*RESID |
  808. c %----------------------------------%
  809. c
  810. if (bmat .eq. 'G') then
  811. * call arscnd (t3)
  812. c tmvbx = tmvbx + (t3 - t2)
  813. end if
  814. c
  815. if (bmat .eq. 'G') then
  816. rnorm = ddot (n, resid, 1, workd, 1)
  817. rnorm = sqrt(abs(rnorm))
  818. else if (bmat .eq. 'I') then
  819. rnorm = dnrm2(n, resid, 1)
  820. end if
  821. cnorm = .false.
  822. 130 continue
  823. c
  824. c if (msglvl .gt. 2) then
  825. c call dvout ( 1, rnorm, ndigit,
  826. c & '_saup2: B-norm of residual for NEV factorization')
  827. c call dvout ( nev, h(1,2), ndigit,
  828. c & '_saup2: main diagonal of compressed H matrix')
  829. c call dvout ( nev-1, h(2,1), ndigit,
  830. c & '_saup2: subdiagonal of compressed H matrix')
  831. c end if
  832. c
  833. go to 1000
  834. c
  835. c %---------------------------------------------------------------%
  836. c | |
  837. c | E N D O F M A I N I T E R A T I O N L O O P |
  838. c | |
  839. c %---------------------------------------------------------------%
  840. c
  841. 1100 continue
  842. c
  843. mxiter = iter
  844. nev = nconv
  845. c
  846. 1200 continue
  847. ido = 99
  848. c
  849. c %------------%
  850. c | Error exit |
  851. c %------------%
  852. c
  853. * call arscnd (t1)
  854. c tsaup2 = t1 - t0
  855. c
  856. 9000 continue
  857. ITRAK(1)=NOPX
  858. ITRAK(2)=NBX
  859. ITRAK(3)=NRORTH
  860. ITRAK(4)=NITREF
  861. ITRAK(5)=NRSTRT
  862. c
  863. c %---------------%
  864. c | End of dsaup2 |
  865. c %---------------%
  866. c
  867. end
  868.  
  869.  
  870.  
  871.  
  872.  

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