1 SUBROUTINE pzheevd( JOBZ, UPLO, N, A, IA, JA, DESCA, W, Z, IZ, JZ,
2 $ DESCZ, WORK, LWORK, RWORK, LRWORK, IWORK,
12 INTEGER IA, INFO, IZ, JA, JZ, LIWORK, LRWORK, LWORK, N
15 INTEGER DESCA( * ), DESCZ( * ), IWORK( * )
16 DOUBLE PRECISION RWORK( * ), W( * )
17 COMPLEX*16 A( * ), WORK( * ), Z( * )
163 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, CTXT_, M_, N_,
164 $ MB_, NB_, RSRC_, CSRC_, LLD_
165 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
166 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
167 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
168 DOUBLE PRECISION ZERO, ONE
169 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0 )
170 COMPLEX*16 CZERO, CONE
171 parameter( czero = ( 0.0d+0, 0.0d+0 ),
172 $ cone = ( 1.0d+0, 0.0d+0 ) )
175 LOGICAL LOWER, LQUERY
176 INTEGER CSRC_A, I, IACOL, IAROW, ICOFFA, IINFO, IIZ,
177 $ indd, inde, inde2, indrwork, indtau, indwork,
178 $ indz, ipr, ipz, iroffa, iroffz, iscale, izcol,
179 $ izrow, j, jjz, ldr, ldz, liwmin, llrwork,
180 $ llwork, lrwmin, lwmin, mb_a, mycol, myrow, nb,
181 $ nb_a, nn, np0, npcol, nprow, nq, nq0, offset,
183 DOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
187 INTEGER DESCRZ( 9 ), IDUM1( 2 ), IDUM2( 2 )
191 INTEGER INDXG2L, INDXG2P, NUMROC
192 DOUBLE PRECISION PZLANHE, PDLAMCH
193 EXTERNAL lsame, indxg2l, indxg2p, numroc, pzlanhe,
203 INTRINSIC dcmplx, ichar,
max,
min, mod, dble, sqrt
207 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
219 ictxt = desca( ctxt_ )
220 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
222 IF( nprow.EQ.-1 )
THEN
223 info = -( 700+ctxt_ )
225 CALL chk1mat( n, 3, n, 3, ia, ja, desca, 7, info )
226 CALL chk1mat( n, 3, n, 3, iz, jz, descz, 12, info )
228 lower = lsame( uplo,
'L' )
232 rsrc_a = desca( rsrc_ )
233 csrc_a = desca( csrc_ )
234 iroffa = mod( ia-1, mb_a )
235 icoffa = mod( ja-1, nb_a )
236 iarow = indxg2p( ia, nb_a, myrow, rsrc_a, nprow )
237 iacol = indxg2p( ja, mb_a, mycol, csrc_a, npcol )
238 np0 = numroc( n, nb, myrow, iarow, nprow )
239 nq0 = numroc( n, nb, mycol, iacol, npcol )
240 iroffz = mod( iz-1, mb_a )
241 CALL infog2l( iz, jz, descz, nprow, npcol, myrow, mycol,
242 $ iiz, jjz, izrow, izcol )
243 lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 .OR. lrwork.EQ.-1 )
248 nq = numroc( nn, nb, 0, 0, npcol )
249 lwmin = n + ( np0+nq+nb )*nb
250 lrwmin = 1 + 9*n + 3*np0*nq0
251 liwmin = 7*n + 8*npcol + 2
252 work( 1 ) = dcmplx( lwmin )
253 rwork( 1 ) = dble( lrwmin )
255 IF( .NOT.lsame( jobz,
'V' ) )
THEN
257 ELSE IF( .NOT.( lower .OR. lsame( uplo,
'U' ) ) )
THEN
259 ELSE IF( lwork.LT.lwmin .AND. lwork.NE.-1 )
THEN
261 ELSE IF( lrwork.LT.lrwmin .AND. lrwork.NE.-1 )
THEN
263 ELSE IF( iroffa.NE.0 )
THEN
265 ELSE IF( desca( mb_ ).NE.desca( nb_ ) )
THEN
267 ELSE IF( iroffa.NE.iroffz )
THEN
269 ELSE IF( iarow.NE.izrow )
THEN
271 ELSE IF( desca( m_ ).NE.descz( m_ ) )
THEN
273 ELSE IF( desca( n_ ).NE.descz( n_ ) )
THEN
275 ELSE IF( desca( mb_ ).NE.descz( mb_ ) )
THEN
277 ELSE IF( desca( nb_ ).NE.descz( nb_ ) )
THEN
279 ELSE IF( desca( rsrc_ ).NE.descz( rsrc_ ) )
THEN
280 info = -( 1200+rsrc_ )
281 ELSE IF( desca( ctxt_ ).NE.descz( ctxt_ ) )
THEN
282 info = -( 1200+ctxt_ )
286 idum1( 1 ) = ichar(
'L' )
288 idum1( 1 ) = ichar(
'U' )
291 IF( lwork.EQ.-1 )
THEN
297 CALL pchk2mat( n, 3, n, 3, ia, ja, desca, 7, n, 3, n, 3, iz,
298 $ jz, descz, 11, 2, idum1, idum2, info )
302 CALL pxerbla( desca( ctxt_ ),
'PZHEEVD', -info )
304 ELSE IF( lquery )
THEN
310 safmin = pdlamch( desca( ctxt_ ),
'Safe minimum' )
311 eps = pdlamch( desca( ctxt_ ),
'Precision' )
312 smlnum = safmin / eps
313 bignum = one / smlnum
314 rmin = sqrt( smlnum )
315 rmax =
min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
321 llwork = lwork - indwork + 1
329 llrwork = lrwork - indrwork + 1
335 anrm = pzlanhe(
'M', uplo, n, a, ia, ja, desca,
336 $ rwork( indrwork ) )
339 IF( anrm.GT.zero .AND. anrm.LT.rmin )
THEN
342 ELSE IF( anrm.GT.rmax )
THEN
347 IF( iscale.EQ.1 )
THEN
348 CALL pzlascl( uplo, one, sigma, n, n, a, ia, ja, desca, iinfo )
353 CALL pzhetrd( uplo, n, a, ia, ja, desca, rwork( indd ),
354 $ rwork( inde2 ), work( indtau ), work( indwork ),
364 IF( ia.EQ.1 .AND. ja.EQ.1 .AND. rsrc_a.EQ.0 .AND. csrc_a.EQ.0 )
366 CALL pdlared1d( n, ia, ja, desca, rwork( indd ), w,
367 $ rwork( indrwork ), llrwork )
369 CALL pdlared1d( n, ia, ja, desca, rwork( inde2 ),
370 $ rwork( inde ), rwork( indrwork ), llrwork )
375 CALL pzelget(
'A',
' ', work( indwork ), a, i+ia-1, i+ja-1,
377 w( i ) = dble( work( indwork ) )
379 IF( lsame( uplo,
'U' ) )
THEN
381 CALL pzelget(
'A',
' ', work( indwork ), a, i+ia-1, i+ja,
383 rwork( inde+i-1 ) = dble( work( indwork ) )
387 CALL pzelget(
'A',
' ', work( indwork ), a, i+ia, i+ja-1,
389 rwork( inde+i-1 ) = dble( work( indwork ) )
397 indrwork = indz + np0*nq0
398 llrwork = lrwork - indrwork + 1
400 CALL descinit( descrz, descz( m_ ), descz( n_ ), descz( mb_ ),
401 $ descz( nb_ ), descz( rsrc_ ), descz( csrc_ ),
402 $ descz( ctxt_ ), ldr, info )
403 CALL pzlaset(
'Full', n, n, czero, cone, z, iz, jz, descz )
404 CALL pdlaset(
'Full', n, n, zero, one, rwork( indz ), 1, 1,
406 CALL pdstedc(
'I', n, w, rwork( inde+offset ), rwork( indz ), iz,
407 $ jz, descrz, rwork( indrwork ), llrwork, iwork,
412 iiz = indxg2l( iz, nb, myrow, myrow, nprow )
413 jjz = indxg2l( jz, nb, mycol, mycol, npcol )
414 ipz = iiz + ( jjz-1 )*ldz
415 ipr = indz - 1 + iiz + ( jjz-1 )*ldr
418 z( ipz+i+j*ldz ) = rwork( ipr+i+j*ldr )
424 CALL pzunmtr(
'L', uplo,
'N', n, n, a, ia, ja, desca,
425 $ work( indtau ), z, iz, jz, descz, work( indwork ),
430 IF( iscale.EQ.1 )
THEN
431 CALL dscal( n, one / sigma, w, 1 )
434 work( 1 ) = dcmplx( lwmin )
435 rwork( 1 ) = dble( lrwmin )