ScaLAPACK 2.1  2.1
ScaLAPACK: Scalable Linear Algebra PACKage
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
pdlaed1
subroutine pdlaed1(N, N1, D, ID, Q, IQ, JQ, DESCQ, RHO, WORK, IWORK, INFO)
Definition: pdlaed1.f:3
infog2l
subroutine infog2l(GRINDX, GCINDX, DESC, NPROW, NPCOL, MYROW, MYCOL, LRINDX, LCINDX, RSRC, CSRC)
Definition: infog2l.f:3
pdlaed0
subroutine pdlaed0(N, D, E, Q, IQ, JQ, DESCQ, WORK, IWORK, INFO)
Definition: pdlaed0.f:2
pxerbla
subroutine pxerbla(ICTXT, SRNAME, INFO)
Definition: pxerbla.f:2
min
#define min(A, B)
Definition: pcgemr.c:181