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 JOBZ, RANGE, UPLO
14 INTEGER IA, IB, IBTYPE, IL, INFO, IU, 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 $ ICOFFB, 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
521 EXTERNAL blacs_gridinfo,
chk1mat, dgebr2d, dgebs2d,
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_ )
536 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
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
659 ELSE IF( desca( mb_ ).NE.descb( mb_ ) )
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 )