Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/mathlibs/src/arpack/dnaup2.f
5213 views
1
c\BeginDoc
2
c
3
c\Name: dnaup2
4
c
5
c\Description:
6
c Intermediate level interface called by dnaupd.
7
c
8
c\Usage:
9
c call dnaup2
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 dnaupd.
17
c MODE, ISHIFT, MXITER: see the definition of IPARAM in dnaupd.
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 Double precision 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 Double precision (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, Double precision 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 Double precision 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 Double precision (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 Double precision 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 dneigh.
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 Double precision 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 dgetv0 ARPACK initial vector generation routine.
139
c dnaitr ARPACK Arnoldi factorization routine.
140
c dnapps ARPACK application of implicit shifts routine.
141
c dnconv ARPACK convergence of Ritz values routine.
142
c dneigh ARPACK compute Ritz values and error bounds routine.
143
c dngets ARPACK reorder Ritz values and error bounds routine.
144
c dsortc ARPACK sorting routine.
145
c ivout ARPACK utility routine that prints integers.
146
c second ARPACK utility routine for timing.
147
c dmout ARPACK utility routine that prints matrices
148
c dvout ARPACK utility routine that prints vectors.
149
c dlamch LAPACK routine that determines machine constants.
150
c dlapy2 LAPACK routine to compute sqrt(x**2+y**2) carefully.
151
c dcopy Level 1 BLAS that copies one vector to another .
152
c ddot Level 1 BLAS that computes the scalar product of two vectors.
153
c dnrm2 Level 1 BLAS that computes the norm of a vector.
154
c dswap 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.4 DATE OF SID: 7/30/96 RELEASE: 2
166
c
167
c\Remarks
168
c 1. None
169
c
170
c\EndLib
171
c
172
c-----------------------------------------------------------------------
173
c
174
subroutine dnaup2
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
c
184
c
185
c\SCCS Information: @(#)
186
c FILE: debug.h SID: 2.3 DATE OF SID: 11/16/95 RELEASE: 2
187
c
188
c %---------------------------------%
189
c | See debug.doc for documentation |
190
c %---------------------------------%
191
integer logfil, ndigit, mgetv0,
192
& msaupd, msaup2, msaitr, mseigt, msapps, msgets, mseupd,
193
& mnaupd, mnaup2, mnaitr, mneigh, mnapps, mngets, mneupd,
194
& mcaupd, mcaup2, mcaitr, mceigh, mcapps, mcgets, mceupd
195
common /debug/
196
& logfil, ndigit, mgetv0,
197
& msaupd, msaup2, msaitr, mseigt, msapps, msgets, mseupd,
198
& mnaupd, mnaup2, mnaitr, mneigh, mnapps, mngets, mneupd,
199
& mcaupd, mcaup2, mcaitr, mceigh, mcapps, mcgets, mceupd
200
c %--------------------------------%
201
c | See stat.doc for documentation |
202
c %--------------------------------%
203
c
204
c\SCCS Information: @(#)
205
c FILE: stat.h SID: 2.2 DATE OF SID: 11/16/95 RELEASE: 2
206
c
207
real t0, t1, t2, t3, t4, t5
208
c save t0, t1, t2, t3, t4, t5
209
c
210
integer nopx, nbx, nrorth, nitref, nrstrt
211
real tsaupd, tsaup2, tsaitr, tseigt, tsgets, tsapps, tsconv,
212
& tnaupd, tnaup2, tnaitr, tneigh, tngets, tnapps, tnconv,
213
& tcaupd, tcaup2, tcaitr, tceigh, tcgets, tcapps, tcconv,
214
& tmvopx, tmvbx, tgetv0, titref, trvec
215
common /timing/
216
& nopx, nbx, nrorth, nitref, nrstrt,
217
& tsaupd, tsaup2, tsaitr, tseigt, tsgets, tsapps, tsconv,
218
& tnaupd, tnaup2, tnaitr, tneigh, tngets, tnapps, tnconv,
219
& tcaupd, tcaup2, tcaitr, tceigh, tcgets, tcapps, tcconv,
220
& tmvopx, tmvbx, tgetv0, titref, trvec
221
c %------------------%
222
c | Scalar Arguments |
223
c %------------------%
224
c
225
character bmat*1, which*2
226
integer ido, info, ishift, iupd, mode, ldh, ldq, ldv, mxiter,
227
& n, nev, np
228
Double precision
229
& tol
230
c
231
c %-----------------%
232
c | Array Arguments |
233
c %-----------------%
234
c
235
integer ipntr(13)
236
Double precision
237
& bounds(nev+np), h(ldh,nev+np), q(ldq,nev+np), resid(n),
238
& ritzi(nev+np), ritzr(nev+np), v(ldv,nev+np),
239
& workd(3*n), workl( (nev+np)*(nev+np+3) )
240
c
241
c %------------%
242
c | Parameters |
243
c %------------%
244
c
245
Double precision
246
& one, zero
247
parameter (one = 1.0D+0, zero = 0.0D+0)
248
c
249
c %---------------%
250
c | Local Scalars |
251
c %---------------%
252
c
253
character wprime*2
254
logical cnorm, getv0, initv, update, ushift
255
integer ierr, iter, j, kplusp, msglvl, nconv, nevbef, nev0,
256
& np0, nptemp, numcnv
257
Double precision
258
& rnorm, temp, eps23
259
c
260
c %-----------------------%
261
c | Local array arguments |
262
c %-----------------------%
263
c
264
integer kp(4)
265
save
266
267
c
268
c %----------------------%
269
c | External Subroutines |
270
c %----------------------%
271
c
272
external dcopy, dgetv0, dnaitr, dnconv, dneigh, dngets, dnapps,
273
& dvout, ivout, second
274
c
275
c %--------------------%
276
c | External Functions |
277
c %--------------------%
278
c
279
Double precision
280
& ddot, dnrm2, dlapy2, dlamch
281
external ddot, dnrm2, dlapy2, dlamch
282
c
283
c %---------------------%
284
c | Intrinsic Functions |
285
c %---------------------%
286
c
287
intrinsic min, max, abs, sqrt
288
c
289
c %-----------------------%
290
c | Executable Statements |
291
c %-----------------------%
292
c
293
if (ido .eq. 0) then
294
c
295
call second (t0)
296
c
297
msglvl = mnaup2
298
c
299
c %-------------------------------------%
300
c | Get the machine dependent constant. |
301
c %-------------------------------------%
302
c
303
eps23 = dlamch('Epsilon-Machine')
304
eps23 = eps23**(2.0D+0 / 3.0D+0)
305
c
306
nev0 = nev
307
np0 = np
308
c
309
c %-------------------------------------%
310
c | kplusp is the bound on the largest |
311
c | Lanczos factorization built. |
312
c | nconv is the current number of |
313
c | "converged" eigenvlues. |
314
c | iter is the counter on the current |
315
c | iteration step. |
316
c %-------------------------------------%
317
c
318
kplusp = nev + np
319
nconv = 0
320
iter = 0
321
c
322
c %---------------------------------------%
323
c | Set flags for computing the first NEV |
324
c | steps of the Arnoldi factorization. |
325
c %---------------------------------------%
326
c
327
getv0 = .true.
328
update = .false.
329
ushift = .false.
330
cnorm = .false.
331
c
332
if (info .ne. 0) then
333
c
334
c %--------------------------------------------%
335
c | User provides the initial residual vector. |
336
c %--------------------------------------------%
337
c
338
initv = .true.
339
info = 0
340
else
341
initv = .false.
342
end if
343
end if
344
c
345
c %---------------------------------------------%
346
c | Get a possibly random starting vector and |
347
c | force it into the range of the operator OP. |
348
c %---------------------------------------------%
349
c
350
10 continue
351
c
352
if (getv0) then
353
call dgetv0 (ido, bmat, 1, initv, n, 1, v, ldv, resid, rnorm,
354
& ipntr, workd, info)
355
c
356
if (ido .ne. 99) go to 9000
357
c
358
if (rnorm .eq. zero) then
359
c
360
c %-----------------------------------------%
361
c | The initial vector is zero. Error exit. |
362
c %-----------------------------------------%
363
c
364
info = -9
365
go to 1100
366
end if
367
getv0 = .false.
368
ido = 0
369
end if
370
c
371
c %-----------------------------------%
372
c | Back from reverse communication : |
373
c | continue with update step |
374
c %-----------------------------------%
375
c
376
if (update) go to 20
377
c
378
c %-------------------------------------------%
379
c | Back from computing user specified shifts |
380
c %-------------------------------------------%
381
c
382
if (ushift) go to 50
383
c
384
c %-------------------------------------%
385
c | Back from computing residual norm |
386
c | at the end of the current iteration |
387
c %-------------------------------------%
388
c
389
if (cnorm) go to 100
390
c
391
c %----------------------------------------------------------%
392
c | Compute the first NEV steps of the Arnoldi factorization |
393
c %----------------------------------------------------------%
394
c
395
call dnaitr (ido, bmat, n, 0, nev, mode, resid, rnorm, v, ldv,
396
& h, ldh, ipntr, workd, info)
397
c
398
c %---------------------------------------------------%
399
c | ido .ne. 99 implies use of reverse communication |
400
c | to compute operations involving OP and possibly B |
401
c %---------------------------------------------------%
402
c
403
if (ido .ne. 99) go to 9000
404
c
405
if (info .gt. 0) then
406
np = info
407
mxiter = iter
408
info = -9999
409
go to 1200
410
end if
411
c
412
c %--------------------------------------------------------------%
413
c | |
414
c | M A I N ARNOLDI I T E R A T I O N L O O P |
415
c | Each iteration implicitly restarts the Arnoldi |
416
c | factorization in place. |
417
c | |
418
c %--------------------------------------------------------------%
419
c
420
1000 continue
421
c
422
iter = iter + 1
423
c
424
if (msglvl .gt. 0) then
425
call ivout (logfil, 1, [iter], ndigit,
426
& '_naup2: **** Start of major iteration number ****')
427
end if
428
c
429
c %-----------------------------------------------------------%
430
c | Compute NP additional steps of the Arnoldi factorization. |
431
c | Adjust NP since NEV might have been updated by last call |
432
c | to the shift application routine dnapps. |
433
c %-----------------------------------------------------------%
434
c
435
np = kplusp - nev
436
c
437
if (msglvl .gt. 1) then
438
call ivout (logfil, 1, [nev], ndigit,
439
& '_naup2: The length of the current Arnoldi factorization')
440
call ivout (logfil, 1, [np], ndigit,
441
& '_naup2: Extend the Arnoldi factorization by')
442
end if
443
c
444
c %-----------------------------------------------------------%
445
c | Compute NP additional steps of the Arnoldi factorization. |
446
c %-----------------------------------------------------------%
447
c
448
ido = 0
449
20 continue
450
update = .true.
451
c
452
call dnaitr (ido, bmat, n, nev, np, mode, resid, rnorm, v, ldv,
453
& h, ldh, ipntr, workd, info)
454
c
455
c %---------------------------------------------------%
456
c | ido .ne. 99 implies use of reverse communication |
457
c | to compute operations involving OP and possibly B |
458
c %---------------------------------------------------%
459
c
460
if (ido .ne. 99) go to 9000
461
c
462
if (info .gt. 0) then
463
np = info
464
mxiter = iter
465
info = -9999
466
go to 1200
467
end if
468
update = .false.
469
c
470
if (msglvl .gt. 1) then
471
call dvout (logfil, 1, [rnorm], ndigit,
472
& '_naup2: Corresponding B-norm of the residual')
473
end if
474
c
475
c %--------------------------------------------------------%
476
c | Compute the eigenvalues and corresponding error bounds |
477
c | of the current upper Hessenberg matrix. |
478
c %--------------------------------------------------------%
479
c
480
call dneigh (rnorm, kplusp, h, ldh, ritzr, ritzi, bounds,
481
& q, ldq, workl, ierr)
482
c
483
if (ierr .ne. 0) then
484
info = -8
485
go to 1200
486
end if
487
c
488
c %----------------------------------------------------%
489
c | Make a copy of eigenvalues and corresponding error |
490
c | bounds obtained from dneigh. |
491
c %----------------------------------------------------%
492
c
493
call dcopy(kplusp, ritzr, 1, workl(kplusp**2+1), 1)
494
call dcopy(kplusp, ritzi, 1, workl(kplusp**2+kplusp+1), 1)
495
call dcopy(kplusp, bounds, 1, workl(kplusp**2+2*kplusp+1), 1)
496
c
497
c %---------------------------------------------------%
498
c | Select the wanted Ritz values and their bounds |
499
c | to be used in the convergence test. |
500
c | The wanted part of the spectrum and corresponding |
501
c | error bounds are in the last NEV loc. of RITZR, |
502
c | RITZI and BOUNDS respectively. The variables NEV |
503
c | and NP may be updated if the NEV-th wanted Ritz |
504
c | value has a non zero imaginary part. In this case |
505
c | NEV is increased by one and NP decreased by one. |
506
c | NOTE: The last two arguments of dngets are no |
507
c | longer used as of version 2.1. |
508
c %---------------------------------------------------%
509
c
510
nev = nev0
511
np = np0
512
numcnv = nev
513
call dngets (ishift, which, nev, np, ritzr, ritzi,
514
& bounds, workl, workl(np+1))
515
if (nev .eq. nev0+1) numcnv = nev0+1
516
c
517
c %-------------------%
518
c | Convergence test. |
519
c %-------------------%
520
c
521
call dcopy (nev, bounds(np+1), 1, workl(2*np+1), 1)
522
call dnconv (nev, ritzr(np+1), ritzi(np+1), workl(2*np+1),
523
& tol, nconv)
524
c
525
if (msglvl .gt. 2) then
526
kp(1) = nev
527
kp(2) = np
528
kp(3) = numcnv
529
kp(4) = nconv
530
call ivout (logfil, 4, kp, ndigit,
531
& '_naup2: NEV, NP, NUMCNV, NCONV are')
532
call dvout (logfil, kplusp, ritzr, ndigit,
533
& '_naup2: Real part of the eigenvalues of H')
534
call dvout (logfil, kplusp, ritzi, ndigit,
535
& '_naup2: Imaginary part of the eigenvalues of H')
536
call dvout (logfil, kplusp, bounds, ndigit,
537
& '_naup2: Ritz estimates of the current NCV Ritz values')
538
end if
539
c
540
c %---------------------------------------------------------%
541
c | Count the number of unwanted Ritz values that have zero |
542
c | Ritz estimates. If any Ritz estimates are equal to zero |
543
c | then a leading block of H of order equal to at least |
544
c | the number of Ritz values with zero Ritz estimates has |
545
c | split off. None of these Ritz values may be removed by |
546
c | shifting. Decrease NP the number of shifts to apply. If |
547
c | no shifts may be applied, then prepare to exit |
548
c %---------------------------------------------------------%
549
c
550
nptemp = np
551
do 30 j=1, nptemp
552
if (bounds(j) .eq. zero) then
553
np = np - 1
554
nev = nev + 1
555
end if
556
30 continue
557
c
558
if ( (nconv .ge. numcnv) .or.
559
& (iter .gt. mxiter) .or.
560
& (np .eq. 0) ) then
561
c
562
if (msglvl .gt. 4) then
563
call dvout(logfil, kplusp, workl(kplusp**2+1), ndigit,
564
& '_naup2: Real part of the eig computed by _neigh:')
565
call dvout(logfil, kplusp, workl(kplusp**2+kplusp+1),
566
& ndigit,
567
& '_naup2: Imag part of the eig computed by _neigh:')
568
call dvout(logfil, kplusp, workl(kplusp**2+kplusp*2+1),
569
& ndigit,
570
& '_naup2: Ritz eistmates computed by _neigh:')
571
end if
572
c
573
c %------------------------------------------------%
574
c | Prepare to exit. Put the converged Ritz values |
575
c | and corresponding bounds in RITZ(1:NCONV) and |
576
c | BOUNDS(1:NCONV) respectively. Then sort. Be |
577
c | careful when NCONV > NP |
578
c %------------------------------------------------%
579
c
580
c %------------------------------------------%
581
c | Use h( 3,1 ) as storage to communicate |
582
c | rnorm to _neupd if needed |
583
c %------------------------------------------%
584
585
h(3,1) = rnorm
586
c
587
c %----------------------------------------------%
588
c | To be consistent with dngets, we first do a |
589
c | pre-processing sort in order to keep complex |
590
c | conjugate pairs together. This is similar |
591
c | to the pre-processing sort used in dngets |
592
c | except that the sort is done in the opposite |
593
c | order. |
594
c %----------------------------------------------%
595
c
596
if (which .eq. 'LM') wprime = 'SR'
597
if (which .eq. 'SM') wprime = 'LR'
598
if (which .eq. 'LR') wprime = 'SM'
599
if (which .eq. 'SR') wprime = 'LM'
600
if (which .eq. 'LI') wprime = 'SM'
601
if (which .eq. 'SI') wprime = 'LM'
602
c
603
call dsortc (wprime, .true., kplusp, ritzr, ritzi, bounds)
604
c
605
c %----------------------------------------------%
606
c | Now sort Ritz values so that converged Ritz |
607
c | values appear within the first NEV locations |
608
c | of ritzr, ritzi and bounds, and the most |
609
c | desired one appears at the front. |
610
c %----------------------------------------------%
611
c
612
if (which .eq. 'LM') wprime = 'SM'
613
if (which .eq. 'SM') wprime = 'LM'
614
if (which .eq. 'LR') wprime = 'SR'
615
if (which .eq. 'SR') wprime = 'LR'
616
if (which .eq. 'LI') wprime = 'SI'
617
if (which .eq. 'SI') wprime = 'LI'
618
c
619
call dsortc(wprime, .true., kplusp, ritzr, ritzi, bounds)
620
c
621
c %--------------------------------------------------%
622
c | Scale the Ritz estimate of each Ritz value |
623
c | by 1 / max(eps23,magnitude of the Ritz value). |
624
c %--------------------------------------------------%
625
c
626
do 35 j = 1, nev0
627
temp = max(eps23,dlapy2(ritzr(j),
628
& ritzi(j)))
629
bounds(j) = bounds(j)/temp
630
35 continue
631
c
632
c %----------------------------------------------------%
633
c | Sort the Ritz values according to the scaled Ritz |
634
c | esitmates. This will push all the converged ones |
635
c | towards the front of ritzr, ritzi, bounds |
636
c | (in the case when NCONV < NEV.) |
637
c %----------------------------------------------------%
638
c
639
wprime = 'LR'
640
call dsortc(wprime, .true., nev0, bounds, ritzr, ritzi)
641
c
642
c %----------------------------------------------%
643
c | Scale the Ritz estimate back to its original |
644
c | value. |
645
c %----------------------------------------------%
646
c
647
do 40 j = 1, nev0
648
temp = max(eps23, dlapy2(ritzr(j),
649
& ritzi(j)))
650
bounds(j) = bounds(j)*temp
651
40 continue
652
c
653
c %------------------------------------------------%
654
c | Sort the converged Ritz values again so that |
655
c | the "threshold" value appears at the front of |
656
c | ritzr, ritzi and bound. |
657
c %------------------------------------------------%
658
c
659
call dsortc(which, .true., nconv, ritzr, ritzi, bounds)
660
c
661
if (msglvl .gt. 1) then
662
call dvout (logfil, kplusp, ritzr, ndigit,
663
& '_naup2: Sorted real part of the eigenvalues')
664
call dvout (logfil, kplusp, ritzi, ndigit,
665
& '_naup2: Sorted imaginary part of the eigenvalues')
666
call dvout (logfil, kplusp, bounds, ndigit,
667
& '_naup2: Sorted ritz estimates.')
668
end if
669
c
670
c %------------------------------------%
671
c | Max iterations have been exceeded. |
672
c %------------------------------------%
673
c
674
if (iter .gt. mxiter .and. nconv .lt. numcnv) info = 1
675
c
676
c %---------------------%
677
c | No shifts to apply. |
678
c %---------------------%
679
c
680
if (np .eq. 0 .and. nconv .lt. numcnv) info = 2
681
c
682
np = nconv
683
go to 1100
684
c
685
else if ( (nconv .lt. numcnv) .and. (ishift .eq. 1) ) then
686
c
687
c %-------------------------------------------------%
688
c | Do not have all the requested eigenvalues yet. |
689
c | To prevent possible stagnation, adjust the size |
690
c | of NEV. |
691
c %-------------------------------------------------%
692
c
693
nevbef = nev
694
nev = nev + min(nconv, np/2)
695
if (nev .eq. 1 .and. kplusp .ge. 6) then
696
nev = kplusp / 2
697
else if (nev .eq. 1 .and. kplusp .gt. 3) then
698
nev = 2
699
end if
700
np = kplusp - nev
701
c
702
c %---------------------------------------%
703
c | If the size of NEV was just increased |
704
c | resort the eigenvalues. |
705
c %---------------------------------------%
706
c
707
if (nevbef .lt. nev)
708
& call dngets (ishift, which, nev, np, ritzr, ritzi,
709
& bounds, workl, workl(np+1))
710
c
711
end if
712
c
713
if (msglvl .gt. 0) then
714
call ivout (logfil, 1, [nconv], ndigit,
715
& '_naup2: no. of "converged" Ritz values at this iter.')
716
if (msglvl .gt. 1) then
717
kp(1) = nev
718
kp(2) = np
719
call ivout (logfil, 2, kp, ndigit,
720
& '_naup2: NEV and NP are')
721
call dvout (logfil, nev, ritzr(np+1), ndigit,
722
& '_naup2: "wanted" Ritz values -- real part')
723
call dvout (logfil, nev, ritzi(np+1), ndigit,
724
& '_naup2: "wanted" Ritz values -- imag part')
725
call dvout (logfil, nev, bounds(np+1), ndigit,
726
& '_naup2: Ritz estimates of the "wanted" values ')
727
end if
728
end if
729
c
730
if (ishift .eq. 0) then
731
c
732
c %-------------------------------------------------------%
733
c | User specified shifts: reverse comminucation to |
734
c | compute the shifts. They are returned in the first |
735
c | 2*NP locations of WORKL. |
736
c %-------------------------------------------------------%
737
c
738
ushift = .true.
739
ido = 3
740
go to 9000
741
end if
742
c
743
50 continue
744
c
745
c %------------------------------------%
746
c | Back from reverse communication; |
747
c | User specified shifts are returned |
748
c | in WORKL(1:2*NP) |
749
c %------------------------------------%
750
c
751
ushift = .false.
752
c
753
if ( ishift .eq. 0 ) then
754
c
755
c %----------------------------------%
756
c | Move the NP shifts from WORKL to |
757
c | RITZR, RITZI to free up WORKL |
758
c | for non-exact shift case. |
759
c %----------------------------------%
760
c
761
call dcopy (np, workl, 1, ritzr, 1)
762
call dcopy (np, workl(np+1), 1, ritzi, 1)
763
end if
764
c
765
if (msglvl .gt. 2) then
766
call ivout (logfil, 1, [np], ndigit,
767
& '_naup2: The number of shifts to apply ')
768
call dvout (logfil, np, ritzr, ndigit,
769
& '_naup2: Real part of the shifts')
770
call dvout (logfil, np, ritzi, ndigit,
771
& '_naup2: Imaginary part of the shifts')
772
if ( ishift .eq. 1 )
773
& call dvout (logfil, np, bounds, ndigit,
774
& '_naup2: Ritz estimates of the shifts')
775
end if
776
c
777
c %---------------------------------------------------------%
778
c | Apply the NP implicit shifts by QR bulge chasing. |
779
c | Each shift is applied to the whole upper Hessenberg |
780
c | matrix H. |
781
c | The first 2*N locations of WORKD are used as workspace. |
782
c %---------------------------------------------------------%
783
c
784
call dnapps (n, nev, np, ritzr, ritzi, v, ldv,
785
& h, ldh, resid, q, ldq, workl, workd)
786
c
787
c %---------------------------------------------%
788
c | Compute the B-norm of the updated residual. |
789
c | Keep B*RESID in WORKD(1:N) to be used in |
790
c | the first step of the next call to dnaitr. |
791
c %---------------------------------------------%
792
c
793
cnorm = .true.
794
call second (t2)
795
if (bmat .eq. 'G') then
796
nbx = nbx + 1
797
call dcopy (n, resid, 1, workd(n+1), 1)
798
ipntr(1) = n + 1
799
ipntr(2) = 1
800
ido = 2
801
c
802
c %----------------------------------%
803
c | Exit in order to compute B*RESID |
804
c %----------------------------------%
805
c
806
go to 9000
807
else if (bmat .eq. 'I') then
808
call dcopy (n, resid, 1, workd, 1)
809
end if
810
c
811
100 continue
812
c
813
c %----------------------------------%
814
c | Back from reverse communication; |
815
c | WORKD(1:N) := B*RESID |
816
c %----------------------------------%
817
c
818
if (bmat .eq. 'G') then
819
call second (t3)
820
tmvbx = tmvbx + (t3 - t2)
821
end if
822
c
823
if (bmat .eq. 'G') then
824
rnorm = ddot (n, resid, 1, workd, 1)
825
rnorm = sqrt(abs(rnorm))
826
else if (bmat .eq. 'I') then
827
rnorm = dnrm2(n, resid, 1)
828
end if
829
cnorm = .false.
830
c
831
if (msglvl .gt. 2) then
832
call dvout (logfil, 1, [rnorm], ndigit,
833
& '_naup2: B-norm of residual for compressed factorization')
834
call dmout (logfil, nev, nev, h, ldh, ndigit,
835
& '_naup2: Compressed upper Hessenberg matrix H')
836
end if
837
c
838
go to 1000
839
c
840
c %---------------------------------------------------------------%
841
c | |
842
c | E N D O F M A I N I T E R A T I O N L O O P |
843
c | |
844
c %---------------------------------------------------------------%
845
c
846
1100 continue
847
c
848
mxiter = iter
849
nev = numcnv
850
c
851
1200 continue
852
ido = 99
853
c
854
c %------------%
855
c | Error Exit |
856
c %------------%
857
c
858
call second (t1)
859
tnaup2 = t1 - t0
860
c
861
9000 continue
862
c
863
c %---------------%
864
c | End of dnaup2 |
865
c %---------------%
866
c
867
return
868
end
869
870