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 BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
240 $ lld_, mb_, m_, nb_, n_, rsrc_
242 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
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, elem2, elem3, elem4,
263 $ cs, sn, elem5, tmp, lwkopt
266 INTEGER DESCH2( DLEN_ )
269 INTEGER PILAENVX, NUMROC, ICEIL
271 EXTERNAL pilaenvx, lsame, numroc, iceil
284 ictxt = desch( ctxt_ )
285 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
287 IF( nprow.EQ.-1 ) info = -(600+ctxt_)
289 wantt = lsame( job,
'S' )
290 initz = lsame( compz,
'I' )
291 wantz = initz .OR. lsame( compz,
'V' )
295 lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 )
297 IF( .NOT.lsame( job,
'E' ) .AND. .NOT.wantt )
THEN
299 ELSE IF( .NOT.lsame( compz,
'N' ) .AND. .NOT.wantz )
THEN
301 ELSE IF( n.LT.0 )
THEN
303 ELSE IF( ilo.LT.1 .OR. ilo.GT.
max( 1, n ) )
THEN
305 ELSE IF( ihi.LT.
min( ilo, n ) .OR. ihi.GT.n )
THEN
307 ELSEIF( descz( ctxt_ ).NE.desch( ctxt_ ) )
THEN
308 info = -( 1000+ctxt_ )
309 ELSEIF( desch( mb_ ).NE.desch( nb_ ) )
THEN
311 ELSEIF( descz( mb_ ).NE.descz( nb_ ) )
THEN
313 ELSEIF( desch( mb_ ).NE.descz( mb_ ) )
THEN
315 ELSEIF( desch( mb_ ).LT.6 )
THEN
317 ELSEIF( descz( mb_ ).LT.6 )
THEN
320 CALL chk1mat( n, 3, n, 3, 1, 1, desch, 7, info )
322 $
CALL chk1mat( n, 3, n, 3, 1, 1, descz, 11, info )
324 $
CALL pchk2mat( n, 3, n, 3, 1, 1, desch, 7, n, 3, n, 3,
325 $ 1, 1, descz, 11, 0, iwork, iwork, info )
331 CALL pslaqr1( wantt, wantz, n, ilo, ihi, h, desch, wr, wi,
332 $ ilo, ihi, z, descz, work, -1, iwork, -1, info )
335 CALL pslaqr0( wantt, wantz, n, ilo, ihi, h, desch, wr, wi,
336 $ ilo, ihi, z, descz, work, -1, iwork, -1, info, 0 )
338 hrows = numroc( nl, nb, myrow, desch(rsrc_), nprow )
339 hcols = numroc( nl, nb, mycol, desch(csrc_), npcol )
340 work(1) = work(1) + float(2*hrows*hcols)
342 lwkopt =
max( lwkopt, work(1) )
343 liwkopt =
max( liwkopt, iwork(1) )
347 IF( .NOT.lquery .AND. lwork.LT.int(lwkopt) )
THEN
349 ELSEIF( .NOT.lquery .AND. liwork.LT.liwkopt )
THEN
357 CALL pxerbla( ictxt,
'PSHSEQR', -info )
360 ELSE IF( n.EQ.0 )
THEN
366 ELSE IF( lquery )
THEN
377 CALL infog2l( i, i, desch, nprow, npcol, myrow, mycol, ii,
379 IF( myrow.EQ.hrsrc .AND. mycol.EQ.hcsrc )
THEN
380 wr( i ) = h( (jj-1)*lldh + ii )
387 $
CALL sgsum2d( ictxt,
'All',
'1-Tree', ilo-1, 1, wr, n, -1,
390 CALL infog2l( i, i, desch, nprow, npcol, myrow, mycol, ii,
392 IF( myrow.EQ.hrsrc .AND. mycol.EQ.hcsrc )
THEN
393 wr( i ) = h( (jj-1)*lldh + ii )
400 $
CALL sgsum2d( ictxt,
'All',
'1-Tree', n-ihi, 1, wr(ihi+1),
406 $
CALL pslaset(
'A', n, n, zero, one, z, 1, 1, descz )
411 IF( ilo.EQ.ihi )
THEN
412 CALL infog2l( ilo, ilo, desch, nprow, npcol, myrow,
413 $ mycol, ii, jj, hrsrc, hcsrc )
414 IF( myrow.EQ.hrsrc .AND. mycol.EQ.hcsrc )
THEN
415 wr( ilo ) = h( (jj-1)*lldh + ii )
417 $
CALL sgebs2d( ictxt,
'All',
'1-Tree', 1, 1, wr(ilo),
420 CALL sgebr2d( ictxt,
'All',
'1-Tree', 1, 1, wr(ilo),
430 nmin = pilaenvx( ictxt, 12,
'PSHSEQR',
431 $ job( : 1 ) // compz( : 1 ), n, ilo, ihi, lwork )
432 nmin =
max( ntiny, nmin )
436 IF( (.NOT. crsover .AND. nh.GT.ntiny) .OR. nh.GT.nmin .OR.
437 $ desch(rsrc_).NE.0 .OR. desch(csrc_).NE.0 )
THEN
438 CALL pslaqr0( wantt, wantz, n, ilo, ihi, h, desch, wr, wi,
439 $ ilo, ihi, z, descz, work, lwork, iwork, liwork, info,
441 IF( info.GT.0 .AND. ( desch(rsrc_).NE.0 .OR.
442 $ desch(csrc_).NE.0 ) )
THEN
448 CALL pslaqr1( wantt, wantz, n, ilo, ihi, h, desch, wr,
449 $ wi, ilo, ihi, z, descz, work, lwork, iwork,
457 CALL pslaqr1( wantt, wantz, n, ilo, ihi, h, desch, wr, wi,
458 $ ilo, ihi, z, descz, work, lwork, iwork, liwork, info )
472 CALL pslaqr0( wantt, wantz, n, ilo, kbot, h, desch,
473 $ wr, wi, ilo, ihi, z, descz, work, lwork,
474 $ iwork, liwork, info, 0 )
482 hrows = numroc( nl, nb, myrow, desch(rsrc_), nprow )
483 hcols = numroc( nl, nb, mycol, desch(csrc_), npcol )
484 CALL descinit( desch2, nl, nl, nb, nb, desch(rsrc_),
485 $ desch(csrc_), ictxt,
max(1, hrows), info )
486 CALL pslacpy(
'All', n, n, h, 1, 1, desch, work, 1,
488 CALL pselset( work, n+1, n, desch2, zero )
489 CALL pslaset(
'All', nl, nl-n, zero, zero, work, 1,
491 ipw = 1 + desch2(lld_)*hcols
492 CALL pslaqr0( wantt, wantz, nl, ilo, kbot, work,
493 $ desch2, wr, wi, ilo, ihi, z, descz,
494 $ work(ipw), lwork-ipw+1, iwork,
496 IF( wantt .OR. info.NE.0 )
497 $
CALL pslacpy(
'All', n, n, work, 1, 1, desch2,
506 IF( ( wantt .OR. info.NE.0 ) .AND. n.GT.2 )
507 $
CALL pslaset(
'L', n-2, n-2, zero, zero, h, 3, 1, desch )
513 CALL pselget(
'All',
' ', tmp3, h, i+1, i, desch )
514 IF( tmp3.NE.0.0e+00 )
THEN
515 CALL pselget(
'All',
' ', tmp1, h, i, i, desch )
516 CALL pselget(
'All',
' ', tmp2, h, i, i+1, desch )
517 CALL pselget(
'All',
' ', tmp4, h, i+1, i+1, desch )
518 CALL slanv2( tmp1, tmp2, tmp3, tmp4, dum1, dum2, dum3,
520 IF( tmp3.EQ.0.0e+00 )
THEN
523 $
CALL psrot( n-i-1, h, i, i+2, desch,
524 $ desch(m_), h, i+1, i+2, desch, desch(m_),
525 $ cs, sn, work, lwork, info )
526 CALL psrot( i-1, h, 1, i, desch, 1, h, 1, i+1,
527 $ desch, 1, cs, sn, work, lwork, info )
530 CALL psrot( n, z, 1, i, descz, 1, z, 1, i+1, descz,
531 $ 1, cs, sn, work, lwork, info )
533 CALL pselset( h, i, i, desch, tmp1 )
534 CALL pselset( h, i, i+1, desch, tmp2 )
535 CALL pselset( h, i+1, i, desch, tmp3 )
536 CALL pselset( h, i+1, i+1, desch, tmp4 )
560 IF( .NOT. pair )
THEN
561 border = mod( k, nb ).EQ.0 .OR. ( k.NE.1 .AND.
562 $ mod( k, nb ).EQ.1 )
563 IF( .NOT. border )
THEN
564 CALL infog2l( k, k, desch, nprow, npcol, myrow,
565 $ mycol, iloc1, jloc1, hrsrc1, hcsrc1 )
566 IF( myrow.EQ.hrsrc1 .AND. mycol.EQ.hcsrc1 )
THEN
567 elem1 = h((jloc1-1)*lldh+iloc1)
569 elem3 = h((jloc1-1)*lldh+iloc1+1)
573 IF( elem3.NE.zero )
THEN
574 elem2 = h((jloc1)*lldh+iloc1)
575 elem4 = h((jloc1)*lldh+iloc1+1)
576 CALL slanv2( elem1, elem2, elem3, elem4,
577 $ wr( k ), wi( k ), wr( k+1 ), wi( k+1 ),
582 tmp = h((jloc1-2)*lldh+iloc1)
583 IF( tmp.NE.zero )
THEN
584 elem1 = h((jloc1-2)*lldh+iloc1-1)
585 elem2 = h((jloc1-1)*lldh+iloc1-1)
586 elem3 = h((jloc1-2)*lldh+iloc1)
587 elem4 = h((jloc1-1)*lldh+iloc1)
588 CALL slanv2( elem1, elem2, elem3,
589 $ elem4, wr( k-1 ), wi( k-1 ),
590 $ wr( k ), wi( k ), sn, cs )
613 DO 60 k = iceil(ilo,nb)*nb, ihi-1, nb
614 CALL infog2l( k, k, desch, nprow, npcol, myrow, mycol,
615 $ iloc1, jloc1, hrsrc1, hcsrc1 )
616 CALL infog2l( k, k+1, desch, nprow, npcol, myrow, mycol,
617 $ iloc2, jloc2, hrsrc2, hcsrc2 )
618 CALL infog2l( k+1, k, desch, nprow, npcol, myrow, mycol,
619 $ iloc3, jloc3, hrsrc3, hcsrc3 )
620 CALL infog2l( k+1, k+1, desch, nprow, npcol, myrow, mycol,
621 $ iloc4, jloc4, hrsrc4, hcsrc4 )
622 IF( myrow.EQ.hrsrc2 .AND. mycol.EQ.hcsrc2 )
THEN
623 elem2 = h((jloc2-1)*lldh+iloc2)
624 IF( hrsrc1.NE.hrsrc2 .OR. hcsrc1.NE.hcsrc2 )
625 $
CALL sgesd2d( ictxt, 1, 1, elem2, 1, hrsrc1, hcsrc1)
627 IF( myrow.EQ.hrsrc3 .AND. mycol.EQ.hcsrc3 )
THEN
628 elem3 = h((jloc3-1)*lldh+iloc3)
629 IF( hrsrc1.NE.hrsrc3 .OR. hcsrc1.NE.hcsrc3 )
630 $
CALL sgesd2d( ictxt, 1, 1, elem3, 1, hrsrc1, hcsrc1)
632 IF( myrow.EQ.hrsrc4 .AND. mycol.EQ.hcsrc4 )
THEN
633 work(1) = h((jloc4-1)*lldh+iloc4)
635 work(2) = h((jloc4-1)*lldh+iloc4+1)
639 IF( hrsrc1.NE.hrsrc4 .OR. hcsrc1.NE.hcsrc4 )
640 $
CALL sgesd2d( ictxt, 2, 1, work, 2, hrsrc1, hcsrc1 )
642 IF( myrow.EQ.hrsrc1 .AND. mycol.EQ.hcsrc1 )
THEN
643 elem1 = h((jloc1-1)*lldh+iloc1)
644 IF( hrsrc1.NE.hrsrc2 .OR. hcsrc1.NE.hcsrc2 )
645 $
CALL sgerv2d( ictxt, 1, 1, elem2, 1, hrsrc2, hcsrc2)
646 IF( hrsrc1.NE.hrsrc3 .OR. hcsrc1.NE.hcsrc3 )
647 $
CALL sgerv2d( ictxt, 1, 1, elem3, 1, hrsrc3, hcsrc3)
648 IF( hrsrc1.NE.hrsrc4 .OR. hcsrc1.NE.hcsrc4 )
649 $
CALL sgerv2d( ictxt, 2, 1, work, 2, hrsrc4, hcsrc4 )
652 IF( elem5.EQ.zero )
THEN
653 IF( wr( k ).EQ.zero .AND. wi( k ).EQ.zero )
THEN
654 CALL slanv2( elem1, elem2, elem3, elem4, wr( k ),
655 $ wi( k ), wr( k+1 ), wi( k+1 ), sn, cs )
656 ELSEIF( wr( k+1 ).EQ.zero .AND. wi( k+1 ).EQ.zero )
660 ELSEIF( wr( k ).EQ.zero .AND. wi( k ).EQ.zero )
667 IF( nprocs.GT.1 )
THEN
668 CALL sgsum2d( ictxt,
'All',
' ', ihi-ilo+1, 1, wr(ilo), n,
670 CALL sgsum2d( ictxt,
'All',
' ', ihi-ilo+1, 1, wi(ilo), n,