1 SUBROUTINE pdsygvx( 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, IWORK, LIWORK, IFAIL, ICLUSTR,
13 CHARACTER , RANGE, UPLO
14 INTEGER IA, IB, IBTYPE, IL, INFO, , IZ, JA, JB, JZ,
15 $ LIWORK, LWORK, M, N, NZ
16 DOUBLE PRECISION ABSTOL, ORFAC, VL, VU
20 INTEGER DESCA( * ), DESCB( * ), DESCZ( * ),
21 $ ICLUSTR( * ), IFAIL( * ), IWORK( * )
22 DOUBLE PRECISION A( * ), B( * ), GAP( * ), W( * ), WORK( * ),
489 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, CTXT_, M_, N_,
490 $ MB_, NB_, RSRC_, CSRC_, LLD_
491 PARAMETER ( BLOCK_CYCLIC_2D = 1, dlen_ = 9, dtype_ = 1,
492 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
493 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
495 parameter( one = 1.0d+0 )
496 DOUBLE PRECISION FIVE, ZERO
497 PARAMETER ( FIVE = 5.0d+0, zero = 0.0d+0 )
499 parameter( ierrnpd = 16 )
502 LOGICAL ALLEIG, INDEIG, LQUERY, UPPER, VALEIG, WANTZ
504 INTEGER ANB, IACOL, IAROW, IBCOL, IBROW, ICOFFA,
505 $ , ICTXT, IROFFA, IROFFB, LIWMIN, LWMIN,
506 $ lwopt, mq0, mycol, myrow, nb, neig, nn, np0,
507 $ npcol, nprow, nps, nq0, nsygst_lwopt,
508 $ nsytrd_lwopt, sqnpc
509 DOUBLE PRECISION EPS, SCALE
512 INTEGER IDUM1( 5 ), IDUM2( 5 )
516 INTEGER ICEIL, INDXG2P, NUMROC, PJLAENV
517 DOUBLE PRECISION PDLAMCH
518 EXTERNAL LSAME, ICEIL, INDXG2P, NUMROC, PJLAENV, PDLAMCH
526 INTRINSIC abs, dble, ichar, int,
max,
min, mod, sqrt
530 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
535 ictxt = desca( ctxt_ )
541 IF( nprow.EQ.-1 )
THEN
542 info = -( 900+ctxt_ )
543 ELSE IF( desca( ctxt_ ).NE.descb( ctxt_ ) )
THEN
544 info = -( 1300+ctxt_ )
545 ELSE IF( desca( ctxt_ ).NE.descz( ctxt_ ) )
THEN
546 info = -( 2600+ctxt_ )
551 eps = pdlamch( desca( ctxt_ ),
'Precision' )
553 wantz = lsame( jobz,
'V' )
554 upper = lsame( uplo,
'U' )
555 alleig = lsame( range,
'A' )
556 valeig = lsame( range,
'V' )
557 indeig = lsame( range,
'I' )
558 CALL chk1mat( n, 4, n, 4, ia, ja, desca, 9, info )
559 CALL chk1mat( n, 4, n, 4, ib, jb, descb, 13, info )
560 CALL chk1mat( n, 4, n, 4, iz, jz, descz, 26, info )
562 IF( myrow.EQ.0 .AND. mycol.EQ.0 )
THEN
571 CALL dgebs2d( desca( ctxt_
'ALL',
' ', 3, 1, work, 3 )
573 CALL dgebr2d( desca( ctxt_ ),
'ALL',
' ', 3, 1, work, 3,
576 iarow = indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
578 ibrow = indxg2p( ib, descb( mb_ ), myrow, descb( rsrc_ ),
580 iacol = indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
582 ibcol = indxg2p( jb, descb( nb_ ), mycol, descb( csrc_ ),
584 iroffa = mod( ia-1, desca( mb_ ) )
585 icoffa = mod( ja-1, desca( nb_ ) )
586 iroffb = mod( ib-1, descb( mb_ ) )
587 icoffb = mod( jb-1, descb( nb_ ) )
592 IF( lwork.EQ.-1 .OR. liwork.EQ.-1 )
595 liwmin = 6*
max( n, ( nprow*npcol )+1, 4 )
599 np0 = numroc( nn, nb, 0, 0, nprow )
601 IF( ( .NOT.wantz ) .OR. ( valeig .AND. ( .NOT.lquery ) ) )
603 lwmin = 5*n +
max( 5*nn, nb*( np0+1 ) )
605 mq0 = numroc(
max( n, nb, 2 ), nb, 0, 0, npcol )
606 lwopt = 5*n +
max( 5*nn, np0*mq0+2*nb*nb )
612 IF( alleig .OR. valeig )
THEN
614 ELSE IF( indeig )
THEN
617 mq0 = numroc(
max( neig, nb, 2 ), nb, 0, 0, npcol )
618 lwmin = 5*n +
max( 5*nn, np0*mq0+2*nb*nb ) +
619 $ iceil( neig, nprow*npcol )*nn
627 anb = pjlaenv( ictxt, 3,
'PDSYTTRD',
'L', 0, 0, 0, 0 )
628 sqnpc = int( sqrt( dble( nprow*npcol ) ) )
629 nps =
max( numroc( n, 1, 0, 0, sqnpc ), 2*anb )
630 nsytrd_lwopt = 2*( anb+1 )*( 4*nps+2 ) + ( nps+4 )*nps
632 np0 = numroc( n, nb, 0, 0, nprow )
633 nq0 = numroc( n, nb, 0, 0, npcol )
634 nsygst_lwopt = 2*np0*nb + nq0*nb + nb*nb
635 lwopt =
max( lwopt, n+nsytrd_lwopt, nsygst_lwopt )
639 IF( ibtype.LT.1 .OR. ibtype.GT.3 )
THEN
641 ELSE IF( .NOT.( wantz .OR. lsame( jobz,
'N' ) ) )
THEN
643 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) )
THEN
645 ELSE IF( .NOT.upper .AND. .NOT.lsame( uplo,
'L' ) )
THEN
647 ELSE IF( n.LT.0 )
THEN
649 ELSE IF( iroffa.NE.0 )
THEN
651 ELSE IF( icoffa.NE.0 )
THEN
653 ELSE IF( desca( mb_ ).NE.desca( nb_ ) )
THEN
655 ELSE IF( desca( m_ ).NE.descb( m_ ) )
THEN
657 ELSE IF( desca( n_ ).NE.descb( n_ ) )
THEN
661 ELSE IF( desca( nb_ ).NE.descb( nb_ ) )
THEN
663 ELSE IF( desca( rsrc_ ).NE.descb( rsrc_ ) )
THEN
664 info = -( 1300+rsrc_ )
665 ELSE IF( desca( csrc_ ).NE.descb( csrc_ ) )
THEN
666 info = -( 1300+csrc_ )
667 ELSE IF( desca( ctxt_ ).NE.descb( ctxt_ ) )
THEN
668 info = -( 1300+ctxt_ )
669 ELSE IF( desca( m_ ).NE.descz( m_ ) )
THEN
671 ELSE IF( desca( n_ ).NE.descz( n_ ) )
THEN
673 ELSE IF( desca( mb_ ).NE.descz( mb_ ) )
THEN
675 ELSE IF( desca( nb_ ).NE.descz( nb_ ) )
THEN
677 ELSE IF( desca( rsrc_ ).NE.descz( rsrc_ ) )
THEN
678 info = -( 2200+rsrc_ )
679 ELSE IF( desca( csrc_ ).NE.descz( csrc_ ) )
THEN
680 info = -( 2200+csrc_ )
681 ELSE IF( desca( ctxt_ ).NE.descz( ctxt_ ) )
THEN
682 info = -( 2200+ctxt_ )
683 ELSE IF( iroffb.NE.0 .OR. ibrow.NE.iarow )
THEN
685 ELSE IF( icoffb.NE.0 .OR. ibcol.NE.iacol )
THEN
687 ELSE IF( valeig .AND. n.GT.0 .AND. vu.LE.vl )
THEN
689 ELSE IF( indeig .AND. ( il.LT.1 .OR. il.GT.
max( 1, n ) ) )
692 ELSE IF( indeig .AND. ( iu.LT.
min( n, il ) .OR. iu.GT.n ) )
695 ELSE IF( valeig .AND. ( abs( work( 2 )-vl ).GT.five*eps*
698 ELSE IF( valeig .AND. ( abs( work( 3 )-vu ).GT.five*eps*
701 ELSE IF( abs( work( 1 )-abstol ).GT.five*eps*abs( abstol ) )
704 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
706 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
713 idum1( 2 ) = ichar(
'V' )
715 idum1( 2 ) = ichar(
'N' )
719 idum1( 3 ) = ichar(
'U' )
721 idum1( 3 ) = ichar(
'L' )
725 idum1( 4 ) = ichar(
'A' )
726 ELSE IF( indeig )
THEN
727 idum1( 4 ) = ichar(
'I' )
729 idum1( 4 ) = ichar(
'V' )
738 CALL pchk2mat( n, 4, n, 4, ia, ja, desca, 9, n, 4, n, 4, ib,
739 $ jb, descb, 13, 5, idum1, idum2, info )
740 CALL pchk1mat( n, 4, n, 4, iz, jz, descz, 26, 0, idum1, idum2,
745 work( 1 ) = dble( lwopt )
748 CALL pxerbla( ictxt,
'PDSYGVX ', -info )
750 ELSE IF( lquery )
THEN
756 CALL pdpotrf( uplo, n, b, ib, jb, descb, info )
759 work( 1 ) = dble( lwopt )
767 CALL pdsyngst( ibtype, uplo, n, a, ia, ja, desca, b, ib, jb,
768 $ descb, scale, work, lwork, info )
769 CALL pdsyevx( jobz, range, uplo, n, a, ia, ja, desca, vl, vu, il,
770 $ iu, abstol, m, nz, w, orfac, z, iz, jz, descz, work,
771 $ lwork, iwork, liwork, ifail, iclustr, gap, info )
778 IF( ibtype.EQ.1 .OR. ibtype.EQ.2 )
THEN
790 CALL pdtrsm(
'Left', uplo, trans,
'Non-unit', n, neig, one,
791 $ b, ib, jb, descb, z, iz, jz, descz )
793 ELSE IF( ibtype.EQ.3 )
THEN
804 CALL pdtrmm(
'Left', uplo, trans,
'Non-unit', n, neig, one,
805 $ b, ib, jb, descb, z, iz, jz, descz )
809 IF( scale.NE.one )
THEN
810 CALL dscal( n, scale, w, 1 )
814 work( 1 ) = dble( lwopt )