1 RECURSIVE SUBROUTINE pslaqr0( WANTT, WANTZ, N, ILO, IHI, H,
2 $ DESCH, WR, WI, ILOZ, IHIZ, Z, DESCZ, WORK, LWORK,
3 $ IWORK, LIWORK, INFO, RECLEVEL )
16 INTEGER ihi, ihiz, ilo, iloz, info, liwork, lwork, n,
21 INTEGER desch( * ), descz( * ), iwork( * )
22 REAL h( * ), wi( n ), work( * ), wr( n ),
246 INTEGER block_cyclic_2d, csrc_, ctxt_, dlen_, dtype_,
247 $ lld_, mb_, m_, nb_, n_, rsrc_
249 PARAMETER ( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
250 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
251 $ rsrc_ = 7, csrc_ = 8, lld_ = 9, recmax = 3 )
253 PARAMETER ( ntiny = 11 )
255 parameter( kexnw = 5, kexsh = 6 )
257 parameter( wilk1 = 0.75e0, wilk2 = -0.4375e0 )
259 parameter( zero = 0.0e0, one = 1.0e0 )
262 REAL aa, bb, cc, cs, dd, sn, ss, swap, elem, t0,
263 $ elem1, elem2, elem3, alpha, sdsum, stamp
264 INTEGER i, j, inf, it, itmax, k, kacc22, kbot, kdu, ks,
265 $ kt, ktop, ku, kv, kwh, kwtop, kwv, ld, ls,
266 $ lwkopt, ndfl, nh, nho, nibble, nmin, ns, nsmax,
267 $ nsr, nve, nw, nwmax, nwr, lldh, lldz, ii, jj,
268 $ ictxt, nprow, npcol, myrow, mycol, ipv, ipt,
269 $ ipw, ipwrk, vrows, vcols, trows, tcols, wrows,
270 $ wcols, hrsrc, hcsrc, nb, is, ie, nprocs, kk,
271 $ iroffh, icoffh, hrsrc3, hcsrc3, nwin, totit,
272 $ sweep, jw, totns, liwkopt, npmin, ictxt_new,
273 $ myrow_new, mycol_new
274 LOGICAL nwinc, sorted, lquery, recursion
282 INTEGER descv( dlen_ ), desct( dlen_ ), descw( dlen_ ),
288 $
pselget, slaqr0, slaset, psgemr2d
291 INTRINSIC abs, float, int,
max,
min, mod
295 ictxt = desch( ctxt_ )
296 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
298 recursion = reclevel .LT. recmax
323 lquery = lwork.EQ.-1 .OR. liwork.EQ.-1
334 IF( n.LE.ntiny )
THEN
338 CALL pslaqr1( wantt, wantz, n, ilo, ihi, h, desch, wr, wi,
339 $ iloz, ihiz, z, descz, work, lwork, iwork, liwork, info )
340 lwkopt = int( work(1) )
345 ELSEIF( n.LE.nb )
THEN
346 IF( myrow.EQ.desch(rsrc_) .AND. mycol.EQ.desch(csrc_) )
THEN
347 CALL slaqr0( wantt, wantz, n, ilo, ihi, h, desch(lld_),
348 $ wr, wi, iloz, ihiz, z, descz(lld_), work, lwork, info )
350 $
CALL slaset(
'L', n-2, n-2, zero, zero, h(3),
352 lwkopt = int( work(1) )
382 nwr =
pilaenvx( ictxt, 13,
'PSLAQR0', jbcmpz, n, ilo, ihi,
385 nwr =
min( ihi-ilo+1, nwr )
393 nwin =
pilaenvx( ictxt, 19,
'PSLAQR0', jbcmpz, n, nb, nb, nb )
394 nsr =
pilaenvx( ictxt, 15,
'PSLAQR0', jbcmpz, n, ilo, ihi,
396 nsr =
min( nsr, ihi-ilo )
397 nsr =
max( 2, nsr-mod( nsr, 2 ) )
405 CALL pslaqr3( wantt, wantz, n, ilo, ihi, nwr+1, h,
406 $ desch, iloz, ihiz, z, descz, ls, ld, wr, wi, h,
407 $ desch, n, h, desch, n, h, desch, work, -1, iwork,
409 lwkopt = lwkopt + int( work( 1 ) )
414 CALL pslaqr5( wantt, wantz, 2, n, 1, n, n, wr, wi, h,
415 $ desch, iloz, ihiz, z, descz, work, -1, iwork,
420 lwkopt =
max( lwkopt, int( work( 1 ) ) )
421 liwkopt =
max( liwkopt, iwork( 1 ) )
426 work( 1 ) = float( lwkopt )
433 nmin =
pilaenvx( ictxt, 12,
'PSLAQR0', jbcmpz, n, ilo, ihi,
435 nmin =
max( ntiny, nmin )
439 nibble =
pilaenvx( ictxt, 14,
'PSLAQR0', jbcmpz, n, ilo, ihi,
441 nibble =
max( 0, nibble )
446 kacc22 =
pilaenvx( ictxt, 16,
'PSLAQR0', jbcmpz, n, ilo, ihi,
448 kacc22 =
max( 1, kacc22 )
449 kacc22 =
min( 2, kacc22 )
454 nwmax =
min( ( n-1 ) / 3, lwork / 2 )
459 nsmax =
min( ( n+6 ) / 9, lwork - lwork/3 )
460 nsmax = nsmax - mod( nsmax, 2 )
468 itmax =
max( 30, 2*kexsh )*
max( 10, ( ihi-ilo+1 ) )
486 DO 10 k = kbot, ilo + 1, -1
487 CALL infog2l( k, k-1, desch, nprow, npcol, myrow, mycol,
488 $ ii, jj, hrsrc, hcsrc )
489 IF( myrow.EQ.hrsrc .AND. mycol.EQ.hcsrc )
THEN
490 IF( h( ii + (jj-1)*lldh ).EQ.zero )
498 $
CALL igamx2d( ictxt,
'All',
'1-Tree', 1, 1, ktop, 1,
499 $ -1, -1, -1, -1, -1 )
504 IF( nh.LE.ntiny )
THEN
506 ELSEIF( ndfl.LT.kexnw .OR. nh.LT.nw )
THEN
515 IF( nh.LE.
min( nmin, nwmax ) )
THEN
518 nw =
min( nwr, nh, nwmax )
519 IF( nw.LT.nwmax )
THEN
520 IF( nw.GE.nh-1 )
THEN
523 kwtop = kbot - nw + 1
524 CALL pselget(
'All',
'1-Tree', elem1, h, kwtop,
526 CALL pselget(
'All',
'1-Tree', elem2, h,
527 $ kwtop-1, kwtop-2, desch )
528 IF( abs( elem1 ).GT.abs( elem2 ) ) nw = nw + 1
542 IF( nwinc .AND. nw.LT.
min( nwmax, nh ) )
THEN
543 nw =
min( nwmax, nh, 2*nw )
546 IF( nw.EQ.nh .AND. nh.GT.2 )
562 nho = ( n-nw-1 ) - kt + 1
564 nve = ( n-nw ) - kwv + 1
566 jw =
min( nw, kbot-ktop+1 )
567 kwtop = kbot - jw + 1
568 iroffh = mod( kwtop - 1, nb )
570 hrsrc =
indxg2p( kwtop, nb, myrow, desch(rsrc_), nprow )
571 hcsrc =
indxg2p( kwtop, nb, mycol, desch(csrc_), npcol )
572 vrows =
numroc( jw+iroffh, nb, myrow, hrsrc, nprow )
573 vcols =
numroc( jw+icoffh, nb, mycol, hcsrc, npcol )
574 CALL descinit( descv, jw+iroffh, jw+icoffh, nb, nb,
575 $ hrsrc, hcsrc, ictxt,
max(1, vrows), info )
577 trows =
numroc( jw+iroffh, nb, myrow, hrsrc, nprow )
578 tcols =
numroc( jw+icoffh, nb, mycol, hcsrc, npcol )
579 CALL descinit( desct, jw+iroffh, jw+icoffh, nb, nb,
580 $ hrsrc, hcsrc, ictxt,
max(1, trows), info )
581 wrows =
numroc( jw+iroffh, nb, myrow, hrsrc, nprow )
582 wcols =
numroc( jw+icoffh, nb, mycol, hcsrc, npcol )
583 CALL descinit( descw, jw+iroffh, jw+icoffh, nb, nb,
584 $ hrsrc, hcsrc, ictxt,
max(1, wrows), info )
587 ipt = ipv + descv( lld_ ) * vcols
588 ipw = ipt + desct( lld_ ) * tcols
589 ipwrk = ipw + descw( lld_ ) * wcols
594 CALL pslaqr3( wantt, wantz, n, ktop, kbot, nw, h,
595 $ desch, iloz, ihiz, z, descz, ls, ld, wr, wi,
596 $ work(ipv), descv, nho, work(ipt), desct, nve,
597 $ work(ipw), descw, work(ipwrk), lwork-ipwrk+1,
598 $ iwork, liwork, reclevel )
614 IF( ( ld.EQ.0 ) .OR. ( ( 100*ld.LE.nw*nibble ) .AND. ( kbot-
615 $ ktop+1.GT.
min( nmin, nwmax ) ) ) )
THEN
621 ns =
min( nsmax, nsr,
max( 2, kbot-ktop ) )
622 ns = ns - mod( ns, 2 )
631 IF( mod( ndfl, kexsh ).EQ.0 )
THEN
633 DO 30 i = kbot,
max( ks+1, ktop+2 ), -2
634 CALL pselget(
'All',
'1-Tree', elem1, h, i, i-1,
636 CALL pselget(
'All',
'1-Tree', elem2, h, i-1, i-2,
638 CALL pselget(
'All',
'1-Tree', elem3, h, i, i,
640 ss = abs( elem1 ) + abs( elem2 )
641 aa = wilk1*ss + elem3
645 CALL slanv2( aa, bb, cc, dd, wr( i-1 ), wi( i-1 ),
646 $ wr( i ), wi( i ), cs, sn )
648 IF( ks.EQ.ktop )
THEN
649 CALL pselget(
'All',
'1-Tree', elem1, h, ks+1,
653 wr( ks ) = wr( ks+1 )
654 wi( ks ) = wi( ks+1 )
662 IF( kbot-ks+1.LE.ns / 2 )
THEN
665 npmin =
pilaenvx( ictxt, 23,
'PSLAQR0',
'EN', ns,
670 npmin =
min(npmin, 8)
671 IF(
min(nprow, npcol).LE.npmin+1 .OR.
672 $ reclevel.GE.1 )
THEN
677 iroffh = mod( ks - 1, nb )
679 IF( ns.GT.nmin )
THEN
680 hrsrc =
indxg2p( ks, nb, myrow, desch(rsrc_),
682 hcsrc =
indxg2p( ks, nb, myrow, desch(csrc_),
688 trows =
numroc( ns+iroffh, nb, myrow, hrsrc,
690 tcols =
numroc( ns+icoffh, nb, mycol, hcsrc,
692 CALL descinit( desct, ns+iroffh, ns+icoffh, nb,
693 $ nb, hrsrc, hcsrc, ictxt,
max(1, trows),
696 ipwrk = ipt + desct(lld_) * tcols
698 IF( ns.GT.nmin .AND. recursion )
THEN
699 CALL pslacpy(
'All', ns, ns, h, ks, ks,
700 $ desch, work(ipt), 1+iroffh, 1+icoffh,
702 CALL pslaqr0( .false., .false., iroffh+ns,
703 $ 1+iroffh, iroffh+ns, work(ipt),
704 $ desct, wr( ks-iroffh ),
705 $ wi( ks-iroffh ), 1, 1, zdum,
706 $ descz, work( ipwrk ),
707 $ lwork-ipwrk+1, iwork, liwork,
710 CALL pslamve(
'All', ns, ns, h, ks, ks,
711 $ desch, work(ipt), 1+iroffh, 1+icoffh,
712 $ desct, work(ipwrk) )
713 CALL pslaqr1( .false., .false., iroffh+ns,
714 $ 1+iroffh, iroffh+ns, work(ipt),
715 $ desct, wr( ks-iroffh ),
716 $ wi( ks-iroffh ), 1+iroffh, iroffh+ns,
717 $ zdum, descz, work( ipwrk ),
718 $ lwork-ipwrk+1, iwork, liwork, inf )
729 pmap( j+1+i*npmin ) =
730 $ blacs_pnum( ictxt, i, j )
733 CALL blacs_gridmap( ictxt_new, pmap, npmin,
735 CALL blacs_gridinfo( ictxt_new, npmin, npmin,
736 $ myrow_new, mycol_new )
737 IF( myrow.GE.npmin .OR. mycol.GE.npmin )
740 IF( ictxt_new.GE.0 )
THEN
741 trows =
numroc( ns, nb, myrow_new, 0, npmin )
742 tcols =
numroc( ns, nb, mycol_new, 0, npmin )
743 CALL descinit( desct, ns, ns, nb, nb, 0, 0,
744 $ ictxt_new,
max(1,trows), info )
746 ipwrk = ipt + desct(lld_) * tcols
753 CALL psgemr2d( ns, ns, h, ks, ks, desch,
754 $ work(ipt), 1, 1, desct, ictxt )
762 IF( ictxt_new.GE.0 )
THEN
770 CALL pslaqr1( .false., .false., ns, 1,
771 $ ns, work(ipt), desct, wr( ks ),
772 $ wi( ks ), 1, ns, zdum, desct,
773 $ work( ipwrk ), lwork-ipwrk+1, iwork,
776 CALL blacs_gridexit( ictxt_new )
778 IF( myrow+mycol.GT.0 )
THEN
784 CALL igamn2d( ictxt,
'All',
'1-Tree', 1, 1, inf,
785 $ 1, -1, -1, -1, -1, -1 )
786 CALL sgsum2d( ictxt,
'All',
' ', ns, 1, wr(ks),
788 CALL sgsum2d( ictxt,
'All',
' ', ns, 1, wi(ks),
797 IF( ks.GE.kbot )
THEN
798 CALL pselget(
'All',
'1-Tree', aa, h, kbot-1,
800 CALL pselget(
'All',
'1-Tree', cc, h, kbot,
802 CALL pselget(
'All',
'1-Tree', bb, h, kbot-1,
804 CALL pselget(
'All',
'1-Tree', dd, h, kbot,
806 CALL slanv2( aa, bb, cc, dd, wr( kbot-1 ),
807 $ wi( kbot-1 ), wr( kbot ),
808 $ wi( kbot ), cs, sn )
813 IF( kbot-ks+1.GT.ns )
THEN
820 DO 80 k = kbot, ks + 1, -1
825 IF( abs( wr( i ) )+abs( wi( i ) ).LT.
826 $ abs( wr( i+1 ) )+abs( wi( i+1 ) ) )
THEN
848 DO 100 i = kbot, ks + 2, -2
849 IF( wi( i ).NE.-wi( i-1 ) )
THEN
853 wr( i-1 ) = wr( i-2 )
858 wi( i-1 ) = wi( i-2 )
867 IF( kbot-ks+1.EQ.2 )
THEN
868 IF( wi( kbot ).EQ.zero )
THEN
869 CALL pselget(
'All',
'1-Tree', elem, h, kbot,
871 IF( abs( wr( kbot )-elem ).LT.
872 $ abs( wr( kbot-1 )-elem ) )
THEN
873 wr( kbot-1 ) = wr( kbot )
875 wr( kbot ) = wr( kbot-1 )
885 ns =
min( ns, kbot-ks+1 )
886 ns = ns - mod( ns, 2 )
893 CALL pslaqr5( wantt, wantz, kacc22, n, ktop, kbot,
894 $ ns, wr( ks ), wi( ks ), h, desch, iloz, ihiz, z,
895 $ descz, work, lwork, iwork, liwork )
918 work( 1 ) = float( lwkopt )
920 IF( .NOT. lquery )
THEN