1 SUBROUTINE pchegvx( 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, RANGE, UPLO
14 INTEGER IA, IB, IBTYPE, IL, INFO, IU, IZ, JA, JB, JZ,
15 $ LIWORK, LRWORK, LWORK, M, N, NZ
16 REAL ABSTOL, ORFAC, VL, VU
20 INTEGER DESCA( * ), DESCB( * ), DESCZ( * ),
21 $ ICLUSTR( * ), IFAIL( * ), IWORK( * )
22 REAL GAP( * ), RWORK( * ), W( * )
23 COMPLEX 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.0e+0 )
502 PARAMETER ( FIVE = 5.0e+0, zero = 0.0e+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
517 INTEGER IDUM1( 5 ), IDUM2( 5 )
521 INTEGER ICEIL, INDXG2P, NUMROC, PJLAENV
523 EXTERNAL LSAME, ICEIL, INDXG2P, NUMROC, PJLAENV, PSLAMCH
528 $
pxerbla, sgebr2d, sgebs2d, sscal
531 INTRINSIC abs,
cmplx, dble, ichar, int,
max,
min, mod,
536 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
541 ictxt = desca( ctxt_ )
542 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
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 = pslamch( 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 sgebs2d( desca( ctxt_ ),
'ALL',
' ', 3, 1, rwork,
580 CALL sgebr2d( 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,
'PCHETTRD',
'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 )-vl ).GT.five*eps*
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 ) =
cmplx( real( lwopt ) )
759 rwork( 1 ) = real( lrwopt )
762 CALL pxerbla( ictxt,
'PCHEGVX ', -info )
764 ELSE IF( lquery )
THEN
770 CALL pcpotrf( uplo, n, b, ib, jb, descb, info )
773 work( 1 ) =
cmplx( real( lwopt ) )
774 rwork( 1 ) = real( lrwopt )
782 CALL pchengst( ibtype, uplo, n, a, ia, ja, desca, b, ib, jb,
783 $ descb, scale, work, lwork, info )
784 CALL pcheevx( 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 pctrsm(
'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 pctrmm(
'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 sscal( n, scale, w, 1 )
830 work( 1 ) =
cmplx( real( lwopt ) )
831 rwork( 1 ) = real( lrwopt )