1 SUBROUTINE pssyevx( JOBZ, RANGE, UPLO, N, A, IA, JA, DESCA, VL,
2 $ VU, IL, IU, ABSTOL, M, NZ, W, ORFAC, Z, IZ,
3 $ JZ, DESCZ, WORK, LWORK, IWORK, LIWORK, IFAIL,
12 CHARACTER JOBZ, RANGE, UPLO
13 INTEGER IA, IL, INFO, IU, IZ, JA, JZ, LIWORK, LWORK, M,
15 REAL ABSTOL, ORFAC, VL, VU
18 INTEGER DESCA( * ), DESCZ( * ), ICLUSTR( * ),
19 $ IFAIL( * ), IWORK( * )
20 REAL A( * ), GAP( * ), W( * ), WORK( * ), Z( * )
464 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, CTXT_, M_,
466 PARAMETER ( BLOCK_CYCLIC_2D = 1, dlen_ = 9, dtype_ = 1,
467 $ ctxt_ = 2, m_ = 3, n_ =
469 REAL ZERO, ONE, TEN, FIVE
472 INTEGER IERREIN, IERRCLS, , IERREBZ
477 LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, QUICKRETURN,
480 INTEGER ANB, CSRC_A, I, IAROW, ICOFFA, ICTXT, IINFO,
481 $ INDD, INDD2, INDE, INDE2, , INDISP,
483 $ isizestebz, isizestein, izrow, lallwork,
485 $ mq0, mycol, myrow, nb, nb_a, neig, nn, nnp,
486 $ np0, npcol, nprocs, nprow, nps, nsplit,
487 $ nsytrd_lwopt, nzz, offset, rsrc_a, rsrc_z,
488 $ sizeormtr, sizestein, sizesyevx, sqnpc
489 REAL ABSTLL, ANRM, BIGNUM, EPS, RMAX
493 INTEGER IDUM1( 4 ), IDUM2( 4 )
497 INTEGER ICEIL, INDXG2P, NUMROC, PJLAENV
498 REAL PSLAMCH, PSLANSY
499 EXTERNAL lsame, iceil, indxg2p, numroc, pjlaenv,
509 INTRINSIC abs, dble, ichar, int,
max,
min, mod, real,
514 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
517 quickreturn = ( n.EQ.0 )
521 ictxt = desca( ctxt_ )
525 wantz = lsame( jobz,
'V' )
526 IF( nprow.EQ.-1 )
THEN
527 info = -( 800+ctxt_ )
528 ELSE IF( wantz )
THEN
529 IF( ictxt.NE.descz( ctxt_ ) )
THEN
530 info = -( 2100+ctxt_ )
534 CALL chk1mat( n, 4, n, 4, ia, ja, desca, 8, info )
536 $
CALL chk1mat( n, 4, n, 4, iz, jz, descz, 21, info )
542 safmin = pslamch( ictxt,
'Safe minimum' )
543 eps = pslamch( ictxt,
'Precision' )
544 smlnum = safmin / eps
545 bignum = one / smlnum
546 rmin = sqrt( smlnum )
547 rmax =
min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
550 lower = lsame( uplo,
'L' )
551 alleig = lsame( range,
'A' )
552 valeig = lsame( range, 'v
' )
553 INDEIG = LSAME( RANGE, 'i
' )
563 LLWORK = LWORK - INDWORK + 1
567 ISIZESTEIN = 3*N + NPROCS + 1
568 ISIZESTEBZ = MAX( 4*N, 14, NPROCS )
569 INDIBL = ( MAX( ISIZESTEIN, ISIZESTEBZ ) ) + 1
575.EQ..OR..EQ.
IF( LWORK-1 LIWORK-1 )
578 NNP = MAX( N, NPROCS+1, 4 )
587 RSRC_A = DESCA( RSRC_ )
588 CSRC_A = DESCA( CSRC_ )
589 IROFFA = MOD( IA-1, MB_A )
590 ICOFFA = MOD( JA-1, NB_A )
591 IAROW = INDXG2P( 1, NB_A, MYROW, RSRC_A, NPROW )
592 NP0 = NUMROC( N+IROFFA, NB, 0, 0, NPROW )
593 MQ0 = NUMROC( N+ICOFFA, NB, 0, 0, NPCOL )
595 RSRC_Z = DESCZ( RSRC_ )
596 IROFFZ = MOD( IZ-1, MB_A )
597 IZROW = INDXG2P( 1, NB_A, MYROW, RSRC_Z, NPROW )
603.NOT..OR..AND..NOT.
IF( ( WANTZ ) ( VALEIG ( LQUERY ) ) )
605 LWMIN = 5*N + MAX( 5*NN, NB*( NP0+1 ) )
607 MQ0 = NUMROC( MAX( N, NB, 2 ), NB, 0, 0, NPCOL )
608 LWOPT = 5*N + MAX( 5*NN, NP0*MQ0+2*NB*NB )
614.OR.
IF( ALLEIG VALEIG ) THEN
616 ELSE IF( INDEIG ) THEN
619 MQ0 = NUMROC( MAX( NEIG, NB, 2 ), NB, 0, 0, NPCOL )
620 LWMIN = 5*N + MAX( 5*NN, NP0*MQ0+2*NB*NB ) +
621 $ ICEIL( NEIG, NPROW*NPCOL )*NN
629 ANB = PJLAENV( ICTXT, 3, 'pssyttrd', 'l
', 0, 0, 0, 0 )
630 SQNPC = INT( SQRT( DBLE( NPROW*NPCOL ) ) )
631 NPS = MAX( NUMROC( N, 1, 0, 0, SQNPC ), 2*ANB )
632 NSYTRD_LWOPT = 2*( ANB+1 )*( 4*NPS+2 ) + ( NPS+4 )*NPS
633 LWOPT = MAX( LWOPT, 5*N+NSYTRD_LWOPT )
637.EQ..AND..EQ.
IF( MYROW0 MYCOL0 ) THEN
646 CALL SGEBS2D( ICTXT, 'all
', ' ', 3, 1, WORK, 3 )
648 CALL SGEBR2D( ICTXT, 'all
', ' ', 3, 1, WORK, 3, 0, 0 )
650.NOT..OR.
IF( ( WANTZ LSAME( JOBZ, 'n
' ) ) ) THEN
652.NOT..OR..OR.
ELSE IF( ( ALLEIG VALEIG INDEIG ) ) THEN
654.NOT..OR.
ELSE IF( ( LOWER LSAME( UPLO, 'u
' ) ) ) THEN
656.AND..GT..AND..LE.
ELSE IF( VALEIG N0 VUVL ) THEN
658.AND..LT..OR..GT.
ELSE IF( INDEIG ( IL1 ILMAX( 1, N ) ) )
661.AND..LT..OR..GT.
ELSE IF( INDEIG ( IUMIN( N, IL ) IUN ) )
664.LT..AND..NE.
ELSE IF( LWORKLWMIN LWORK-1 ) THEN
666.LT..AND..NE.
ELSE IF( LIWORKLIWMIN LIWORK-1 ) THEN
668.AND..GT.
ELSE IF( VALEIG ( ABS( WORK( 2 )-VL )FIVE*EPS*
671.AND..GT.
ELSE IF( VALEIG ( ABS( WORK( 3 )-VU )FIVE*EPS*
674.GT.
ELSE IF( ABS( WORK( 1 )-ABSTOL )FIVE*EPS*ABS( ABSTOL ) )
677.NE.
ELSE IF( IROFFA0 ) THEN
679.NE.
ELSE IF( DESCA( MB_ )DESCA( NB_ ) ) THEN
683.NE.
IF( IROFFAIROFFZ ) THEN
685.NE.
ELSE IF( IAROWIZROW ) THEN
687.NE.
ELSE IF( DESCA( M_ )DESCZ( M_ ) ) THEN
689.NE.
ELSE IF( DESCA( N_ )DESCZ( N_ ) ) THEN
691.NE.
ELSE IF( DESCA( MB_ )DESCZ( MB_ ) ) THEN
693.NE.
ELSE IF( DESCA( NB_ )DESCZ( NB_ ) ) THEN
695.NE.
ELSE IF( DESCA( RSRC_ )DESCZ( RSRC_ ) ) THEN
696 INFO = -( 2100+RSRC_ )
697.NE.
ELSE IF( DESCA( CSRC_ )DESCZ( CSRC_ ) ) THEN
698 INFO = -( 2100+CSRC_ )
699.NE.
ELSE IF( ICTXTDESCZ( CTXT_ ) ) THEN
700 INFO = -( 2100+CTXT_ )
705 IDUM1( 1 ) = ICHAR( 'v
' )
707 IDUM1( 1 ) = ICHAR( 'n
' )
711 IDUM1( 2 ) = ICHAR( 'l
' )
713 IDUM1( 2 ) = ICHAR( 'u
' )
717 IDUM1( 3 ) = ICHAR( 'a
' )
718 ELSE IF( INDEIG ) THEN
719 IDUM1( 3 ) = ICHAR( 'i
' )
721 IDUM1( 3 ) = ICHAR( 'v
' )
731 CALL PCHK2MAT( N, 4, N, 4, IA, JA, DESCA, 8, N, 4, N, 4, IZ,
732 $ JZ, DESCZ, 21, 4, IDUM1, IDUM2, INFO )
734 CALL PCHK1MAT( N, 4, N, 4, IA, JA, DESCA, 8, 4, IDUM1,
737 WORK( 1 ) = REAL( LWOPT )
742 CALL PXERBLA( ICTXT, 'pssyevx', -INFO )
744 ELSE IF( LQUERY ) THEN
750 IF( QUICKRETURN ) THEN
756 WORK( 1 ) = REAL( LWOPT )
773 ANRM = PSLANSY( 'm
', UPLO, N, A, IA, JA, DESCA, WORK( INDWORK ) )
775.GT..AND..LT.
IF( ANRMZERO ANRMRMIN ) THEN
779.GT.
ELSE IF( ANRMRMAX ) THEN
785.EQ.
IF( ISCALE1 ) THEN
786 CALL PSLASCL( UPLO, ONE, SIGMA, N, N, A, IA, JA, DESCA, IINFO )
788 $ ABSTLL = ABSTOL*SIGMA
792.EQ.
IF( VUUVLL ) THEN
793 VUU = VUU + 2*MAX( ABS( VUU )*EPS, SAFMIN )
802 CALL PSSYNTRD( UPLO, N, A, IA, JA, DESCA, WORK( INDD ),
803 $ WORK( INDE ), WORK( INDTAU ), WORK( INDWORK ),
814.EQ..AND..EQ..AND..EQ..AND..EQ.
IF( IA1 JA1 RSRC_A0 CSRC_A0 )
816 CALL PSLARED1D( N, IA, JA, DESCA, WORK( INDD ), WORK( INDD2 ),
817 $ WORK( INDWORK ), LLWORK )
819 CALL PSLARED1D( N, IA, JA, DESCA, WORK( INDE ), WORK( INDE2 ),
820 $ WORK( INDWORK ), LLWORK )
825 CALL PSELGET( 'a
', ' ', WORK( INDD2+I-1 ), A, I+IA-1,
828 IF( LSAME( UPLO, 'u
' ) ) THEN
830 CALL PSELGET( 'a
', ' ', WORK( INDE2+I-1 ), A, I+IA-1,
835 CALL PSELGET( 'a
', ' ', work( inde2+i-1 ), a, i+ia,
849 CALL psstebz( ictxt, range, order, n, vll, vuu, il, iu, abstll,
850 $ work( indd2 ), work( inde2+offset ), m, nsplit, w,
851 $ iwork( indibl ), iwork( indisp ), work( indwork ),
852 $ llwork, iwork( 1 ), isizestebz, iinfo )
862 IF( iinfo.NE.0 )
THEN
863 info = info + ierrebz
865 iwork( indibl+i-1 ) = abs( iwork( indibl+i-1 ) )
882 CALL igamn2d( ictxt,
'A',
' ', 1, 1, lallwork, 1, 1, 1, -1,
885 maxeigs = descz( n_ )
887 DO 50 nz =
min( maxeigs, m ), 0, -1
889 sizestein = iceil( nz, nprocs )*n +
max( 5*n, np0*mq0 )
890 sizeormtr =
max( ( nb*( nb-1 ) ) / 2, ( mq0+np0 )*nb ) +
893 sizesyevx =
max( sizestein, sizeormtr )
894 IF( sizesyevx.LE.lallwork )
903 info = info + ierrspc
918 IF( nsplit.GT.1 )
THEN
919 CALL slasrt(
'I', m, w, iinfo )
923 vuu = w( nz ) - ten*( eps*anrm+safmin )
924 IF( vll.GE.vuu )
THEN
927 CALL psstebz( ictxt, range, order, n, vll, vuu, il,
928 $ iu, abstll, work( indd2 ),
929 $ work( inde2+offset ), nzz, nsplit, w,
930 $ iwork( indibl ), iwork( indisp ),
931 $ work( indwork ), llwork, iwork( 1 ),
932 $ isizestebz, iinfo )
935 IF( mod( info / ierrebz, 1 ).EQ.0 )
THEN
936 IF( nzz.GT.nz .OR. iinfo.NE.0 )
THEN
937 info = info + ierrebz
945 CALL psstein( n, work( indd2 ), work( inde2+offset ), nz, w,
946 $ iwork( indibl ), iwork( indisp ), orfac, z, iz,
947 $ jz, descz, work( indwork ), lallwork, iwork( 1 ),
948 $ isizestein, ifail, iclustr, gap, iinfo )
951 $ info = info + ierrcls
952 IF( mod( iinfo, nz+1 ).NE.0 )
953 $ info = info + ierrein
959 CALL psormtr(
'L', uplo,
'N', n, nz, a, ia, ja, desca,
960 $ work( indtau ), z, iz, jz, descz,
961 $ work( indwork ), llwork, iinfo )
968 IF( iscale.EQ.1 )
THEN
969 CALL sscal( m, one / sigma, w, 1 )
972 work( 1 ) = real( lwopt )