Télécharger dsaitr.eso

Retour à la liste

Numérotation des lignes :

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

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