|
|
| |
| # lines: |
268 | | # code: |
268 | | # comment: | 0 | |
# blank: | 0 |
| # Variables: | 46 |
| # Callers: | 2 |
| # Callings: | 2 |
| # Words: | 172 |
| # Keywords: | 112 |
|
|
|
|
|
..
.. Array Arguments ..
..
Purpose
=======
PDSTEDC computes all eigenvalues and eigenvectors of a
symmetric tridiagonal matrix in parallel, using the divide and
conquer algorithm.
This code makes very mild assumptions about floating point
arithmetic. It will work on machines with a guard digit in
add/subtract, or on those binary machines without guard digits
which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or Cray-2.
It could conceivably fail on hexadecimal or decimal machines
without guard digits, but we know of none. See DLAED3 for details.
Arguments
=========
COMPZ (input) CHARACTER*1
= 'N': Compute eigenvalues only. (NOT IMPLEMENTED YET)
= 'I': Compute eigenvectors of tridiagonal matrix also.
= 'V': Compute eigenvectors of original dense symmetric
matrix also. On entry, Z contains the orthogonal
matrix used to reduce the original matrix to
tridiagonal form. (NOT IMPLEMENTED YET)
N (global input) INTEGER
The order of the tridiagonal matrix T. N >= 0.
D (global input/output) DOUBLE PRECISION array, dimension (N)
On entry, the diagonal elements of the tridiagonal matrix.
On exit, if INFO = 0, the eigenvalues in descending order.
E (global input/output) DOUBLE PRECISION array, dimension (N-1)
On entry, the subdiagonal elements of the tridiagonal matrix.
On exit, E has been destroyed.
Q (local output) DOUBLE PRECISION array,
local dimension ( LLD_Q, LOCc(JQ+N-1))
Q contains the orthonormal eigenvectors of the symmetric
tridiagonal matrix.
On output, Q is distributed across the P processes in block
cyclic format.
IQ (global input) INTEGER
Q's global row index, which points to the beginning of the
submatrix which is to be operated on.
JQ (global input) INTEGER
Q's global column index, which points to the beginning of
the submatrix which is to be operated on.
DESCQ (global and local input) INTEGER array of dimension DLEN_.
The array descriptor for the distributed matrix Z.
WORK (local workspace/output) DOUBLE PRECISION array,
dimension (LWORK)
On output, WORK(1) returns the workspace needed.
LWORK (local input/output) INTEGER,
the dimension of the array WORK.
LWORK = 6*N + 2*NP*NQ
NP = NUMROC( N, NB, MYROW, DESCQ( RSRC_ ), NPROW )
NQ = NUMROC( N, NB, MYCOL, DESCQ( CSRC_ ), NPCOL )
If LWORK = -1, the LWORK is global input and a workspace
query is assumed; the routine only calculates the minimum
size for the WORK array. The required workspace is returned
as the first element of WORK and no error message is issued
by PXERBLA.
IWORK (local workspace/output) INTEGER array, dimension (LIWORK)
On exit, if LIWORK > 0, IWORK(1) returns the optimal LIWORK.
LIWORK (input) INTEGER
The dimension of the array IWORK.
LIWORK = 2 + 7*N + 8*NPCOL
INFO (global output) INTEGER
= 0: successful exit
< 0: If the i-th argument is an array and the j-entry had
an illegal value, then INFO = -(i*100+j), if the i-th
argument is a scalar and had an illegal value, then
INFO = -i.
> 0: The algorithm failed to compute the INFO/(N+1) th
eigenvalue while working on the submatrix lying in
global rows and columns mod(INFO,N+1).
Further Details
======= =======
Contributed by Francoise Tisseur, University of Manchester.
Reference: F. Tisseur and J. Dongarra, "A Parallel Divide and
Conquer Algorithm for the Symmetric Eigenvalue Problem
on Distributed Memory Architectures",
SIAM J. Sci. Comput., 6:20 (1999), pp. 2223--2236.
(see also LAPACK Working Note 132)
http://www.netlib.org/lapack/lawns/lawn132.ps
=====================================================================
.. Parameters ..
|
|
|
|
001 SUBROUTINE PDSTEDC( COMPZ , N , D , E , Q , IQ , JQ , DESCQ , WORK , LWORK ,
002 $IWORK , LIWORK , INFO )
003
004 * -- ScaLAPACK routine(version 1.7) --
005 * University of Tennessee , Knoxville , Oak Ridge National Laboratory ,
006 * and University of California , Berkeley.
007 * March 13 , 2000
008
009 * .. Scalar Arguments ..
010 CHARACTER COMPZ
011 INTEGER INFO , IQ , JQ , LIWORK , LWORK , N
012 INTEGER BLOCK_CYCLIC_2D , DLEN_ , DTYPE_ , CTXT_ , M_ , N_ ,
013 $MB_ , NB_ , RSRC_ , CSRC_ , LLD_
014 PARAMETER( BLOCK_CYCLIC_2D = 1 , DLEN_ = 9 , DTYPE_ = 1 ,
015 $CTXT_ = 2 , M_ = 3 , N_ = 4 , MB_ = 5 , NB_ = 6 ,
016 $RSRC_ = 7 , CSRC_ = 8 , LLD_ = 9 )
017 DOUBLE PRECISION ZERO , ONE
018 PARAMETER( ZERO = 0.0D + 0 , ONE = 1.0D + 0 )
019 * ..
020 * .. Local Scalars ..
021 LOGICAL LQUERY
022 INTEGER ICOFFQ , IIQ , IPQ , IQCOL , IQROW , IROFFQ , JJQ ,
023 $LDQ , LIWMIN , LWMIN , MYCOL , MYROW , NB , NP ,
024 $NPCOL , NPROW , NQ
025 DOUBLE PRECISION ORGNRM
026 * ..
027 * .. External Functions ..
028 LOGICAL LSAME
029 INTEGER INDXG2P , NUMROC
030 DOUBLE PRECISION DLANST
031 EXTERNAL INDXG2P , LSAME , NUMROC , DLANST
032 * ..
033 * .. External Subroutines ..
034 EXTERNAL BLACS_GRIDINFO , CHK1MAT , DLASCL , DSTEDC ,
035 $INFOG2L , PDLAED0 , PDLASRT , PXERBLA
036 * ..
037 * .. Intrinsic Functions ..
038 INTRINSIC DBLE , MOD
039 * ..
040 * .. Executable Statements ..
041
042 * This is just to keep ftnchek and toolpack / 1 happy
043 IF( BLOCK_CYCLIC_2D*CSRC_*CTXT_*DLEN_*DTYPE_*LLD_*MB_*M_*NB_*N_*
043
044 $ RSRC_.LT.0 )RETURN
045
046 * Test the input parameters.
047
048 CALL BLACS_GRIDINFO( DESCQ( CTXT_ ) , NPROW , NPCOL , MYROW , MYCOL )
049 LDQ = DESCQ( LLD_ )
050 NB = DESCQ( NB_ )
051 NP = NUMROC( N , NB , MYROW , DESCQ( RSRC_ ) , NPROW )
052 NQ = NUMROC( N , NB , MYCOL , DESCQ( CSRC_ ) , NPCOL )
053 INFO = 0
054 IF( NPROW.EQ. - 1 ) THEN
054
055 INFO = - ( 600 + CTXT_ )
056 ELSE
056
057 CALL CHK1MAT( N , 2 , N , 2 , IQ , JQ , DESCQ , 8 , INFO )
058 IF( INFO.EQ.0 ) THEN
058
059 NB = DESCQ( NB_ )
060 IROFFQ = MOD( IQ - 1 , DESCQ( MB_ ) )
061 ICOFFQ = MOD( JQ - 1 , DESCQ( NB_ ) )
062 IQROW = INDXG2P( IQ , NB , MYROW , DESCQ( RSRC_ ) , NPROW )
063 IQCOL = INDXG2P( JQ , NB , MYCOL , DESCQ( CSRC_ ) , NPCOL )
064 LWMIN = 6*N + 2*NP*NQ
065 LIWMIN = 2 + 7*N + 8*NPCOL
066
067 WORK( 1 ) = DBLE( LWMIN )
068 IWORK( 1 ) = LIWMIN
069 LQUERY =( LWORK.EQ. - 1 .OR. LIWORK.EQ. - 1 )
070 IF( .NOT.LSAME( COMPZ , 'I' ) ) THEN
070
071 INFO = - 1
072 ELSE IF( N.LT.0 ) THEN
072
073 INFO = - 2
074 ELSE IF( IROFFQ.NE.ICOFFQ .OR. ICOFFQ.NE.0 ) THEN
074
075 INFO = - 5
076 ELSE IF( DESCQ( MB_ ).NE.DESCQ( NB_ ) ) THEN
076
077 INFO = - ( 700 + NB_ )
078 ELSE IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN
078
079 INFO = - 10
080 ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THEN
080
081 INFO = - 12
082 END IF
083 END IF
084 END IF
085 IF( INFO.NE.0 ) THEN
085
086 CALL PXERBLA( DESCQ( CTXT_ ) , 'PDSTEDC' , - INFO )
087 RETURN
088 ELSE IF( LQUERY ) THEN
088
089 RETURN
090 END IF
091
092 * Quick return
093
094 IF( N.EQ.0 )
094
095 $ GO TO 10
096 CALL INFOG2L( IQ , JQ , DESCQ , NPROW , NPCOL , MYROW , MYCOL , IIQ , JJQ ,
097 $ IQROW , IQCOL )
098 IF( N.EQ.1 ) THEN
098
099 IF( MYROW.EQ.IQROW .AND. MYCOL.EQ.IQCOL )
099
100 $ Q( 1 ) = ONE
101 GO TO 10
102 END IF
103
104 * If N is smaller than the minimum divide size NB , then
105 * solve the problem with the serial divide and conquer
106 * code locally.
107
108 IF( N.LE.NB ) THEN
108
109 IF(( MYROW.EQ.IQROW ) .AND.( MYCOL.EQ.IQCOL ) ) THEN
109
110 IPQ = IIQ + ( JJQ - 1 )*LDQ
111 CALL DSTEDC( 'I' , N , D , E , Q( IPQ ) , LDQ , WORK , LWORK ,
112 $ IWORK , LIWORK , INFO )
113 IF( INFO.NE.0 ) THEN
113
114 INFO =( N + 1 ) + N
115 GO TO 10
116 END IF
117 END IF
118 GO TO 10
119 END IF
120
121 * If P = NPROW*NPCOL = 1 , solve the problem with DSTEDC.
122
123 IF( NPCOL*NPROW.EQ.1 ) THEN
123
124 IPQ = IIQ + ( JJQ - 1 )*LDQ
125 CALL DSTEDC( 'I' , N , D , E , Q( IPQ ) , LDQ , WORK , LWORK , IWORK ,
126 $ LIWORK , INFO )
127 GO TO 10
128 END IF
129
130 * Scale matrix to allowable range , if necessary.
131
132 ORGNRM = DLANST( 'M' , N , D , E )
133 IF( ORGNRM.NE.ZERO ) THEN
133
134 CALL DLASCL( 'G' , 0 , 0 , ORGNRM , ONE , N , 1 , D , N , INFO )
135 CALL DLASCL( 'G' , 0 , 0 , ORGNRM , ONE , N - 1 , 1 , E , N - 1 , INFO )
136 END IF
137
138 CALL PDLAED0 ( N , D , E , Q , IQ , JQ , DESCQ , WORK , IWORK , INFO )
139
140 * Sort eigenvalues and corresponding eigenvectors
141
142 CALL PDLASRT ( 'I' , N , D , Q , IQ , JQ , DESCQ , WORK , LWORK , IWORK ,
143 $ LIWORK , INFO )
144
145 * Scale back.
146
147 IF( ORGNRM.NE.ZERO )
147
148 $ CALL DLASCL( 'G' , 0 , 0 , ONE , ORGNRM , N , 1 , D , N , INFO )
149
150 10 CONTINUE
151
152 IF( LWORK.GT.0 )
152
153 $ WORK( 1 ) = DBLE( LWMIN )
154 IF( LIWORK.GT.0 )
154
155 $ IWORK( 1 ) = LIWMIN
156 RETURN
157
158 * End of PDSTEDC
159
160 END23
23
|
|
Variables in Routine PDSTEDC()
| Summary Report |
| Data Type | Quantity | Size(byte) |
| CHARACTER | 1 | 1 |
| DOUBLE PRECISION | 4 | 16 |
| INTEGER | 37 | 148 |
| LOGICAL | 2 | 2 |
| REAL | 2 | 8 |
| TOTAL | 46 | 175 |
List of Variables
CHARACTER
DOUBLE PRECISION
INTEGER
| BLOCK_CYCLIC_2D | CSRC_ | CTXT_ | DLEN_ | DTYPE_ |
| ICOFFQ | IIQ | INDXG2P | INFO | IPQ |
| IQ | IQCOL | IQROW | IROFFQ | IWORK |
| JJQ | JQ | LDQ | LIWMIN | LIWORK |
| LLD_ | LWMIN | LWORK | M_ | MB_ |
| MYCOL | MYROW | N | N_ | NB |
| NB_ | NP | NPCOL | NPROW | NQ |
| NUMROC | RSRC_ | | | |
LOGICAL
REAL
Variables Dependence Graph Put the mouse over a right hand side variable to display the corresponding line of the dependence | | - | | - | - | | ICOFFQ | <--- | JQICOFFQ = MOD( JQ-1, DESCQ( NB_ ) ), NB_ICOFFQ = MOD( JQ-1, DESCQ( NB_ ) ) |
| INFO | <--- | NINFO = ( N+1 ) + N, NB_INFO = -( 700+NB_ ), CTXT_INFO = -( 600+CTXT_ ) |
| IPQ | <--- | JJQIPQ = IIQ + ( JJQ-1 )*LDQ{2IPQ = IIQ + ( JJQ-1 )*LDQ}, LDQIPQ = IIQ + ( JJQ-1 )*LDQ{2IPQ = IIQ + ( JJQ-1 )*LDQ}, IIQIPQ = IIQ + ( JJQ-1 )*LDQ{2IPQ = IIQ + ( JJQ-1 )*LDQ} |
| IQCOL | <--- | INDXG2PIQCOL = INDXG2P( JQ, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ), JQIQCOL = INDXG2P( JQ, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ), CSRC_IQCOL = INDXG2P( JQ, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ), MYCOLIQCOL = INDXG2P( JQ, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ), NBIQCOL = INDXG2P( JQ, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ), NPCOLIQCOL = INDXG2P( JQ, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ) |
| IQROW | <--- | INDXG2PIQROW = INDXG2P( IQ, NB, MYROW, DESCQ( RSRC_ ), NPROW ), IQIQROW = INDXG2P( IQ, NB, MYROW, DESCQ( RSRC_ ), NPROW ), MYROWIQROW = INDXG2P( IQ, NB, MYROW, DESCQ( RSRC_ ), NPROW ), NBIQROW = INDXG2P( IQ, NB, MYROW, DESCQ( RSRC_ ), NPROW ), NPROWIQROW = INDXG2P( IQ, NB, MYROW, DESCQ( RSRC_ ), NPROW ), RSRC_IQROW = INDXG2P( IQ, NB, MYROW, DESCQ( RSRC_ ), NPROW ) |
| IROFFQ | <--- | IQIROFFQ = MOD( IQ-1, DESCQ( MB_ ) ), MB_IROFFQ = MOD( IQ-1, DESCQ( MB_ ) ) |
| IWORK | <--- | LIWMINIWORK( 1 ) = LIWMIN |
| LDQ | <--- | LLD_LDQ = DESCQ( LLD_ ) |
| LIWMIN | <--- | NLIWMIN = 2 + 7*N + 8*NPCOL, NPCOLLIWMIN = 2 + 7*N + 8*NPCOL |
| LWMIN | <--- | NLWMIN = 6*N + 2*NP*NQ, NPLWMIN = 6*N + 2*NP*NQ, NQLWMIN = 6*N + 2*NP*NQ |
| NB | <--- | NB_NB = DESCQ( NB_ ){2NB = DESCQ( NB_ )} |
| NP | <--- | MYROWNP = NUMROC( N, NB, MYROW, DESCQ( RSRC_ ), NPROW ), NNP = NUMROC( N, NB, MYROW, DESCQ( RSRC_ ), NPROW ), NBNP = NUMROC( N, NB, MYROW, DESCQ( RSRC_ ), NPROW ), NPROWNP = NUMROC( N, NB, MYROW, DESCQ( RSRC_ ), NPROW ), NUMROCNP = NUMROC( N, NB, MYROW, DESCQ( RSRC_ ), NPROW ), RSRC_NP = NUMROC( N, NB, MYROW, DESCQ( RSRC_ ), NPROW ) |
| NQ | <--- | CSRC_NQ = NUMROC( N, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ), MYCOLNQ = NUMROC( N, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ), NNQ = NUMROC( N, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ), NBNQ = NUMROC( N, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ), NPCOLNQ = NUMROC( N, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ), NUMROCNQ = NUMROC( N, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ) |
| ORGNRM | <--- | NORGNRM = DLANST( 'M', N, D, E ), DLANSTORGNRM = DLANST( 'M', N, D, E ) |
| WORK | <--- | LWMINWORK( 1 ) = DBLE( LWMIN ) |
|
|
Analysis elements of the routine PDSTEDC() Put the mouse over each element to display detailed matching information
Assigned variables |
| | | BLOCK_CYCLIC_2D , CSRC_ , CTXT_ , DLEN_ , DTYPE_ , ICOFFQ , INFO , IPQ , IQCOL , IQROW , IROFFQ , IWORK , LDQ , LIWMIN , LLD_ , LQUERY , LWMIN , M_ , MB_ , N_ , NB , NB_ , NP , NPCOL , NQ , ONE , ORGNRM , Q , RSRC_ , WORK , ZERO |
|
Active variables |
| | | BLOCK_CYCLIC_2D , COMPZ , CSRC_ , CTXT_ , D , DESCQ , DLANST , DLEN_ , DTYPE_ , E , ICOFFQ , IIQ , INDXG2P , INFO , IPQ , IQ , IQCOL , IQROW , IROFFQ , IWORK , JJQ , JQ , LDQ , LIWMIN , LIWORK , LLD_ , LQUERY , LSAME , LWMIN , LWORK , M_ , MB_ , MYCOL , MYROW , N , N_ , NB , NB_ , NP , NPCOL , NPROW , NQ , NUMROC , ONE , ORGNRM , Q , RSRC_ , WORK , ZERO |
|
Accessed arrays [ array name : associated index ] |
| | DESCQ | : CSRC_ , CSRC_ , CTXT_ , CTXT_ , LLD_ , MB_ , MB_ , NB_ , NB_ , NB_ , NB_ , RSRC_ , RSRC_ |
| | DLANST | : 'M', N, D, E |
| | INDXG2P | : IQ, NB, MYROW, DESCQ( RSRC_ ), NPROW , JQ, NB, MYCOL, DESCQ( CSRC_ ), NPCOL |
| | IWORK | : 1 , 1 |
| | LSAME | : COMPZ, 'I' |
| | NUMROC | : N, NB, MYCOL, DESCQ( CSRC_ ), NPCOL , N, NB, MYROW, DESCQ( RSRC_ ), NPROW |
| | Q | : 1 , IPQ , IPQ |
| | WORK | : 1 , 1 |
|
Conditional statements [ statement : associated predicate ] |
| | if | : ( BLOCK_CYCLIC_2D*CSRC_*CTXT_*DLEN_*DTYPE_*LLD_*MB_*M_*NB_*N_* ) , ( NPROW.EQ. - 1 ) , ( INFO.EQ.0 ) , ( (.NOT.LSAME( COMPZ , 'I' ) ) ) , ( N.LT.0 ) , ( IROFFQ.NE.ICOFFQ .OR. ICOFFQ.NE.0 ) , ( (DESCQ( MB_ ).NE.DESCQ( NB_ ) ) ) , ( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) , ( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) , ( INFO.NE.0 ) , ( LQUERY ) , ( N.EQ.0 ) , ( N.EQ.1 ) , ( MYROW.EQ.IQROW .AND. MYCOL.EQ.IQCOL ) , ( N is smaller than the minimum divide size NB , ) , ( N.LE.NB ) , ( (( MYROW.EQ.IQROW ) .AND. ( MYCOL.EQ.IQCOL ) ) ) , ( INFO.NE.0 ) , ( P=NPROW*NPCOL = 1 , solve the problem with DSTEDC. ) , ( NPCOL*NPROW.EQ.1 ) , ( necessary. ) , ( ORGNRM.NE.ZERO ) , ( ORGNRM.NE.ZERO ) , ( LWORK.GT.0 ) , ( LIWORK.GT.0 ) |
|
| List of variables | BLOCK_CYCLIC_2D COMPZ CSRC_ CTXT_ DLANST DLEN_ DTYPE_
| ICOFFQ IIQ INDXG2P INFO IPQ IQ IQCOL IQROW
| IROFFQ IWORK JJQ JQ LDQ LIWMIN LIWORK LLD_
| LQUERY LSAME LWMIN LWORK M_ MB_ MYCOL MYROW
| N N_ NB NB_ NP NPCOL NPROW NQ
| NUMROC ONE ORGNRM Q RSRC_ WORK ZERO | | close
| |
BLOCK_CYCLIC_2D
COMPZ
CSRC_
CTXT_
DLANST
DLEN_
DTYPE_
ICOFFQ
IIQ
INDXG2P
INFO
IPQ
IQ
IQCOL
IQROW
IROFFQ
IWORK
JJQ
JQ
LDQ
LIWMIN
LIWORK
LLD_
LQUERY
LSAME
LWMIN
LWORK
M_
MB_
MYCOL
MYROW
N
N_
NB
NB_
NP
NPCOL
NPROW
NQ
NUMROC
ONE
ORGNRM
Q
RSRC_
WORK
ZERO
211#243
| |