Télécharger dnaitr.eso

Retour à la liste

Numérotation des lignes :

dnaitr
  1. C DNAITR SOURCE FANDEUR 22/05/02 21:15:10 11359
  2. c-----------------------------------------------------------------------
  3. c\BeginDoc
  4. c
  5. c\Name: dnaitr
  6. c
  7. c\Description:
  8. c Reverse communication interface for applying NP additional steps to
  9. c a K step nonsymmetric Arnoldi factorization.
  10. c
  11. c Input: OP*V_{k} - V_{k}*H = r_{k}*e_{k}^T
  12. c
  13. c with (V_{k}^T)*B*V_{k} = I, (V_{k}^T)*B*r_{k} = 0.
  14. c
  15. c Output: OP*V_{k+p} - V_{k+p}*H = r_{k+p}*e_{k+p}^T
  16. c
  17. c with (V_{k+p}^T)*B*V_{k+p} = I, (V_{k+p}^T)*B*r_{k+p} = 0.
  18. c
  19. c where OP and B are as in dnaupd. The B-norm of r_{k+p} is also
  20. c computed and returned.
  21. c
  22. c\Usage:
  23. c call dnaitr
  24. c ( IDO, BMAT, N, K, NP, NB, RESID, RNORM, V, LDV, H, LDH,
  25. c IPNTR, WORKD, INFO )
  26. c
  27. c\Arguments
  28. c IDO Integer. (INPUT/OUTPUT)
  29. c Reverse communication flag.
  30. c -------------------------------------------------------------
  31. c IDO = 0: first call to the reverse communication interface
  32. c IDO = -1: compute Y = OP * X where
  33. c IPNTR(1) is the pointer into WORK for X,
  34. c IPNTR(2) is the pointer into WORK for Y.
  35. c This is for the restart phase to force the new
  36. c starting vector into the range of OP.
  37. c IDO = 1: compute Y = OP * X where
  38. c IPNTR(1) is the pointer into WORK for X,
  39. c IPNTR(2) is the pointer into WORK for Y,
  40. c IPNTR(3) is the pointer into WORK for B * X.
  41. c IDO = 2: compute Y = B * X where
  42. c IPNTR(1) is the pointer into WORK for X,
  43. c IPNTR(2) is the pointer into WORK for Y.
  44. c IDO = 99: done
  45. c -------------------------------------------------------------
  46. c When the routine is used in the "shift-and-invert" mode, the
  47. c vector B * Q is already available and do not need to be
  48. c recompute in forming OP * Q.
  49. c
  50. c BMAT Character*1. (INPUT)
  51. c BMAT specifies the type of the matrix B that defines the
  52. c semi-inner product for the operator OP. See dnaupd.
  53. c B = 'I' -> standard eigenvalue problem A*x = lambda*x
  54. c B = 'G' -> generalized eigenvalue problem A*x = lambda*M**x
  55. c
  56. c N Integer. (INPUT)
  57. c Dimension of the eigenproblem.
  58. c
  59. c K Integer. (INPUT)
  60. c Current size of V and H.
  61. c
  62. c NP Integer. (INPUT)
  63. c Number of additional Arnoldi steps to take.
  64. c
  65. c NB Integer. (INPUT)
  66. c Blocksize to be used in the recurrence.
  67. c Only work for NB = 1 right now. The goal is to have a
  68. c program that implement both the block and non-block method.
  69. c
  70. c RESID Double precision array of length N. (INPUT/OUTPUT)
  71. c On INPUT: RESID contains the residual vector r_{k}.
  72. c On OUTPUT: RESID contains the residual vector r_{k+p}.
  73. c
  74. c RNORM Double precision scalar. (INPUT/OUTPUT)
  75. c B-norm of the starting residual on input.
  76. c B-norm of the updated residual r_{k+p} on output.
  77. c
  78. c V REAL*8 N by K+NP array. (INPUT/OUTPUT)
  79. c On INPUT: V contains the Arnoldi vectors in the first K
  80. c columns.
  81. c On OUTPUT: V contains the new NP Arnoldi vectors in the next
  82. c NP columns. The first K columns are unchanged.
  83. c
  84. c LDV Integer. (INPUT)
  85. c Leading dimension of V exactly as declared in the calling
  86. c program.
  87. c
  88. c H REAL*8 (K+NP) by (K+NP) array. (INPUT/OUTPUT)
  89. c H is used to store the generated upper Hessenberg matrix.
  90. c
  91. c LDH Integer. (INPUT)
  92. c Leading dimension of H exactly as declared in the calling
  93. c program.
  94. c
  95. c IPNTR Integer array of length 3. (OUTPUT)
  96. c Pointer to mark the starting locations in the WORK for
  97. c vectors used by the Arnoldi iteration.
  98. c -------------------------------------------------------------
  99. c IPNTR(1): pointer to the current operand vector X.
  100. c IPNTR(2): pointer to the current result vector Y.
  101. c IPNTR(3): pointer to the vector B * X when used in the
  102. c shift-and-invert mode. X is the current operand.
  103. c -------------------------------------------------------------
  104. c
  105. c WORKD Double precision work array of length 3*N. (REVERSE COMMUNICATION)
  106. c Distributed array to be used in the basic Arnoldi iteration
  107. c for reverse communication. The calling program should not
  108. c use WORKD as temporary workspace during the iteration !!!!!!
  109. c On input, WORKD(1:N) = B*RESID and is used to save some
  110. c computation at the first step.
  111. c
  112. c INFO Integer. (OUTPUT)
  113. c = 0: Normal exit.
  114. c > 0: Size of the spanning invariant subspace of OP found.
  115. c
  116. c\EndDoc
  117. c
  118. c-----------------------------------------------------------------------
  119. c
  120. c\BeginLib
  121. c
  122. c\Local variables:
  123. c xxxxxx real
  124. c
  125. c\References:
  126. c 1. D.C. Sorensen, "Implicit Application of Polynomial Filters in
  127. c a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992),
  128. c pp 357-385.
  129. c 2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly
  130. c Restarted Arnoldi Iteration", Rice University Technical Report
  131. c TR95-13, Department of Computational and Applied Mathematics.
  132. c
  133. c\Routines called:
  134. c dgetv0 ARPACK routine to generate the initial vector.
  135. c ivout ARPACK utility routine that prints integers.
  136. c arscnd ARPACK utility routine for timing. -> deleted by BP in 2020
  137. c dmout ARPACK utility routine that prints matrices
  138. c dvout ARPACK utility routine that prints vectors.
  139. c dlabad LAPACK routine that computes machine constants.
  140. c dlamch LAPACK routine that determines machine constants.
  141. c dlascl LAPACK routine for careful scaling of a matrix.
  142. c dlanhs LAPACK routine that computes various norms of a matrix.
  143. c dgemv Level 2 BLAS routine for matrix vector multiplication.
  144. c daxpy Level 1 BLAS that computes a vector triad.
  145. c dscal Level 1 BLAS that scales a vector.
  146. c dcopy Level 1 BLAS that copies one vector to another .
  147. c ddot Level 1 BLAS that computes the scalar product of two vectors.
  148. c dnrm2 Level 1 BLAS that computes the norm of a vector.
  149. c
  150. c\Author
  151. c Danny Sorensen Phuong Vu
  152. c Richard Lehoucq CRPC / Rice University
  153. c Dept. of Computational & Houston, Texas
  154. c Applied Mathematics
  155. c Rice University
  156. c Houston, Texas
  157. c
  158. c\Revision history:
  159. c xx/xx/92: Version ' 2.4'
  160. c
  161. c\SCCS Information: @(#)
  162. c FILE: naitr.F SID: 2.4 DATE OF SID: 8/27/96 RELEASE: 2
  163. c
  164. c\Remarks
  165. c The algorithm implemented is:
  166. c
  167. c restart = .false.
  168. c Given V_{k} = [v_{1}, ..., v_{k}], r_{k};
  169. c r_{k} contains the initial residual vector even for k = 0;
  170. c Also assume that rnorm = || B*r_{k} || and B*r_{k} are already
  171. c computed by the calling program.
  172. c
  173. c betaj = rnorm ; p_{k+1} = B*r_{k} ;
  174. c For j = k+1, ..., k+np Do
  175. c 1) if ( betaj < tol ) stop or restart depending on j.
  176. c ( At present tol is zero )
  177. c if ( restart ) generate a new starting vector.
  178. c 2) v_{j} = r(j-1)/betaj; V_{j} = [V_{j-1}, v_{j}];
  179. c p_{j} = p_{j}/betaj
  180. c 3) r_{j} = OP*v_{j} where OP is defined as in dnaupd
  181. c For shift-invert mode p_{j} = B*v_{j} is already available.
  182. c wnorm = || OP*v_{j} ||
  183. c 4) Compute the j-th step residual vector.
  184. c w_{j} = V_{j}^T * B * OP * v_{j}
  185. c r_{j} = OP*v_{j} - V_{j} * w_{j}
  186. c H(:,j) = w_{j};
  187. c H(j,j-1) = rnorm
  188. c rnorm = || r_(j) ||
  189. c If (rnorm > 0.717*wnorm) accept step and go back to 1)
  190. c 5) Re-orthogonalization step:
  191. c s = V_{j}'*B*r_{j}
  192. c r_{j} = r_{j} - V_{j}*s; rnorm1 = || r_{j} ||
  193. c alphaj = alphaj + s_{j};
  194. c 6) Iterative refinement step:
  195. c If (rnorm1 > 0.717*rnorm) then
  196. c rnorm = rnorm1
  197. c accept step and go back to 1)
  198. c Else
  199. c rnorm = rnorm1
  200. c If this is the first time in step 6), go to 5)
  201. c Else r_{j} lies in the span of V_{j} numerically.
  202. c Set r_{j} = 0 and rnorm = 0; go to 1)
  203. c EndIf
  204. c End Do
  205. c
  206. c\EndLib
  207. c
  208. c-----------------------------------------------------------------------
  209. c
  210. subroutine dnaitr
  211. & (ido, bmat, n, k, np, nb, resid, rnorm, v, ldv, h, ldh,
  212. & ipntr, workd, ITRAK, info)
  213. c
  214. c %----------------------------------------------------%
  215. c | Include files for debugging and timing information |
  216. c -INC TARTRAK
  217. c %----------------------------------------------------%
  218. c
  219. c
  220. c %------------------%
  221. c | Scalar Arguments |
  222. c %------------------%
  223. c
  224. character bmat*1
  225. integer ido, info, k, ldh, ldv, n, nb, np
  226. REAL*8
  227. & rnorm
  228. c REAL*8 T0,T1,T2,T3,T4,T5
  229. c
  230. c %-----------------%
  231. c | Array Arguments |
  232. c %-----------------%
  233. c
  234. integer ipntr(3)
  235. INTEGER ITRAK(5)
  236. REAL*8
  237. & h(ldh,k+np), resid(n), v(ldv,k+np), workd(3*n)
  238. c
  239. c %------------%
  240. c | Parameters |
  241. c %------------%
  242. c
  243. REAL*8
  244. & one, zero
  245. parameter (one = 1.0D+0, zero = 0.0D+0)
  246. c
  247. c %---------------%
  248. c | Local Scalars |
  249. c %---------------%
  250. c
  251. logical first, orth1, orth2, rstart, step3, step4
  252. integer ierr, i, infol, ipj, irj, ivj, iter, itry, j, msglvl,
  253. & jj
  254. REAL*8
  255. & betaj, ovfl, temp1, rnorm1, smlnum, tst1, ulp, unfl,
  256. & wnorm
  257. save first, orth1, orth2, rstart, step3, step4,
  258. c & ierr, ipj, irj, ivj, iter, itry, j, msglvl, ovfl,
  259. & ierr, ipj, irj, ivj, iter, itry, j, ovfl,
  260. & betaj, rnorm1, smlnum, ulp, unfl, wnorm
  261. parameter (msglvl=0)
  262. c
  263. c %-----------------------%
  264. c | Local Array Arguments |
  265. c %-----------------------%
  266. c
  267. REAL*8
  268. & xtemp(2)
  269. c
  270. c %----------------------%
  271. c | External Subroutines |
  272. c %----------------------%
  273. c
  274. external daxpy, dcopy, dscal, dgemv,
  275. & dvout, dmout, ivout
  276. c
  277. c %--------------------%
  278. c | External Functions |
  279. c %--------------------%
  280. c
  281. REAL*8
  282. external ddot, dnrm2, dlanhs, dlamch
  283. c
  284. c %---------------------%
  285. **c | Intrinsic Functions |
  286. **c %---------------------%
  287. **c
  288. ** intrinsic abs, sqrt
  289. **c
  290. **c %-----------------%
  291. **c | Data statements |
  292. **c %-----------------%
  293. **c
  294. data first / .true. /
  295. **c
  296. **c %-----------------------%
  297. **c | Executable Statements |
  298. c %-----------------------%
  299. c T0 = 0.D0
  300. c T1 = 0.D0
  301. c T2 = 0.D0
  302. c T3 = 0.D0
  303. c T4 = 0.D0
  304. c T5 = 0.D0
  305. NOPX =ITRAK(1)
  306. NBX =ITRAK(2)
  307. NRORTH=ITRAK(3)
  308. NITREF=ITRAK(4)
  309. NRSTRT=ITRAK(5)
  310. c
  311. if (first) then
  312. c
  313. c %-----------------------------------------%
  314. c | Set machine-dependent constants for the |
  315. c | the splitting and deflation criterion. |
  316. c | If norm(H) <= sqrt(OVFL), |
  317. c | overflow should not occur. |
  318. c | REFERENCE: LAPACK subroutine dlahqr |
  319. c %-----------------------------------------%
  320. c
  321. unfl = dlamch( 'safe minimum' )
  322. ovfl = one / unfl
  323. call dlabad( unfl, ovfl )
  324. ulp = dlamch( 'precision' )
  325. smlnum = unfl*( n / ulp )
  326. first = .false.
  327. end if
  328. c
  329. if (ido .eq. 0) then
  330. c
  331. c %-------------------------------%
  332. c | Initialize timing statistics |
  333. c | & message level for debugging |
  334. c %-------------------------------%
  335. c
  336. * call arscnd (t0)
  337. c msglvl = mnaitr
  338. c
  339. c %------------------------------%
  340. c | Initial call to this routine |
  341. c %------------------------------%
  342. c
  343. info = 0
  344. step3 = .false.
  345. step4 = .false.
  346. rstart = .false.
  347. orth1 = .false.
  348. orth2 = .false.
  349. j = k + 1
  350. ipj = 1
  351. irj = ipj + n
  352. ivj = irj + n
  353. end if
  354. c
  355. c %-------------------------------------------------%
  356. c | When in reverse communication mode one of: |
  357. c | STEP3, STEP4, ORTH1, ORTH2, RSTART |
  358. c | will be .true. when .... |
  359. c | STEP3: return from computing OP*v_{j}. |
  360. c | STEP4: return from computing B-norm of OP*v_{j} |
  361. c | ORTH1: return from computing B-norm of r_{j+1} |
  362. c | ORTH2: return from computing B-norm of |
  363. c | correction to the residual vector. |
  364. c | RSTART: return from OP computations needed by |
  365. c | dgetv0. |
  366. c %-------------------------------------------------%
  367. c
  368. if (step3) go to 50
  369. if (step4) go to 60
  370. if (orth1) go to 70
  371. if (orth2) go to 90
  372. if (rstart) go to 30
  373. c
  374. c %-----------------------------%
  375. c | Else this is the first step |
  376. c %-----------------------------%
  377. c
  378. c %--------------------------------------------------------------%
  379. c | |
  380. c | A R N O L D I I T E R A T I O N L O O P |
  381. c | |
  382. c | Note: B*r_{j-1} is already in WORKD(1:N)=WORKD(IPJ:IPJ+N-1) |
  383. c %--------------------------------------------------------------%
  384.  
  385. 1000 continue
  386. c
  387. c if (msglvl .gt. 1) then
  388. c call ivout ( 1, j, ndigit,
  389. c & '_naitr: generating Arnoldi vector number')
  390. c call dvout ( 1, rnorm, ndigit,
  391. c & '_naitr: B-norm of the current residual is')
  392. c end if
  393. c
  394. c %---------------------------------------------------%
  395. c | STEP 1: Check if the B norm of j-th residual |
  396. c | vector is zero. Equivalent to determing whether |
  397. c | an exact j-step Arnoldi factorization is present. |
  398. c %---------------------------------------------------%
  399. c
  400. betaj = rnorm
  401. if (rnorm .gt. zero) go to 40
  402. c
  403. c %---------------------------------------------------%
  404. c | Invariant subspace found, generate a new starting |
  405. c | vector which is orthogonal to the current Arnoldi |
  406. c | basis and continue the iteration. |
  407. c %---------------------------------------------------%
  408. c
  409. if (msglvl .gt. 0) then
  410. call ivout ( 1, j, ndigit,
  411. & '_naitr: ****** RESTART AT STEP ******')
  412. end if
  413. c
  414. c %---------------------------------------------%
  415. c | ITRY is the loop variable that controls the |
  416. c | maximum amount of times that a restart is |
  417. c %---------------------------------------------%
  418. c
  419. betaj = zero
  420. nrstrt = nrstrt + 1
  421. itry = 1
  422. 20 continue
  423. rstart = .true.
  424. ido = 0
  425. 30 continue
  426. c
  427. c %--------------------------------------%
  428. c | If in reverse communication mode and |
  429. c | RSTART = .true. flow returns here. |
  430. c %--------------------------------------%
  431. c
  432. call dgetv0 (ido, bmat, itry, .false., n, j, v, ldv,
  433. & resid, rnorm, ipntr, workd, nopx,nbx, ierr)
  434. if (ido .ne. 99) go to 9000
  435. if (ierr .lt. 0) then
  436. itry = itry + 1
  437. if (itry .le. 3) go to 20
  438. c
  439. c %------------------------------------------------%
  440. c | Give up after several restart attempts. |
  441. c | Set INFO to the size of the invariant subspace |
  442. c | which spans OP and exit. |
  443. c %------------------------------------------------%
  444. c
  445. info = j - 1
  446. * call arscnd (t1)
  447. c tnaitr = tnaitr + (t1 - t0)
  448. ido = 99
  449. go to 9000
  450. end if
  451. c
  452. 40 continue
  453. c
  454. c %---------------------------------------------------------%
  455. c | STEP 2: v_{j} = r_{j-1}/rnorm and p_{j} = p_{j}/rnorm |
  456. c | Note that p_{j} = B*r_{j-1}. In order to avoid overflow |
  457. c | when reciprocating a small RNORM, test against lower |
  458. c | machine bound. |
  459. c %---------------------------------------------------------%
  460. c
  461. call dcopy (n, resid, 1, v(1,j), 1)
  462. if (rnorm .ge. unfl) then
  463. temp1 = one / rnorm
  464. call dscal (n, temp1, v(1,j), 1)
  465. call dscal (n, temp1, workd(ipj), 1)
  466. else
  467. c
  468. c %-----------------------------------------%
  469. c | To scale both v_{j} and p_{j} carefully |
  470. c | use LAPACK routine SLASCL |
  471. c %-----------------------------------------%
  472. c
  473. call dlascl ('General', i, i, rnorm, one, n, 1,
  474. & v(1,j), n, infol)
  475. call dlascl ('General', i, i, rnorm, one, n, 1,
  476. & workd(ipj), n, infol)
  477. end if
  478. c
  479. c %------------------------------------------------------%
  480. c | STEP 3: r_{j} = OP*v_{j}; Note that p_{j} = B*v_{j} |
  481. c | Note that this is not quite yet r_{j}. See STEP 4 |
  482. c %------------------------------------------------------%
  483. c
  484. step3 = .true.
  485. nopx = nopx + 1
  486. * call arscnd (t2)
  487. call dcopy (n, v(1,j), 1, workd(ivj), 1)
  488. ipntr(1) = ivj
  489. ipntr(2) = irj
  490. ipntr(3) = ipj
  491. ido = 1
  492. c
  493. c %-----------------------------------%
  494. c | Exit in order to compute OP*v_{j} |
  495. c %-----------------------------------%
  496. c
  497. go to 9000
  498. 50 continue
  499. c
  500. c %----------------------------------%
  501. c | Back from reverse communication; |
  502. c | WORKD(IRJ:IRJ+N-1) := OP*v_{j} |
  503. c | if step3 = .true. |
  504. c %----------------------------------%
  505. c
  506. * call arscnd (t3)
  507. c tmvopx = tmvopx + (t3 - t2)
  508.  
  509. step3 = .false.
  510. c
  511. c %------------------------------------------%
  512. c | Put another copy of OP*v_{j} into RESID. |
  513. c %------------------------------------------%
  514. c
  515. call dcopy (n, workd(irj), 1, resid, 1)
  516. c
  517. c %---------------------------------------%
  518. c | STEP 4: Finish extending the Arnoldi |
  519. c | factorization to length j. |
  520. c %---------------------------------------%
  521. c
  522. * call arscnd (t2)
  523. if (bmat .eq. 'G') then
  524. nbx = nbx + 1
  525. step4 = .true.
  526. ipntr(1) = irj
  527. ipntr(2) = ipj
  528. ido = 2
  529. c
  530. c %-------------------------------------%
  531. c | Exit in order to compute B*OP*v_{j} |
  532. c %-------------------------------------%
  533. c
  534. go to 9000
  535. else if (bmat .eq. 'I') then
  536. call dcopy (n, resid, 1, workd(ipj), 1)
  537. end if
  538. 60 continue
  539. c
  540. c %----------------------------------%
  541. c | Back from reverse communication; |
  542. c | WORKD(IPJ:IPJ+N-1) := B*OP*v_{j} |
  543. c | if step4 = .true. |
  544. c %----------------------------------%
  545. c
  546. c if (bmat .eq. 'G') then
  547. * call arscnd (t3)
  548. c tmvbx = tmvbx + (t3 - t2)
  549. c end if
  550. c
  551. step4 = .false.
  552. c
  553. c %-------------------------------------%
  554. c | The following is needed for STEP 5. |
  555. c | Compute the B-norm of OP*v_{j}. |
  556. c %-------------------------------------%
  557. c
  558. if (bmat .eq. 'G') then
  559. wnorm = ddot (n, resid, 1, workd(ipj), 1)
  560. wnorm = sqrt(abs(wnorm))
  561. else if (bmat .eq. 'I') then
  562. wnorm = dnrm2(n, resid, 1)
  563. end if
  564. c
  565. c %-----------------------------------------%
  566. c | Compute the j-th residual corresponding |
  567. c | to the j step factorization. |
  568. c | Use Classical Gram Schmidt and compute: |
  569. c | w_{j} <- V_{j}^T * B * OP * v_{j} |
  570. c | r_{j} <- OP*v_{j} - V_{j} * w_{j} |
  571. c %-----------------------------------------%
  572. c
  573. c
  574. c %------------------------------------------%
  575. c | Compute the j Fourier coefficients w_{j} |
  576. c | WORKD(IPJ:IPJ+N-1) contains B*OP*v_{j}. |
  577. c %------------------------------------------%
  578. c
  579. call dgemv ('T', n, j, one, v, ldv, workd(ipj), 1,
  580. & zero, h(1,j), 1)
  581. c
  582. c %--------------------------------------%
  583. c | Orthogonalize r_{j} against V_{j}. |
  584. c | RESID contains OP*v_{j}. See STEP 3. |
  585. c %--------------------------------------%
  586. c
  587. call dgemv ('N', n, j, -one, v, ldv, h(1,j), 1,
  588. & one, resid, 1)
  589. c
  590. if (j .gt. 1) h(j,j-1) = betaj
  591. c
  592. * call arscnd (t4)
  593. c
  594. orth1 = .true.
  595. c
  596. * call arscnd (t2)
  597. if (bmat .eq. 'G') then
  598. nbx = nbx + 1
  599. call dcopy (n, resid, 1, workd(irj), 1)
  600. ipntr(1) = irj
  601. ipntr(2) = ipj
  602. ido = 2
  603. c
  604. c %----------------------------------%
  605. c | Exit in order to compute B*r_{j} |
  606. c %----------------------------------%
  607. c
  608. go to 9000
  609. else if (bmat .eq. 'I') then
  610. call dcopy (n, resid, 1, workd(ipj), 1)
  611. end if
  612. 70 continue
  613. c
  614. c %---------------------------------------------------%
  615. c | Back from reverse communication if ORTH1 = .true. |
  616. c | WORKD(IPJ:IPJ+N-1) := B*r_{j}. |
  617. c %---------------------------------------------------%
  618. c
  619. c if (bmat .eq. 'G') then
  620. * call arscnd (t3)
  621. c tmvbx = tmvbx + (t3 - t2)
  622. c end if
  623. c
  624. orth1 = .false.
  625. c
  626. c %------------------------------%
  627. c | Compute the B-norm of r_{j}. |
  628. c %------------------------------%
  629. c
  630. if (bmat .eq. 'G') then
  631. rnorm = ddot (n, resid, 1, workd(ipj), 1)
  632. rnorm = sqrt(abs(rnorm))
  633. else if (bmat .eq. 'I') then
  634. rnorm = dnrm2(n, resid, 1)
  635. end if
  636. c
  637. c %-----------------------------------------------------------%
  638. c | STEP 5: Re-orthogonalization / Iterative refinement phase |
  639. c | Maximum NITER_ITREF tries. |
  640. c | |
  641. c | s = V_{j}^T * B * r_{j} |
  642. c | r_{j} = r_{j} - V_{j}*s |
  643. c | alphaj = alphaj + s_{j} |
  644. c | |
  645. c | The stopping criteria used for iterative refinement is |
  646. c | discussed in Parlett's book SEP, page 107 and in Gragg & |
  647. c | Reichel ACM TOMS paper; Algorithm 686, Dec. 1990. |
  648. c | Determine if we need to correct the residual. The goal is |
  649. c | to enforce ||v(:,1:j)^T * r_{j}|| .le. eps * || r_{j} || |
  650. c | The following test determines whether the sine of the |
  651. c | angle between OP*x and the computed residual is less |
  652. c | than or equal to 0.717. |
  653. c %-----------------------------------------------------------%
  654. c
  655. if (rnorm .gt. 0.717*wnorm) go to 100
  656. iter = 0
  657. nrorth = nrorth + 1
  658. c
  659. c %---------------------------------------------------%
  660. c | Enter the Iterative refinement phase. If further |
  661. c | refinement is necessary, loop back here. The loop |
  662. c | variable is ITER. Perform a step of Classical |
  663. c | Gram-Schmidt using all the Arnoldi vectors V_{j} |
  664. c %---------------------------------------------------%
  665. c
  666. 80 continue
  667. c
  668. c if (msglvl .gt. 2) then
  669. c xtemp(1) = wnorm
  670. c xtemp(2) = rnorm
  671. c call dvout ( 2, xtemp, ndigit,
  672. c & '_naitr: re-orthonalization; wnorm and rnorm are')
  673. c call dvout ( j, h(1,j), ndigit,
  674. c & '_naitr: j-th column of H')
  675. c end if
  676. c
  677. c %----------------------------------------------------%
  678. c | Compute V_{j}^T * B * r_{j}. |
  679. c | WORKD(IRJ:IRJ+J-1) = v(:,1:J)'*WORKD(IPJ:IPJ+N-1). |
  680. c %----------------------------------------------------%
  681. c
  682. call dgemv ('T', n, j, one, v, ldv, workd(ipj), 1,
  683. & zero, workd(irj), 1)
  684. c
  685. c %---------------------------------------------%
  686. c | Compute the correction to the residual: |
  687. c | r_{j} = r_{j} - V_{j} * WORKD(IRJ:IRJ+J-1). |
  688. c | The correction to H is v(:,1:J)*H(1:J,1:J) |
  689. c | + v(:,1:J)*WORKD(IRJ:IRJ+J-1)*e'_j. |
  690. c %---------------------------------------------%
  691. c
  692. call dgemv ('N', n, j, -one, v, ldv, workd(irj), 1,
  693. & one, resid, 1)
  694. call daxpy (j, one, workd(irj), 1, h(1,j), 1)
  695. c
  696. orth2 = .true.
  697. * call arscnd (t2)
  698. if (bmat .eq. 'G') then
  699. nbx = nbx + 1
  700. call dcopy (n, resid, 1, workd(irj), 1)
  701. ipntr(1) = irj
  702. ipntr(2) = ipj
  703. ido = 2
  704. c
  705. c %-----------------------------------%
  706. c | Exit in order to compute B*r_{j}. |
  707. c | r_{j} is the corrected residual. |
  708. c %-----------------------------------%
  709. c
  710. go to 9000
  711. else if (bmat .eq. 'I') then
  712. call dcopy (n, resid, 1, workd(ipj), 1)
  713. end if
  714. 90 continue
  715. c
  716. c %---------------------------------------------------%
  717. c | Back from reverse communication if ORTH2 = .true. |
  718. c %---------------------------------------------------%
  719. c
  720. c if (bmat .eq. 'G') then
  721. * call arscnd (t3)
  722. c tmvbx = tmvbx + (t3 - t2)
  723. c end if
  724. c
  725. c %-----------------------------------------------------%
  726. c | Compute the B-norm of the corrected residual r_{j}. |
  727. c %-----------------------------------------------------%
  728. c
  729. if (bmat .eq. 'G') then
  730. rnorm1 = ddot (n, resid, 1, workd(ipj), 1)
  731. rnorm1 = sqrt(abs(rnorm1))
  732. else if (bmat .eq. 'I') then
  733. rnorm1 = dnrm2(n, resid, 1)
  734. end if
  735. c
  736. if (msglvl .gt. 0 .and. iter .gt. 0) then
  737. call ivout ( 1, j, ndigit,
  738. & '_naitr: Iterative refinement for Arnoldi residual')
  739. c if (msglvl .gt. 2) then
  740. c xtemp(1) = rnorm
  741. c xtemp(2) = rnorm1
  742. c call dvout ( 2, xtemp, ndigit,
  743. c & '_naitr: iterative refinement ; rnorm and rnorm1 are')
  744. c end if
  745. end if
  746. c
  747. c %-----------------------------------------%
  748. c | Determine if we need to perform another |
  749. c | step of re-orthogonalization. |
  750. c %-----------------------------------------%
  751. c
  752. if (rnorm1 .gt. 0.717*rnorm) then
  753. c
  754. c %---------------------------------------%
  755. c | No need for further refinement. |
  756. c | The cosine of the angle between the |
  757. c | corrected residual vector and the old |
  758. c | residual vector is greater than 0.717 |
  759. c | In other words the corrected residual |
  760. c | and the old residual vector share an |
  761. c | angle of less than arcCOS(0.717) |
  762. c %---------------------------------------%
  763. c
  764. rnorm = rnorm1
  765. c
  766. else
  767. c
  768. c %-------------------------------------------%
  769. c | Another step of iterative refinement step |
  770. c %-------------------------------------------%
  771. c
  772. nitref = nitref + 1
  773. rnorm = rnorm1
  774. iter = iter + 1
  775. if (iter .le. 1) go to 80
  776. c
  777. c %-------------------------------------------------%
  778. c | Otherwise RESID is numerically in the span of V |
  779. c %-------------------------------------------------%
  780. c
  781. do 95 jj = 1, n
  782. resid(jj) = zero
  783. 95 continue
  784. rnorm = zero
  785. end if
  786. c
  787. c %----------------------------------------------%
  788. c | Branch here directly if iterative refinement |
  789. c | wasn't necessary or after at most NITER_REF |
  790. c | steps of iterative refinement. |
  791. c %----------------------------------------------%
  792. c
  793. 100 continue
  794. c
  795. rstart = .false.
  796. orth2 = .false.
  797. c
  798. * call arscnd (t5)
  799. c titref = titref + (t5 - t4)
  800. c
  801. c %------------------------------------%
  802. c | STEP 6: Update j = j+1; Continue |
  803. c %------------------------------------%
  804. c
  805. j = j + 1
  806. if (j .gt. k+np) then
  807. * call arscnd (t1)
  808. c tnaitr = tnaitr + (t1 - t0)
  809. ido = 99
  810. do 110 i = max(1,k), k+np-1
  811. c
  812. c %--------------------------------------------%
  813. c | Check for splitting and deflation. |
  814. c | Use a standard test as in the QR algorithm |
  815. c | REFERENCE: LAPACK subroutine dlahqr |
  816. c %--------------------------------------------%
  817. c
  818. tst1 = abs( h( i, i ) ) + abs( h( i+1, i+1 ) )
  819. if( tst1.eq.zero )
  820. & tst1 = dlanhs( '1', k+np, h, ldh, workd(n+1) )
  821. if( abs( h( i+1,i ) ).le.max( ulp*tst1, smlnum ) )
  822. & h(i+1,i) = zero
  823. 110 continue
  824. c
  825. c if (msglvl .gt. 2) then
  826. c call dmout (logfil, k+np, k+np, h, ldh, ndigit,
  827. c & '_naitr: Final upper Hessenberg matrix H of order K+NP')
  828. c end if
  829. c
  830. go to 9000
  831. end if
  832. c
  833. c %--------------------------------------------------------%
  834. c | Loop back to extend the factorization by another step. |
  835. c %--------------------------------------------------------%
  836. c
  837. go to 1000
  838. c
  839. c %---------------------------------------------------------------%
  840. c | |
  841. c | E N D O F M A I N I T E R A T I O N L O O P |
  842. c | |
  843. c %---------------------------------------------------------------%
  844. c
  845. 9000 continue
  846. ITRAK(1)=NOPX
  847. ITRAK(2)=NBX
  848. ITRAK(3)=NRORTH
  849. ITRAK(4)=NITREF
  850. ITRAK(5)=NRSTRT
  851. c
  852. c %---------------%
  853. c | End of dnaitr |
  854. c %---------------%
  855. c
  856. end
  857.  
  858.  
  859.  
  860.  
  861.  
  862.  

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