1 SUBROUTINE pshseqr( JOB, COMPZ, N, ILO, IHI, H, DESCH, WR, WI, Z,
2 $ DESCZ, WORK, LWORK, IWORK, LIWORK, INFO )
15 INTEGER IHI, ILO, INFO, LWORK, LIWORK, N
19 INTEGER DESCH( * ) , DESCZ( * ), IWORK( * )
20 REAL H( * ), WI( N ), WORK( * ), WR( N ), Z( * )
239 INTEGER , CSRC_, CTXT_, DLEN_, DTYPE_,
240 $ lld_, mb_, m_, nb_, n_, rsrc_
242 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_
243 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
244 $ rsrc_ = 7, csrc_ = 8, lld_ = 9,
247 parameter( ntiny = 11 )
251 parameter( zero = 0.0e0, one = 1.0e0 )
254 INTEGER I, KBOT, NMIN, LLDH, LLDZ, ICTXT, NPROW, NPCOL,
255 $ myrow, mycol, hrows, hcols, ipw, nh, nb,
256 $ ii, jj, hrsrc, hcsrc, nprocs, iloc1, jloc1,
257 $ hrsrc1, hcsrc1, k, iloc2, jloc2, iloc3, jloc3,
258 $ iloc4, jloc4, hrsrc2, hcsrc2, hrsrc3, hcsrc3,
259 $ hrsrc4, hcsrc4, liwkopt
260 LOGICAL INITZ, LQUERY, WANTT, WANTZ, PAIR, BORDER
261 REAL TMP1, TMP2, TMP3, TMP4, DUM1, DUM2, DUM3,
262 $ dum4, elem1, elem4,
263 $ cs, sn, elem5, tmp, lwkopt
266 INTEGER DESCH2( DLEN_ )
267 REAL ELEM2( 1 ), ELEM3( 1 )
270 INTEGER PILAENVX, NUMROC, ICEIL
272 EXTERNAL pilaenvx, lsame, numroc, iceil
285 ictxt = desch( ctxt_ )
288 IF( nprow.EQ.-1 ) info = -(600+ctxt_)
290 wantt = lsame( job,
'S' )
291 initz = lsame( compz,
'I' )
292 wantz = initz .OR. lsame( compz,
'V' )
296 lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 )
298 IF( .NOT.lsame( job,
'E' ) .AND. .NOT.wantt )
THEN
300 ELSE IF( .NOT.lsame( compz,
'N' ) .AND. .NOT.wantz )
THEN
302 ELSE IF( n.LT.0 )
THEN
304 ELSE IF( ilo.LT.1 .OR. ilo.GT.
max( 1, n ) )
THEN
306 ELSE IF( ihi.LT.
min( ilo, n ) .OR. ihi.GT.n )
THEN
308 ELSEIF( descz( ctxt_ ).NE.desch( ctxt_ ) )
THEN
309 info = -( 1000+ctxt_ )
310 ELSEIF( desch( mb_ ).NE.desch( nb_ ) )
THEN
312 ELSEIF( descz( mb_ ).NE.descz( nb_ ) )
THEN
314 ELSEIF( desch( mb_ ).NE.descz( mb_ ) )
THEN
316 ELSEIF( desch( mb_ ).LT.6 )
THEN
318 ELSEIF( descz( mb_ ).LT.6 )
THEN
321 CALL chk1mat( n, 3, n, 3, 1, 1, desch, 7, info
323 $
CALL chk1mat( n, 3, n, 3, 1, 1, descz, 11, info )
325 $
CALL pchk2mat( n, 3, n, 3, 1, 1, desch, 7, n, 3, n, 3,
326 $ 1, 1, descz, 11, 0, iwork, iwork, info )
332 CALL pslaqr1( wantt, wantz, n, ilo, ihi, h, desch, wr, wi,
333 $ ilo, ihi, z, descz, work, -1, iwork, -1, info )
336 CALL pslaqr0( wantt, wantz, n, ilo, ihi, h, desch, wr, wi,
337 $ ilo, ihi, z, descz, work, -1, iwork, -1, info, 0 )
339 hrows = numroc( nl, nb, myrow, desch(rsrc_), nprow )
340 hcols = numroc( nl, nb, mycol
341 work(1) = work(1) + float(2*hrows*hcols)
343 lwkopt =
max( lwkopt, work(1) )
344 liwkopt =
max( liwkopt, iwork(1) )
348 IF( .NOT.lquery .AND. lwork.LT.int(lwkopt) )
THEN
350 ELSEIF( .NOT.lquery .AND. liwork.LT.liwkopt )
THEN
361.EQ.
ELSE IF( N0 ) THEN
367 ELSE IF( LQUERY ) THEN
378 CALL INFOG2L( I, I, DESCH, NPROW, NPCOL, MYROW, MYCOL, II,
380.EQ..AND..EQ.
IF( MYROWHRSRC MYCOLHCSRC ) THEN
381 WR( I ) = H( (JJ-1)*LLDH + II )
388 $ CALL SGSUM2D( ICTXT, 'all
', '1-tree
', ILO-1, 1, WR, N, -1,
391 CALL INFOG2L( I, I, DESCH, NPROW, NPCOL, MYROW, MYCOL, II,
393.EQ..AND..EQ.
IF( MYROWHRSRC MYCOLHCSRC ) THEN
394 WR( I ) = H( (JJ-1)*LLDH + II )
401 $ CALL SGSUM2D( ICTXT, 'all
', '1-tree
', N-IHI, 1, WR(IHI+1),
407 $ CALL PSLASET( 'a
', N, N, ZERO, ONE, Z, 1, 1, DESCZ )
412.EQ.
IF( ILOIHI ) THEN
413 CALL INFOG2L( ILO, ILO, DESCH, NPROW, NPCOL, MYROW,
414 $ MYCOL, II, JJ, HRSRC, HCSRC )
415.EQ..AND..EQ.
IF( MYROWHRSRC MYCOLHCSRC ) THEN
416 WR( ILO ) = H( (JJ-1)*LLDH + II )
418 $ CALL SGEBS2D( ICTXT, 'all
', '1-tree
', 1, 1, WR(ILO),
421 CALL SGEBR2D( ICTXT, 'all
', '1-tree
', 1, 1, WR(ILO),
431 NMIN = PILAENVX( ICTXT, 12, 'pshseqr',
432 $ JOB( : 1 ) // COMPZ( : 1 ), N, ILO, IHI, LWORK )
433 NMIN = MAX( NTINY, NMIN )
437.NOT..AND..GT..OR..GT..OR.
IF( ( CRSOVER NHNTINY) NHNMIN
438.NE..OR..NE.
$ DESCH(RSRC_)0 DESCH(CSRC_)0 ) THEN
439 CALL PSLAQR0( WANTT, WANTZ, N, ILO, IHI, H, DESCH, WR, WI,
440 $ ILO, IHI, Z, DESCZ, WORK, LWORK, IWORK, LIWORK, INFO,
442.GT..AND..NE..OR.
IF( INFO0 ( DESCH(RSRC_)0
443.NE.
$ DESCH(CSRC_)0 ) ) THEN
449 CALL PSLAQR1( WANTT, WANTZ, N, ILO, IHI, H, DESCH, WR,
450 $ WI, ILO, IHI, Z, DESCZ, WORK, LWORK, IWORK,
458 CALL PSLAQR1( WANTT, WANTZ, N, ILO, IHI, H, DESCH, WR, WI,
459 $ ILO, IHI, Z, DESCZ, WORK, LWORK, IWORK, LIWORK, INFO )
473 CALL PSLAQR0( WANTT, WANTZ, N, ILO, KBOT, H, DESCH,
474 $ WR, WI, ILO, IHI, Z, DESCZ, WORK, LWORK,
475 $ IWORK, LIWORK, INFO, 0 )
483 HROWS = NUMROC( NL, NB, MYROW, DESCH(RSRC_), NPROW )
484 HCOLS = NUMROC( NL, NB, MYCOL, DESCH(CSRC_), NPCOL )
485 CALL DESCINIT( DESCH2, NL, NL, NB, NB, DESCH(RSRC_),
486 $ DESCH(CSRC_), ICTXT, MAX(1, HROWS), INFO )
487 CALL PSLACPY( 'all
', N, N, H, 1, 1, DESCH, WORK, 1,
489 CALL PSELSET( WORK, N+1, N, DESCH2, ZERO )
490 CALL PSLASET( 'all
', NL, NL-N, ZERO, ZERO, WORK, 1,
492 IPW = 1 + DESCH2(LLD_)*HCOLS
493 CALL PSLAQR0( WANTT, WANTZ, NL, ILO, KBOT, WORK,
494 $ DESCH2, WR, WI, ILO, IHI, Z, DESCZ,
495 $ WORK(IPW), LWORK-IPW+1, IWORK,
497.OR..NE.
IF( WANTT INFO0 )
498 $ CALL PSLACPY( 'all
', N, N, WORK, 1, 1, DESCH2,
507.OR..NE..AND..GT.
IF( ( WANTT INFO0 ) N2 )
508 $ CALL PSLASET( 'l
', N-2, N-2, ZERO, ZERO, H, 3, 1, DESCH )
514 CALL PSELGET( 'all
', ' ', tmp3, h, i+1, i, desch )
515 IF( tmp3.NE.0.0e+00 )
THEN
516 CALL pselget(
'All',
' ', tmp1, h, i, i, desch )
517 CALL pselget(
'All',
' ', tmp2, h, i, i+1, desch )
518 CALL pselget(
'All',
' ', tmp4, h, i+1, i+1, desch )
519 CALL slanv2( tmp1, tmp2, tmp3, tmp4, dum1, dum2, dum3,
521 IF( tmp3.EQ.0.0e+00 )
THEN
524 $
CALL psrot( n-i-1, h, i, i+2, desch,
525 $ desch(m_), h, i+1, i+2, desch, desch(m_),
526 $ cs, sn, work, lwork, info )
527 CALL psrot( i-1, h, 1, i, desch, 1, h, 1, i+1,
528 $ desch, 1, cs, sn, work, lwork, info )
531 CALL psrot( n, z, 1, i, descz, 1, z, 1, i+1, descz,
532 $ 1, cs, sn, work, lwork, info )
534 CALL pselset( h, i, i, desch, tmp1 )
535 CALL pselset( h, i, i+1, desch, tmp2 )
536 CALL pselset( h, i+1, i, desch, tmp3 )
537 CALL pselset( h, i+1, i+1, desch, tmp4 )
561 IF( .NOT. pair )
THEN
562 border = mod( k, nb ).EQ.0 .OR. ( k.NE.1 .AND.
563 $ mod( k, nb ).EQ.1 )
564 IF( .NOT. border )
THEN
565 CALL infog2l( k, k, desch, nprow, npcol, myrow,
566 $ mycol, iloc1, jloc1, hrsrc1, hcsrc1 )
567 IF( myrow.EQ.hrsrc1 .AND. mycol.EQ.hcsrc1 )
THEN
568 elem1 = h((jloc1-1)*lldh
570 elem3( 1 ) = h((jloc1-1)*lldh+iloc1+1)
574 IF( elem3( 1 ).NE.zero )
THEN
575 elem2( 1 ) = h((jloc1)*lldh+iloc1)
576 elem4 = h((jloc1)*lldh+iloc1+1)
577 CALL slanv2( elem1, elem2( 1 ), elem3( 1 ),
578 $ elem4, wr( k ), wi( k ), wr( k+1 ),
579 $ wi( k+1 ), sn, cs )
583 tmp = h((jloc1-2)*lldh+iloc1)
584 IF( tmp.NE.zero )
THEN
585 elem1 = h((jloc1-2)*lldh+iloc1-1)
586 elem2( 1 ) = h((jloc1-1)*lldh+iloc1-1)
587 elem3( 1 ) = h((jloc1-2)*lldh+iloc1)
588 elem4 = h((jloc1-1)*lldh+iloc1)
589 CALL slanv2( elem1, elem2( 1 ),
590 $ elem3( 1 ), elem4, wr( k-1 ),
591 $ wi( k-1 ), wr( k ), wi( k ), sn, cs )
614 DO 60 k = iceil(ilo,nb)*nb, ihi-1, nb
615 CALL infog2l( k, k, desch, nprow, npcol, myrow, mycol,
616 $ iloc1, jloc1, hrsrc1, hcsrc1 )
617 CALL infog2l( k, k+1, desch, nprow, npcol, myrow, mycol,
618 $ iloc2, jloc2, hrsrc2, hcsrc2 )
619 CALL infog2l( k+1, k, desch, nprow, npcol, myrow, mycol,
620 $ iloc3, jloc3, hrsrc3, hcsrc3 )
621 CALL infog2l( k+1, k+1, desch, nprow, npcol, myrow, mycol,
622 $ iloc4, jloc4, hrsrc4, hcsrc4 )
623 IF( myrow.EQ.hrsrc2 .AND. mycol.EQ.hcsrc2 )
THEN
624 elem2( 1 ) = h((jloc2-1)*lldh+iloc2)
625 IF( hrsrc1.NE.hrsrc2 .OR. hcsrc1.NE.hcsrc2 )
626 $
CALL sgesd2d( ictxt, 1, 1, elem2, 1, hrsrc1, hcsrc1)
628 IF( myrow.EQ.hrsrc3 .AND. mycol.EQ.hcsrc3 )
THEN
629 elem3( 1 ) = h((jloc3-1)*lldh+iloc3)
630 IF( hrsrc1.NE.hrsrc3 .OR. hcsrc1.NE.hcsrc3 )
631 $
CALL sgesd2d( ictxt, 1, 1, elem3, 1, hrsrc1, hcsrc1)
633 IF( myrow.EQ.hrsrc4 .AND. mycol.EQ.hcsrc4 )
THEN
634 work(1) = h((jloc4-1)*lldh+iloc4)
636 work(2) = h((jloc4-1)*lldh+iloc4+1)
640 IF( hrsrc1.NE.hrsrc4 .OR. hcsrc1.NE.hcsrc4 )
641 $
CALL sgesd2d( ictxt, 2, 1, work, 2, hrsrc1, hcsrc1 )
643 IF( myrow.EQ.hrsrc1 .AND. mycol.EQ.hcsrc1 )
THEN
644 elem1 = h((jloc1-1)*lldh+iloc1)
645 IF( hrsrc1.NE.hrsrc2 .OR. hcsrc1.NE.hcsrc2 )
646 $
CALL sgerv2d( ictxt, 1, 1, elem2, 1, hrsrc2, hcsrc2)
647 IF( hrsrc1.NE.hrsrc3 .OR. hcsrc1.NE.hcsrc3 )
648 $
CALL sgerv2d( ictxt, 1, 1, elem3, 1, hrsrc3, hcsrc3)
649 IF( hrsrc1.NE.hrsrc4 .OR. hcsrc1.NE.hcsrc4 )
650 $
CALL sgerv2d( ictxt, 2, 1, work, 2, hrsrc4, hcsrc4 )
653 IF( elem5.EQ.zero )
THEN
654 IF( wr( k ).EQ.zero .AND. wi( k ).EQ.zero )
THEN
655 CALL slanv2( elem1, elem2( 1 ), elem3( 1 ), elem4,
656 $ wr( k ), wi( k ), wr( k+1 ), wi( k+1 ), sn,
658 ELSEIF( wr( k+1 ).EQ.zero .AND. wi( k+1 ).EQ.zero )
662 ELSEIF( wr( k ).EQ.zero .AND. wi( k ).EQ.zero )
669 IF( nprocs.GT.1 )
THEN
670 CALL sgsum2d( ictxt,
'All',
' ', ihi-ilo+1, 1, wr(ilo), n,
672 CALL sgsum2d( ictxt,
'All',
' ', ihi-ilo+1, 1, wi(ilo), n,