1 SUBROUTINE pstrsen( JOB, COMPQ, SELECT, PARA, N, T, IT, JT,
2 $ DESCT, Q, IQ, JQ, DESCQ, WR, WI, M, S, SEP, WORK, LWORK,
3 $ IWORK, LIWORK, INFO )
17 INTEGER INFO, LIWORK, LWORK, M, N,
23 INTEGER PARA( 6 ), DESCT( * ), DESCQ( * ), IWORK( * )
24 REAL Q( * ), T( * ), WI( * ), WORK( * ), WR( * )
344 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
345 $ lld_, mb_, m_, nb_, n_, rsrc_
347 PARAMETER ( TOP =
'1-Tree',
348 $ block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
349 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
350 $ rsrc_ = 7, csrc_ = 8, lld_ = 9,
351 $ zero = 0.0, one = 1.0 )
354 LOGICAL LQUERY, WANTBH, WANTQ, WANTS, WANTSP
355 INTEGER ICOFFT12, ICTXT, IDUM1, IDUM2, IERR, ILOC1,
356 $ ipw1, iter, itt, jloc1, jtt, k, liwmin, lldt,
357 $ lldq, lwmin, mmax, mmin, myrow, mycol, n1, n2,
358 $ nb, noexsy, npcol, nprocs, nprow, space,
359 $ t12rows, t12cols, tcols, tcsrc, trows, trsrc,
360 $ wrk1, iwrk1, wrk2, iwrk2, wrk3, iwrk3
361 REAL DPDUM1, ELEM, EST, SCALE, RNORM
363 INTEGER DESCT12( DLEN_ ), MBNB2( 2 )
369 EXTERNAL lsame, numroc, pslange
384 ictxt = desct( ctxt_ )
385 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
391 IF( nprow.EQ.-1 )
THEN
397 lquery = lwork.EQ.-1 .OR. liwork.EQ.-1
402 CALL chk1mat( n, 5, n, 5, it, jt, desct, 9, info )
405 CALL chk1mat( n, 5, n, 5, iq, jq, descq, 13, info )
411 IF( desct( mb_ ).NE.desct( nb_ ) ) info = -(1000*9 + mb_)
414 IF( descq( mb_ ).NE.descq( nb_ ) ) info = -(1000*13 + mb_)
417 IF( desct( mb_ ).NE.descq( mb_ ) ) info = -(1000*9 + mb_)
423 IF( n.NE.desct( mb_ ) .AND. desct( mb_ ).LT.3 )
424 $ info = -(1000*9 + mb_)
425 IF( n.NE.descq( mb_ ) .AND. descq( mb_ ).LT.3 )
426 $ info = -(1000*13 + mb_)
433 IF( para(1).LT.1 .OR. para(1).GT.
min(nprow,npcol) )
434 $ info = -(1000 * 4 + 1)
435 IF( para(2).LT.1 .OR. para(2).GE.para(3) )
436 $ info = -(1000 * 4 + 2)
437 IF( para(3).LT.1 .OR. para(3).GT.nb )
438 $ info = -(1000 * 4 + 3)
439 IF( para(4).LT.0 .OR. para(4).GT.100 )
440 $ info = -(1000 * 4 + 4)
441 IF( para(5).LT.1 .OR. para(5).GT.nb )
442 $ info = -(1000 * 4 + 5)
443 IF( para(6).LT.1 .OR. para(6).GT.para(2) )
444 $ info = -(1000 * 4 + 6)
450 IF( it.NE.1 ) info = -7
451 IF( jt.NE.it ) info = -8
452 IF( iq.NE.1 ) info = -11
453 IF( jq.NE.iq ) info = -12
459 CALL pchk1mat( n, 5, n, 5, it, jt, desct, 9, 0, idum1,
463 CALL pchk1mat( n, 5, n, 5, iq, jq, descq, 13, 0, idum1,
467 CALL pchk2mat( n, 5, n, 5, it, jt, desct, 9, n, 5, n, 5,
468 $ iq, jq, descq, 13, 0, idum1, idum2, info )
473 IF( info.EQ.0 .OR. lquery )
THEN
474 wantbh = lsame( job,
'B' )
475 wants = lsame( job,
'E' ) .OR. wantbh
476 wantsp = lsame( job,
'V' ) .OR. wantbh
477 wantq = lsame( compq,
'V' )
479 IF( .NOT.lsame( job,
'N' ) .AND. .NOT.wants .AND. .NOT.wantsp )
482 ELSEIF( .NOT.lsame( compq,
'N' ) .AND. .NOT.wantq )
THEN
484 ELSEIF( n.LT.0 )
THEN
507 CALL infog2l( k+1, k, desct, nprow, npcol,
508 $ myrow, mycol, itt, jtt, trsrc, tcsrc )
509 IF( myrow.EQ.trsrc .AND. mycol.EQ.tcsrc )
THEN
510 elem = t( (jtt-1)*lldt + itt )
511 IF( elem.NE.zero )
THEN
512 IF(
SELECT(k) .AND. .NOT.
SELECT(k+1) )
THEN
515 ELSEIF( .NOT.
SELECT(k) .AND.
SELECT(k+1) )
THEN
522 IF(
SELECT(k) ) m = m + 1
527 $
CALL igamx2d( ictxt,
'All', top, 1, 1, mmax, 1, -1,
530 $
CALL igamn2d( ictxt,
'All', top, 1, 1, mmin, 1, -1,
532 IF( mmax.GT.mmin )
THEN
535 $
CALL igamx2d( ictxt,
'All', top, n, 1, iwork, n,
536 $ -1, -1, -1, -1, -1 )
542 mbnb2( 1 ) =
min(
max( para( 3 ), para( 2 )*2 ), nb )
543 mbnb2( 2 ) = mbnb2( 1 )
577 trows = numroc( n, nb, myrow, desct(rsrc_), nprow )
578 tcols = numroc( n, nb, mycol, desct(csrc_), npcol )
579 wrk3 = n + 7*nb**2 + 2*trows*para( 3 ) + tcols*para( 3 ) +
580 $
max( trows*para( 3 ), tcols*para( 3 ) )
581 iwrk3 = 5*para( 1 ) + para(2)*para(3) -
582 $ para(2) * (para(2) + 1 ) / 2
585 lwmin =
max( 1,
max( wrk2, wrk3) )
586 liwmin =
max( 1,
max( iwrk2, iwrk3 ) )+n
587 ELSE IF( lsame( job,
'N' ) )
THEN
588 lwmin =
max( 1, wrk3 )
590 ELSE IF( lsame( job,
'E' ) )
THEN
591 lwmin =
max( 1,
max( wrk1, wrk3) )
592 liwmin =
max( 1,
max( iwrk1, iwrk3 ) )+n
595 IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
597 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
606 $
CALL igamx2d( ictxt,
'All', top, 1, 1, info, 1, -1, -1, -1,
611 IF( info.NE.0 .AND. .NOT.lquery )
THEN
615 CALL pxerbla( ictxt,
'PSTRSEN', -info )
617 ELSEIF( lquery )
THEN
618 work( 1 ) = float(lwmin)
625 IF( m.EQ.n .OR. m.EQ.0 )
THEN
629 $ sep = pslange(
'1', n, n, t, it, jt, desct, work )
635 CALL pstrord( compq, iwork, para, n, t, it, jt,
636 $ desct, q, iq, jq, descq, wr, wi, m, work, lwork,
637 $ iwork(n+1), liwork-n, info )
646 CALL infog2l( 1, n1+1, desct, nprow, npcol, myrow,
647 $ mycol, iloc1, jloc1, trsrc, tcsrc )
648 icofft12 = mod( n1, nb )
649 t12rows = numroc( n1, nb, myrow, trsrc, nprow )
650 t12cols = numroc( n2+icofft12, nb, mycol, tcsrc, npcol )
651 CALL descinit( desct12, n1, n2+icofft12, nb, nb, trsrc,
652 $ tcsrc, ictxt,
max(1,t12rows), ierr )
653 CALL pslacpy(
'All', n1, n2, t, 1, n1+1, desct, work,
654 $ 1, 1+icofft12, desct12 )
658 space = desct12( lld_ ) * t12cols
674 rnorm = pslange(
'Frobenius', n1, n2, work, 1, 1+icofft12,
676 IF( rnorm.EQ.zero )
THEN
679 s = scale / ( sqrt( scale*scale / rnorm+rnorm )*
691 est = est * sqrt(float(n1*n2))