~ubuntu-branches/ubuntu/hoary/scilab/hoary

« back to all changes in this revision

Viewing changes to routines/arpack/znaup2.f

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2005-01-09 22:58:21 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050109225821-473xr8vhgugxxx5j
Tags: 3.0-12
changed configure.in to build scilab's own malloc.o, closes: #255869

Show diffs side-by-side

added added

removed removed

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