1 SUBROUTINE pssygvx( 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 REAL ABSTOL, ORFAC, VL, VU
20 INTEGER DESCA( * ), DESCB( * ), DESCZ( * ),
21 $ ICLUSTR( * ), IFAIL( * ), IWORK( * )
22 REAL 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.0e+0 )
497 PARAMETER ( FIVE = 5.0e+0, zero = 0.0e+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
512 INTEGER IDUM1( 5 ), IDUM2( 5 )
516 INTEGER ICEIL, INDXG2P, NUMROC, PJLAENV
518 EXTERNAL LSAME, ICEIL, INDXG2P, NUMROC, PJLAENV, PSLAMCH
523 $
pxerbla, sgebr2d, sgebs2d, sscal
526 INTRINSIC abs, dble, ichar, int,
max,
min, mod, real,
531 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
536 ictxt = desca( ctxt_ )
537 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
542 IF( nprow.EQ.-1 )
THEN
543 info = -( 900+ctxt_ )
544 ELSE IF( desca( ctxt_ ).NE.descb( ctxt_ ) )
THEN
545 info = -( 1300+ctxt_ )
546 ELSE IF( desca( ctxt_ ).NE.descz( ctxt_ ) )
THEN
547 info = -( 2600+ctxt_ )
552 eps = pslamch( desca( ctxt_ ),
'Precision' )
554 wantz = lsame( jobz,
'V' )
555 upper = lsame( uplo,
'U' )
556 alleig = lsame( range,
'A' )
557 valeig = lsame( range,
'V' )
558 indeig = lsame( range,
'I' )
559 CALL chk1mat( n, 4, n, 4, ia, ja, desca, 9, info )
560 CALL chk1mat( n, 4, n, 4, ib, jb, descb, 13, info )
561 CALL chk1mat( n, 4, n, 4, iz, jz, descz, 26, info )
563 IF( myrow.EQ.0 .AND. mycol.EQ.0 )
THEN
572 CALL sgebs2d( desca( ctxt_ ),
'ALL',
' ', 3, 1, work, 3 )
574 CALL sgebr2d( desca( ctxt_ ),
'ALL',
' ', 3, 1, work, 3,
577 iarow = indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
579 ibrow = indxg2p( ib, descb( mb_ ), myrow, descb( rsrc_ ),
581 iacol = indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
583 ibcol = indxg2p( jb, descb( nb_ ), mycol, descb( csrc_ ),
585 iroffa = mod( ia-1, desca( mb_ ) )
586 icoffa = mod( ja-1, desca( nb_ ) )
587 iroffb = mod( ib-1, descb( mb_ ) )
588 icoffb = mod( jb-1, descb( nb_ ) )
593 IF( lwork.EQ.-1 .OR. liwork.EQ.-1 )
596 liwmin = 6*
max( n, ( nprow*npcol )+1, 4 )
600 np0 = numroc( nn, nb, 0, 0, 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,
'PSSYTTRD',
'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
633 np0 = numroc( n, nb, 0, 0, nprow )
634 nq0 = numroc( n, nb, 0, 0, npcol )
635 nsygst_lwopt = 2*np0*nb + nq0*nb + nb*nb
636 lwopt =
max( lwopt, n+nsytrd_lwopt, nsygst_lwopt )
640 IF( ibtype.LT.1 .OR. ibtype.GT.3 )
THEN
642 ELSE IF( .NOT.( wantz .OR. lsame( jobz,
'N' ) ) )
THEN
644 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) )
THEN
646 ELSE IF( .NOT.upper .AND. .NOT.lsame( uplo,
'L' ) )
THEN
648 ELSE IF( n.LT.0 )
THEN
650 ELSE IF( iroffa.NE.0 )
THEN
652 ELSE IF( icoffa.NE.0 )
THEN
654 ELSE IF( desca( mb_ ).NE.desca( nb_ ) )
THEN
656 ELSE IF( desca( m_ ).NE.descb( m_ ) )
THEN
658 ELSE IF( desca( n_ ).NE.descb( n_ ) )
THEN
660 ELSE IF( desca( mb_ ).NE.descb( mb_ ) )
THEN
662 ELSE IF( desca( nb_ ).NE.descb( nb_ ) )
THEN
664 ELSE IF( desca( rsrc_ ).NE.descb( rsrc_ ) )
THEN
665 info = -( 1300+rsrc_ )
666 ELSE IF( desca( csrc_ ).NE.descb( csrc_ ) )
THEN
667 info = -( 1300+csrc_ )
668 ELSE IF( desca( ctxt_ ).NE.descb( ctxt_ ) )
THEN
669 info = -( 1300+ctxt_ )
670 ELSE IF( desca( m_ ).NE.descz( m_ ) )
THEN
672 ELSE IF( desca( n_ ).NE.descz( n_ ) )
THEN
674 ELSE IF( desca( mb_ ).NE.descz( mb_ ) )
THEN
676 ELSE IF( desca( nb_ ).NE.descz( nb_ ) )
THEN
678 ELSE IF( desca( rsrc_ ).NE.descz( rsrc_ ) )
THEN
679 info = -( 2200+rsrc_ )
680 ELSE IF( desca( csrc_ ).NE.descz( csrc_ ) )
THEN
681 info = -( 2200+csrc_ )
682 ELSE IF( desca( ctxt_ ).NE.descz( ctxt_ ) )
THEN
683 info = -( 2200+ctxt_ )
684 ELSE IF( iroffb.NE.0 .OR. ibrow.NE.iarow )
THEN
686 ELSE IF( icoffb.NE.0 .OR. ibcol.NE.iacol )
THEN
688 ELSE IF( valeig .AND. n.GT.0 .AND. vu.LE.vl )
THEN
690 ELSE IF( indeig .AND. ( il.LT.1 .OR. il.GT.
max( 1, n ) ) )
693 ELSE IF( indeig .AND. ( iu.LT.
min( n, il ) .OR. iu.GT.n ) )
696 ELSE IF( valeig .AND. ( abs( work( 2 )-vl ).GT.five*eps*
699 ELSE IF( valeig .AND. ( abs( work( 3 )-vu ).GT.five*eps*
702 ELSE IF( abs( work( 1 )-abstol ).GT.five*eps*abs( abstol ) )
705 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
707 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
714 idum1( 2 ) = ichar(
'V' )
716 idum1( 2 ) = ichar(
'N' )
720 idum1( 3 ) = ichar(
'U' )
722 idum1( 3 ) = ichar(
'L' )
726 idum1( 4 ) = ichar(
'A' )
727 ELSE IF( indeig )
THEN
728 idum1( 4 ) = ichar(
'I' )
730 idum1( 4 ) = ichar(
'V' )
739 CALL pchk2mat( n, 4, n, 4, ia, ja, desca, 9, n, 4, n, 4, ib,
740 $ jb, descb, 13, 5, idum1, idum2, info )
741 CALL pchk1mat( n, 4, n, 4, iz, jz, descz, 26, 0, idum1, idum2,
746 work( 1 ) = real( lwopt )
749 CALL pxerbla( ictxt,
'PSSYGVX ', -info )
751 ELSE IF( lquery )
THEN
757 CALL pspotrf( uplo, n, b, ib, jb, descb, info )
760 work( 1 ) = real( lwopt )
768 CALL pssyngst( ibtype, uplo, n, a, ia, ja, desca, b, ib, jb,
769 $ descb, scale, work, lwork, info )
770 CALL pssyevx( jobz, range, uplo, n, a, ia, ja, desca, vl, vu, il,
771 $ iu, abstol, m, nz, w, orfac, z, iz, jz, descz, work,
772 $ lwork, iwork, liwork, ifail, iclustr, gap, info )
779 IF( ibtype.EQ.1 .OR. ibtype.EQ.2 )
THEN
791 CALL pstrsm(
'Left', uplo, trans,
'Non-unit', n, neig, one,
792 $ b, ib, jb, descb, z, iz, jz, descz )
794 ELSE IF( ibtype.EQ.3 )
THEN
805 CALL pstrmm(
'Left', uplo, trans,
'Non-unit', n, neig, one,
806 $ b, ib, jb, descb, z, iz, jz, descz )
810 IF( scale.NE.one )
THEN
811 CALL sscal( n, scale, w, 1 )
815 work( 1 ) = real( lwopt )