1 SUBROUTINE pssyevd( 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 REAL 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 )
161 parameter( zero = 0.0e+0, one = 1.0e+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 REAL ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
174 INTEGER IDUM1( 2 ), IDUM2( 2 )
178 INTEGER INDXG2P, NUMROC
179 REAL PSLAMCH, PSLANSY
180 EXTERNAL lsame, indxg2p, numroc, pslamch, pslansy
188 INTRINSIC ichar,
max,
min, mod, real, sqrt
192 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
202 ictxt = descz( ctxt_ )
203 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
206 IF( nprow.EQ.-1 )
THEN
207 info = -( 600+ctxt_ )
209 CALL chk1mat( n, 3, n, 3, ia, ja, desca, 7, info )
210 CALL chk1mat( n, 3, n, 3, iz, jz, descz, 12, info )
212 upper = lsame( uplo,
'U' )
214 iroffa = mod( ia-1, desca( mb_ ) )
215 icoffa = mod( ja-1, desca( nb_ ) )
216 iroffz = mod( iz-1, descz( mb_ ) )
217 icoffz = mod( jz-1, descz( nb_ ) )
218 iarow = indxg2p( ia, nb, myrow, desca( rsrc_ ), nprow )
219 iacol = indxg2p( ja, nb, mycol, desca( csrc_ ), npcol )
220 np = numroc( n, nb, myrow, iarow, nprow )
221 nq = numroc( n, nb, mycol, iacol, npcol )
223 lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 )
224 trilwmin = 3*n +
max( nb*( np+1 ), 3*nb )
225 lwmin =
max( 1+6*n+2*np*nq, trilwmin ) + 2*n
226 liwmin = 7*n + 8*npcol + 2
227 work( 1 ) = real( lwmin )
229 IF( .NOT.lsame( jobz,
'V' ) )
THEN
231 ELSE IF( .NOT.upper .AND. .NOT.lsame( uplo,
'L' ) )
THEN
233 ELSE IF( iroffa.NE.icoffa .OR. icoffa.NE.0 )
THEN
235 ELSE IF( iroffa.NE.iroffz .OR. icoffa.NE.icoffz )
THEN
237 ELSE IF( desca( m_ ).NE.descz( m_ ) )
THEN
239 ELSE IF( desca( mb_ ).NE.desca( nb_ ) )
THEN
241 ELSE IF( descz( mb_ ).NE.descz( nb_ ) )
THEN
243 ELSE IF( desca( mb_ ).NE.descz( mb_ ) )
THEN
245 ELSE IF( desca( ctxt_ ).NE.descz( ctxt_ ) )
THEN
246 info = -( 1200+ctxt_ )
247 ELSE IF( desca( rsrc_ ).NE.descz( rsrc_ ) )
THEN
248 info = -( 1200+rsrc_ )
249 ELSE IF( desca( csrc_ ).NE.descz( csrc_ ) )
THEN
250 info = -( 1200+csrc_ )
251 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
253 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
258 idum1( 1 ) = ichar(
'U' )
260 idum1( 1 ) = ichar(
'L' )
263 IF( lwork.EQ.-1 )
THEN
269 CALL pchk1mat( n, 3, n, 3, ia, ja, desca, 7, 2, idum1, idum2,
273 CALL pxerbla( ictxt,
'PSSYEVD', -info )
275 ELSE IF( lquery )
THEN
286 llwork = lwork - indwork + 1
288 llwork2 = lwork - indwork2 + 1
293 safmin = pslamch( desca( ctxt_ ),
'Safe minimum' )
294 eps = pslamch( desca( ctxt_ ),
'Precision' )
295 smlnum = safmin / eps
296 bignum = one / smlnum
297 rmin = sqrt( smlnum )
298 rmax =
min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
299 anrm = pslansy(
'M', uplo, n, a, ia, ja, desca, work( indwork ) )
301 IF( anrm.GT.zero .AND. anrm.LT.rmin )
THEN
304 ELSE IF( anrm.GT.rmax )
THEN
309 IF( iscale.EQ.1 )
THEN
310 CALL pslascl( uplo, one, sigma, n, n, a, ia, ja, desca, iinfo )
316 CALL pssytrd( uplo, n, a, ia, ja, desca, work( indd ),
317 $ work( inde2 ), work( indtau ), work( indwork ),
322 CALL pslared1d( n, ia, ja, desca, work( indd ), w,
323 $ work( indwork ), llwork )
325 CALL pslared1d( n, ia, ja, desca, work( inde2 ), work( inde ),
326 $ work( indwork ), llwork )
328 CALL pslaset(
'Full', n, n, zero, one, z, 1, 1, descz )
335 CALL psstedc(
'I', n, w, work( inde+offset ), z, iz, jz, descz,
336 $ work( indwork2 ), llwork2, iwork, liwork, info )
338 CALL psormtr(
'L', uplo,
'N', n, n, a, ia, ja, desca,
339 $ work( indtau ), z, iz, jz, descz, work( indwork2 ),
344 IF( iscale.EQ.1 )
THEN
345 CALL sscal( n, one / sigma, w, 1 )