1 SUBROUTINE pcheev( JOBZ, UPLO, N, A, IA, JA, DESCA, W, Z, IZ, JZ,
2 $ DESCZ, WORK, LWORK, RWORK, LRWORK, INFO )
11 INTEGER IA, INFO, IZ, JA, JZ, LRWORK, LWORK, N
14 INTEGER DESCA( * ), DESCZ( * )
15 REAL RWORK( * ), W( * )
16 COMPLEX A( * ), WORK( * ), Z( * )
238 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, CTXT_, M_, N_,
239 $ mb_, nb_, rsrc_, csrc_, lld_
240 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
241 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
242 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
244 parameter( zero = 0.0e+0, one = 1.0e+0 )
246 parameter( czero = ( 0.0e+0, 0.0e+0 ),
247 $ cone = ( 1.0e+0, 0.0e+0 ) )
249 parameter( ithval = 10 )
253 INTEGER CONTEXTC, CSRC_A, I, IACOL, IAROW, ICOFFA,
254 $ iinfo, indd, inde, indrd, indre, indrwork,
255 $ indtau, indwork, indwork2, iroffa, iroffz,
256 $ iscale, izrow, j, k, ldc, llrwork, llwork,
257 $ lrmin, lrwmin, lwmin, mb_a, mb_z, mycol,
258 $ mypcolc, myprowc, myrow, nb, nb_a, nb_z, np0,
259 $ npcol, npcolc, nprocs, nprow, nprowc, nq0, nrc,
260 $ rsizecsteqr2, rsrc_a, rsrc_z, sizecsteqr2,
261 $ sizepchetrd, sizepcunmtr
262 REAL ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
266 INTEGER DESCQR( 10 ), IDUM1( 3 ), IDUM2( 3 )
270 INTEGER INDXG2P, NUMROC, SL_GRIDRESHAPE
271 REAL PCLANHE, PSLAMCH
272 EXTERNAL lsame, indxg2p, numroc, sl_gridreshape,
276 EXTERNAL blacs_gridexit, blacs_gridinfo,
chk1mat,
279 $
pxerbla, scopy, sgamn2d, sgamx2d, sscal
282 INTRINSIC abs,
cmplx, ichar, int,
max,
min, mod, real,
287 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
297 CALL blacs_gridinfo( desca( ctxt_ ), nprow, npcol, myrow, mycol )
312 wantz = lsame( jobz,
'V' )
313 IF( nprow.EQ.-1 )
THEN
314 info = -( 700+ctxt_ )
315 ELSE IF( wantz )
THEN
316 IF( desca( ctxt_ ).NE.descz( ctxt_ ) )
THEN
317 info = -( 1200+ctxt_ )
321 CALL chk1mat( n, 3, n, 3, ia, ja, desca, 7, info )
323 $
CALL chk1mat( n, 3, n, 3, iz, jz, descz, 12, info )
329 safmin = pslamch( desca( ctxt_ ),
'Safe minimum' )
330 eps = pslamch( desca( ctxt_ ),
'Precision' )
331 smlnum = safmin / eps
332 bignum = one / smlnum
333 rmin = sqrt( smlnum )
334 rmax =
min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
340 lower = lsame( uplo,
'L' )
342 rsrc_a = desca( rsrc_ )
343 csrc_a = desca( csrc_ )
344 iroffa = mod( ia-1, mb_a )
345 icoffa = mod( ja-1, nb_a )
346 iarow = indxg2p( 1, nb_a, myrow, rsrc_a, nprow )
347 iacol = indxg2p( 1, mb_a, mycol, csrc_a, npcol )
348 np0 = numroc( n+iroffa, nb, myrow, iarow, nprow )
349 nq0 = numroc( n+icoffa, nb, mycol, iacol, npcol )
353 rsrc_z = descz( rsrc_ )
354 iroffz = mod( iz-1, mb_a )
355 izrow = indxg2p( 1, nb_a, myrow, rsrc_z, nprow )
363 CALL pchetrd( uplo, n, a, ia, ja, desca, rwork( indd ),
364 $ rwork( inde ), work( indtau ),
365 $ work( indwork ), -1, iinfo )
366 sizepchetrd = int( abs( work( 1 ) ) )
371 CALL pcunmtr(
'L', uplo,
'N', n, n, a, ia, ja, desca,
372 $ work( indtau ), z, iz, jz, descz,
373 $ work( indwork ), -1, iinfo )
374 sizepcunmtr = int( abs( work( 1 ) ) )
382 rsizecsteqr2 =
min( 1, 2*n-2 )
395 contextc = sl_gridreshape( desca( ctxt_ ), 0, 1, 1,
397 CALL blacs_gridinfo( contextc, nprowc, npcolc, myprowc,
399 nrc = numroc( n, nb_a, myprowc, 0, nprocs )
401 CALL descinit( descqr, n, n, nb, nb, 0, 0, contextc, ldc,
419 indwork2 = indwork + n*ldc
420 llwork = lwork - indwork + 1
427 llrwork = lrwork - indrwork + 1
431 lrwmin = 2*n + rsizecsteqr2
432 lwmin = 3*n +
max( sizepchetrd, sizepcunmtr, sizecsteqr2 )
436 IF( .NOT.( wantz .OR. lsame( jobz,
'N' ) ) )
THEN
438 ELSE IF( .NOT.( lower .OR. lsame( uplo,
'U' ) ) )
THEN
440 ELSE IF( lwork.LT.lwmin .AND. lwork.NE.-1 )
THEN
442 ELSE IF( lrwork.LT.lrwmin .AND. lrwork.NE.-1 )
THEN
444 ELSE IF( iroffa.NE.0 )
THEN
446 ELSE IF( desca( mb_ ).NE.desca( nb_ ) )
THEN
450 IF( iroffa.NE.iroffz )
THEN
452 ELSE IF( iarow.NE.izrow )
THEN
454 ELSE IF( desca( m_ ).NE.descz( m_ ) )
THEN
456 ELSE IF( desca( n_ ).NE.descz( n_ ) )
THEN
458 ELSE IF( desca( mb_ ).NE.descz( mb_ ) )
THEN
460 ELSE IF( desca( nb_ ).NE.descz( nb_ ) )
THEN
462 ELSE IF( desca( rsrc_ ).NE.descz( rsrc_ ) )
THEN
463 info = -( 1200+rsrc_ )
464 ELSE IF( desca( ctxt_ ).NE.descz( ctxt_ ) )
THEN
465 info = -( 1200+ctxt_ )
470 idum1( 1 ) = ichar(
'V' )
472 idum1( 1 ) = ichar(
'N' )
476 idum1( 2 ) = ichar(
'L' )
478 idum1( 2 ) = ichar(
'U' )
481 IF( lwork.EQ.-1 )
THEN
488 CALL pchk2mat( n, 3, n, 3, ia, ja, desca, 7, n, 3, n, 3, iz,
489 $ jz, descz, 12, 3, idum1, idum2, info )
491 CALL pchk1mat( n, 3, n, 3, ia, ja, desca, 7, 3, idum1,
494 work( 1 ) =
cmplx( lwmin )
495 rwork( 1 ) = real( lrwmin )
499 CALL pxerbla( desca( ctxt_ ),
'PCHEEV', -info )
501 $
CALL blacs_gridexit( contextc )
503 ELSE IF( lwork.EQ.-1 .OR. lrwork.EQ.-1 )
THEN
505 $
CALL blacs_gridexit( contextc )
513 anrm = pclanhe(
'M', uplo, n, a, ia, ja, desca,
514 $ rwork( indrwork ) )
517 IF( anrm.GT.zero .AND. anrm.LT.rmin )
THEN
520 ELSE IF( anrm.GT.rmax )
THEN
525 IF( iscale.EQ.1 )
THEN
526 CALL pclascl( uplo, one, sigma, n, n, a, ia, ja, desca, iinfo )
531 CALL pchetrd( uplo, n, a, ia, ja, desca, rwork( indrd ),
532 $ rwork( indre ), work( indtau ), work( indwork ),
538 CALL pcelget(
'A',
' ', work( indd+i-1 ), a, i+ia-1, i+ja-1,
540 rwork( indrd+i-1 ) = real( work( indd+i-1 ) )
542 IF( lsame( uplo,
'U' ) )
THEN
544 CALL pcelget(
'A',
' ', work( inde+i-1 ), a, i+ia-1, i+ja,
546 rwork( indre+i-1 ) = real( work( inde+i-1 ) )
550 CALL pcelget(
'A',
' ', work( inde+i-1 ), a, i+ia, i+ja-1,
552 rwork( indre+i-1 ) = real( work( inde+i-1 ) )
558 CALL pclaset(
'Full', n, n, czero, cone, work( indwork ), 1, 1,
565 CALL csteqr2(
'I', n, rwork( indrd ), rwork( indre ),
566 $ work( indwork ), ldc, nrc, rwork( indrwork ),
569 CALL pcgemr2d( n, n, work( indwork ), 1, 1, descqr, z, ia, ja,
572 CALL pcunmtr(
'L', uplo,
'N', n, n, a, ia, ja, desca,
573 $ work( indtau ), z, iz, jz, descz,
574 $ work( indwork ), llwork, iinfo )
578 CALL csteqr2(
'N', n, rwork( indrd ), rwork( indre ),
579 $ work( indwork ), 1, 1, rwork( indrwork ), info )
584 CALL scopy( n, rwork( indd ), 1, w, 1 )
588 IF( iscale.EQ.1 )
THEN
589 CALL sscal( n, one / sigma, w, 1 )
592 work( 1 ) = real( lwmin )
597 CALL blacs_gridexit( contextc )
603 IF( n.LE.ithval )
THEN
611 lrmin = int( rwork( 1 ) )
615 rwork( i+indtau ) = w( ( i-1 )*k+1 )
616 rwork( i+inde ) = w( ( i-1 )*k+1 )
619 CALL sgamn2d( desca( ctxt_ ),
'All',
' ', j, 1, rwork( 1+indtau ),
620 $ j, 1, 1, -1, -1, 0 )
621 CALL sgamx2d( desca( ctxt_ ),
'All',
' ', j, 1, rwork( 1+inde ),
622 $ j, 1, 1, -1, -1, 0 )
625 IF( info.EQ.0 .AND. ( rwork( i+indtau )-rwork( i+inde ).NE.