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