1 SUBROUTINE pdtrsen( 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,
19 DOUBLE PRECISION S, SEP
23 INTEGER PARA( 6 ), DESCT( * ), DESCQ( * ), IWORK( * )
24 DOUBLE PRECISION Q( * ), T( * ), WI( * ), WORK( * ), WR( * )
344 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
345 $ lld_, mb_, m_, nb_, n_, rsrc_
346 DOUBLE PRECISION ZERO, ONE
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.0d+0, one = 1.0d+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 DOUBLE PRECISION ELEM, EST, SCALE, RNORM
363 INTEGER DESCT12( DLEN_ ), MBNB2( 2 ), MMAX( 1 ),
365 DOUBLE PRECISION DPDUM1( 1 )
370 DOUBLE PRECISION PDLANGE
371 EXTERNAL lsame, numroc, pdlange
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,
530 $ -1, -1, -1, -1, -1 )
532 $
CALL igamn2d( ictxt,
'All', top, 1, 1, mmin( 1 ), 1,
533 $ -1, -1, -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
608 $
CALL igamx2d( ictxt,
'All', top, 1, 1, info, 1, -1, -1, -1,
613 IF( info.NE.0 .AND. .NOT.lquery )
THEN
617 CALL pxerbla( ictxt,
'PDTRSEN', -info )
619 ELSEIF( lquery )
THEN
620 work( 1 ) = dble(lwmin)
627 IF( m.EQ.n .OR. m.EQ.0 )
THEN
631 $ sep = pdlange(
'1', n, n, t, it, jt, desct, work )
637 CALL pdtrord( compq, iwork, para, n, t, it, jt,
638 $ desct, q, iq, jq, descq, wr, wi, m, work, lwork,
639 $ iwork(n+1), liwork-n, info )
648 CALL infog2l( 1, n1+1, desct, nprow, npcol, myrow,
649 $ mycol, iloc1, jloc1, trsrc, tcsrc )
650 icofft12 = mod( n1, nb )
651 t12rows = numroc( n1, nb, myrow, trsrc, nprow )
652 t12cols = numroc( n2+icofft12, nb, mycol, tcsrc, npcol )
653 CALL descinit( desct12, n1, n2+icofft12, nb, nb, trsrc,
654 $ tcsrc, ictxt,
max(1,t12rows), ierr )
655 CALL pdlacpy(
'All', n1, n2, t, 1, n1+1, desct, work,
656 $ 1, 1+icofft12, desct12 )
660 space = desct12( lld_ ) * t12cols
676 rnorm = pdlange(
'Frobenius', n1, n2, work, 1, 1+icofft12,
678 IF( rnorm.EQ.zero )
THEN
681 s = scale / ( sqrt( scale*scale / rnorm+rnorm )*
693 est = est * sqrt(dble(n1*n2))