1 SUBROUTINE pzhegvx( IBTYPE, JOBZ, RANGE, UPLO, N, A, IA, JA,
2 $ DESCA, B, IB, JB, DESCB, VL, VU, IL, IU,
3 $ ABSTOL, M, NZ, W, ORFAC, Z, IZ, JZ, DESCZ,
4 $ WORK, LWORK, RWORK, LRWORK, IWORK, LIWORK,
5 $ IFAIL, ICLUSTR, GAP, INFO )
13 CHARACTER JOBZ, , UPLO
14 INTEGER IA, , IBTYPE, IL, INFO, IU, IZ, JA, JB, JZ,
15 $ LIWORK, LRWORK, LWORK, M, N, NZ
16 DOUBLE PRECISION ABSTOL, ORFAC, VL,
20 INTEGER DESCA( * ), DESCB( * ), DESCZ( * ),
21 $ ICLUSTR( * ), IFAIL( * ), IWORK( * )
22 DOUBLE PRECISION GAP( * ), RWORK( * ), W( * )
23 COMPLEX*16 A( * ), B( * ), WORK( * ), Z(
494 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, CTXT_, M_, N_,
495 $ MB_, NB_, RSRC_, CSRC_, LLD_
496 PARAMETER ( BLOCK_CYCLIC_2D = 1, dlen_ = 9, dtype_ = 1,
497 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
498 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
500 parameter( one = 1.0d+0 )
501 DOUBLE PRECISION FIVE, ZERO
502 PARAMETER ( FIVE = 5.0d+0, zero = 0.0d+0 )
504 parameter( ierrnpd = 16 )
507 LOGICAL ALLEIG, INDEIG, LQUERY, UPPER, VALEIG, WANTZ
509 INTEGER ANB, IACOL, IAROW, IBCOL, IBROW, ICOFFA,
510 $ ICOFFB, ICTXT, IROFFA, IROFFB, LIWMIN, LRWMIN,
511 $ lrwopt, lwmin, lwopt, mq0, mycol, myrow, nb,
512 $ neig, nhegst_lwopt, nhetrd_lwopt, nn, np0,
513 $ npcol, nprow, nps, nq0, sqnpc
514 DOUBLE PRECISION EPS, SCALE
517 INTEGER IDUM1( 5 ), IDUM2( 5 )
521 INTEGER ICEIL, INDXG2P, NUMROC, PJLAENV
522 DOUBLE PRECISION PDLAMCH
523 EXTERNAL LSAME, ICEIL, INDXG2P, NUMROC, PJLAENV, PDLAMCH
531 INTRINSIC abs, dble, dcmplx, ichar, int,
max,
min, mod,
536 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
541 ictxt = desca( ctxt_ )
547 IF( nprow.EQ.-1 )
THEN
548 info = -( 900+ctxt_ )
549 ELSE IF( desca( ctxt_ ).NE.descb( ctxt_ ) )
THEN
550 info = -( 1300+ctxt_ )
551 ELSE IF( desca( ctxt_ ).NE.descz( ctxt_ ) )
THEN
552 info = -( 2600+ctxt_ )
557 eps = pdlamch( desca( ctxt_ ),
'Precision' )
559 wantz = lsame( jobz,
'V' )
560 upper = lsame( uplo,
'U' )
561 alleig = lsame( range,
'A' )
562 valeig = lsame( range,
'V' )
563 indeig = lsame( range,
'I' )
564 CALL chk1mat( n, 4, n, 4, ia, ja, desca, 9, info )
565 CALL chk1mat( n, 4, n, 4, ib, jb, descb, 13, info )
566 CALL chk1mat( n, 4, n, 4, iz, jz, descz, 26, info )
568 IF( myrow.EQ.0 .AND. mycol.EQ.0 )
THEN
577 CALL dgebs2d( desca( ctxt_ ),
'ALL',
' ', 3, 1, rwork,
580 CALL dgebr2d( desca( ctxt_ ),
'ALL',
' ', 3, 1, rwork, 3,
583 iarow = indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
585 ibrow = indxg2p( ib, descb( mb_ ), myrow, descb( rsrc_ ),
587 iacol = indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
589 ibcol = indxg2p( jb, descb( nb_ ), mycol, descb( csrc_ ),
591 iroffa = mod( ia-1, desca( mb_ ) )
592 icoffa = mod( ja-1, desca( nb_ ) )
593 iroffb = mod( ib-1, descb( mb_ ) )
594 icoffb = mod( jb-1, descb( nb_ ) )
599 IF( lwork.EQ.-1 .OR. liwork.EQ.-1 .OR. lrwork.EQ.-1 )
602 liwmin = 6*
max( n, ( nprow*npcol )+1, 4 )
606 np0 = numroc( nn, nb, 0, 0, nprow )
608 IF( ( .NOT.wantz ) .OR. ( valeig .AND. ( .NOT.lquery ) ) )
610 lwmin = n +
max( nb*( np0+1 ), 3 )
614 mq0 = numroc(
max( n, nb, 2 ), nb, 0, 0, npcol )
615 lrwopt = 4*n +
max( 5*nn, np0*mq0 )
621 IF( alleig .OR. valeig )
THEN
623 ELSE IF( indeig )
THEN
626 mq0 = numroc(
max( neig, nb, 2 ), nb, 0, 0, npcol )
627 lwmin = n + ( np0+mq0+nb )*nb
629 lrwmin = 4*n +
max( 5*nn, np0*mq0 ) +
630 $ iceil( neig, nprow*npcol )*nn
638 anb = pjlaenv( ictxt, 3,
'PZHETTRD',
'L', 0, 0, 0, 0 )
639 sqnpc = int( sqrt( dble( nprow*npcol ) ) )
640 nps =
max( numroc( n, 1, 0, 0, sqnpc ), 2*anb )
641 nhetrd_lwopt = 2*( anb+1 )*( 4*nps+2 ) + ( nps+4 )*nps
643 np0 = numroc( n, nb, 0, 0, nprow )
644 nq0 = numroc( n, nb, 0, 0, npcol )
645 nhegst_lwopt = 2*np0*nb + nq0*nb + nb*nb
646 lwopt =
max( lwopt, n+nhetrd_lwopt, nhegst_lwopt )
650 IF( ibtype.LT.1 .OR. ibtype.GT.3 )
THEN
652 ELSE IF( .NOT.( wantz .OR. lsame( jobz,
'N' ) ) )
THEN
654 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) )
THEN
656 ELSE IF( .NOT.upper .AND. .NOT.lsame( uplo,
'L' ) )
THEN
658 ELSE IF( n.LT.0 )
THEN
660 ELSE IF( iroffa.NE.0 )
THEN
662 ELSE IF( icoffa.NE.0 )
THEN
664 ELSE IF( desca( mb_ ).NE.desca( nb_ ) )
THEN
666 ELSE IF( desca( m_ ).NE.descb( m_ ) )
THEN
668 ELSE IF( desca( n_ ).NE.descb( n_ ) )
THEN
670 ELSE IF( desca( mb_ ).NE.descb( mb_ ) )
THEN
672 ELSE IF( desca( nb_ ).NE.descb( nb_ ) )
THEN
674 ELSE IF( desca( rsrc_ ).NE.descb( rsrc_ ) )
THEN
675 info = -( 1300+rsrc_ )
676 ELSE IF( desca( csrc_ ).NE.descb( csrc_ ) )
THEN
677 info = -( 1300+csrc_ )
678 ELSE IF( desca( ctxt_ ).NE.descb( ctxt_ ) )
THEN
679 info = -( 1300+ctxt_ )
680 ELSE IF( desca( m_ ).NE.descz( m_ ) )
THEN
682 ELSE IF( desca( n_ ).NE.descz( n_ ) )
THEN
684 ELSE IF( desca( mb_ ).NE.descz( mb_ ) )
THEN
686 ELSE IF( desca( nb_ ).NE.descz( nb_ ) )
THEN
688 ELSE IF( desca( rsrc_ ).NE.descz( rsrc_ ) )
THEN
689 info = -( 2200+rsrc_ )
690 ELSE IF( desca( csrc_ ).NE.descz( csrc_ ) )
THEN
691 info = -( 2200+csrc_ )
692 ELSE IF( desca( ctxt_ ).NE.descz( ctxt_ ) )
THEN
693 info = -( 2200+ctxt_ )
694 ELSE IF( iroffb.NE.0 .OR. ibrow.NE.iarow )
THEN
696 ELSE IF( icoffb.NE.0 .OR. ibcol.NE.iacol )
THEN
698 ELSE IF( valeig .AND. n.GT.0 .AND. vu.LE.vl )
THEN
700 ELSE IF( indeig .AND. ( il.LT.1 .OR. il.GT.
max( 1, n ) ) )
703 ELSE IF( indeig .AND. ( iu.LT.
min( n, il ) .OR. iu.GT.n ) )
706 ELSE IF( valeig .AND. ( abs( rwork( 2
709 ELSE IF( valeig .AND. ( abs( rwork( 3 )-vu ).GT.five*eps*
712 ELSE IF( abs( rwork( 1 )-abstol ).GT.five*eps*
713 $ abs( abstol ) )
THEN
715 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
717 ELSE IF( lrwork.LT.lrwmin .AND. .NOT.lquery )
THEN
719 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
726 idum1( 2 ) = ichar(
'V' )
728 idum1( 2 ) = ichar(
'N' )
732 idum1( 3 ) = ichar(
'U' )
734 idum1( 3 ) = ichar(
'L' )
738 idum1( 4 ) = ichar(
'A' )
739 ELSE IF( indeig )
THEN
740 idum1( 4 ) = ichar(
'I' )
742 idum1( 4 ) = ichar(
'V' )
751 CALL pchk2mat( n, 4, n, 4, ia, ja, desca, 9, n, 4, n, 4, ib,
752 $ jb, descb, 13, 5, idum1, idum2, info )
753 CALL pchk1mat( n, 4, n, 4, iz, jz, descz, 26, 0, idum1, idum2,
758 work( 1 ) = dcmplx( dble( lwopt ) )
759 rwork( 1 ) = dble( lrwopt )
762 CALL pxerbla( ictxt,
'PZHEGVX ', -info )
764 ELSE IF( lquery )
THEN
770 CALL pzpotrf( uplo, n, b, ib, jb, descb, info )
773 work( 1 ) = dcmplx( dble( lwopt ) )
774 rwork( 1 ) = dble( lrwopt )
782 CALL pzhengst( ibtype, uplo, n, a, ia, ja, desca, b, ib, jb,
783 $ descb, scale, work, lwork, info )
784 CALL pzheevx( jobz, range, uplo, n, a, ia, ja, desca, vl, vu, il,
785 $ iu, abstol, m, nz, w, orfac, z, iz, jz, descz, work,
786 $ lwork, rwork, lrwork, iwork, liwork, ifail, iclustr,
794 IF( ibtype.EQ.1 .OR. ibtype.EQ.2 )
THEN
806 CALL pztrsm(
'Left', uplo, trans,
'Non-unit', n, neig, one,
807 $ b, ib, jb, descb, z, iz, jz, descz )
809 ELSE IF( ibtype.EQ.3 )
THEN
820 CALL pztrmm(
'Left', uplo, trans,
'Non-unit', n, neig, one,
821 $ b, ib, jb, descb, z, iz, jz, descz )
825 IF( scale.NE.one )
THEN
826 CALL dscal( n, scale, w, 1 )
830 work( 1 ) = dcmplx( dble( lwopt ) )
831 rwork( 1 ) = dble( lrwopt )