SCALAPACK 2.2.2
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
pdlaed0.f
Go to the documentation of this file.
1 SUBROUTINE pdlaed0( N, D, E, Q, IQ, JQ, DESCQ, WORK, IWORK, INFO )
2*
3* -- ScaLAPACK auxiliary routine (version 1.7) --
4* University of Tennessee, Knoxville, Oak Ridge National Laboratory,
5* and University of California, Berkeley.
6* December 31, 1998
7*
8* .. Scalar Arguments ..
9 INTEGER INFO, IQ, JQ, N
10* ..
11* .. Array Arguments ..
12 INTEGER DESCQ( * ), IWORK( * )
13 DOUBLE PRECISION D( * ), E( * ), Q( * ), WORK( * )
14* ..
15*
16* Purpose
17* =======
18*
19* PDLAED0 computes all eigenvalues and corresponding eigenvectors of a
20* symmetric tridiagonal matrix using the divide and conquer method.
21*
22*
23* Arguments
24* =========
25*
26* N (global input) INTEGER
27* The order of the tridiagonal matrix T. N >= 0.
28*
29* D (global input/output) DOUBLE PRECISION array, dimension (N)
30* On entry, the diagonal elements of the tridiagonal matrix.
31* On exit, if INFO = 0, the eigenvalues in descending order.
32*
33* E (global input/output) DOUBLE PRECISION array, dimension (N-1)
34* On entry, the subdiagonal elements of the tridiagonal matrix.
35* On exit, E has been destroyed.
36*
37* Q (local output) DOUBLE PRECISION array,
38* global dimension (N, N),
39* local dimension ( LLD_Q, LOCc(JQ+N-1))
40* Q contains the orthonormal eigenvectors of the symmetric
41* tridiagonal matrix.
42* On output, Q is distributed across the P processes in block
43* cyclic format.
44*
45* IQ (global input) INTEGER
46* Q's global row index, which points to the beginning of the
47* submatrix which is to be operated on.
48*
49* JQ (global input) INTEGER
50* Q's global column index, which points to the beginning of
51* the submatrix which is to be operated on.
52*
53* DESCQ (global and local input) INTEGER array of dimension DLEN_.
54* The array descriptor for the distributed matrix Z.
55*
56*
57* WORK (local workspace ) DOUBLE PRECISION array, dimension (LWORK)
58* LWORK = 6*N + 2*NP*NQ, with
59* NP = NUMROC( N, MB_Q, MYROW, IQROW, NPROW )
60* NQ = NUMROC( N, NB_Q, MYCOL, IQCOL, NPCOL )
61* IQROW = INDXG2P( IQ, NB_Q, MYROW, RSRC_Q, NPROW )
62* IQCOL = INDXG2P( JQ, MB_Q, MYCOL, CSRC_Q, NPCOL )
63*
64* IWORK (local workspace/output) INTEGER array, dimension (LIWORK)
65* LIWORK = 2 + 7*N + 8*NPCOL
66*
67* INFO (global output) INTEGER
68* = 0: successful exit
69* < 0: If the i-th argument is an array and the j-entry had
70* an illegal value, then INFO = -(i*100+j), if the i-th
71* argument is a scalar and had an illegal value, then
72* INFO = -i.
73* > 0: The algorithm failed to compute the INFO/(N+1) th
74* eigenvalue while working on the submatrix lying in
75* global rows and columns mod(INFO,N+1).
76*
77* =====================================================================
78*
79* .. Parameters ..
80*
81 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, CTXT_, M_, N_,
82 $ MB_, NB_, RSRC_, CSRC_, LLD_
83 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
84 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
85 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
86* ..
87* .. Local Scalars ..
88 INTEGER I, ID, IDCOL, IDROW, IID, IINFO, IIQ, IM1, IM2,
89 $ IPQ, IQCOL, IQROW, J, JJD, JJQ, LDQ, MATSIZ,
90 $ MYCOL, MYROW, N1, NB, NBL, NBL1, NPCOL, NPROW,
91 $ SUBPBS, TSUBPBS
92* ..
93* .. External Subroutines ..
94 EXTERNAL blacs_gridinfo, dgebr2d, dgebs2d, dgerv2d,
95 $ dgesd2d, dsteqr, infog2l, pdlaed1, pxerbla
96* ..
97* .. External Functions ..
98* ..
99* .. Intrinsic Functions ..
100 INTRINSIC abs, min
101* ..
102* .. Executable Statements ..
103*
104* This is just to keep ftnchek and toolpack/1 happy
105 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
106 $ rsrc_.LT.0 )RETURN
107*
108* Test the input parameters.
109*
110 CALL blacs_gridinfo( descq( ctxt_ ), nprow, npcol, myrow, mycol )
111 info = 0
112 IF( descq( nb_ ).GT.n .OR. n.LT.2 )
113 $ info = -1
114 IF( info.NE.0 ) THEN
115 CALL pxerbla( descq( ctxt_ ), 'PDLAED0', -info )
116 RETURN
117 END IF
118*
119 nb = descq( nb_ )
120 ldq = descq( lld_ )
121 CALL infog2l( iq, jq, descq, nprow, npcol, myrow, mycol, iiq, jjq,
122 $ iqrow, iqcol )
123*
124* Determine the size and placement of the submatrices, and save in
125* the leading elements of IWORK.
126*
127 tsubpbs = ( n-1 ) / nb + 1
128 iwork( 1 ) = tsubpbs
129 subpbs = 1
130 10 CONTINUE
131 IF( iwork( subpbs ).GT.1 ) THEN
132 DO 20 j = subpbs, 1, -1
133 iwork( 2*j ) = ( iwork( j )+1 ) / 2
134 iwork( 2*j-1 ) = iwork( j ) / 2
135 20 CONTINUE
136 subpbs = 2*subpbs
137 GO TO 10
138 END IF
139 DO 30 j = 2, subpbs
140 iwork( j ) = iwork( j ) + iwork( j-1 )
141 30 CONTINUE
142*
143* Divide the matrix into TSUBPBS submatrices of size at most NB
144* using rank-1 modifications (cuts).
145*
146 DO 40 i = nb + 1, n, nb
147 im1 = i - 1
148 d( im1 ) = d( im1 ) - abs( e( im1 ) )
149 d( i ) = d( i ) - abs( e( im1 ) )
150 40 CONTINUE
151*
152* Solve each submatrix eigenproblem at the bottom of the divide and
153* conquer tree. D is the same on each process.
154*
155 DO 50 id = 1, n, nb
156 CALL infog2l( iq-1+id, jq-1+id, descq, nprow, npcol, myrow,
157 $ mycol, iid, jjd, idrow, idcol )
158 matsiz = min( nb, n-id+1 )
159 IF( myrow.EQ.idrow .AND. mycol.EQ.idcol ) THEN
160 ipq = iid + ( jjd-1 )*ldq
161 CALL dsteqr( 'I', matsiz, d( id ), e( id ), q( ipq ), ldq,
162 $ work, info )
163 IF( info.NE.0 ) THEN
164 CALL pxerbla( descq( ctxt_ ), 'DSTEQR', -info )
165 RETURN
166 END IF
167 IF( myrow.NE.iqrow .OR. mycol.NE.iqcol ) THEN
168 CALL dgesd2d( descq( ctxt_ ), matsiz, 1, d( id ), matsiz,
169 $ iqrow, iqcol )
170 END IF
171 ELSE IF( myrow.EQ.iqrow .AND. mycol.EQ.iqcol ) THEN
172 CALL dgerv2d( descq( ctxt_ ), matsiz, 1, d( id ), matsiz,
173 $ idrow, idcol )
174 END IF
175 50 CONTINUE
176*
177 IF( myrow.EQ.iqrow .AND. mycol.EQ.iqcol ) THEN
178 CALL dgebs2d( descq( ctxt_ ), 'A', ' ', n, 1, d, n )
179 ELSE
180 CALL dgebr2d( descq( ctxt_ ), 'A', ' ', n, 1, d, n, iqrow,
181 $ iqcol )
182 END IF
183*
184* Successively merge eigensystems of adjacent submatrices
185* into eigensystem for the corresponding larger matrix.
186*
187* while ( SUBPBS > 1 )
188*
189 60 CONTINUE
190 IF( subpbs.GT.1 ) THEN
191 im2 = subpbs - 2
192 DO 80 i = 0, im2, 2
193 IF( i.EQ.0 ) THEN
194 nbl = iwork( 2 )
195 nbl1 = iwork( 1 )
196 IF( nbl1.EQ.0 )
197 $ GO TO 70
198 id = 1
199 matsiz = min( n, nbl*nb )
200 n1 = nbl1*nb
201 ELSE
202 nbl = iwork( i+2 ) - iwork( i )
203 nbl1 = nbl / 2
204 IF( nbl1.EQ.0 )
205 $ GO TO 70
206 id = iwork( i )*nb + 1
207 matsiz = min( nb*nbl, n-id+1 )
208 n1 = nbl1*nb
209 END IF
210*
211* Merge lower order eigensystems (of size N1 and MATSIZ - N1)
212* into an eigensystem of size MATSIZ.
213*
214 CALL pdlaed1( matsiz, n1, d( id ), id, q, iq, jq, descq,
215 $ e( id+n1-1 ), work, iwork( subpbs+1 ), iinfo )
216 IF( iinfo.NE.0 ) THEN
217 info = iinfo*( n+1 ) + id
218 END IF
219*
220 70 CONTINUE
221 iwork( i / 2+1 ) = iwork( i+2 )
222 80 CONTINUE
223 subpbs = subpbs / 2
224*
225 GO TO 60
226 END IF
227*
228* end while
229*
230 90 CONTINUE
231 RETURN
232*
233* End of PDLAED0
234*
235 END
subroutine infog2l(grindx, gcindx, desc, nprow, npcol, myrow, mycol, lrindx, lcindx, rsrc, csrc)
Definition infog2l.f:3
#define min(A, B)
Definition pcgemr.c:181
subroutine pdlaed0(n, d, e, q, iq, jq, descq, work, iwork, info)
Definition pdlaed0.f:2
subroutine pdlaed1(n, n1, d, id, q, iq, jq, descq, rho, work, iwork, info)
Definition pdlaed1.f:3
subroutine pxerbla(ictxt, srname, info)
Definition pxerbla.f:2