1 SUBROUTINE pdsyevd( JOBZ, UPLO, N, A, IA, JA, DESCA, W, Z, IZ, JZ,
2 $ DESCZ, WORK, LWORK, IWORK, LIWORK, INFO )
11 INTEGER IA, INFO, IZ, JA, JZ, LIWORK, LWORK, N
14 INTEGER DESCA( * ), DESCZ( * ), IWORK( * )
15 DOUBLE PRECISION A( * ), W( * ), WORK( * ), Z( * )
155 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, CTXT_, M_, N_,
156 $ mb_, nb_, rsrc_, csrc_, lld_
157 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
158 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
159 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
160 DOUBLE PRECISION ZERO, ONE
161 parameter( zero = 0.0d+0, one = 1.0d+0 )
164 LOGICAL LQUERY, UPPER
165 INTEGER IACOL, IAROW, ICOFFA, ICOFFZ, ICTXT, IINFO,
166 $ indd, inde, inde2, indtau, indwork, indwork2,
167 $ iroffa, iroffz, iscale, liwmin, llwork,
168 $ llwork2, lwmin, mycol, myrow, nb, np, npcol,
169 $ nprow, nq, offset, trilwmin
170 DOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
175 INTEGER IDUM1( 2 ), IDUM2( 2 )
179 INTEGER INDXG2P, NUMROC
180 DOUBLE PRECISION PDLAMCH, PDLANSY
181 EXTERNAL lsame, indxg2p, numroc, pdlamch, pdlansy
189 INTRINSIC dble, ichar,
max,
min, mod, sqrt
193 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
203 ictxt = descz( ctxt_ )
204 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
207 IF( nprow.EQ.-1 )
THEN
208 info = -( 600+ctxt_ )
210 CALL chk1mat( n, 3, n, 3, ia, ja, desca, 7, info )
211 CALL chk1mat( n, 3, n, 3, iz, jz, descz, 12, info )
213 upper = lsame( uplo,
'U' )
215 iroffa = mod( ia-1, desca( mb_ ) )
216 icoffa = mod( ja-1, desca( nb_ ) )
217 iroffz = mod( iz-1, descz( mb_ ) )
218 icoffz = mod( jz-1, descz( nb_ ) )
219 iarow = indxg2p( ia, nb, myrow, desca( rsrc_ ), nprow )
220 iacol = indxg2p( ja, nb, mycol, desca( csrc_ ), npcol )
221 np = numroc( n, nb, myrow, iarow, nprow )
222 nq = numroc( n, nb, mycol, iacol, npcol )
224 lquery = ( lwork.EQ.-1 )
225 trilwmin = 3*n +
max( nb*( np+1 ), 3*nb )
226 lwmin =
max( 1+6*n+2*np*nq, trilwmin ) + 2*n
227 liwmin = 7*n + 8*npcol + 2
228 work( 1 ) = dble( lwmin )
230 IF( .NOT.lsame( jobz,
'V' ) )
THEN
232 ELSE IF( .NOT.upper .AND. .NOT.lsame( uplo,
'L' ) )
THEN
234 ELSE IF( iroffa.NE.icoffa .OR. icoffa.NE.0 )
THEN
236 ELSE IF( iroffa.NE.iroffz .OR. icoffa.NE.icoffz )
THEN
238 ELSE IF( desca( m_ ).NE.descz( m_ ) )
THEN
240 ELSE IF( desca( mb_ ).NE.desca( nb_ ) )
THEN
242 ELSE IF( descz( mb_ ).NE.descz( nb_ ) )
THEN
244 ELSE IF( desca( mb_ ).NE.descz( mb_ ) )
THEN
246 ELSE IF( desca( ctxt_ ).NE.descz( ctxt_ ) )
THEN
247 info = -( 1200+ctxt_ )
248 ELSE IF( desca( rsrc_ ).NE.descz( rsrc_ ) )
THEN
249 info = -( 1200+rsrc_ )
250 ELSE IF( desca( csrc_ ).NE.descz( csrc_ ) )
THEN
251 info = -( 1200+csrc_ )
252 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
254 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
259 idum1( 1 ) = ichar(
'U' )
261 idum1( 1 ) = ichar(
'L' )
264 IF( lwork.EQ.-1 )
THEN
270 CALL pchk1mat( n, 3, n, 3, ia, ja, desca, 7, 2, idum1, idum2,
274 CALL pxerbla( ictxt,
'PDSYEVD', -info )
276 ELSE IF( lquery )
THEN
287 llwork = lwork - indwork + 1
289 llwork2 = lwork - indwork2 + 1
294 safmin = pdlamch( desca( ctxt_ ),
'Safe minimum' )
295 eps = pdlamch( desca( ctxt_ ),
'Precision' )
296 smlnum = safmin / eps
297 bignum = one / smlnum
298 rmin = sqrt( smlnum )
299 rmax =
min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
300 anrm = pdlansy(
'M', uplo, n, a, ia, ja, desca, work( indwork ) )
302 IF( anrm.GT.zero .AND. anrm.LT.rmin )
THEN
305 ELSE IF( anrm.GT.rmax )
THEN
310 IF( iscale.EQ.1 )
THEN
311 CALL pdlascl( uplo, one, sigma, n, n, a, ia, ja, desca, iinfo )
317 CALL pdsytrd( uplo, n, a, ia, ja, desca, work( indd ),
318 $ work( inde2 ), work( indtau ), work( indwork ),
323 CALL pdlared1d( n, ia, ja, desca, work( indd ), w,
324 $ work( indwork ), llwork )
326 CALL pdlared1d( n, ia, ja, desca, work( inde2 ), work( inde ),
327 $ work( indwork ), llwork )
329 CALL pdlaset(
'Full', n, n, zero, one, z, 1, 1, descz )
336 CALL pdstedc(
'I', n, w, work( inde+offset ), z, iz, jz, descz,
337 $ work( indwork2 ), llwork2, iwork, liwork, info )
339 CALL pdormtr(
'L', uplo,
'N', n, n, a, ia, ja, desca,
340 $ work( indtau ), z, iz, jz, descz, work( indwork2 ),
345 IF( iscale.EQ.1 )
THEN
346 CALL dscal( n, one / sigma, w, 1 )