1 SUBROUTINE pdsyevx( 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 DOUBLE PRECISION ABSTOL, ORFAC, VL, VU
18 INTEGER DESCA( * ), DESCZ( * ), ICLUSTR( * ),
19 $ IFAIL( * ), IWORK( * )
20 DOUBLE PRECISION A( * ), GAP( * ), W( * ), WORK( * ), Z( * )
464 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, CTXT_, M_, N_,
465 $ MB_, NB_, RSRC_, CSRC_, LLD_
466 PARAMETER ( BLOCK_CYCLIC_2D = 1, dlen_ = 9, dtype_ = 1,
467 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
468 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
469 DOUBLE PRECISION ZERO, ONE, TEN, FIVE
470 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0, ten = 10.0d+0,
472 INTEGER IERREIN, IERRCLS, IERRSPC, IERREBZ
473 parameter( ierrein = 1, ierrcls = 2, ierrspc = 4,
477 LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, QUICKRETURN,
480 INTEGER ANB, CSRC_A, I, IAROW, ICOFFA, ICTXT, IINFO,
481 $ INDD, INDD2, INDE, INDE2, INDIBL, INDISP,
482 $ indtau, indwork, iroffa, iroffz, iscale,
483 $ isizestebz, isizestein, izrow, lallwork,
484 $ liwmin, llwork, lwmin, lwopt, maxeigs, mb_a,
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 DOUBLE PRECISION ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN,
490 $ SIGMA, SMLNUM, VLL, VUU
493 INTEGER IDUM1( 4 ), IDUM2( 4 )
497 INTEGER ICEIL, INDXG2P, NUMROC, PJLAENV
498 DOUBLE PRECISION PDLAMCH,
499 EXTERNAL lsame, iceil, indxg2p, numroc, pjlaenv,
509 INTRINSIC abs, dble, ichar, int,
max,
min, mod, sqrt
513 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
516 quickreturn = ( n.EQ.0 )
520 ictxt = desca( ctxt_ )
524 wantz = lsame( jobz,
'V' )
525 IF( nprow.EQ.-1 )
THEN
526 info = -( 800+ctxt_ )
527 ELSE IF( wantz )
THEN
528 IF( ictxt.NE.descz( ctxt_ ) )
THEN
529 info = -( 2100+ctxt_ )
533 CALL chk1mat( n, 4, n, 4, ia, ja, desca, 8, info )
535 $
CALL chk1mat( n, 4, n, 4, iz, jz, descz, 21, info )
541 safmin = pdlamch( ictxt,
'Safe minimum' )
542 eps = pdlamch( ictxt,
'Precision' )
543 smlnum = safmin / eps
544 bignum = one / smlnum
545 rmin = sqrt( smlnum )
546 rmax =
min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
549 lower = lsame( uplo,
'L' )
550 alleig = lsame( range,
'A' )
551 valeig = lsame( range,
'V' )
552 indeig = lsame( range,
'I' )
562 llwork = lwork - indwork + 1
566 isizestein = 3*n + nprocs + 1
567 isizestebz =
max( 4*n, 14, nprocs )
568 indibl = (
max( isizestein, isizestebz ) ) + 1
574 IF( lwork.EQ.-1 .OR. liwork.EQ.-1 )
577 nnp =
max( n, nprocs+1, 4 )
586 rsrc_a = desca( rsrc_ )
587 csrc_a = desca( csrc_ )
588 iroffa = mod( ia-1, mb_a )
589 icoffa = mod( ja-1, nb_a )
590 iarow = indxg2p( 1, nb_a, myrow, rsrc_a, nprow )
591 np0 = numroc( n+iroffa, nb, 0, 0, nprow )
592 mq0 = numroc( n+icoffa, nb, 0, 0, npcol )
594 rsrc_z = descz( rsrc_ )
595 iroffz = mod( iz-1, mb_a )
596 izrow = indxg2p( 1, nb_a, myrow, rsrc_z, nprow )
602 IF( ( .NOT.wantz ) .OR. ( valeig .AND. ( .NOT.lquery ) ) )
604 lwmin = 5*n +
max( 5*nn, nb*( np0+1 ) )
606 mq0 = numroc(
max( n, nb, 2 ), nb, 0, 0, npcol )
607 lwopt = 5*n +
max( 5*nn, np0*mq0+2*nb*nb )
613 IF( alleig .OR. valeig )
THEN
615 ELSE IF( indeig )
THEN
618 mq0 = numroc(
max( neig, nb, 2 ), nb, 0, 0, npcol )
619 lwmin = 5*n +
max( 5*nn, np0*mq0+2*nb*nb ) +
620 $ iceil( neig, nprow*npcol )*nn
628 anb = pjlaenv( ictxt, 3,
'PDSYTTRD',
'L', 0, 0, 0, 0 )
629 sqnpc = int( sqrt( dble( nprow*npcol ) ) )
630 nps =
max( numroc( n, 1, 0, 0, sqnpc ), 2*anb )
631 nsytrd_lwopt = 2*( anb+1 )*( 4*nps+2 ) + ( nps+4 )*nps
632 lwopt =
max( lwopt, 5*n+nsytrd_lwopt
636 IF( myrow.EQ.0 .AND. mycol.EQ.0 )
THEN
645 CALL dgebs2d( ictxt,
'ALL',
' ', 3, 1, work, 3 )
647 CALL dgebr2d( ictxt,
'ALL',
' ', 3, 1, work, 3, 0, 0 )
649 IF( .NOT.( wantz .OR. lsame( jobz,
'N' ) ) )
THEN
651 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) )
THEN
653 ELSE IF( .NOT.( lower .OR. lsame( uplo,
'U' ) ) )
THEN
655 ELSE IF( valeig .AND. n.GT.0 .AND. vu.LE.vl )
THEN
657 ELSE IF( indeig .AND. ( il.LT.1 .OR. il.GT.
max( 1, n ) ) )
660 ELSE IF( indeig .AND. ( iu.LT.
min( n, il ) .OR. iu.GT.n ) )
663 ELSE IF( lwork.LT.lwmin .AND. lwork.NE.-1 )
THEN
665 ELSE IF( liwork.LT.liwmin .AND. liwork.NE.-1 )
THEN
667 ELSE IF( valeig .AND. ( abs( work( 2 )-vl ).GT.five*eps*
670 ELSE IF( valeig .AND. ( abs( work( 3 )-vu ).GT.five*eps*
673 ELSE IF( abs( work( 1 )-abstol ).GT.five*eps*abs( abstol ) )
676 ELSE IF( iroffa.NE.0 )
THEN
678 ELSE IF( desca( mb_ ).NE.desca( nb_ ) )
THEN
682 IF( iroffa.NE.iroffz )
THEN
684 ELSE IF( iarow.NE.izrow )
THEN
686 ELSE IF( desca( m_ ).NE.descz( m_ ) )
THEN
688 ELSE IF( desca( n_ ).NE.descz( n_ ) )
THEN
690 ELSE IF( desca( mb_ ).NE.descz( mb_ ) )
THEN
692 ELSE IF( desca( nb_ ).NE.descz( nb_ ) )
THEN
694 ELSE IF( desca( rsrc_ ).NE.descz( rsrc_ ) )
THEN
695 info = -( 2100+rsrc_ )
696 ELSE IF( desca( csrc_ ).NE.descz( csrc_ ) )
THEN
697 info = -( 2100+csrc_ )
698 ELSE IF( ictxt.NE.descz( ctxt_ ) )
THEN
699 info = -( 2100+ctxt_ )
704 idum1( 1 ) = ichar(
'V' )
706 idum1( 1 ) = ichar( 'n
' )
710 IDUM1( 2 ) = ICHAR( 'l
' )
712 IDUM1( 2 ) = ICHAR( 'u
' )
716 IDUM1( 3 ) = ICHAR( 'a
' )
717 ELSE IF( INDEIG ) THEN
718 IDUM1( 3 ) = ICHAR( 'i
' )
720 IDUM1( 3 ) = ICHAR( 'v
' )
730 CALL PCHK2MAT( N, 4, N, 4, IA, JA, DESCA, 8, N, 4, N, 4, IZ,
731 $ JZ, DESCZ, 21, 4, IDUM1, IDUM2, INFO )
733 CALL PCHK1MAT( N, 4, N, 4, IA, JA, DESCA, 8, 4, IDUM1,
736 WORK( 1 ) = DBLE( LWOPT )
741 CALL PXERBLA( ICTXT, 'pdsyevx', -INFO )
743 ELSE IF( LQUERY ) THEN
749 IF( QUICKRETURN ) THEN
755 WORK( 1 ) = DBLE( LWOPT )
772 ANRM = PDLANSY( 'm
', UPLO, N, A, IA, JA, DESCA, WORK( INDWORK ) )
774.GT..AND..LT.
IF( ANRMZERO ANRMRMIN ) THEN
778.GT.
ELSE IF( ANRMRMAX ) THEN
784.EQ.
IF( ISCALE1 ) THEN
785 CALL PDLASCL( UPLO, ONE, SIGMA, N, N, A, IA, JA, DESCA, IINFO )
787 $ ABSTLL = ABSTOL*SIGMA
791.EQ.
IF( VUUVLL ) THEN
792 VUU = VUU + 2*MAX( ABS( VUU )*EPS, SAFMIN )
801 CALL PDSYNTRD( UPLO, N, A, IA, JA, DESCA, WORK( INDD ),
802 $ WORK( INDE ), WORK( INDTAU ), WORK( INDWORK ),
813.EQ..AND..EQ..AND..EQ..AND..EQ.
IF( IA1 JA1 RSRC_A0 CSRC_A0 )
815 CALL PDLARED1D( N, IA, JA, DESCA, WORK( INDD ), WORK( INDD2 ),
816 $ WORK( INDWORK ), LLWORK )
818 CALL PDLARED1D( N, IA, JA, DESCA, WORK( INDE ), WORK( INDE2 ),
819 $ WORK( INDWORK ), LLWORK )
824 CALL PDELGET( 'a
', ' ', WORK( INDD2+I-1 ), A, I+IA-1,
827 IF( LSAME( UPLO, 'u
' ) ) THEN
829 CALL PDELGET( 'a
', ' ', WORK( INDE2+I-1 ), A, I+IA-1,
834 CALL PDELGET( 'a
', ' ', WORK( INDE2+I-1 ), A, I+IA,
848 CALL PDSTEBZ( ICTXT, RANGE, ORDER, N, VLL, VUU, IL, IU, ABSTLL,
849 $ WORK( INDD2 ), WORK( INDE2+OFFSET ), M, NSPLIT, W,
850 $ IWORK( INDIBL ), IWORK( INDISP ), WORK( INDWORK ),
851 $ LLWORK, IWORK( 1 ), ISIZESTEBZ, IINFO )
861.NE.
IF( IINFO0 ) THEN
862 INFO = INFO + IERREBZ
864 IWORK( INDIBL+I-1 ) = ABS( IWORK( INDIBL+I-1 ) )
881 CALL IGAMN2D( ICTXT, 'a
', ' ', 1, 1, LALLWORK, 1, 1, 1, -1,
884 MAXEIGS = DESCZ( N_ )
886 DO 50 NZ = MIN( MAXEIGS, M ), 0, -1
887 MQ0 = NUMROC( NZ, NB, 0, 0, NPCOL )
888 SIZESTEIN = ICEIL( NZ, NPROCS )*N + MAX( 5*N, NP0*MQ0 )
889 SIZEORMTR = MAX( ( NB*( NB-1 ) ) / 2, ( MQ0+NP0 )*NB ) +
892 SIZESYEVX = MAX( SIZESTEIN, SIZEORMTR )
893.LE.
IF( SIZESYEVXLALLWORK )
902 INFO = INFO + IERRSPC
917.GT.
IF( NSPLIT1 ) THEN
918 CALL DLASRT( 'i
', M, W, IINFO )
922 VUU = W( NZ ) - TEN*( EPS*ANRM+SAFMIN )
923.GE.
IF( VLLVUU ) THEN
926 CALL PDSTEBZ( ICTXT, RANGE, ORDER, N, VLL, VUU, IL,
927 $ IU, ABSTLL, WORK( INDD2 ),
928 $ WORK( INDE2+OFFSET ), NZZ, NSPLIT, W,
929 $ IWORK( INDIBL ), IWORK( INDISP ),
930 $ WORK( INDWORK ), LLWORK, IWORK( 1 ),
931 $ ISIZESTEBZ, IINFO )
934.EQ.
IF( MOD( INFO / IERREBZ, 1 )0 ) THEN
935.GT..OR..NE.
IF( NZZNZ IINFO0 ) THEN
936 INFO = INFO + IERREBZ
944 CALL PDSTEIN( N, WORK( INDD2 ), WORK( INDE2+OFFSET ), NZ, W,
945 $ IWORK( INDIBL ), IWORK( INDISP ), ORFAC, Z, IZ,
946 $ JZ, DESCZ, WORK( INDWORK ), LALLWORK, IWORK( 1 ),
947 $ ISIZESTEIN, IFAIL, ICLUSTR, GAP, IINFO )
950 $ INFO = INFO + IERRCLS
951.NE.
IF( MOD( IINFO, NZ+1 )0 )
952 $ INFO = INFO + IERREIN
958 CALL PDORMTR( 'l
', UPLO, 'n
', N, NZ, A, IA, JA, DESCA,
959 $ WORK( INDTAU ), Z, IZ, JZ, DESCZ,
960 $ WORK( INDWORK ), LLWORK, IINFO )
967.EQ.
IF( ISCALE1 ) THEN
968 CALL DSCAL( M, ONE / SIGMA, W, 1 )
971 WORK( 1 ) = DBLE( LWOPT )