Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/mathlibs/src/parpack/pcneupd.f
5192 views
1
c\BeginDoc
2
c
3
c\Name: pcneupd
4
c
5
c Message Passing Layer: MPI
6
c
7
c\Description:
8
c This subroutine returns the converged approximations to eigenvalues
9
c of A*z = lambda*B*z and (optionally):
10
c
11
c (1) The corresponding approximate eigenvectors;
12
c
13
c (2) An orthonormal basis for the associated approximate
14
c invariant subspace;
15
c
16
c (3) Both.
17
c
18
c There is negligible additional cost to obtain eigenvectors. An orthonormal
19
c basis is always computed. There is an additional storage cost of n*nev
20
c if both are requested (in this case a separate array Z must be supplied).
21
c
22
c The approximate eigenvalues and eigenvectors of A*z = lambda*B*z
23
c are derived from approximate eigenvalues and eigenvectors of
24
c of the linear operator OP prescribed by the MODE selection in the
25
c call to PCNAUPD. PCNAUPD must be called before this routine is called.
26
c These approximate eigenvalues and vectors are commonly called Ritz
27
c values and Ritz vectors respectively. They are referred to as such
28
c in the comments that follow. The computed orthonormal basis for the
29
c invariant subspace corresponding to these Ritz values is referred to as a
30
c Schur basis.
31
c
32
c The definition of OP as well as other terms and the relation of computed
33
c Ritz values and vectors of OP with respect to the given problem
34
c A*z = lambda*B*z may be found in the header of PCNAUPD. For a brief
35
c description, see definitions of IPARAM(7), MODE and WHICH in the
36
c documentation of PCNAUPD.
37
c
38
c\Usage:
39
c call pcneupd
40
c ( COMM, RVEC, HOWMNY, SELECT, D, Z, LDZ, SIGMA, WORKEV, BMAT,
41
c N, WHICH, NEV, TOL, RESID, NCV, V, LDV, IPARAM, IPNTR, WORKD,
42
c WORKL, LWORKL, RWORK, INFO )
43
c
44
c\Arguments
45
c COMM MPI Communicator for the processor grid. (INPUT)
46
c
47
c RVEC LOGICAL (INPUT)
48
c Specifies whether a basis for the invariant subspace corresponding
49
c to the converged Ritz value approximations for the eigenproblem
50
c A*z = lambda*B*z is computed.
51
c
52
c RVEC = .FALSE. Compute Ritz values only.
53
c
54
c RVEC = .TRUE. Compute Ritz vectors or Schur vectors.
55
c See Remarks below.
56
c
57
c HOWMNY Character*1 (INPUT)
58
c Specifies the form of the basis for the invariant subspace
59
c corresponding to the converged Ritz values that is to be computed.
60
c
61
c = 'A': Compute NEV Ritz vectors;
62
c = 'P': Compute NEV Schur vectors;
63
c = 'S': compute some of the Ritz vectors, specified
64
c by the logical array SELECT.
65
c
66
c SELECT Logical array of dimension NCV. (INPUT)
67
c If HOWMNY = 'S', SELECT specifies the Ritz vectors to be
68
c computed. To select the Ritz vector corresponding to a
69
c Ritz value D(j), SELECT(j) must be set to .TRUE..
70
c If HOWMNY = 'A' or 'P', SELECT need not be initialized
71
c but it is used as internal workspace.
72
c
73
c D Complex array of dimension NEV+1. (OUTPUT)
74
c On exit, D contains the Ritz approximations
75
c to the eigenvalues lambda for A*z = lambda*B*z.
76
c
77
c Z Complex N by NEV array (OUTPUT)
78
c On exit, if RVEC = .TRUE. and HOWMNY = 'A', then the columns of
79
c Z represents approximate eigenvectors (Ritz vectors) corresponding
80
c to the NCONV=IPARAM(5) Ritz values for eigensystem
81
c A*z = lambda*B*z.
82
c
83
c If RVEC = .FALSE. or HOWMNY = 'P', then Z is NOT REFERENCED.
84
c
85
c NOTE: If if RVEC = .TRUE. and a Schur basis is not required,
86
c the array Z may be set equal to first NEV+1 columns of the Arnoldi
87
c basis array V computed by PCNAUPD. In this case the Arnoldi basis
88
c will be destroyed and overwritten with the eigenvector basis.
89
c
90
c LDZ Integer. (INPUT)
91
c The leading dimension of the array Z. If Ritz vectors are
92
c desired, then LDZ .ge. max( 1, N ) is required.
93
c In any case, LDZ .ge. 1 is required.
94
c
95
c SIGMA Complex (INPUT)
96
c If IPARAM(7) = 3 then SIGMA represents the shift.
97
c Not referenced if IPARAM(7) = 1 or 2.
98
c
99
c WORKEV Complex work array of dimension 2*NCV. (WORKSPACE)
100
c
101
c **** The remaining arguments MUST be the same as for the ****
102
c **** call to PCNAUPD that was just completed. ****
103
c
104
c NOTE: The remaining arguments
105
c
106
c BMAT, N, WHICH, NEV, TOL, RESID, NCV, V, LDV, IPARAM, IPNTR,
107
c WORKD, WORKL, LWORKL, RWORK, INFO
108
c
109
c must be passed directly to CNEUPD following the last call
110
c to PCNAUPD. These arguments MUST NOT BE MODIFIED between
111
c the the last call to PCNAUPD and the call to CNEUPD.
112
c
113
c Three of these parameters (V, WORKL and INFO) are also output parameters:
114
c
115
c V Complex N by NCV array. (INPUT/OUTPUT)
116
c
117
c Upon INPUT: the NCV columns of V contain the Arnoldi basis
118
c vectors for OP as constructed by PCNAUPD .
119
c
120
c Upon OUTPUT: If RVEC = .TRUE. the first NCONV=IPARAM(5) columns
121
c contain approximate Schur vectors that span the
122
c desired invariant subspace.
123
c
124
c NOTE: If the array Z has been set equal to first NEV+1 columns
125
c of the array V and RVEC=.TRUE. and HOWMNY= 'A', then the
126
c Arnoldi basis held by V has been overwritten by the desired
127
c Ritz vectors. If a separate array Z has been passed then
128
c the first NCONV=IPARAM(5) columns of V will contain approximate
129
c Schur vectors that span the desired invariant subspace.
130
c
131
c WORKL Real work array of length LWORKL. (OUTPUT/WORKSPACE)
132
c WORKL(1:ncv*ncv+2*ncv) contains information obtained in
133
c PCNAUPD. They are not changed by PCNEUPD.
134
c WORKL(ncv*ncv+2*ncv+1:3*ncv*ncv+4*ncv) holds the
135
c untransformed Ritz values, the untransformed error estimates of
136
c the Ritz values, the upper triangular matrix for H, and the
137
c associated matrix representation of the invariant subspace for H.
138
c
139
c Note: IPNTR(9:13) contains the pointer into WORKL for addresses
140
c of the above information computed by PCNEUPD.
141
c -------------------------------------------------------------
142
c IPNTR(9): pointer to the NCV RITZ values of the
143
c original system.
144
c IPNTR(10): Not used
145
c IPNTR(11): pointer to the NCV corresponding error estimates.
146
c IPNTR(12): pointer to the NCV by NCV upper triangular
147
c Schur matrix for H.
148
c IPNTR(13): pointer to the NCV by NCV matrix of eigenvectors
149
c of the upper Hessenberg matrix H. Only referenced by
150
c PCNEUPD if RVEC = .TRUE. See Remark 2 below.
151
c -------------------------------------------------------------
152
c
153
c INFO Integer. (OUTPUT)
154
c Error flag on output.
155
c = 0: Normal exit.
156
c
157
c = 1: The Schur form computed by LAPACK routine csheqr
158
c could not be reordered by LAPACK routine ctrsen.
159
c Re-enter subroutine pcneupd with IPARAM(5)=NCV and
160
c increase the size of the array D to have
161
c dimension at least dimension NCV and allocate at least NCV
162
c columns for Z. NOTE: Not necessary if Z and V share
163
c the same space. Please notify the authors if this error
164
c occurs.
165
c
166
c = -1: N must be positive.
167
c = -2: NEV must be positive.
168
c = -3: NCV-NEV >= 2 and less than or equal to N.
169
c = -5: WHICH must be one of 'LM', 'SM', 'LR', 'SR', 'LI', 'SI'
170
c = -6: BMAT must be one of 'I' or 'G'.
171
c = -7: Length of private work WORKL array is not sufficient.
172
c = -8: Error return from LAPACK eigenvalue calculation.
173
c This should never happened.
174
c = -9: Error return from calculation of eigenvectors.
175
c Informational error from LAPACK routine ctrevc.
176
c = -10: IPARAM(7) must be 1,2,3
177
c = -11: IPARAM(7) = 1 and BMAT = 'G' are incompatible.
178
c = -12: HOWMNY = 'S' not yet implemented
179
c = -13: HOWMNY must be one of 'A' or 'P' if RVEC = .true.
180
c = -14: PCNAUPD did not find any eigenvalues to sufficient
181
c accuracy.
182
c = -15: CNEUPD got a different count of the number of converged
183
c Ritz values than CNAUPD got. This indicates the user
184
c probably made an error in passing data from CNAUPD to
185
c CNEUPD or that the data was modified before entering
186
c CNEUPD.
187
c
188
c\BeginLib
189
c
190
c\References:
191
c 1. D.C. Sorensen, "Implicit Application of Polynomial Filters in
192
c a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992),
193
c pp 357-385.
194
c 2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly
195
c Restarted Arnoldi Iteration", Rice University Technical Report
196
c TR95-13, Department of Computational and Applied Mathematics.
197
c 3. B. Nour-Omid, B. N. Parlett, T. Ericsson and P. S. Jensen,
198
c "How to Implement the Spectral Transformation", Math Comp.,
199
c Vol. 48, No. 178, April, 1987 pp. 664-673.
200
c
201
c\Routines called:
202
c pivout Parallel ARPACK utility routine that prints integers.
203
c pcmout Parallel ARPACK utility routine that prints matrices
204
c pcvout Parallel ARPACK utility routine that prints vectors.
205
c cgeqr2 LAPACK routine that computes the QR factorization of
206
c a matrix.
207
c clacpy LAPACK matrix copy routine.
208
c clahqr LAPACK routine that computes the Schur form of a
209
c upper Hessenberg matrix.
210
c claset LAPACK matrix initialization routine.
211
c ctrevc LAPACK routine to compute the eigenvectors of a matrix
212
c in upper triangular form.
213
c ctrsen LAPACK routine that re-orders the Schur form.
214
c cunm2r LAPACK routine that applies an orthogonal matrix in
215
c factored form.
216
c pslamch ScaLAPACK routine that determines machine constants.
217
c ctrmm Level 3 BLAS matrix times an upper triangular matrix.
218
c cgeru Level 2 BLAS rank one update to a matrix.
219
c ccopy Level 1 BLAS that copies one vector to another .
220
c cscal Level 1 BLAS that scales a vector.
221
c csscal Level 1 BLAS that scales a complex vector by a real number.
222
c scnrm2 Level 1 BLAS that computes the norm of a complex vector.
223
c
224
c\Remarks
225
c
226
c 1. Currently only HOWMNY = 'A' and 'P' are implemented.
227
c
228
c 2. Schur vectors are an orthogonal representation for the basis of
229
c Ritz vectors. Thus, their numerical properties are often superior.
230
c If RVEC = .true. then the relationship
231
c A * V(:,1:IPARAM(5)) = V(:,1:IPARAM(5)) * T, and
232
c V(:,1:IPARAM(5))` * V(:,1:IPARAM(5)) = I are approximately satisfied.
233
c Here T is the leading submatrix of order IPARAM(5) of the
234
c upper triangular matrix stored workl(ipntr(12)).
235
c
236
c\Authors
237
c Danny Sorensen Phuong Vu
238
c Richard Lehoucq CRPC / Rice University
239
c Chao Yang Houston, Texas
240
c Dept. of Computational &
241
c Applied Mathematics
242
c Rice University
243
c Houston, Texas
244
c
245
c\Parallel Modifications
246
c Kristi Maschhoff
247
c
248
c\Revision history:
249
c Starting Point: Complex Serial Code FILE: neupd.F SID: 2.2
250
c
251
c\SCCS Information:
252
c FILE: neupd.F SID: 1.6 DATE OF SID: 04/10/01
253
c
254
c\EndLib
255
c
256
c-----------------------------------------------------------------------
257
subroutine pcneupd
258
& ( comm , rvec , howmny, select, d ,
259
& z , ldz , sigma , workev, bmat ,
260
& n , which , nev , tol , resid,
261
& ncv , v , ldv , iparam, ipntr,
262
& workd, workl , lworkl, rwork , info )
263
c
264
c %--------------------%
265
c | MPI Communicator |
266
c %--------------------%
267
c
268
integer comm
269
c
270
c %----------------------------------------------------%
271
c | Include files for debugging and timing information |
272
c %----------------------------------------------------%
273
c
274
include 'debug.h'
275
include 'stat.h'
276
c
277
c %------------------%
278
c | Scalar Arguments |
279
c %------------------%
280
c
281
character bmat, howmny, which*2
282
logical rvec
283
integer info, ldz, ldv, lworkl, n, ncv, nev
284
Complex
285
& sigma
286
Real
287
& tol
288
c
289
c %-----------------%
290
c | Array Arguments |
291
c %-----------------%
292
c
293
integer iparam(11), ipntr(14)
294
logical select(ncv)
295
Real
296
& rwork(ncv)
297
Complex
298
& d(nev) , resid(n) , v(ldv,ncv) ,
299
& z(ldz, nev), workd(3*n), workl(lworkl),
300
& workev(2*ncv)
301
c
302
c %------------%
303
c | Parameters |
304
c %------------%
305
c
306
Complex
307
& one, zero
308
parameter (one = (1.0, 0.0) , zero = (0.0, 0.0) )
309
c
310
c %---------------%
311
c | Local Scalars |
312
c %---------------%
313
c
314
character type*6
315
integer bounds, ierr , ih , ihbds, iheig , nconv ,
316
& invsub, iuptri, iwev , j , ldh , ldq ,
317
& mode , msglvl, ritz , wr , k , irz ,
318
& ibd , outncv, iq , np , numcnv, jj ,
319
& ishift
320
Complex
321
& rnorm, temp, vl(1)
322
Real
323
& conds, sep, rtemp, eps23
324
logical reord
325
c
326
c %----------------------%
327
c | External Subroutines |
328
c %----------------------%
329
c
330
external ccopy ,cgeru,cgeqr2,clacpy,pcmout,
331
& cunm2r,ctrmm,pcvout,pivout,
332
& clahqr
333
c
334
c %--------------------%
335
c | External Functions |
336
c %--------------------%
337
c
338
Real
339
& scnrm2,pslamch10,slapy2
340
external scnrm2,pslamch10,slapy2
341
c
342
Complex
343
& cdotc
344
external cdotc
345
c
346
c %---------------------%
347
c | Intrinsic Functions |
348
c %---------------------%
349
c
350
intrinsic abs
351
c
352
c %-----------------------%
353
c | Executable Statements |
354
c %-----------------------%
355
c
356
c %------------------------%
357
c | Set default parameters |
358
c %------------------------%
359
c
360
msglvl = mceupd
361
mode = iparam(7)
362
nconv = iparam(5)
363
info = 0
364
c
365
c
366
c %---------------------------------%
367
c | Get machine dependent constant. |
368
c %---------------------------------%
369
c
370
eps23 = pslamch10(comm, 'Epsilon-Machine')
371
eps23 = eps23**(2.0 / 3.0 )
372
c
373
c %-------------------------------%
374
c | Quick return |
375
c | Check for incompatible input |
376
c %-------------------------------%
377
c
378
ierr = 0
379
c
380
if (nconv .le. 0) then
381
ierr = -14
382
else if (n .le. 0) then
383
ierr = -1
384
else if (nev .le. 0) then
385
ierr = -2
386
else if (ncv .le. nev+1 .or. ncv .gt. n) then
387
ierr = -3
388
else if (which .ne. 'LM' .and.
389
& which .ne. 'SM' .and.
390
& which .ne. 'LR' .and.
391
& which .ne. 'SR' .and.
392
& which .ne. 'LI' .and.
393
& which .ne. 'SI') then
394
ierr = -5
395
else if (bmat .ne. 'I' .and. bmat .ne. 'G') then
396
ierr = -6
397
else if (lworkl .lt. 3*ncv**2 + 4*ncv) then
398
ierr = -7
399
else if ( (howmny .ne. 'A' .and.
400
& howmny .ne. 'P' .and.
401
& howmny .ne. 'S') .and. rvec ) then
402
ierr = -13
403
else if (howmny .eq. 'S' ) then
404
ierr = -12
405
end if
406
c
407
if (mode .eq. 1 .or. mode .eq. 2) then
408
type = 'REGULR'
409
else if (mode .eq. 3 ) then
410
type = 'SHIFTI'
411
else
412
ierr = -10
413
end if
414
if (mode .eq. 1 .and. bmat .eq. 'G') ierr = -11
415
c
416
c %------------%
417
c | Error Exit |
418
c %------------%
419
c
420
if (ierr .ne. 0) then
421
info = ierr
422
go to 9000
423
end if
424
c
425
c %--------------------------------------------------------%
426
c | Pointer into WORKL for address of H, RITZ, WORKEV, Q |
427
c | etc... and the remaining workspace. |
428
c | Also update pointer to be used on output. |
429
c | Memory is laid out as follows: |
430
c | workl(1:ncv*ncv) := generated Hessenberg matrix |
431
c | workl(ncv*ncv+1:ncv*ncv+ncv) := ritz values |
432
c | workl(ncv*ncv+ncv+1:ncv*ncv+2*ncv) := error bounds |
433
c %--------------------------------------------------------%
434
c
435
c %-----------------------------------------------------------%
436
c | The following is used and set by CNEUPD. |
437
c | workl(ncv*ncv+2*ncv+1:ncv*ncv+3*ncv) := The untransformed |
438
c | Ritz values. |
439
c | workl(ncv*ncv+3*ncv+1:ncv*ncv+4*ncv) := The untransformed |
440
c | error bounds of |
441
c | the Ritz values |
442
c | workl(ncv*ncv+4*ncv+1:2*ncv*ncv+4*ncv) := Holds the upper |
443
c | triangular matrix |
444
c | for H. |
445
c | workl(2*ncv*ncv+4*ncv+1: 3*ncv*ncv+4*ncv) := Holds the |
446
c | associated matrix |
447
c | representation of |
448
c | the invariant |
449
c | subspace for H. |
450
c | GRAND total of NCV * ( 3 * NCV + 4 ) locations. |
451
c %-----------------------------------------------------------%
452
c
453
ih = ipntr(5)
454
ritz = ipntr(6)
455
iq = ipntr(7)
456
bounds = ipntr(8)
457
ldh = ncv
458
ldq = ncv
459
iheig = bounds + ldh
460
ihbds = iheig + ldh
461
iuptri = ihbds + ldh
462
invsub = iuptri + ldh*ncv
463
ipntr(9) = iheig
464
ipntr(11) = ihbds
465
ipntr(12) = iuptri
466
ipntr(13) = invsub
467
wr = 1
468
iwev = wr + ncv
469
c
470
c %-----------------------------------------%
471
c | irz points to the Ritz values computed |
472
c | by _neigh before exiting _naup2. |
473
c | ibd points to the Ritz estimates |
474
c | computed by _neigh before exiting |
475
c | _naup2. |
476
c %-----------------------------------------%
477
c
478
irz = ipntr(14) + ncv*ncv
479
ibd = irz + ncv
480
c
481
c %------------------------------------%
482
c | RNORM is B-norm of the RESID(1:N). |
483
c %------------------------------------%
484
c
485
rnorm = workl(ih+2)
486
workl(ih+2) = zero
487
c
488
if (msglvl .gt. 2) then
489
call pcvout(comm, logfil, ncv, workl(irz), ndigit,
490
& '_neupd: Ritz values passed in from _NAUPD.')
491
call pcvout(comm, logfil, ncv, workl(ibd), ndigit,
492
& '_neupd: Ritz estimates passed in from _NAUPD.')
493
end if
494
c
495
if (rvec) then
496
c
497
reord = .false.
498
c
499
c %---------------------------------------------------%
500
c | Use the temporary bounds array to store indices |
501
c | These will be used to mark the select array later |
502
c %---------------------------------------------------%
503
c
504
do 10 j = 1,ncv
505
workl(bounds+j-1) = j
506
select(j) = .false.
507
10 continue
508
c
509
c %-------------------------------------%
510
c | Select the wanted Ritz values. |
511
c | Sort the Ritz values so that the |
512
c | wanted ones appear at the tailing |
513
c | NEV positions of workl(irr) and |
514
c | workl(iri). Move the corresponding |
515
c | error estimates in workl(ibd) |
516
c | accordingly. |
517
c %-------------------------------------%
518
c
519
np = ncv - nev
520
ishift = 0
521
call pcngets(comm, ishift, which ,
522
& nev , np , workl(irz),
523
& workl(bounds))
524
c
525
if (msglvl .gt. 2) then
526
call pcvout(comm,logfil, ncv, workl(irz), ndigit,
527
& '_neupd: Ritz values after calling _NGETS.')
528
call pcvout(comm,logfil, ncv, workl(bounds), ndigit,
529
& '_neupd: Ritz value indices after calling _NGETS.')
530
end if
531
c
532
c %-----------------------------------------------------%
533
c | Record indices of the converged wanted Ritz values |
534
c | Mark the select array for possible reordering |
535
c %-----------------------------------------------------%
536
c
537
numcnv = 0
538
do 11 j = 1,ncv
539
rtemp = max(eps23,
540
& slapy2 ( real (workl(irz+ncv-j)),
541
& aimag(workl(irz+ncv-j)) ))
542
jj = workl(bounds + ncv - j)
543
if (numcnv .lt. nconv .and.
544
& slapy2( real (workl(ibd+jj-1)),
545
& aimag(workl(ibd+jj-1)) )
546
& .le. tol*rtemp) then
547
select(jj) = .true.
548
numcnv = numcnv + 1
549
if (jj .gt. nev) reord = .true.
550
endif
551
11 continue
552
c
553
c %-----------------------------------------------------------%
554
c | Check the count (numcnv) of converged Ritz values with |
555
c | the number (nconv) reported by dnaupd. If these two |
556
c | are different then there has probably been an error |
557
c | caused by incorrect passing of the dnaupd data. |
558
c %-----------------------------------------------------------%
559
c
560
if (msglvl .gt. 2) then
561
call pivout(comm, logfil, 1, [numcnv], ndigit,
562
& '_neupd: Number of specified eigenvalues')
563
call pivout(comm, logfil, 1, [nconv], ndigit,
564
& '_neupd: Number of "converged" eigenvalues')
565
end if
566
c
567
if (numcnv .ne. nconv) then
568
info = -15
569
go to 9000
570
end if
571
c
572
c %-------------------------------------------------------%
573
c | Call LAPACK routine clahqr to compute the Schur form |
574
c | of the upper Hessenberg matrix returned by PCNAUPD. |
575
c | Make a copy of the upper Hessenberg matrix. |
576
c | Initialize the Schur vector matrix Q to the identity. |
577
c %-------------------------------------------------------%
578
c
579
call ccopy(ldh*ncv, workl(ih), 1, workl(iuptri), 1)
580
call claset('All', ncv, ncv, zero, one, workl(invsub), ldq)
581
call clahqr(.true. , .true. , ncv ,
582
& 1 , ncv , workl(iuptri),
583
& ldh , workl(iheig) , 1 ,
584
& ncv , workl(invsub), ldq ,
585
& ierr )
586
call ccopy(ncv, workl(invsub+ncv-1), ldq, workl(ihbds), 1)
587
c
588
if (ierr .ne. 0) then
589
info = -8
590
go to 9000
591
end if
592
c
593
if (msglvl .gt. 1) then
594
call pcvout(comm, logfil, ncv, workl(iheig), ndigit,
595
& '_neupd: Eigenvalues of H')
596
call pcvout(comm, logfil, ncv, workl(ihbds), ndigit,
597
& '_neupd: Last row of the Schur vector matrix')
598
if (msglvl .gt. 3) then
599
call pcmout(comm, logfil, ncv, ncv,
600
& workl(iuptri), ldh, ndigit,
601
& '_neupd: The upper triangular matrix ')
602
end if
603
end if
604
if (reord) then
605
c
606
c %-----------------------------------------------%
607
c | Reorder the computed upper triangular matrix. |
608
c %-----------------------------------------------%
609
c
610
call ctrsen('None' , 'V' , select ,
611
& ncv , workl(iuptri), ldh ,
612
& workl(invsub), ldq , workl(iheig),
613
& nconv , conds , sep ,
614
& workev, ncv, ierr)
615
c
616
if (ierr .eq. 1) then
617
info = 1
618
go to 9000
619
end if
620
c
621
if (msglvl .gt. 2) then
622
call pcvout (comm, logfil, ncv, workl(iheig), ndigit,
623
& '_neupd: Eigenvalues of H--reordered')
624
if (msglvl .gt. 3) then
625
call pcmout (comm, logfil, ncv, ncv,
626
& workl(iuptri), ldq, ndigit,
627
& '_neupd: Triangular matrix after re-ordering')
628
end if
629
end if
630
end if
631
c
632
c %---------------------------------------------%
633
c | Copy the last row of the Schur basis matrix |
634
c | to workl(ihbds). This vector will be used |
635
c | to compute the Ritz estimates of converged |
636
c | Ritz values. |
637
c %---------------------------------------------%
638
c
639
call ccopy(ncv, workl(invsub+ncv-1), ldq, workl(ihbds), 1)
640
c
641
c %--------------------------------------------%
642
c | Place the computed eigenvalues of H into D |
643
c | if a spectral transformation was not used. |
644
c %--------------------------------------------%
645
c
646
if (type .eq. 'REGULR') then
647
call ccopy(nconv, workl(iheig), 1, d, 1)
648
end if
649
c
650
c %----------------------------------------------------------%
651
c | Compute the QR factorization of the matrix representing |
652
c | the wanted invariant subspace located in the first NCONV |
653
c | columns of workl(invsub,ldq). |
654
c %----------------------------------------------------------%
655
c
656
call cgeqr2(ncv, nconv , workl(invsub),
657
& ldq, workev, workev(ncv+1),
658
& ierr)
659
c
660
c %--------------------------------------------------------%
661
c | * Postmultiply V by Q using cunm2r. |
662
c | * Copy the first NCONV columns of VQ into Z. |
663
c | * Postmultiply Z by R. |
664
c | The N by NCONV matrix Z is now a matrix representation |
665
c | of the approximate invariant subspace associated with |
666
c | the Ritz values in workl(iheig). The first NCONV |
667
c | columns of V are now approximate Schur vectors |
668
c | associated with the upper triangular matrix of order |
669
c | NCONV in workl(iuptri). |
670
c %--------------------------------------------------------%
671
c
672
call cunm2r('Right', 'Notranspose', n ,
673
& ncv , nconv , workl(invsub),
674
& ldq , workev , v ,
675
& ldv , workd(n+1) , ierr )
676
call clacpy('All', n, nconv, v, ldv, z, ldz)
677
c
678
do 20 j=1, nconv
679
c
680
c %---------------------------------------------------%
681
c | Perform both a column and row scaling if the |
682
c | diagonal element of workl(invsub,ldq) is negative |
683
c | I'm lazy and don't take advantage of the upper |
684
c | triangular form of workl(iuptri,ldq). |
685
c | Note that since Q is orthogonal, R is a diagonal |
686
c | matrix consisting of plus or minus ones. |
687
c %---------------------------------------------------%
688
c
689
if ( real ( workl(invsub+(j-1)*ldq+j-1) ) .lt.
690
& real (zero) ) then
691
call cscal(nconv, -one, workl(iuptri+j-1), ldq)
692
call cscal(nconv, -one, workl(iuptri+(j-1)*ldq), 1)
693
end if
694
c
695
20 continue
696
c
697
if (howmny .eq. 'A') then
698
c
699
c %--------------------------------------------%
700
c | Compute the NCONV wanted eigenvectors of T |
701
c | located in workl(iuptri,ldq). |
702
c %--------------------------------------------%
703
c
704
do 30 j=1, ncv
705
if (j .le. nconv) then
706
select(j) = .true.
707
else
708
select(j) = .false.
709
end if
710
30 continue
711
c
712
call ctrevc('Right', 'Select' , select ,
713
& ncv , workl(iuptri), ldq ,
714
& vl , 1 , workl(invsub),
715
& ldq , ncv , outncv ,
716
& workev , rwork , ierr )
717
c
718
if (ierr .ne. 0) then
719
info = -9
720
go to 9000
721
end if
722
c
723
c %------------------------------------------------%
724
c | Scale the returning eigenvectors so that their |
725
c | Euclidean norms are all one. LAPACK subroutine |
726
c | ctrevc returns each eigenvector normalized so |
727
c | that the element of largest magnitude has |
728
c | magnitude 1. |
729
c %------------------------------------------------%
730
c
731
do 40 j=1, nconv
732
rtemp = scnrm2(ncv, workl(invsub+(j-1)*ldq), 1)
733
rtemp = real (one) / rtemp
734
call csscal ( ncv, rtemp,
735
& workl(invsub+(j-1)*ldq), 1 )
736
c
737
c %------------------------------------------%
738
c | Ritz estimates can be obtained by taking |
739
c | the inner product of the last row of the |
740
c | Schur basis of H with eigenvectors of T. |
741
c | Note that the eigenvector matrix of T is |
742
c | upper triangular, thus the length of the |
743
c | inner product can be set to j. |
744
c %------------------------------------------%
745
c
746
workev(j) = cdotc(j, workl(ihbds), 1,
747
& workl(invsub+(j-1)*ldq), 1)
748
40 continue
749
c
750
if (msglvl .gt. 2) then
751
call ccopy(nconv, workl(invsub+ncv-1), ldq,
752
& workl(ihbds), 1)
753
call pcvout(comm, logfil, nconv, workl(ihbds), ndigit,
754
& '_neupd: Last row of the eigenvector matrix for T')
755
if (msglvl .gt. 3) then
756
call pcmout(comm, logfil, nconv, ncv,
757
& workl(invsub), ldq, ndigit,
758
& '_neupd: The eigenvector matrix for T')
759
end if
760
end if
761
c
762
c %---------------------------------------%
763
c | Copy Ritz estimates into workl(ihbds) |
764
c %---------------------------------------%
765
c
766
call ccopy(nconv, workev, 1, workl(ihbds), 1)
767
c
768
c %----------------------------------------------%
769
c | The eigenvector matrix Q of T is triangular. |
770
c | Form Z*Q. |
771
c %----------------------------------------------%
772
c
773
call ctrmm('Right' , 'Upper' , 'No transpose',
774
& 'Non-unit', n , nconv ,
775
& one , workl(invsub), ldq ,
776
& z , ldz)
777
c
778
end if
779
c
780
else
781
c
782
c %--------------------------------------------------%
783
c | An approximate invariant subspace is not needed. |
784
c | Place the Ritz values computed PCNAUPD into D. |
785
c %--------------------------------------------------%
786
c
787
call ccopy(nconv, workl(ritz), 1, d, 1)
788
call ccopy(nconv, workl(ritz), 1, workl(iheig), 1)
789
call ccopy(nconv, workl(bounds), 1, workl(ihbds), 1)
790
c
791
end if
792
c
793
c %------------------------------------------------%
794
c | Transform the Ritz values and possibly vectors |
795
c | and corresponding error bounds of OP to those |
796
c | of A*x = lambda*B*x. |
797
c %------------------------------------------------%
798
c
799
if (type .eq. 'REGULR') then
800
c
801
if (rvec)
802
& call cscal(ncv, rnorm, workl(ihbds), 1)
803
c
804
else
805
c
806
c %---------------------------------------%
807
c | A spectral transformation was used. |
808
c | * Determine the Ritz estimates of the |
809
c | Ritz values in the original system. |
810
c %---------------------------------------%
811
c
812
if (rvec)
813
& call cscal(ncv, rnorm, workl(ihbds), 1)
814
c
815
do 50 k=1, ncv
816
temp = workl(iheig+k-1)
817
workl(ihbds+k-1) = workl(ihbds+k-1) / temp / temp
818
50 continue
819
c
820
end if
821
c
822
c %-----------------------------------------------------------%
823
c | * Transform the Ritz values back to the original system. |
824
c | For TYPE = 'SHIFTI' the transformation is |
825
c | lambda = 1/theta + sigma |
826
c | NOTES: |
827
c | *The Ritz vectors are not affected by the transformation. |
828
c %-----------------------------------------------------------%
829
c
830
if (type .eq. 'SHIFTI') then
831
do 60 k=1, nconv
832
d(k) = one / workl(iheig+k-1) + sigma
833
60 continue
834
end if
835
c
836
if (type .ne. 'REGULR' .and. msglvl .gt. 1) then
837
call pcvout (comm, logfil, nconv, d, ndigit,
838
& '_neupd: Untransformed Ritz values.')
839
call pcvout (comm, logfil, nconv, workl(ihbds), ndigit,
840
& '_neupd: Ritz estimates of the untransformed Ritz values.')
841
else if ( msglvl .gt. 1) then
842
call pcvout (comm, logfil, nconv, d, ndigit,
843
& '_neupd: Converged Ritz values.')
844
call pcvout (comm, logfil, nconv, workl(ihbds), ndigit,
845
& '_neupd: Associated Ritz estimates.')
846
end if
847
c
848
c %-------------------------------------------------%
849
c | Eigenvector Purification step. Formally perform |
850
c | one of inverse subspace iteration. Only used |
851
c | for MODE = 3. See reference 3. |
852
c %-------------------------------------------------%
853
c
854
if (rvec .and. howmny .eq. 'A' .and. type .eq. 'SHIFTI') then
855
c
856
c %------------------------------------------------%
857
c | Purify the computed Ritz vectors by adding a |
858
c | little bit of the residual vector: |
859
c | T |
860
c | resid(:)*( e s ) / theta |
861
c | NCV |
862
c | where H s = s theta. |
863
c %------------------------------------------------%
864
c
865
do 100 j=1, nconv
866
if (workl(iheig+j-1) .ne. zero) then
867
workev(j) = workl(invsub+(j-1)*ldq+ncv-1)
868
& / workl(iheig+j-1)
869
endif
870
100 continue
871
c %---------------------------------------%
872
c | Perform a rank one update to Z and |
873
c | purify all the Ritz vectors together. |
874
c %---------------------------------------%
875
c
876
call cgeru(n, nconv, one, resid, 1, workev, 1, z, ldz)
877
c
878
end if
879
c
880
9000 continue
881
c
882
return
883
c
884
c %----------------%
885
c | End of pcneupd |
886
c %----------------%
887
c
888
end
889
890