296 SUBROUTINE dtgsyl( TRANS, IJOB, M, N, A, LDA, B, LDB, C, LDC, D,
297 $ LDD, E, LDE, F, LDF, SCALE, DIF, WORK, LWORK,
306 INTEGER IJOB, INFO, LDA, LDB, LDC, LDD, LDE, LDF,
308 DOUBLE PRECISION DIF, SCALE
312 DOUBLE PRECISION A( LDA, * ), B( LDB, * ), C( LDC, * ),
313 $ d( ldd, * ), e( lde, * ), f( ldf, * ),
322 DOUBLE PRECISION ZERO, ONE
323 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0 )
326 LOGICAL LQUERY, NOTRAN
327 INTEGER I, IE, IFUNC, IROUND, IS, ISOLVE, J, JE, JS, K,
328 $ linfo, lwmin, mb, nb, p, ppqq, pq, q
329 DOUBLE PRECISION DSCALE, DSUM, SCALE2, SCALOC
334 EXTERNAL lsame, ilaenv
340 INTRINSIC dble, max, sqrt
347 notran = lsame( trans,
'N' )
348 lquery = ( lwork.EQ.-1 )
350 IF( .NOT.notran .AND. .NOT.lsame( trans,
'T' ) )
THEN
352 ELSE IF( notran )
THEN
353 IF( ( ijob.LT.0 ) .OR. ( ijob.GT.4 ) )
THEN
360 ELSE IF( n.LE.0 )
THEN
362 ELSE IF( lda.LT.max( 1, m ) )
THEN
364 ELSE IF( ldb.LT.max( 1, n ) )
THEN
366 ELSE IF( ldc.LT.max( 1, m ) )
THEN
368 ELSE IF( ldd.LT.max( 1, m ) )
THEN
370 ELSE IF( lde.LT.max( 1, n ) )
THEN
372 ELSE IF( ldf.LT.max( 1, m ) )
THEN
379 IF( ijob.EQ.1 .OR. ijob.EQ.2 )
THEN
380 lwmin = max( 1, 2*m*n )
389 IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
395 CALL xerbla(
'DTGSYL', -info )
397 ELSE IF( lquery )
THEN
403 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
415 mb = ilaenv( 2,
'DTGSYL', trans, m, n, -1, -1 )
416 nb = ilaenv( 5,
'DTGSYL', trans, m, n, -1, -1 )
423 CALL dlaset(
'F', m, n, zero, zero, c, ldc )
424 CALL dlaset(
'F', m, n, zero, zero, f, ldf )
425 ELSE IF( ijob.GE.1 )
THEN
430 IF( ( mb.LE.1 .AND. nb.LE.1 ) .OR. ( mb.GE.m .AND. nb.GE.n ) )
433 DO 30 iround = 1, isolve
440 CALL dtgsy2( trans, ifunc, m, n, a, lda, b, ldb, c, ldc, d,
441 $ ldd, e, lde, f, ldf, scale, dsum, dscale,
443 IF( dscale.NE.zero )
THEN
444 IF( ijob.EQ.1 .OR. ijob.EQ.3 )
THEN
445 dif = sqrt( dble( 2*m*n ) ) / ( dscale*sqrt( dsum ) )
447 dif = sqrt( dble( pq ) ) / ( dscale*sqrt( dsum ) )
451 IF( isolve.EQ.2 .AND. iround.EQ.1 )
THEN
456 CALL dlacpy(
'F', m, n, c, ldc, work, m )
457 CALL dlacpy(
'F', m, n, f, ldf, work( m*n+1 ), m )
458 CALL dlaset(
'F', m, n, zero, zero, c, ldc )
459 CALL dlaset(
'F', m, n, zero, zero, f, ldf )
460 ELSE IF( isolve.EQ.2 .AND. iround.EQ.2 )
THEN
461 CALL dlacpy(
'F', m, n, work, m, c, ldc )
462 CALL dlacpy(
'F', m, n, work( m*n+1 ), m, f, ldf )
482 IF( a( i, i-1 ).NE.zero )
488 IF( iwork( p ).EQ.iwork( p+1 ) )
503 IF( b( j, j-1 ).NE.zero )
509 IF( iwork( q ).EQ.iwork( q+1 ) )
514 DO 150 iround = 1, isolve
527 je = iwork( j+1 ) - 1
531 ie = iwork( i+1 ) - 1
534 CALL dtgsy2( trans, ifunc, mb, nb, a( is, is ), lda,
535 $ b( js, js ), ldb, c( is, js ), ldc,
536 $ d( is, is ), ldd, e( js, js ), lde,
537 $ f( is, js ), ldf, scaloc, dsum, dscale,
538 $ iwork( q+2 ), ppqq, linfo )
543 IF( scaloc.NE.one )
THEN
545 CALL dscal( m, scaloc, c( 1, k ), 1 )
546 CALL dscal( m, scaloc, f( 1, k ), 1 )
549 CALL dscal( is-1, scaloc, c( 1, k ), 1 )
550 CALL dscal( is-1, scaloc, f( 1, k ), 1 )
553 CALL dscal( m-ie, scaloc, c( ie+1, k ), 1 )
554 CALL dscal( m-ie, scaloc, f( ie+1, k ), 1 )
557 CALL dscal( m, scaloc, c( 1, k ), 1 )
558 CALL dscal( m, scaloc, f( 1, k ), 1 )
567 CALL dgemm(
'N',
'N', is-1, nb, mb, -one,
568 $ a( 1, is ), lda, c( is, js ), ldc, one,
570 CALL dgemm(
'N',
'N', is-1, nb, mb, -one,
571 $ d( 1, is ), ldd, c( is, js ), ldc, one,
575 CALL dgemm(
'N',
'N', mb, n-je, nb, one,
576 $ f( is, js ), ldf, b( js, je+1 ), ldb,
577 $ one, c( is, je+1 ), ldc )
578 CALL dgemm(
'N',
'N', mb, n-je, nb, one,
579 $ f( is, js ), ldf, e( js, je+1 ), lde,
580 $ one, f( is, je+1 ), ldf )
584 IF( dscale.NE.zero )
THEN
585 IF( ijob.EQ.1 .OR. ijob.EQ.3 )
THEN
586 dif = sqrt( dble( 2*m*n ) ) / ( dscale*sqrt( dsum ) )
588 dif = sqrt( dble( pq ) ) / ( dscale*sqrt( dsum ) )
591 IF( isolve.EQ.2 .AND. iround.EQ.1 )
THEN
596 CALL dlacpy(
'F', m, n, c, ldc, work, m )
597 CALL dlacpy(
'F', m, n, f, ldf, work( m*n+1 ), m )
598 CALL dlaset(
'F', m, n, zero, zero, c, ldc )
599 CALL dlaset(
'F', m, n, zero, zero, f, ldf )
600 ELSE IF( isolve.EQ.2 .AND. iround.EQ.2 )
THEN
601 CALL dlacpy(
'F', m, n, work, m, c, ldc )
602 CALL dlacpy(
'F', m, n, work( m*n+1 ), m, f, ldf )
617 ie = iwork( i+1 ) - 1
619 DO 200 j = q, p + 2, -1
621 je = iwork( j+1 ) - 1
623 CALL dtgsy2( trans, ifunc, mb, nb, a( is, is ), lda,
624 $ b( js, js ), ldb, c( is, js ), ldc,
625 $ d( is, is ), ldd, e( js, js ), lde,
626 $ f( is, js ), ldf, scaloc, dsum, dscale,
627 $ iwork( q+2 ), ppqq, linfo )
630 IF( scaloc.NE.one )
THEN
632 CALL dscal( m, scaloc, c( 1, k ), 1 )
633 CALL dscal( m, scaloc, f( 1, k ), 1 )
636 CALL dscal( is-1, scaloc, c( 1, k ), 1 )
637 CALL dscal( is-1, scaloc, f( 1, k ), 1 )
640 CALL dscal( m-ie, scaloc, c( ie+1, k ), 1 )
641 CALL dscal( m-ie, scaloc, f( ie+1, k ), 1 )
644 CALL dscal( m, scaloc, c( 1, k ), 1 )
645 CALL dscal( m, scaloc, f( 1, k ), 1 )
653 CALL dgemm(
'N',
'T', mb, js-1, nb, one, c( is, js ),
654 $ ldc, b( 1, js ), ldb, one, f( is, 1 ),
656 CALL dgemm(
'N',
'T', mb, js-1, nb, one, f( is, js ),
657 $ ldf, e( 1, js ), lde, one, f( is, 1 ),
661 CALL dgemm(
'T',
'N', m-ie, nb, mb, -one,
662 $ a( is, ie+1 ), lda, c( is, js ), ldc, one,
663 $ c( ie+1, js ), ldc )
664 CALL dgemm(
'T',
'N', m-ie, nb, mb, -one,
665 $ d( is, ie+1 ), ldd, f( is, js ), ldf, one,
666 $ c( ie+1, js ), ldc )
subroutine dlacpy(UPLO, M, N, A, LDA, B, LDB)
DLACPY copies all or part of one two-dimensional array to another.
subroutine dlaset(UPLO, M, N, ALPHA, BETA, A, LDA)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine dscal(N, DA, DX, INCX)
DSCAL
subroutine dgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
DGEMM
subroutine dtgsy2(TRANS, IJOB, M, N, A, LDA, B, LDB, C, LDC, D, LDD, E, LDE, F, LDF, SCALE, RDSUM, RDSCAL, IWORK, PQ, INFO)
DTGSY2 solves the generalized Sylvester equation (unblocked algorithm).
subroutine dtgsyl(TRANS, IJOB, M, N, A, LDA, B, LDB, C, LDC, D, LDD, E, LDE, F, LDF, SCALE, DIF, WORK, LWORK, IWORK, INFO)
DTGSYL