OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
pdtrsen.f
Go to the documentation of this file.
1 SUBROUTINE pdtrsen( JOB, COMPQ, SELECT, PARA, N, T, IT, JT,
2 $ DESCT, Q, IQ, JQ, DESCQ, WR, WI, M, S, SEP, WORK, LWORK,
3 $ IWORK, LIWORK, INFO )
4*
5* Contribution from the Department of Computing Science and HPC2N,
6* Umea University, Sweden
7*
8* -- ScaLAPACK computational routine (version 2.0.1) --
9* University of Tennessee, Knoxville, Oak Ridge National Laboratory,
10* Univ. of Colorado Denver and University of California, Berkeley.
11* January, 2012
12*
13 IMPLICIT NONE
14*
15* .. Scalar Arguments ..
16 CHARACTER COMPQ, JOB
17 INTEGER INFO, LIWORK, LWORK, M, N,
18 $ it, jt, iq, jq
19 DOUBLE PRECISION S, SEP
20* ..
21* .. Array Arguments ..
22 LOGICAL SELECT( N )
23 INTEGER PARA( 6 ), DESCT( * ), DESCQ( * ), IWORK( * )
24 DOUBLE PRECISION Q( * ), T( * ), WI( * ), WORK( * ), WR( * )
25* ..
26*
27* Purpose
28* =======
29*
30* PDTRSEN reorders the real Schur factorization of a real matrix
31* A = Q*T*Q**T, so that a selected cluster of eigenvalues appears
32* in the leading diagonal blocks of the upper quasi-triangular matrix
33* T, and the leading columns of Q form an orthonormal basis of the
34* corresponding right invariant subspace. The reordering is performed
35* by PDTRORD.
36*
37* Optionally the routine computes the reciprocal condition numbers of
38* the cluster of eigenvalues and/or the invariant subspace. SCASY
39* library is needed for condition estimation.
40*
41* T must be in Schur form (as returned by PDLAHQR), that is, block
42* upper triangular with 1-by-1 and 2-by-2 diagonal blocks.
43*
44* Notes
45* =====
46*
47* Each global data object is described by an associated description
48* vector. This vector stores the information required to establish
49* the mapping between an object element and its corresponding process
50* and memory location.
51*
52* Let A be a generic term for any 2D block cyclicly distributed array.
53* Such a global array has an associated description vector DESCA.
54* In the following comments, the character _ should be read as
55* "of the global array".
56*
57* NOTATION STORED IN EXPLANATION
58* --------------- -------------- --------------------------------------
59* DTYPE_A(global) DESCA( DTYPE_ )The descriptor type. In this case,
60* DTYPE_A = 1.
61* CTXT_A (global) DESCA( CTXT_ ) The BLACS context handle, indicating
62* the BLACS process grid A is distribu-
63* ted over. The context itself is glo-
64* bal, but the handle (the integer
65* value) may vary.
66* M_A (global) DESCA( M_ ) The number of rows in the global
67* array A.
68* N_A (global) DESCA( N_ ) The number of columns in the global
69* array A.
70* MB_A (global) DESCA( MB_ ) The blocking factor used to distribute
71* the rows of the array.
72* NB_A (global) DESCA( NB_ ) The blocking factor used to distribute
73* the columns of the array.
74* RSRC_A (global) DESCA( RSRC_ ) The process row over which the first
75* row of the array A is distributed.
76* CSRC_A (global) DESCA( CSRC_ ) The process column over which the
77* first column of the array A is
78* distributed.
79* LLD_A (local) DESCA( LLD_ ) The leading dimension of the local
80* array. LLD_A >= MAX(1,LOCr(M_A)).
81*
82* Let K be the number of rows or columns of a distributed matrix,
83* and assume that its process grid has dimension p x q.
84* LOCr( K ) denotes the number of elements of K that a process
85* would receive if K were distributed over the p processes of its
86* process column.
87* Similarly, LOCc( K ) denotes the number of elements of K that a
88* process would receive if K were distributed over the q processes of
89* its process row.
90* The values of LOCr() and LOCc() may be determined via a call to the
91* ScaLAPACK tool function, NUMROC:
92* LOCr( M ) = NUMROC( M, MB_A, MYROW, RSRC_A, NPROW ),
93* LOCc( N ) = NUMROC( N, NB_A, MYCOL, CSRC_A, NPCOL ).
94* An upper bound for these quantities may be computed by:
95* LOCr( M ) <= ceil( ceil(M/MB_A)/NPROW )*MB_A
96* LOCc( N ) <= ceil( ceil(N/NB_A)/NPCOL )*NB_A
97*
98* Arguments
99* =========
100*
101* JOB (global input) CHARACTER*1
102* Specifies whether condition numbers are required for the
103* cluster of eigenvalues (S) or the invariant subspace (SEP):
104* = 'N': none;
105* = 'E': for eigenvalues only (S);
106* = 'V': for invariant subspace only (SEP);
107* = 'B': for both eigenvalues and invariant subspace (S and
108* SEP).
109*
110* COMPQ (global input) CHARACTER*1
111* = 'V': update the matrix Q of Schur vectors;
112* = 'N': do not update Q.
113*
114* SELECT (global input) LOGICAL array, dimension (N)
115* SELECT specifies the eigenvalues in the selected cluster. To
116* select a real eigenvalue w(j), SELECT(j) must be set to
117* .TRUE.. To select a complex conjugate pair of eigenvalues
118* w(j) and w(j+1), corresponding to a 2-by-2 diagonal block,
119* either SELECT(j) or SELECT(j+1) or both must be set to
120* .TRUE.; a complex conjugate pair of eigenvalues must be
121* either both included in the cluster or both excluded.
122*
123* PARA (global input) INTEGER*6
124* Block parameters (some should be replaced by calls to
125* PILAENV and others by meaningful default values):
126* PARA(1) = maximum number of concurrent computational windows
127* allowed in the algorithm;
128* 0 < PARA(1) <= min(NPROW,NPCOL) must hold;
129* PARA(2) = number of eigenvalues in each window;
130* 0 < PARA(2) < PARA(3) must hold;
131* PARA(3) = window size; PARA(2) < PARA(3) < DESCT(MB_)
132* must hold;
133* PARA(4) = minimal percentage of flops required for
134* performing matrix-matrix multiplications instead
135* of pipelined orthogonal transformations;
136* 0 <= PARA(4) <= 100 must hold;
137* PARA(5) = width of block column slabs for row-wise
138* application of pipelined orthogonal
139* transformations in their factorized form;
140* 0 < PARA(5) <= DESCT(MB_) must hold.
141* PARA(6) = the maximum number of eigenvalues moved together
142* over a process border; in practice, this will be
143* approximately half of the cross border window size
144* 0 < PARA(6) <= PARA(2) must hold;
145*
146* N (global input) INTEGER
147* The order of the globally distributed matrix T. N >= 0.
148*
149* T (local input/output) DOUBLE PRECISION array,
150* dimension (LLD_T,LOCc(N)).
151* On entry, the local pieces of the global distributed
152* upper quasi-triangular matrix T, in Schur form. On exit, T is
153* overwritten by the local pieces of the reordered matrix T,
154* again in Schur form, with the selected eigenvalues in the
155* globally leading diagonal blocks.
156*
157* IT (global input) INTEGER
158* JT (global input) INTEGER
159* The row and column index in the global array T indicating the
160* first column of sub( T ). IT = JT = 1 must hold.
161*
162* DESCT (global and local input) INTEGER array of dimension DLEN_.
163* The array descriptor for the global distributed matrix T.
164*
165* Q (local input/output) DOUBLE PRECISION array,
166* dimension (LLD_Q,LOCc(N)).
167* On entry, if COMPQ = 'V', the local pieces of the global
168* distributed matrix Q of Schur vectors.
169* On exit, if COMPQ = 'V', Q has been postmultiplied by the
170* global orthogonal transformation matrix which reorders T; the
171* leading M columns of Q form an orthonormal basis for the
172* specified invariant subspace.
173* If COMPQ = 'N', Q is not referenced.
174*
175* IQ (global input) INTEGER
176* JQ (global input) INTEGER
177* The column index in the global array Q indicating the
178* first column of sub( Q ). IQ = JQ = 1 must hold.
179*
180* DESCQ (global and local input) INTEGER array of dimension DLEN_.
181* The array descriptor for the global distributed matrix Q.
182*
183* WR (global output) DOUBLE PRECISION array, dimension (N)
184* WI (global output) DOUBLE PRECISION array, dimension (N)
185* The real and imaginary parts, respectively, of the reordered
186* eigenvalues of T. The eigenvalues are in principle stored in
187* the same order as on the diagonal of T, with WR(i) = T(i,i)
188* and, if T(i:i+1,i:i+1) is a 2-by-2 diagonal block, WI(i) > 0
189* and WI(i+1) = -WI(i).
190* Note also that if a complex eigenvalue is sufficiently
191* ill-conditioned, then its value may differ significantly
192* from its value before reordering.
193*
194* M (global output) INTEGER
195* The dimension of the specified invariant subspace.
196* 0 <= M <= N.
197*
198* S (global output) DOUBLE PRECISION
199* If JOB = 'E' or 'B', S is a lower bound on the reciprocal
200* condition number for the selected cluster of eigenvalues.
201* S cannot underestimate the true reciprocal condition number
202* by more than a factor of sqrt(N). If M = 0 or N, S = 1.
203* If JOB = 'N' or 'V', S is not referenced.
204*
205* SEP (global output) DOUBLE PRECISION
206* If JOB = 'V' or 'B', SEP is the estimated reciprocal
207* condition number of the specified invariant subspace. If
208* M = 0 or N, SEP = norm(T).
209* If JOB = 'N' or 'E', SEP is not referenced.
210*
211* WORK (local workspace/output) DOUBLE PRECISION array,
212* dimension (LWORK)
213* On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
214*
215* LWORK (local input) INTEGER
216* The dimension of the array WORK.
217*
218* If LWORK = -1, then a workspace query is assumed; the routine
219* only calculates the optimal size of the WORK array, returns
220* this value as the first entry of the WORK array, and no error
221* message related to LWORK is issued by PXERBLA.
222*
223* IWORK (local workspace/output) INTEGER array, dimension (LIWORK)
224*
225* LIWORK (local input) INTEGER
226* The dimension of the array IWORK.
227*
228* If LIWORK = -1, then a workspace query is assumed; the
229* routine only calculates the optimal size of the IWORK array,
230* returns this value as the first entry of the IWORK array, and
231* no error message related to LIWORK is issued by PXERBLA.
232*
233* INFO (global output) INTEGER
234* = 0: successful exit
235* < 0: if INFO = -i, the i-th argument had an illegal value.
236* If the i-th argument is an array and the j-entry had
237* an illegal value, then INFO = -(i*1000+j), if the i-th
238* argument is a scalar and had an illegal value, then INFO = -i.
239* > 0: here we have several possibilites
240* *) Reordering of T failed because some eigenvalues are too
241* close to separate (the problem is very ill-conditioned);
242* T may have been partially reordered, and WR and WI
243* contain the eigenvalues in the same order as in T.
244* On exit, INFO = {the index of T where the swap failed}.
245* *) A 2-by-2 block to be reordered split into two 1-by-1
246* blocks and the second block failed to swap with an
247* adjacent block.
248* On exit, INFO = {the index of T where the swap failed}.
249* *) If INFO = N+1, there is no valid BLACS context (see the
250* BLACS documentation for details).
251* *) If INFO = N+2, the routines used in the calculation of
252* the condition numbers raised a positive warning flag
253* (see the documentation for PGESYCTD and PSYCTCON of the
254* SCASY library).
255* *) If INFO = N+3, PGESYCTD raised an input error flag;
256* please report this bug to the authors (see below).
257* If INFO = N+4, PSYCTCON raised an input error flag;
258* please report this bug to the authors (see below).
259* In a future release this subroutine may distinguish between
260* the case 1 and 2 above.
261*
262* Method
263* ======
264*
265* This routine performs parallel eigenvalue reordering in real Schur
266* form by parallelizing the approach proposed in [3]. The condition
267* number estimation part is performed by using techniques and code
268* from SCASY, see http://www.cs.umu.se/research/parallel/scasy.
269*
270* Additional requirements
271* =======================
272*
273* The following alignment requirements must hold:
274* (a) DESCT( MB_ ) = DESCT( NB_ ) = DESCQ( MB_ ) = DESCQ( NB_ )
275* (b) DESCT( RSRC_ ) = DESCQ( RSRC_ )
276* (c) DESCT( CSRC_ ) = DESCQ( CSRC_ )
277*
278* All matrices must be blocked by a block factor larger than or
279* equal to two (3). This to simplify reordering across processor
280* borders in the presence of 2-by-2 blocks.
281*
282* Limitations
283* ===========
284*
285* This algorithm cannot work on submatrices of T and Q, i.e.,
286* IT = JT = IQ = JQ = 1 must hold. This is however no limitation
287* since PDLAHQR does not compute Schur forms of submatrices anyway.
288*
289* References
290* ==========
291*
292* [1] Z. Bai and J. W. Demmel; On swapping diagonal blocks in real
293* Schur form, Linear Algebra Appl., 186:73--95, 1993. Also as
294* LAPACK Working Note 54.
295*
296* [2] Z. Bai, J. W. Demmel, and A. McKenney; On computing condition
297* numbers for the nonsymmetric eigenvalue problem, ACM Trans.
298* Math. Software, 19(2):202--223, 1993. Also as LAPACK Working
299* Note 13.
300*
301* [3] D. Kressner; Block algorithms for reordering standard and
302* generalized Schur forms, ACM TOMS, 32(4):521-532, 2006.
303* Also LAPACK Working Note 171.
304*
305* [4] R. Granat, B. Kagstrom, and D. Kressner; Parallel eigenvalue
306* reordering in real Schur form, Concurrency and Computations:
307* Practice and Experience, 21(9):1225-1250, 2009. Also as
308* LAPACK Working Note 192.
309*
310* Parallel execution recommendations
311* ==================================
312*
313* Use a square grid, if possible, for maximum performance. The block
314* parameters in PARA should be kept well below the data distribution
315* block size. In particular, see [3,4] for recommended settings for
316* these parameters.
317*
318* In general, the parallel algorithm strives to perform as much work
319* as possible without crossing the block borders on the main block
320* diagonal.
321*
322* Contributors
323* ============
324*
325* Implemented by Robert Granat, Dept. of Computing Science and HPC2N,
326* Umea University, Sweden, March 2007,
327* in collaboration with Bo Kagstrom and Daniel Kressner.
328* Modified by Meiyue Shao, October 2011.
329*
330* Revisions
331* =========
332*
333* Please send bug-reports to granat@cs.umu.se
334*
335* Keywords
336* ========
337*
338* Real Schur form, eigenvalue reordering, Sylvester matrix equation
339*
340* =====================================================================
341* ..
342* .. Parameters ..
343 CHARACTER TOP
344 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
345 $ lld_, mb_, m_, nb_, n_, rsrc_
346 DOUBLE PRECISION ZERO, ONE
347 PARAMETER ( TOP = '1-Tree',
348 $ block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
349 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
350 $ rsrc_ = 7, csrc_ = 8, lld_ = 9,
351 $ zero = 0.0d+0, one = 1.0d+0 )
352* ..
353* .. Local Scalars ..
354 LOGICAL LQUERY, WANTBH, WANTQ, WANTS, WANTSP
355 INTEGER ICOFFT12, ICTXT, IDUM1, IDUM2, IERR, ILOC1,
356 $ ipw1, iter, itt, jloc1, jtt, k, liwmin, lldt,
357 $ lldq, lwmin, myrow, mycol, n1, n2,
358 $ nb, noexsy, npcol, nprocs, nprow, space,
359 $ t12rows, t12cols, tcols, tcsrc, trows, trsrc,
360 $ wrk1, iwrk1, wrk2, iwrk2, wrk3, iwrk3
361 DOUBLE PRECISION ELEM, EST, SCALE, RNORM
362* .. Local Arrays ..
363 INTEGER DESCT12( DLEN_ ), MBNB2( 2 ), MMAX( 1 ),
364 $ MMIN( 1 )
365 DOUBLE PRECISION DPDUM1( 1 )
366* ..
367* .. External Functions ..
368 LOGICAL LSAME
369 INTEGER NUMROC
370 DOUBLE PRECISION PDLANGE
371 EXTERNAL lsame, numroc, pdlange
372* ..
373* .. External Subroutines ..
375 $ igamx2d, infog2l, pdlacpy, pdtrord, pxerbla,
377* $ , PGESYCTD, PSYCTCON
378* ..
379* .. Intrinsic Functions ..
380 INTRINSIC max, min, sqrt
381* ..
382* .. Executable Statements ..
383*
384* Get grid parameters
385*
386 ictxt = desct( ctxt_ )
387 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
388 nprocs = nprow*npcol
389*
390* Test if grid is O.K., i.e., the context is valid
391*
392 info = 0
393 IF( nprow.EQ.-1 ) THEN
394 info = n+1
395 END IF
396*
397* Check if workspace
398*
399 lquery = lwork.EQ.-1 .OR. liwork.EQ.-1
400*
401* Test dimensions for local sanity
402*
403 IF( info.EQ.0 ) THEN
404 CALL chk1mat( n, 5, n, 5, it, jt, desct, 9, info )
405 END IF
406 IF( info.EQ.0 ) THEN
407 CALL chk1mat( n, 5, n, 5, iq, jq, descq, 13, info )
408 END IF
409*
410* Check the blocking sizes for alignment requirements
411*
412 IF( info.EQ.0 ) THEN
413 IF( desct( mb_ ).NE.desct( nb_ ) ) info = -(1000*9 + mb_)
414 END IF
415 IF( info.EQ.0 ) THEN
416 IF( descq( mb_ ).NE.descq( nb_ ) ) info = -(1000*13 + mb_)
417 END IF
418 IF( info.EQ.0 ) THEN
419 IF( desct( mb_ ).NE.descq( mb_ ) ) info = -(1000*9 + mb_)
420 END IF
421*
422* Check the blocking sizes for minimum sizes
423*
424 IF( info.EQ.0 ) THEN
425 IF( n.NE.desct( mb_ ) .AND. desct( mb_ ).LT.3 )
426 $ info = -(1000*9 + mb_)
427 IF( n.NE.descq( mb_ ) .AND. descq( mb_ ).LT.3 )
428 $ info = -(1000*13 + mb_)
429 END IF
430*
431* Check parameters in PARA
432*
433 nb = desct( mb_ )
434 IF( info.EQ.0 ) THEN
435 IF( para(1).LT.1 .OR. para(1).GT.min(nprow,npcol) )
436 $ info = -(1000 * 4 + 1)
437 IF( para(2).LT.1 .OR. para(2).GE.para(3) )
438 $ info = -(1000 * 4 + 2)
439 IF( para(3).LT.1 .OR. para(3).GT.nb )
440 $ info = -(1000 * 4 + 3)
441 IF( para(4).LT.0 .OR. para(4).GT.100 )
442 $ info = -(1000 * 4 + 4)
443 IF( para(5).LT.1 .OR. para(5).GT.nb )
444 $ info = -(1000 * 4 + 5)
445 IF( para(6).LT.1 .OR. para(6).GT.para(2) )
446 $ info = -(1000 * 4 + 6)
447 END IF
448*
449* Check requirements on IT, JT, IQ and JQ
450*
451 IF( info.EQ.0 ) THEN
452 IF( it.NE.1 ) info = -7
453 IF( jt.NE.it ) info = -8
454 IF( iq.NE.1 ) info = -11
455 IF( jq.NE.iq ) info = -12
456 END IF
457*
458* Test input parameters for global sanity
459*
460 IF( info.EQ.0 ) THEN
461 CALL pchk1mat( n, 5, n, 5, it, jt, desct, 9, 0, idum1,
462 $ idum2, info )
463 END IF
464 IF( info.EQ.0 ) THEN
465 CALL pchk1mat( n, 5, n, 5, iq, jq, descq, 13, 0, idum1,
466 $ idum2, info )
467 END IF
468 IF( info.EQ.0 ) THEN
469 CALL pchk2mat( n, 5, n, 5, it, jt, desct, 9, n, 5, n, 5,
470 $ iq, jq, descq, 13, 0, idum1, idum2, info )
471 END IF
472*
473* Decode and test the input parameters
474*
475 IF( info.EQ.0 .OR. lquery ) THEN
476 wantbh = lsame( job, 'B' )
477 wants = lsame( job, 'E' ) .OR. wantbh
478 wantsp = lsame( job, 'v.OR.' ) WANTBH
479 WANTQ = LSAME( COMPQ, 'v' )
480*
481.NOT. IF( LSAME( JOB, 'n.AND..NOT..AND..NOT.' ) WANTS WANTSP )
482 $ THEN
483 INFO = -1
484.NOT. ELSEIF( LSAME( COMPQ, 'n.AND..NOT.' ) WANTQ ) THEN
485 INFO = -2
486.LT. ELSEIF( N0 ) THEN
487 INFO = -4
488 ELSE
489*
490* Extract local leading dimension
491*
492 LLDT = DESCT( LLD_ )
493 LLDQ = DESCQ( LLD_ )
494*
495* Check the SELECT vector for consistency and set M to the
496* dimension of the specified invariant subspace.
497*
498 M = 0
499 DO 10 K = 1, N
500*
501* IWORK(1:N) is an integer copy of SELECT.
502*
503 IF( SELECT(K) ) THEN
504 IWORK(K) = 1
505 ELSE
506 IWORK(K) = 0
507 END IF
508.LT. IF( KN ) THEN
509 CALL INFOG2L( K+1, K, DESCT, NPROW, NPCOL,
510 $ MYROW, MYCOL, ITT, JTT, TRSRC, TCSRC )
511.EQ..AND..EQ. IF( MYROWTRSRC MYCOLTCSRC ) THEN
512 ELEM = T( (JTT-1)*LLDT + ITT )
513.NE. IF( ELEMZERO ) THEN
514.AND..NOT. IF( SELECT(K) SELECT(K+1) ) THEN
515* INFO = -3
516 IWORK(K+1) = 1
517.NOT..AND. ELSEIF( SELECT(K) SELECT(K+1) ) THEN
518* INFO = -3
519 IWORK(K) = 1
520 END IF
521 END IF
522 END IF
523 END IF
524 IF( SELECT(K) ) M = M + 1
525 10 CONTINUE
526 MMAX( 1 ) = M
527 MMIN( 1 ) = M
528.GT. IF( NPROCS1 )
529 $ CALL IGAMX2D( ICTXT, 'all', TOP, 1, 1, MMAX( 1 ), 1,
530 $ -1, -1, -1, -1, -1 )
531.GT. IF( NPROCS1 )
532 $ CALL IGAMN2D( ICTXT, 'all', TOP, 1, 1, MMIN( 1 ), 1,
533 $ -1, -1, -1, -1, -1 )
534.GT. IF( MMAX( 1 )MMIN( 1 ) ) THEN
535 M = MMAX( 1 )
536.GT. IF( NPROCS1 )
537 $ CALL IGAMX2D( ICTXT, 'all', TOP, N, 1, IWORK, N,
538 $ -1, -1, -1, -1, -1 )
539 END IF
540*
541* Set parameters for deep pipelining in parallel
542* Sylvester solver.
543*
544 MBNB2( 1 ) = MIN( MAX( PARA( 3 ), PARA( 2 )*2 ), NB )
545 MBNB2( 2 ) = MBNB2( 1 )
546*
547* Compute needed workspace
548*
549 N1 = M
550 N2 = N - M
551 IF( WANTS ) THEN
552c CALL PGESYCTD( 'Solve', 'Schur', 'Schur', 'Notranspose',
553c $ 'Notranspose', -1, 'Demand', N1, N2, T, 1, 1, DESCT,
554c $ T, N1+1, N1+1, DESCT, T, 1, N1+1, DESCT, MBNB2,
555c $ WORK, -1, IWORK(N+1), -1, NOEXSY, SCALE, IERR )
556 WRK1 = INT(WORK(1))
557 IWRK1 = IWORK(N+1)
558 WRK1 = 0
559 IWRK1 = 0
560 ELSE
561 WRK1 = 0
562 IWRK1 = 0
563 END IF
564*
565 IF( WANTSP ) THEN
566c CALL PSYCTCON( 'Notranspose', 'Notranspose', -1,
567c $ 'Demand', N1, N2, T, 1, 1, DESCT, T, N1+1, N1+1,
568c $ DESCT, MBNB2, WORK, -1, IWORK(N+1), -1, EST, ITER,
569c $ IERR )
570 WRK2 = INT(WORK(1))
571 IWRK2 = IWORK(N+1)
572 WRK2 = 0
573 IWRK2 = 0
574 ELSE
575 WRK2 = 0
576 IWRK2 = 0
577 END IF
578*
579 TROWS = NUMROC( N, NB, MYROW, DESCT(RSRC_), NPROW )
580 TCOLS = NUMROC( N, NB, MYCOL, DESCT(CSRC_), NPCOL )
581 WRK3 = N + 7*NB**2 + 2*TROWS*PARA( 3 ) + TCOLS*PARA( 3 ) +
582 $ MAX( TROWS*PARA( 3 ), TCOLS*PARA( 3 ) )
583 IWRK3 = 5*PARA( 1 ) + PARA(2)*PARA(3) -
584 $ PARA(2) * (PARA(2) + 1 ) / 2
585*
586 IF( WANTSP ) THEN
587 LWMIN = MAX( 1, MAX( WRK2, WRK3) )
588 LIWMIN = MAX( 1, MAX( IWRK2, IWRK3 ) )+N
589 ELSE IF( LSAME( JOB, 'n' ) ) THEN
590 LWMIN = MAX( 1, WRK3 )
591 LIWMIN = IWRK3+N
592 ELSE IF( LSAME( JOB, 'e' ) ) THEN
593 LWMIN = MAX( 1, MAX( WRK1, WRK3) )
594 LIWMIN = MAX( 1, MAX( IWRK1, IWRK3 ) )+N
595 END IF
596*
597.LT..AND..NOT. IF( LWORKLWMIN LQUERY ) THEN
598 INFO = -20
599.LT..AND..NOT. ELSE IF( LIWORKLIWMIN LQUERY ) THEN
600 INFO = -22
601 END IF
602 END IF
603 END IF
604*
605* Global maximum on info
606*
607.GT. IF( NPROCS1 )
608 $ CALL IGAMX2D( ICTXT, 'all', TOP, 1, 1, INFO, 1, -1, -1, -1,
609 $ -1, -1 )
610*
611* Return if some argument is incorrect
612*
613.NE..AND..NOT. IF( INFO0 LQUERY ) THEN
614 M = 0
615 S = ONE
616 SEP = ZERO
617 CALL PXERBLA( ICTXT, 'pdtrsen', -INFO )
618 RETURN
619 ELSEIF( LQUERY ) THEN
620 WORK( 1 ) = DBLE(LWMIN)
621 IWORK( 1 ) = LIWMIN
622 RETURN
623 END IF
624*
625* Quick return if possible.
626*
627.EQ..OR..EQ. IF( MN M0 ) THEN
628 IF( WANTS )
629 $ S = ONE
630 IF( WANTSP )
631 $ SEP = PDLANGE( '1', N, N, T, IT, JT, DESCT, WORK )
632 GO TO 50
633 END IF
634*
635* Reorder the eigenvalues.
636*
637 CALL PDTRORD( COMPQ, IWORK, PARA, N, T, IT, JT,
638 $ DESCT, Q, IQ, JQ, DESCQ, WR, WI, M, WORK, LWORK,
639 $ IWORK(N+1), LIWORK-N, INFO )
640*
641 IF( WANTS ) THEN
642*
643* Solve Sylvester equation T11*R - R*T2 = scale*T12 for R in
644* parallel.
645*
646* Copy T12 to workspace.
647*
648 CALL INFOG2L( 1, N1+1, DESCT, NPROW, NPCOL, MYROW,
649 $ MYCOL, ILOC1, JLOC1, TRSRC, TCSRC )
650 ICOFFT12 = MOD( N1, NB )
651 T12ROWS = NUMROC( N1, NB, MYROW, TRSRC, NPROW )
652 T12COLS = NUMROC( N2+ICOFFT12, NB, MYCOL, TCSRC, NPCOL )
653 CALL DESCINIT( DESCT12, N1, N2+ICOFFT12, NB, NB, TRSRC,
654 $ TCSRC, ICTXT, MAX(1,T12ROWS), IERR )
655 CALL PDLACPY( 'all', N1, N2, T, 1, N1+1, DESCT, WORK,
656 $ 1, 1+ICOFFT12, DESCT12 )
657*
658* Solve the equation to get the solution in workspace.
659*
660 SPACE = DESCT12( LLD_ ) * T12COLS
661 IPW1 = 1 + SPACE
662c CALL PGESYCTD( 'Solve', 'Schur', 'Schur', 'Notranspose',
663c $ 'Notranspose', -1, 'Demand', N1, N2, T, 1, 1, DESCT, T,
664c $ N1+1, N1+1, DESCT, WORK, 1, 1+ICOFFT12, DESCT12, MBNB2,
665c $ WORK(IPW1), LWORK-SPACE+1, IWORK(N+1), LIWORK-N, NOEXSY,
666c $ SCALE, IERR )
667.LT. IF( IERR0 ) THEN
668 INFO = N+3
669 ELSE
670 INFO = N+2
671 END IF
672*
673* Estimate the reciprocal of the condition number of the cluster
674* of eigenvalues.
675*
676 RNORM = PDLANGE( 'frobenius', N1, N2, WORK, 1, 1+ICOFFT12,
677 $ DESCT12, DPDUM1 )
678.EQ. IF( RNORMZERO ) THEN
679 S = ONE
680 ELSE
681 S = SCALE / ( SQRT( SCALE*SCALE / RNORM+RNORM )*
682 $ SQRT( RNORM ) )
683 END IF
684 END IF
685*
686 IF( WANTSP ) THEN
687*
688* Estimate sep(T11,T21) in parallel.
689*
690c CALL PSYCTCON( 'Notranspose', 'Notranspose', -1, 'Demand', N1,
691c $ N2, T, 1, 1, DESCT, T, N1+1, N1+1, DESCT, MBNB2, WORK,
692c $ LWORK, IWORK(N+1), LIWORK-N, EST, ITER, IERR )
693 EST = EST * SQRT(DBLE(N1*N2))
694 SEP = ONE / EST
695.LT. IF( IERR0 ) THEN
696 INFO = N+4
697 ELSE
698 INFO = N+2
699 END IF
700 END IF
701*
702* Return to calling program.
703*
704 50 CONTINUE
705*
706 RETURN
707*
708* End of PDTRSEN
709*
710 END
711*
#define min(a, b)
Definition macros.h:20
#define max(a, b)
Definition macros.h:21
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
Definition mpi.f:1577
subroutine pxerbla(contxt, srname, info)
Definition mpi.f:1600
subroutine pchk2mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, mb, mbpos0, nb, nbpos0, ib, jb, descb, descbpos0, nextra, ex, expos, info)
Definition mpi.f:1588
subroutine infog2l(grindx, gcindx, desc, nprow, npcol, myrow, mycol, lrindx, lcindx, rsrc, csrc)
Definition mpi.f:937
subroutine descinit(desc, m, n, mb, nb, irsrc, icsrc, ictxt, lld, info)
Definition mpi.f:777
subroutine blacs_gridinfo(cntxt, nprow, npcol, myrow, mycol)
Definition mpi.f:754
subroutine pchk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, nextra, ex, expos, info)
Definition pchkxmat.f:3
subroutine pdlacpy(uplo, m, n, a, ia, ja, desca, b, ib, jb, descb)
Definition pdlacpy.f:3
subroutine pdtrord(compq, select, para, n, t, it, jt, desct, q, iq, jq, descq, wr, wi, m, work, lwork, iwork, liwork, info)
Definition pdtrord.f:4
subroutine pdtrsen(job, compq, select, para, n, t, it, jt, desct, q, iq, jq, descq, wr, wi, m, s, sep, work, lwork, iwork, liwork, info)
Definition pdtrsen.f:4