296 SUBROUTINE stgsyl( 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,
312 REAL A( lda, * ), B( ldb, * ), C( ldc, * ),
313 $ d( ldd, * ), e( lde, * ), f( ldf, * ),
323 parameter( zero = 0.0e+0, one = 1.0e+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 REAL DSCALE, DSUM, SCALE2, SCALOC
334 EXTERNAL lsame, ilaenv
340 INTRINSIC max,
REAL, 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(
'STGSYL', -info )
397 ELSE IF( lquery )
THEN 403 IF( m.EQ.0 .OR. n.EQ.0 )
THEN 415 mb = ilaenv( 2,
'STGSYL', trans, m, n, -1, -1 )
416 nb = ilaenv( 5,
'STGSYL', trans, m, n, -1, -1 )
423 CALL slaset(
'F', m, n, zero, zero, c, ldc )
424 CALL slaset(
'F', m, n, zero, zero, f, ldf )
425 ELSE IF( ijob.GE.1 .AND. notran )
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 stgsy2( 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(
REAL( 2*M*N ) ) / ( DSCALE*SQRT( dsum ) )
447 dif = sqrt(
REAL( PQ ) ) / ( DSCALE*SQRT( dsum ) )
451 IF( isolve.EQ.2 .AND. iround.EQ.1 )
THEN 456 CALL slacpy(
'F', m, n, c, ldc, work, m )
457 CALL slacpy(
'F', m, n, f, ldf, work( m*n+1 ), m )
458 CALL slaset(
'F', m, n, zero, zero, c, ldc )
459 CALL slaset(
'F', m, n, zero, zero, f, ldf )
460 ELSE IF( isolve.EQ.2 .AND. iround.EQ.2 )
THEN 461 CALL slacpy(
'F', m, n, work, m, c, ldc )
462 CALL slacpy(
'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 stgsy2( 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 sscal( m, scaloc, c( 1, k ), 1 )
546 CALL sscal( m, scaloc, f( 1, k ), 1 )
549 CALL sscal( is-1, scaloc, c( 1, k ), 1 )
550 CALL sscal( is-1, scaloc, f( 1, k ), 1 )
553 CALL sscal( m-ie, scaloc, c( ie+1, k ), 1 )
554 CALL sscal( m-ie, scaloc, f( ie+1, k ), 1 )
557 CALL sscal( m, scaloc, c( 1, k ), 1 )
558 CALL sscal( m, scaloc, f( 1, k ), 1 )
567 CALL sgemm(
'N',
'N', is-1, nb, mb, -one,
568 $ a( 1, is ), lda, c( is, js ), ldc, one,
570 CALL sgemm(
'N',
'N', is-1, nb, mb, -one,
571 $ d( 1, is ), ldd, c( is, js ), ldc, one,
575 CALL sgemm(
'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 sgemm(
'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(
REAL( 2*M*N ) ) / ( DSCALE*SQRT( dsum ) )
588 dif = sqrt(
REAL( PQ ) ) / ( DSCALE*SQRT( dsum ) )
591 IF( isolve.EQ.2 .AND. iround.EQ.1 )
THEN 596 CALL slacpy(
'F', m, n, c, ldc, work, m )
597 CALL slacpy(
'F', m, n, f, ldf, work( m*n+1 ), m )
598 CALL slaset(
'F', m, n, zero, zero, c, ldc )
599 CALL slaset(
'F', m, n, zero, zero, f, ldf )
600 ELSE IF( isolve.EQ.2 .AND. iround.EQ.2 )
THEN 601 CALL slacpy(
'F', m, n, work, m, c, ldc )
602 CALL slacpy(
'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 stgsy2( 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 sscal( m, scaloc, c( 1, k ), 1 )
633 CALL sscal( m, scaloc, f( 1, k ), 1 )
636 CALL sscal( is-1, scaloc, c( 1, k ), 1 )
637 CALL sscal( is-1, scaloc, f( 1, k ), 1 )
640 CALL sscal( m-ie, scaloc, c( ie+1, k ), 1 )
641 CALL sscal( m-ie, scaloc, f( ie+1, k ), 1 )
644 CALL sscal( m, scaloc, c( 1, k ), 1 )
645 CALL sscal( m, scaloc, f( 1, k ), 1 )
653 CALL sgemm(
'N',
'T', mb, js-1, nb, one, c( is, js ),
654 $ ldc, b( 1, js ), ldb, one, f( is, 1 ),
656 CALL sgemm(
'N',
'T', mb, js-1, nb, one, f( is, js ),
657 $ ldf, e( 1, js ), lde, one, f( is, 1 ),
661 CALL sgemm(
'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 sgemm(
'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 xerbla(SRNAME, INFO)
XERBLA
subroutine stgsy2(TRANS, IJOB, M, N, A, LDA, B, LDB, C, LDC, D, LDD, E, LDE, F, LDF, SCALE, RDSUM, RDSCAL, IWORK, PQ, INFO)
STGSY2 solves the generalized Sylvester equation (unblocked algorithm).
subroutine sgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
SGEMM
subroutine slaset(UPLO, M, N, ALPHA, BETA, A, LDA)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values...
subroutine stgsyl(TRANS, IJOB, M, N, A, LDA, B, LDB, C, LDC, D, LDD, E, LDE, F, LDF, SCALE, DIF, WORK, LWORK, IWORK, INFO)
STGSYL
subroutine sscal(N, SA, SX, INCX)
SSCAL
subroutine slacpy(UPLO, M, N, A, LDA, B, LDB)
SLACPY copies all or part of one two-dimensional array to another.