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, 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 ELEM, EST, SCALE, RNORM
363 INTEGER DESCT12( DLEN_ ), MBNB2( 2 ), MMAX( 1 ),
371 EXTERNAL lsame, numroc, pslange
386 ictxt = desct( ctxt_ )
387 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
393 IF( nprow.EQ.-1 )
THEN
399 lquery = lwork.EQ.-1 .OR. liwork.EQ.-1
404 CALL chk1mat( n, 5, n, 5, it, jt, desct, 9, info )
407 CALL chk1mat( n, 5, n, 5, iq, jq, descq, 13, info )
413 IF( desct( mb_ ).NE.desct( nb_ ) ) info = -(1000*9 + mb_)
416 IF( descq( mb_ ).NE.descq( nb_ ) ) info = -(1000*13 + mb_)
419 IF( desct( mb_ ).NE.descq( mb_ ) ) info = -(1000*9 + mb_)
425 IF( n.NE.desct( mb_ ) .AND. desct( mb_ ).LT.3 )
426 $ info = -(1000*9 + mb_)
427 IF( n.NE.descq( mb_ ) .AND. descq( mb_ ).LT.3 )
428 $ info = -(1000*13 + mb_)
435 IF( para(1).LT.1 .OR. para(1).GT.
min(nprow,npcol) )
436 $ info = -(1000 * 4 + 1)
437 IF( para(2).LT.1 .OR. para(2).GE.para(3) )
438 $ info = -(1000 * 4 + 2)
439 IF( para(3).LT.1 .OR. para(3).GT.nb )
440 $ info = -(1000 * 4 + 3)
441 IF( para(4).LT.0 .OR. para(4).GT.100 )
442 $ info = -(1000 * 4 + 4)
443 IF( para(5).LT.1 .OR. para(5).GT.nb )
444 $ info = -(1000 * 4 + 5)
445 IF( para(6).LT.1 .OR. para(6).GT.para(2) )
446 $ info = -(1000 * 4 + 6)
452 IF( it.NE.1 ) info = -7
453 IF( jt.NE.it ) info = -8
454 IF( iq.NE.1 ) info = -11
455 IF( jq.NE.iq ) info = -12
461 CALL pchk1mat( n, 5, n, 5, it, jt, desct, 9, 0, idum1,
465 CALL pchk1mat( n, 5, n, 5, iq, jq, descq, 13, 0, idum1,
469 CALL pchk2mat( n, 5, n, 5, it, jt, desct, 9, n, 5, n, 5,
470 $ iq, jq, descq, 13, 0, idum1, idum2, info )
475 IF( info.EQ.0 .OR. lquery )
THEN
476 wantbh = lsame( job,
'B' )
477 wants = lsame( job,
'E' ) .OR. wantbh
478 wantsp = lsame( job,
'V' ) .OR. wantbh
479 wantq = lsame( compq,
'V' )
481 IF( .NOT.lsame( job,
'N' ) .AND. .NOT.wants .AND. .NOT.wantsp )
484 ELSEIF( .NOT.lsame( compq,
'N' ) .AND. .NOT.wantq )
THEN
486 ELSEIF( n.LT.0 )
THEN
509 CALL infog2l( k+1, k, desct, nprow, npcol,
510 $ myrow, mycol, itt, jtt, trsrc, tcsrc )
511 IF( myrow.EQ.trsrc .AND. mycol.EQ.tcsrc )
THEN
512 elem = t( (jtt-1)*lldt + itt )
513 IF( elem.NE.zero )
THEN
514 IF(
SELECT(k) .AND. .NOT.
SELECT(k+1) )
THEN
517 ELSEIF( .NOT.
SELECT(k) .AND.
SELECT(k+1) )
THEN
524 IF(
SELECT(k) ) m = m + 1
529 $
CALL igamx2d( ictxt,
'All', top, 1, 1, mmax( 1 ), 1, -1,
532 $
CALL igamn2d( ictxt,
'All', top, 1, 1, mmin( 1 ), 1, -1,
534 IF( mmax( 1 ).GT.mmin( 1 ) )
THEN
537 $
CALL igamx2d( ictxt,
'All', top, n, 1, iwork, n,
538 $ -1, -1, -1, -1, -1 )
544 mbnb2( 1 ) =
min(
max( para( 3 ), para( 2 )*2 ), nb )
545 mbnb2( 2 ) = mbnb2( 1 )
579 trows = numroc( n, nb, myrow, desct(rsrc_), nprow )
580 tcols = numroc( n, nb, mycol, desct(csrc_), npcol )
581 wrk3 = n + 7*nb**2 + 2*trows*para( 3 ) + tcols*para( 3 ) +
582 $
max( trows*para( 3 ), tcols*para( 3 ) )
583 iwrk3 = 5*para( 1 ) + para(2)*para(3) -
584 $ para(2) * (para(2) + 1 ) / 2
587 lwmin =
max( 1,
max( wrk2, wrk3) )
588 liwmin =
max( 1,
max( iwrk2, iwrk3 ) )+n
589 ELSE IF( lsame( job,
'N' ) )
THEN
590 lwmin =
max( 1, wrk3 )
592 ELSE IF( lsame( job,
'E' ) )
THEN
593 lwmin =
max( 1,
max( wrk1, wrk3) )
594 liwmin =
max( 1,
max( iwrk1, iwrk3 ) )+n
597 IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
599 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
607 IF( nprocs.GT.1 )
THEN
608 CALL igamx2d( ictxt,
'All', top, 1, 1, info, 1, -1, -1, -1,
614 IF( info.NE.0 .AND. .NOT.lquery )
THEN
618 CALL pxerbla( ictxt,
'PSTRSEN', -info )
620 ELSEIF( lquery )
THEN
621 work( 1 ) = float(lwmin)
628 IF( m.EQ.n .OR. m.EQ.0 )
THEN
632 $ sep = pslange(
'1', n, n, t, it, jt, desct, work )
638 CALL pstrord( compq, iwork, para, n, t, it, jt,
639 $ desct, q, iq, jq, descq, wr, wi, m, work, lwork,
640 $ iwork(n+1), liwork-n, info )
649 CALL infog2l( 1, n1+1, desct, nprow, npcol, myrow,
650 $ mycol, iloc1, jloc1, trsrc, tcsrc )
651 icofft12 = mod( n1, nb )
652 t12rows = numroc( n1, nb, myrow, trsrc, nprow )
653 t12cols = numroc( n2+icofft12, nb, mycol, tcsrc, npcol )
654 CALL descinit( desct12, n1, n2+icofft12, nb, nb, trsrc,
655 $ tcsrc, ictxt,
max(1,t12rows), ierr )
656 CALL pslacpy(
'All', n1, n2, t, 1, n1+1, desct, work,
657 $ 1, 1+icofft12, desct12 )
661 space = desct12( lld_ ) * t12cols
677 rnorm = pslange(
'Frobenius', n1, n2, work, 1, 1+icofft12,
679 IF( rnorm.EQ.zero )
THEN
682 s = scale / ( sqrt( scale*scale / rnorm+rnorm )*
694 est = est * sqrt(float(n1*n2))