comparison libcruft/arpack/src/snaup2.f @ 12274:9f5d2ef078e8 release-3-4-x

import ARPACK sources to libcruft from Debian package libarpack2 2.1+parpack96.dfsg-3+b1
author John W. Eaton <jwe@octave.org>
date Fri, 28 Jan 2011 14:04:33 -0500
parents
children
comparison
equal deleted inserted replaced
12273:83133b5bf392 12274:9f5d2ef078e8
1 c\BeginDoc
2 c
3 c\Name: snaup2
4 c
5 c\Description:
6 c Intermediate level interface called by snaupd.
7 c
8 c\Usage:
9 c call snaup2
10 c ( IDO, BMAT, N, WHICH, NEV, NP, TOL, RESID, MODE, IUPD,
11 c ISHIFT, MXITER, V, LDV, H, LDH, RITZR, RITZI, BOUNDS,
12 c Q, LDQ, WORKL, IPNTR, WORKD, INFO )
13 c
14 c\Arguments
15 c
16 c IDO, BMAT, N, WHICH, NEV, TOL, RESID: same as defined in snaupd.
17 c MODE, ISHIFT, MXITER: see the definition of IPARAM in snaupd.
18 c
19 c NP Integer. (INPUT/OUTPUT)
20 c Contains the number of implicit shifts to apply during
21 c each Arnoldi iteration.
22 c If ISHIFT=1, NP is adjusted dynamically at each iteration
23 c to accelerate convergence and prevent stagnation.
24 c This is also roughly equal to the number of matrix-vector
25 c products (involving the operator OP) per Arnoldi iteration.
26 c The logic for adjusting is contained within the current
27 c subroutine.
28 c If ISHIFT=0, NP is the number of shifts the user needs
29 c to provide via reverse comunication. 0 < NP < NCV-NEV.
30 c NP may be less than NCV-NEV for two reasons. The first, is
31 c to keep complex conjugate pairs of "wanted" Ritz values
32 c together. The second, is that a leading block of the current
33 c upper Hessenberg 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 N by (NEV+NP) array. (INPUT/OUTPUT)
43 c The Arnoldi basis vectors are returned in the first NEV
44 c columns of V.
45 c
46 c LDV Integer. (INPUT)
47 c Leading dimension of V exactly as declared in the calling
48 c program.
49 c
50 c H Real (NEV+NP) by (NEV+NP) array. (OUTPUT)
51 c H is used to store the generated upper Hessenberg matrix
52 c
53 c LDH Integer. (INPUT)
54 c Leading dimension of H exactly as declared in the calling
55 c program.
56 c
57 c RITZR, Real arrays of length NEV+NP. (OUTPUT)
58 c RITZI RITZR(1:NEV) (resp. RITZI(1:NEV)) contains the real (resp.
59 c imaginary) part of the computed Ritz values of OP.
60 c
61 c BOUNDS Real array of length NEV+NP. (OUTPUT)
62 c BOUNDS(1:NEV) contain the error bounds corresponding to
63 c the computed Ritz values.
64 c
65 c Q Real (NEV+NP) by (NEV+NP) array. (WORKSPACE)
66 c Private (replicated) work array used to accumulate the
67 c rotation in the shift application step.
68 c
69 c LDQ Integer. (INPUT)
70 c Leading dimension of Q exactly as declared in the calling
71 c program.
72 c
73 c WORKL Real work array of length at least
74 c (NEV+NP)**2 + 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 shifts calculation, shifts
77 c application and convergence checking.
78 c
79 c On exit, the last 3*(NEV+NP) locations of WORKL contain
80 c the Ritz values (real,imaginary) and associated Ritz
81 c estimates of the current Hessenberg matrix. They are
82 c listed in the same order as returned from sneigh.
83 c
84 c If ISHIFT .EQ. O and IDO .EQ. 3, the first 2*NP locations
85 c of WORKL are used in reverse communication to hold the user
86 c supplied shifts.
87 c
88 c IPNTR Integer array of length 3. (OUTPUT)
89 c Pointer to mark the starting locations in the WORKD for
90 c vectors used by the Arnoldi iteration.
91 c -------------------------------------------------------------
92 c IPNTR(1): pointer to the current operand vector X.
93 c IPNTR(2): pointer to the current result vector Y.
94 c IPNTR(3): pointer to the vector B * X when used in the
95 c shift-and-invert mode. X is the current operand.
96 c -------------------------------------------------------------
97 c
98 c WORKD Real work array of length 3*N. (WORKSPACE)
99 c Distributed array to be used in the basic Arnoldi iteration
100 c for reverse communication. The user should not use WORKD
101 c as temporary workspace during the iteration !!!!!!!!!!
102 c See Data Distribution Note in DNAUPD.
103 c
104 c INFO Integer. (INPUT/OUTPUT)
105 c If INFO .EQ. 0, a randomly initial residual vector is used.
106 c If INFO .NE. 0, RESID contains the initial residual vector,
107 c possibly from a previous run.
108 c Error flag on output.
109 c = 0: Normal return.
110 c = 1: Maximum number of iterations taken.
111 c All possible eigenvalues of OP has been found.
112 c NP returns the number of converged Ritz values.
113 c = 2: No shifts could be applied.
114 c = -8: Error return from LAPACK eigenvalue calculation;
115 c This should never happen.
116 c = -9: Starting vector is zero.
117 c = -9999: Could not build an Arnoldi factorization.
118 c Size that was built in returned in NP.
119 c
120 c\EndDoc
121 c
122 c-----------------------------------------------------------------------
123 c
124 c\BeginLib
125 c
126 c\Local variables:
127 c xxxxxx real
128 c
129 c\References:
130 c 1. D.C. Sorensen, "Implicit Application of Polynomial Filters in
131 c a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992),
132 c pp 357-385.
133 c 2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly
134 c Restarted Arnoldi Iteration", Rice University Technical Report
135 c TR95-13, Department of Computational and Applied Mathematics.
136 c
137 c\Routines called:
138 c sgetv0 ARPACK initial vector generation routine.
139 c snaitr ARPACK Arnoldi factorization routine.
140 c snapps ARPACK application of implicit shifts routine.
141 c snconv ARPACK convergence of Ritz values routine.
142 c sneigh ARPACK compute Ritz values and error bounds routine.
143 c sngets ARPACK reorder Ritz values and error bounds routine.
144 c ssortc ARPACK sorting routine.
145 c ivout ARPACK utility routine that prints integers.
146 c arscnd ARPACK utility routine for timing.
147 c smout ARPACK utility routine that prints matrices
148 c svout ARPACK utility routine that prints vectors.
149 c slamch LAPACK routine that determines machine constants.
150 c slapy2 LAPACK routine to compute sqrt(x**2+y**2) carefully.
151 c scopy Level 1 BLAS that copies one vector to another .
152 c sdot Level 1 BLAS that computes the scalar product of two vectors.
153 c snrm2 Level 1 BLAS that computes the norm of a vector.
154 c sswap Level 1 BLAS that swaps two vectors.
155 c
156 c\Author
157 c Danny Sorensen Phuong Vu
158 c Richard Lehoucq CRPC / Rice University
159 c Dept. of Computational & Houston, Texas
160 c Applied Mathematics
161 c Rice University
162 c Houston, Texas
163 c
164 c\SCCS Information: @(#)
165 c FILE: naup2.F SID: 2.8 DATE OF SID: 10/17/00 RELEASE: 2
166 c
167 c\Remarks
168 c 1. None
169 c
170 c\EndLib
171 c
172 c-----------------------------------------------------------------------
173 c
174 subroutine snaup2
175 & ( ido, bmat, n, which, nev, np, tol, resid, mode, iupd,
176 & ishift, mxiter, v, ldv, h, ldh, ritzr, ritzi, bounds,
177 & q, ldq, workl, ipntr, workd, info )
178 c
179 c %----------------------------------------------------%
180 c | Include files for debugging and timing information |
181 c %----------------------------------------------------%
182 c
183 include 'debug.h'
184 include 'stat.h'
185 c
186 c %------------------%
187 c | Scalar Arguments |
188 c %------------------%
189 c
190 character bmat*1, which*2
191 integer ido, info, ishift, iupd, mode, ldh, ldq, ldv, mxiter,
192 & n, nev, np
193 Real
194 & tol
195 c
196 c %-----------------%
197 c | Array Arguments |
198 c %-----------------%
199 c
200 integer ipntr(13)
201 Real
202 & bounds(nev+np), h(ldh,nev+np), q(ldq,nev+np), resid(n),
203 & ritzi(nev+np), ritzr(nev+np), v(ldv,nev+np),
204 & workd(3*n), workl( (nev+np)*(nev+np+3) )
205 c
206 c %------------%
207 c | Parameters |
208 c %------------%
209 c
210 Real
211 & one, zero
212 parameter (one = 1.0E+0 , zero = 0.0E+0 )
213 c
214 c %---------------%
215 c | Local Scalars |
216 c %---------------%
217 c
218 character wprime*2
219 logical cnorm , getv0, initv, update, ushift
220 integer ierr , iter , j , kplusp, msglvl, nconv,
221 & nevbef, nev0 , np0 , nptemp, numcnv
222 Real
223 & rnorm , temp , eps23
224 save cnorm , getv0, initv, update, ushift,
225 & rnorm , iter , eps23, kplusp, msglvl, nconv ,
226 & nevbef, nev0 , np0 , numcnv
227 c
228 c %-----------------------%
229 c | Local array arguments |
230 c %-----------------------%
231 c
232 integer kp(4)
233 c
234 c %----------------------%
235 c | External Subroutines |
236 c %----------------------%
237 c
238 external scopy , sgetv0, snaitr, snconv, sneigh,
239 & sngets, snapps, svout , ivout , arscnd
240 c
241 c %--------------------%
242 c | External Functions |
243 c %--------------------%
244 c
245 Real
246 & sdot, snrm2, slapy2, slamch
247 external sdot, snrm2, slapy2, slamch
248 c
249 c %---------------------%
250 c | Intrinsic Functions |
251 c %---------------------%
252 c
253 intrinsic min, max, abs, sqrt
254 c
255 c %-----------------------%
256 c | Executable Statements |
257 c %-----------------------%
258 c
259 if (ido .eq. 0) then
260 c
261 call arscnd (t0)
262 c
263 msglvl = mnaup2
264 c
265 c %-------------------------------------%
266 c | Get the machine dependent constant. |
267 c %-------------------------------------%
268 c
269 eps23 = slamch('Epsilon-Machine')
270 eps23 = eps23**(2.0E+0 / 3.0E+0 )
271 c
272 nev0 = nev
273 np0 = np
274 c
275 c %-------------------------------------%
276 c | kplusp is the bound on the largest |
277 c | Lanczos factorization built. |
278 c | nconv is the current number of |
279 c | "converged" eigenvlues. |
280 c | iter is the counter on the current |
281 c | iteration step. |
282 c %-------------------------------------%
283 c
284 kplusp = nev + np
285 nconv = 0
286 iter = 0
287 c
288 c %---------------------------------------%
289 c | Set flags for computing the first NEV |
290 c | steps of the Arnoldi factorization. |
291 c %---------------------------------------%
292 c
293 getv0 = .true.
294 update = .false.
295 ushift = .false.
296 cnorm = .false.
297 c
298 if (info .ne. 0) then
299 c
300 c %--------------------------------------------%
301 c | User provides the initial residual vector. |
302 c %--------------------------------------------%
303 c
304 initv = .true.
305 info = 0
306 else
307 initv = .false.
308 end if
309 end if
310 c
311 c %---------------------------------------------%
312 c | Get a possibly random starting vector and |
313 c | force it into the range of the operator OP. |
314 c %---------------------------------------------%
315 c
316 10 continue
317 c
318 if (getv0) then
319 call sgetv0 (ido, bmat, 1, initv, n, 1, v, ldv, resid, rnorm,
320 & ipntr, workd, info)
321 c
322 if (ido .ne. 99) go to 9000
323 c
324 if (rnorm .eq. zero) then
325 c
326 c %-----------------------------------------%
327 c | The initial vector is zero. Error exit. |
328 c %-----------------------------------------%
329 c
330 info = -9
331 go to 1100
332 end if
333 getv0 = .false.
334 ido = 0
335 end if
336 c
337 c %-----------------------------------%
338 c | Back from reverse communication : |
339 c | continue with update step |
340 c %-----------------------------------%
341 c
342 if (update) go to 20
343 c
344 c %-------------------------------------------%
345 c | Back from computing user specified shifts |
346 c %-------------------------------------------%
347 c
348 if (ushift) go to 50
349 c
350 c %-------------------------------------%
351 c | Back from computing residual norm |
352 c | at the end of the current iteration |
353 c %-------------------------------------%
354 c
355 if (cnorm) go to 100
356 c
357 c %----------------------------------------------------------%
358 c | Compute the first NEV steps of the Arnoldi factorization |
359 c %----------------------------------------------------------%
360 c
361 call snaitr (ido, bmat, n, 0, nev, mode, resid, rnorm, v, ldv,
362 & h, ldh, ipntr, workd, info)
363 c
364 c %---------------------------------------------------%
365 c | ido .ne. 99 implies use of reverse communication |
366 c | to compute operations involving OP and possibly B |
367 c %---------------------------------------------------%
368 c
369 if (ido .ne. 99) go to 9000
370 c
371 if (info .gt. 0) then
372 np = info
373 mxiter = iter
374 info = -9999
375 go to 1200
376 end if
377 c
378 c %--------------------------------------------------------------%
379 c | |
380 c | M A I N ARNOLDI I T E R A T I O N L O O P |
381 c | Each iteration implicitly restarts the Arnoldi |
382 c | factorization in place. |
383 c | |
384 c %--------------------------------------------------------------%
385 c
386 1000 continue
387 c
388 iter = iter + 1
389 c
390 if (msglvl .gt. 0) then
391 call ivout (logfil, 1, iter, ndigit,
392 & '_naup2: **** Start of major iteration number ****')
393 end if
394 c
395 c %-----------------------------------------------------------%
396 c | Compute NP additional steps of the Arnoldi factorization. |
397 c | Adjust NP since NEV might have been updated by last call |
398 c | to the shift application routine snapps. |
399 c %-----------------------------------------------------------%
400 c
401 np = kplusp - nev
402 c
403 if (msglvl .gt. 1) then
404 call ivout (logfil, 1, nev, ndigit,
405 & '_naup2: The length of the current Arnoldi factorization')
406 call ivout (logfil, 1, np, ndigit,
407 & '_naup2: Extend the Arnoldi factorization by')
408 end if
409 c
410 c %-----------------------------------------------------------%
411 c | Compute NP additional steps of the Arnoldi factorization. |
412 c %-----------------------------------------------------------%
413 c
414 ido = 0
415 20 continue
416 update = .true.
417 c
418 call snaitr (ido , bmat, n , nev, np , mode , resid,
419 & rnorm, v , ldv, h , ldh, ipntr, workd,
420 & info)
421 c
422 c %---------------------------------------------------%
423 c | ido .ne. 99 implies use of reverse communication |
424 c | to compute operations involving OP and possibly B |
425 c %---------------------------------------------------%
426 c
427 if (ido .ne. 99) go to 9000
428 c
429 if (info .gt. 0) then
430 np = info
431 mxiter = iter
432 info = -9999
433 go to 1200
434 end if
435 update = .false.
436 c
437 if (msglvl .gt. 1) then
438 call svout (logfil, 1, rnorm, ndigit,
439 & '_naup2: Corresponding B-norm of the residual')
440 end if
441 c
442 c %--------------------------------------------------------%
443 c | Compute the eigenvalues and corresponding error bounds |
444 c | of the current upper Hessenberg matrix. |
445 c %--------------------------------------------------------%
446 c
447 call sneigh (rnorm, kplusp, h, ldh, ritzr, ritzi, bounds,
448 & q, ldq, workl, ierr)
449 c
450 if (ierr .ne. 0) then
451 info = -8
452 go to 1200
453 end if
454 c
455 c %----------------------------------------------------%
456 c | Make a copy of eigenvalues and corresponding error |
457 c | bounds obtained from sneigh. |
458 c %----------------------------------------------------%
459 c
460 call scopy(kplusp, ritzr, 1, workl(kplusp**2+1), 1)
461 call scopy(kplusp, ritzi, 1, workl(kplusp**2+kplusp+1), 1)
462 call scopy(kplusp, bounds, 1, workl(kplusp**2+2*kplusp+1), 1)
463 c
464 c %---------------------------------------------------%
465 c | Select the wanted Ritz values and their bounds |
466 c | to be used in the convergence test. |
467 c | The wanted part of the spectrum and corresponding |
468 c | error bounds are in the last NEV loc. of RITZR, |
469 c | RITZI and BOUNDS respectively. The variables NEV |
470 c | and NP may be updated if the NEV-th wanted Ritz |
471 c | value has a non zero imaginary part. In this case |
472 c | NEV is increased by one and NP decreased by one. |
473 c | NOTE: The last two arguments of sngets are no |
474 c | longer used as of version 2.1. |
475 c %---------------------------------------------------%
476 c
477 nev = nev0
478 np = np0
479 numcnv = nev
480 call sngets (ishift, which, nev, np, ritzr, ritzi,
481 & bounds, workl, workl(np+1))
482 if (nev .eq. nev0+1) numcnv = nev0+1
483 c
484 c %-------------------%
485 c | Convergence test. |
486 c %-------------------%
487 c
488 call scopy (nev, bounds(np+1), 1, workl(2*np+1), 1)
489 call snconv (nev, ritzr(np+1), ritzi(np+1), workl(2*np+1),
490 & tol, nconv)
491 c
492 if (msglvl .gt. 2) then
493 kp(1) = nev
494 kp(2) = np
495 kp(3) = numcnv
496 kp(4) = nconv
497 call ivout (logfil, 4, kp, ndigit,
498 & '_naup2: NEV, NP, NUMCNV, NCONV are')
499 call svout (logfil, kplusp, ritzr, ndigit,
500 & '_naup2: Real part of the eigenvalues of H')
501 call svout (logfil, kplusp, ritzi, ndigit,
502 & '_naup2: Imaginary part of the eigenvalues of H')
503 call svout (logfil, kplusp, bounds, ndigit,
504 & '_naup2: Ritz estimates of the current NCV Ritz values')
505 end if
506 c
507 c %---------------------------------------------------------%
508 c | Count the number of unwanted Ritz values that have zero |
509 c | Ritz estimates. If any Ritz estimates are equal to zero |
510 c | then a leading block of H of order equal to at least |
511 c | the number of Ritz values with zero Ritz estimates has |
512 c | split off. None of these Ritz values may be removed by |
513 c | shifting. Decrease NP the number of shifts to apply. If |
514 c | no shifts may be applied, then prepare to exit |
515 c %---------------------------------------------------------%
516 c
517 nptemp = np
518 do 30 j=1, nptemp
519 if (bounds(j) .eq. zero) then
520 np = np - 1
521 nev = nev + 1
522 end if
523 30 continue
524 c
525 if ( (nconv .ge. numcnv) .or.
526 & (iter .gt. mxiter) .or.
527 & (np .eq. 0) ) then
528 c
529 if (msglvl .gt. 4) then
530 call svout(logfil, kplusp, workl(kplusp**2+1), ndigit,
531 & '_naup2: Real part of the eig computed by _neigh:')
532 call svout(logfil, kplusp, workl(kplusp**2+kplusp+1),
533 & ndigit,
534 & '_naup2: Imag part of the eig computed by _neigh:')
535 call svout(logfil, kplusp, workl(kplusp**2+kplusp*2+1),
536 & ndigit,
537 & '_naup2: Ritz eistmates computed by _neigh:')
538 end if
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 |
545 c %------------------------------------------------%
546 c
547 c %------------------------------------------%
548 c | Use h( 3,1 ) as storage to communicate |
549 c | rnorm to _neupd if needed |
550 c %------------------------------------------%
551
552 h(3,1) = rnorm
553 c
554 c %----------------------------------------------%
555 c | To be consistent with sngets, we first do a |
556 c | pre-processing sort in order to keep complex |
557 c | conjugate pairs together. This is similar |
558 c | to the pre-processing sort used in sngets |
559 c | except that the sort is done in the opposite |
560 c | order. |
561 c %----------------------------------------------%
562 c
563 if (which .eq. 'LM') wprime = 'SR'
564 if (which .eq. 'SM') wprime = 'LR'
565 if (which .eq. 'LR') wprime = 'SM'
566 if (which .eq. 'SR') wprime = 'LM'
567 if (which .eq. 'LI') wprime = 'SM'
568 if (which .eq. 'SI') wprime = 'LM'
569 c
570 call ssortc (wprime, .true., kplusp, ritzr, ritzi, bounds)
571 c
572 c %----------------------------------------------%
573 c | Now sort Ritz values so that converged Ritz |
574 c | values appear within the first NEV locations |
575 c | of ritzr, ritzi and bounds, and the most |
576 c | desired one appears at the front. |
577 c %----------------------------------------------%
578 c
579 if (which .eq. 'LM') wprime = 'SM'
580 if (which .eq. 'SM') wprime = 'LM'
581 if (which .eq. 'LR') wprime = 'SR'
582 if (which .eq. 'SR') wprime = 'LR'
583 if (which .eq. 'LI') wprime = 'SI'
584 if (which .eq. 'SI') wprime = 'LI'
585 c
586 call ssortc(wprime, .true., kplusp, ritzr, ritzi, bounds)
587 c
588 c %--------------------------------------------------%
589 c | Scale the Ritz estimate of each Ritz value |
590 c | by 1 / max(eps23,magnitude of the Ritz value). |
591 c %--------------------------------------------------%
592 c
593 do 35 j = 1, numcnv
594 temp = max(eps23,slapy2(ritzr(j),
595 & ritzi(j)))
596 bounds(j) = bounds(j)/temp
597 35 continue
598 c
599 c %----------------------------------------------------%
600 c | Sort the Ritz values according to the scaled Ritz |
601 c | esitmates. This will push all the converged ones |
602 c | towards the front of ritzr, ritzi, bounds |
603 c | (in the case when NCONV < NEV.) |
604 c %----------------------------------------------------%
605 c
606 wprime = 'LR'
607 call ssortc(wprime, .true., numcnv, bounds, ritzr, ritzi)
608 c
609 c %----------------------------------------------%
610 c | Scale the Ritz estimate back to its original |
611 c | value. |
612 c %----------------------------------------------%
613 c
614 do 40 j = 1, numcnv
615 temp = max(eps23, slapy2(ritzr(j),
616 & ritzi(j)))
617 bounds(j) = bounds(j)*temp
618 40 continue
619 c
620 c %------------------------------------------------%
621 c | Sort the converged Ritz values again so that |
622 c | the "threshold" value appears at the front of |
623 c | ritzr, ritzi and bound. |
624 c %------------------------------------------------%
625 c
626 call ssortc(which, .true., nconv, ritzr, ritzi, bounds)
627 c
628 if (msglvl .gt. 1) then
629 call svout (logfil, kplusp, ritzr, ndigit,
630 & '_naup2: Sorted real part of the eigenvalues')
631 call svout (logfil, kplusp, ritzi, ndigit,
632 & '_naup2: Sorted imaginary part of the eigenvalues')
633 call svout (logfil, kplusp, bounds, ndigit,
634 & '_naup2: Sorted ritz estimates.')
635 end if
636 c
637 c %------------------------------------%
638 c | Max iterations have been exceeded. |
639 c %------------------------------------%
640 c
641 if (iter .gt. mxiter .and. nconv .lt. numcnv) info = 1
642 c
643 c %---------------------%
644 c | No shifts to apply. |
645 c %---------------------%
646 c
647 if (np .eq. 0 .and. nconv .lt. numcnv) info = 2
648 c
649 np = nconv
650 go to 1100
651 c
652 else if ( (nconv .lt. numcnv) .and. (ishift .eq. 1) ) then
653 c
654 c %-------------------------------------------------%
655 c | Do not have all the requested eigenvalues yet. |
656 c | To prevent possible stagnation, adjust the size |
657 c | of NEV. |
658 c %-------------------------------------------------%
659 c
660 nevbef = nev
661 nev = nev + min(nconv, np/2)
662 if (nev .eq. 1 .and. kplusp .ge. 6) then
663 nev = kplusp / 2
664 else if (nev .eq. 1 .and. kplusp .gt. 3) then
665 nev = 2
666 end if
667 np = kplusp - nev
668 c
669 c %---------------------------------------%
670 c | If the size of NEV was just increased |
671 c | resort the eigenvalues. |
672 c %---------------------------------------%
673 c
674 if (nevbef .lt. nev)
675 & call sngets (ishift, which, nev, np, ritzr, ritzi,
676 & bounds, workl, workl(np+1))
677 c
678 end if
679 c
680 if (msglvl .gt. 0) then
681 call ivout (logfil, 1, nconv, ndigit,
682 & '_naup2: no. of "converged" Ritz values at this iter.')
683 if (msglvl .gt. 1) then
684 kp(1) = nev
685 kp(2) = np
686 call ivout (logfil, 2, kp, ndigit,
687 & '_naup2: NEV and NP are')
688 call svout (logfil, nev, ritzr(np+1), ndigit,
689 & '_naup2: "wanted" Ritz values -- real part')
690 call svout (logfil, nev, ritzi(np+1), ndigit,
691 & '_naup2: "wanted" Ritz values -- imag part')
692 call svout (logfil, nev, bounds(np+1), ndigit,
693 & '_naup2: Ritz estimates of the "wanted" values ')
694 end if
695 end if
696 c
697 if (ishift .eq. 0) then
698 c
699 c %-------------------------------------------------------%
700 c | User specified shifts: reverse comminucation to |
701 c | compute the shifts. They are returned in the first |
702 c | 2*NP locations of WORKL. |
703 c %-------------------------------------------------------%
704 c
705 ushift = .true.
706 ido = 3
707 go to 9000
708 end if
709 c
710 50 continue
711 c
712 c %------------------------------------%
713 c | Back from reverse communication; |
714 c | User specified shifts are returned |
715 c | in WORKL(1:2*NP) |
716 c %------------------------------------%
717 c
718 ushift = .false.
719 c
720 if ( ishift .eq. 0 ) then
721 c
722 c %----------------------------------%
723 c | Move the NP shifts from WORKL to |
724 c | RITZR, RITZI to free up WORKL |
725 c | for non-exact shift case. |
726 c %----------------------------------%
727 c
728 call scopy (np, workl, 1, ritzr, 1)
729 call scopy (np, workl(np+1), 1, ritzi, 1)
730 end if
731 c
732 if (msglvl .gt. 2) then
733 call ivout (logfil, 1, np, ndigit,
734 & '_naup2: The number of shifts to apply ')
735 call svout (logfil, np, ritzr, ndigit,
736 & '_naup2: Real part of the shifts')
737 call svout (logfil, np, ritzi, ndigit,
738 & '_naup2: Imaginary part of the shifts')
739 if ( ishift .eq. 1 )
740 & call svout (logfil, np, bounds, ndigit,
741 & '_naup2: Ritz estimates of the shifts')
742 end if
743 c
744 c %---------------------------------------------------------%
745 c | Apply the NP implicit shifts by QR bulge chasing. |
746 c | Each shift is applied to the whole upper Hessenberg |
747 c | matrix H. |
748 c | The first 2*N locations of WORKD are used as workspace. |
749 c %---------------------------------------------------------%
750 c
751 call snapps (n, nev, np, ritzr, ritzi, v, ldv,
752 & h, ldh, resid, q, ldq, workl, workd)
753 c
754 c %---------------------------------------------%
755 c | Compute the B-norm of the updated residual. |
756 c | Keep B*RESID in WORKD(1:N) to be used in |
757 c | the first step of the next call to snaitr. |
758 c %---------------------------------------------%
759 c
760 cnorm = .true.
761 call arscnd (t2)
762 if (bmat .eq. 'G') then
763 nbx = nbx + 1
764 call scopy (n, resid, 1, workd(n+1), 1)
765 ipntr(1) = n + 1
766 ipntr(2) = 1
767 ido = 2
768 c
769 c %----------------------------------%
770 c | Exit in order to compute B*RESID |
771 c %----------------------------------%
772 c
773 go to 9000
774 else if (bmat .eq. 'I') then
775 call scopy (n, resid, 1, workd, 1)
776 end if
777 c
778 100 continue
779 c
780 c %----------------------------------%
781 c | Back from reverse communication; |
782 c | WORKD(1:N) := B*RESID |
783 c %----------------------------------%
784 c
785 if (bmat .eq. 'G') then
786 call arscnd (t3)
787 tmvbx = tmvbx + (t3 - t2)
788 end if
789 c
790 if (bmat .eq. 'G') then
791 rnorm = sdot (n, resid, 1, workd, 1)
792 rnorm = sqrt(abs(rnorm))
793 else if (bmat .eq. 'I') then
794 rnorm = snrm2(n, resid, 1)
795 end if
796 cnorm = .false.
797 c
798 if (msglvl .gt. 2) then
799 call svout (logfil, 1, rnorm, ndigit,
800 & '_naup2: B-norm of residual for compressed factorization')
801 call smout (logfil, nev, nev, h, ldh, ndigit,
802 & '_naup2: Compressed upper Hessenberg matrix H')
803 end if
804 c
805 go to 1000
806 c
807 c %---------------------------------------------------------------%
808 c | |
809 c | E N D O F M A I N I T E R A T I O N L O O P |
810 c | |
811 c %---------------------------------------------------------------%
812 c
813 1100 continue
814 c
815 mxiter = iter
816 nev = numcnv
817 c
818 1200 continue
819 ido = 99
820 c
821 c %------------%
822 c | Error Exit |
823 c %------------%
824 c
825 call arscnd (t1)
826 tnaup2 = t1 - t0
827 c
828 9000 continue
829 c
830 c %---------------%
831 c | End of snaup2 |
832 c %---------------%
833 c
834 return
835 end