178 SUBROUTINE dtrsyl3( TRANA, TRANB, ISGN, M, N, A, LDA, B, LDB, C,
179 $ LDC, SCALE, IWORK, LIWORK, SWORK, LDSWORK,
184 CHARACTER TRANA, TRANB
185 INTEGER INFO, ISGN, LDA, LDB, LDC, M, N,
187 DOUBLE PRECISION SCALE
191 DOUBLE PRECISION A( LDA, * ), B( LDB, * ), C( LDC, * ),
192 $ swork( ldswork, * )
195 DOUBLE PRECISION ZERO, ONE
196 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0 )
199 LOGICAL NOTRNA, NOTRNB, LQUERY, SKIP
200 INTEGER AWRK, BWRK, I, I1, I2, IINFO, J, J1, J2, JJ,
201 $ k, k1, k2, l, l1, l2, ll, nba, nb, nbb, pc
202 DOUBLE PRECISION ANRM, BIGNUM, BNRM, CNRM, SCAL, SCALOC,
203 $ SCAMIN, SGN, XNRM, BUF, SMLNUM
206 DOUBLE PRECISION WNRM( MAX( M, N ) )
211 DOUBLE PRECISION DLANGE, DLAMCH, DLARMM
212 EXTERNAL dlange, dlamch, dlarmm, ilaenv, lsame
218 INTRINSIC abs, dble, exponent, max, min
224 notrna = lsame( trana,
'N' )
225 notrnb = lsame( tranb,
'N' )
229 nb = max(8, ilaenv( 1,
'DTRSYL',
'', m, n, -1, -1) )
233 nba = max( 1, (m + nb - 1) / nb )
234 nbb = max( 1, (n + nb - 1) / nb )
239 lquery = ( liwork.EQ.-1 .OR. ldswork.EQ.-1 )
240 iwork( 1 ) = nba + nbb + 2
243 swork( 1, 1 ) = max( nba, nbb )
244 swork( 2, 1 ) = 2 * nbb + nba
249 IF( .NOT.notrna .AND. .NOT.lsame( trana,
'T' ) .AND. .NOT.
250 $ lsame( trana,
'C' ) )
THEN
252 ELSE IF( .NOT.notrnb .AND. .NOT.lsame( tranb,
'T' ) .AND. .NOT.
253 $ lsame( tranb,
'C' ) )
THEN
255 ELSE IF( isgn.NE.1 .AND. isgn.NE.-1 )
THEN
257 ELSE IF( m.LT.0 )
THEN
259 ELSE IF( n.LT.0 )
THEN
261 ELSE IF( lda.LT.max( 1, m ) )
THEN
263 ELSE IF( ldb.LT.max( 1, n ) )
THEN
265 ELSE IF( ldc.LT.max( 1, m ) )
THEN
269 CALL xerbla(
'DTRSYL3', -info )
271 ELSE IF( lquery )
THEN
278 IF( m.EQ.0 .OR. n.EQ.0 )
284 IF( min( nba, nbb ).EQ.1 .OR. ldswork.LT.max( nba, nbb ) .OR.
285 $ liwork.LT.iwork(1) )
THEN
286 CALL dtrsyl( trana, tranb, isgn, m, n, a, lda, b, ldb,
287 $ c, ldc, scale, info )
293 smlnum = dlamch(
'S' )
294 bignum = one / smlnum
300 iwork( i ) = ( i - 1 ) * nb + 1
302 iwork( nba + 1 ) = m + 1
305 l2 = iwork( k + 1 ) - 1
315 IF( a( l, l+1 ).NE.zero .AND. a( l+1, l ).NE.zero )
THEN
317 IF( l + 1 .EQ. iwork( k + 1 ) )
THEN
318 iwork( k + 1 ) = iwork( k + 1 ) + 1
325 iwork( nba + 1 ) = m + 1
326 IF( iwork( nba ).GE.iwork( nba + 1 ) )
THEN
327 iwork( nba ) = iwork( nba + 1 )
336 iwork( pc + i ) = ( i - 1 ) * nb + 1
338 iwork( pc + nbb + 1 ) = n + 1
341 l2 = iwork( pc + k + 1 ) - 1
351 IF( b( l, l+1 ).NE.zero .AND. b( l+1, l ).NE.zero )
THEN
353 IF( l + 1 .EQ. iwork( pc + k + 1 ) )
THEN
354 iwork( pc + k + 1 ) = iwork( pc + k + 1 ) + 1
361 iwork( pc + nbb + 1 ) = n + 1
362 IF( iwork( pc + nbb ).GE.iwork( pc + nbb + 1 ) )
THEN
363 iwork( pc + nbb ) = iwork( pc + nbb + 1 )
390 swork( k, awrk + l ) = dlange(
'I', k2-k1, l2-l1,
391 $ a( k1, l1 ), lda, wnrm )
393 swork( l, awrk + k ) = dlange(
'1', k2-k1, l2-l1,
394 $ a( k1, l1 ), lda, wnrm )
401 k2 = iwork( pc + k + 1 )
404 l2 = iwork( pc + l + 1 )
406 swork( k, bwrk + l ) = dlange(
'I', k2-k1, l2-l1,
407 $ b( k1, l1 ), ldb, wnrm )
409 swork( l, bwrk + k ) = dlange(
'1', k2-k1, l2-l1,
410 $ b( k1, l1 ), ldb, wnrm )
417 IF( notrna .AND. notrnb )
THEN
448 l2 = iwork( pc + l + 1 )
450 CALL dtrsyl( trana, tranb, isgn, k2-k1, l2-l1,
453 $ c( k1, l1 ), ldc, scaloc, iinfo )
454 info = max( info, iinfo )
456 IF ( scaloc * swork( k, l ) .EQ. zero )
THEN
457 IF( scaloc .EQ. zero )
THEN
465 buf = buf*2.d0**exponent( scaloc )
472 swork( ll, jj ) = min( bignum,
473 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
477 swork( k, l ) = scaloc * swork( k, l )
478 xnrm = dlange(
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
491 cnrm = dlange(
'I', i2-i1, l2-l1, c( i1, l1 ),
493 scamin = min( swork( i, l ), swork( k, l ) )
494 cnrm = cnrm * ( scamin / swork( i, l ) )
495 xnrm = xnrm * ( scamin / swork( k, l ) )
496 anrm = swork( i, awrk + k )
497 scaloc = dlarmm( anrm, xnrm, cnrm )
498 IF( scaloc * scamin .EQ. zero )
THEN
500 buf = buf*2.d0**exponent( scaloc )
503 swork( ll, jj ) = min( bignum,
504 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
507 scamin = scamin / 2.d0**exponent( scaloc )
508 scaloc = scaloc / 2.d0**exponent( scaloc )
516 scal = ( scamin / swork( k, l ) ) * scaloc
517 IF (scal .NE. one)
THEN
519 CALL dscal( k2-k1, scal, c( k1, jj ), 1)
523 scal = ( scamin / swork( i, l ) ) * scaloc
524 IF (scal .NE. one)
THEN
526 CALL dscal( i2-i1, scal, c( i1, ll ), 1)
532 swork( k, l ) = scamin * scaloc
533 swork( i, l ) = scamin * scaloc
535 CALL dgemm(
'N',
'N', i2-i1, l2-l1, k2-k1, -one,
536 $ a( i1, k1 ), lda, c( k1, l1 ), ldc,
537 $ one, c( i1, l1 ), ldc )
546 j2 = iwork( pc + j + 1 )
551 cnrm = dlange(
'I', k2-k1, j2-j1, c( k1, j1 ),
553 scamin = min( swork( k, j ), swork( k, l ) )
554 cnrm = cnrm * ( scamin / swork( k, j ) )
555 xnrm = xnrm * ( scamin / swork( k, l ) )
556 bnrm = swork(l, bwrk + j)
557 scaloc = dlarmm( bnrm, xnrm, cnrm )
558 IF( scaloc * scamin .EQ. zero )
THEN
560 buf = buf*2.d0**exponent( scaloc )
563 swork( ll, jj ) = min( bignum,
564 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
567 scamin = scamin / 2.d0**exponent( scaloc )
568 scaloc = scaloc / 2.d0**exponent( scaloc )
576 scal = ( scamin / swork( k, l ) ) * scaloc
577 IF( scal .NE. one )
THEN
579 CALL dscal( k2-k1, scal, c( k1, ll ), 1 )
583 scal = ( scamin / swork( k, j ) ) * scaloc
584 IF( scal .NE. one )
THEN
586 CALL dscal( k2-k1, scal, c( k1, jj ), 1 )
592 swork( k, l ) = scamin * scaloc
593 swork( k, j ) = scamin * scaloc
595 CALL dgemm(
'N',
'N', k2-k1, j2-j1, l2-l1, -sgn,
596 $ c( k1, l1 ), ldc, b( l1, j1 ), ldb,
597 $ one, c( k1, j1 ), ldc )
601 ELSE IF( .NOT.notrna .AND. notrnb )
THEN
632 l2 = iwork( pc + l + 1 )
634 CALL dtrsyl( trana, tranb, isgn, k2-k1, l2-l1,
637 $ c( k1, l1 ), ldc, scaloc, iinfo )
638 info = max( info, iinfo )
640 IF( scaloc * swork( k, l ) .EQ. zero )
THEN
641 IF( scaloc .EQ. zero )
THEN
649 buf = buf*2.d0**exponent( scaloc )
656 swork( ll, jj ) = min( bignum,
657 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
661 swork( k, l ) = scaloc * swork( k, l )
662 xnrm = dlange(
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
675 cnrm = dlange(
'I', i2-i1, l2-l1, c( i1, l1 ),
677 scamin = min( swork( i, l ), swork( k, l ) )
678 cnrm = cnrm * ( scamin / swork( i, l ) )
679 xnrm = xnrm * ( scamin / swork( k, l ) )
680 anrm = swork( i, awrk + k )
681 scaloc = dlarmm( anrm, xnrm, cnrm )
682 IF( scaloc * scamin .EQ. zero )
THEN
684 buf = buf*2.d0**exponent( scaloc )
687 swork( ll, jj ) = min( bignum,
688 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
691 scamin = scamin / 2.d0**exponent( scaloc )
692 scaloc = scaloc / 2.d0**exponent( scaloc )
700 scal = ( scamin / swork( k, l ) ) * scaloc
701 IF (scal .NE. one)
THEN
703 CALL dscal( k2-k1, scal, c( k1, ll ), 1 )
707 scal = ( scamin / swork( i, l ) ) * scaloc
708 IF (scal .NE. one)
THEN
710 CALL dscal( i2-i1, scal, c( i1, ll ), 1 )
716 swork( k, l ) = scamin * scaloc
717 swork( i, l ) = scamin * scaloc
719 CALL dgemm(
'T',
'N', i2-i1, l2-l1, k2-k1, -one,
720 $ a( k1, i1 ), lda, c( k1, l1 ), ldc,
721 $ one, c( i1, l1 ), ldc )
729 j2 = iwork( pc + j + 1 )
734 cnrm = dlange(
'I', k2-k1, j2-j1, c( k1, j1 ),
736 scamin = min( swork( k, j ), swork( k, l ) )
737 cnrm = cnrm * ( scamin / swork( k, j ) )
738 xnrm = xnrm * ( scamin / swork( k, l ) )
739 bnrm = swork( l, bwrk + j )
740 scaloc = dlarmm( bnrm, xnrm, cnrm )
741 IF( scaloc * scamin .EQ. zero )
THEN
743 buf = buf*2.d0**exponent( scaloc )
746 swork( ll, jj ) = min( bignum,
747 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
750 scamin = scamin / 2.d0**exponent( scaloc )
751 scaloc = scaloc / 2.d0**exponent( scaloc )
759 scal = ( scamin / swork( k, l ) ) * scaloc
760 IF( scal .NE. one )
THEN
762 CALL dscal( k2-k1, scal, c( k1, ll ), 1 )
766 scal = ( scamin / swork( k, j ) ) * scaloc
767 IF( scal .NE. one )
THEN
769 CALL dscal( k2-k1, scal, c( k1, jj ), 1 )
775 swork( k, l ) = scamin * scaloc
776 swork( k, j ) = scamin * scaloc
778 CALL dgemm(
'N',
'N', k2-k1, j2-j1, l2-l1, -sgn,
779 $ c( k1, l1 ), ldc, b( l1, j1 ), ldb,
780 $ one, c( k1, j1 ), ldc )
784 ELSE IF( .NOT.notrna .AND. .NOT.notrnb )
THEN
815 l2 = iwork( pc + l + 1 )
817 CALL dtrsyl( trana, tranb, isgn, k2-k1, l2-l1,
820 $ c( k1, l1 ), ldc, scaloc, iinfo )
821 info = max( info, iinfo )
823 swork( k, l ) = scaloc * swork( k, l )
824 IF( scaloc * swork( k, l ) .EQ. zero )
THEN
825 IF( scaloc .EQ. zero )
THEN
833 buf = buf*2.d0**exponent( scaloc )
840 swork( ll, jj ) = min( bignum,
841 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
845 xnrm = dlange(
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
858 cnrm = dlange(
'I', i2-i1, l2-l1, c( i1, l1 ),
860 scamin = min( swork( i, l ), swork( k, l ) )
861 cnrm = cnrm * ( scamin / swork( i, l ) )
862 xnrm = xnrm * ( scamin / swork( k, l ) )
863 anrm = swork( i, awrk + k )
864 scaloc = dlarmm( anrm, xnrm, cnrm )
865 IF( scaloc * scamin .EQ. zero )
THEN
867 buf = buf*2.d0**exponent( scaloc )
870 swork( ll, jj ) = min( bignum,
871 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
874 scamin = scamin / 2.d0**exponent( scaloc )
875 scaloc = scaloc / 2.d0**exponent( scaloc )
883 scal = ( scamin / swork( k, l ) ) * scaloc
884 IF (scal .NE. one)
THEN
886 CALL dscal( k2-k1, scal, c( k1, ll ), 1 )
890 scal = ( scamin / swork( i, l ) ) * scaloc
891 IF (scal .NE. one)
THEN
893 CALL dscal( i2-i1, scal, c( i1, ll ), 1 )
899 swork( k, l ) = scamin * scaloc
900 swork( i, l ) = scamin * scaloc
902 CALL dgemm(
'T',
'N', i2-i1, l2-l1, k2-k1, -one,
903 $ a( k1, i1 ), lda, c( k1, l1 ), ldc,
904 $ one, c( i1, l1 ), ldc )
912 j2 = iwork( pc + j + 1 )
917 cnrm = dlange(
'I', k2-k1, j2-j1, c( k1, j1 ),
919 scamin = min( swork( k, j ), swork( k, l ) )
920 cnrm = cnrm * ( scamin / swork( k, j ) )
921 xnrm = xnrm * ( scamin / swork( k, l ) )
922 bnrm = swork( l, bwrk + j )
923 scaloc = dlarmm( bnrm, xnrm, cnrm )
924 IF( scaloc * scamin .EQ. zero )
THEN
926 buf = buf*2.d0**exponent( scaloc )
929 swork( ll, jj ) = min( bignum,
930 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
933 scamin = scamin / 2.d0**exponent( scaloc )
934 scaloc = scaloc / 2.d0**exponent( scaloc )
942 scal = ( scamin / swork( k, l ) ) * scaloc
943 IF( scal .NE. one )
THEN
945 CALL dscal( k2-k1, scal, c( k1, ll ), 1)
949 scal = ( scamin / swork( k, j ) ) * scaloc
950 IF( scal .NE. one )
THEN
952 CALL dscal( k2-k1, scal, c( k1, jj ), 1 )
958 swork( k, l ) = scamin * scaloc
959 swork( k, j ) = scamin * scaloc
961 CALL dgemm(
'N',
'T', k2-k1, j2-j1, l2-l1, -sgn,
962 $ c( k1, l1 ), ldc, b( j1, l1 ), ldb,
963 $ one, c( k1, j1 ), ldc )
967 ELSE IF( notrna .AND. .NOT.notrnb )
THEN
998 l2 = iwork( pc + l + 1 )
1000 CALL dtrsyl( trana, tranb, isgn, k2-k1, l2-l1,
1003 $ c( k1, l1 ), ldc, scaloc, iinfo )
1004 info = max( info, iinfo )
1006 IF( scaloc * swork( k, l ) .EQ. zero )
THEN
1007 IF( scaloc .EQ. zero )
THEN
1015 buf = buf*2.d0**exponent( scaloc )
1022 swork( ll, jj ) = min( bignum,
1023 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
1027 swork( k, l ) = scaloc * swork( k, l )
1028 xnrm = dlange(
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
1041 cnrm = dlange(
'I', i2-i1, l2-l1, c( i1, l1 ),
1043 scamin = min( swork( i, l ), swork( k, l ) )
1044 cnrm = cnrm * ( scamin / swork( i, l ) )
1045 xnrm = xnrm * ( scamin / swork( k, l ) )
1046 anrm = swork( i, awrk + k )
1047 scaloc = dlarmm( anrm, xnrm, cnrm )
1048 IF( scaloc * scamin .EQ. zero )
THEN
1050 buf = buf*2.d0**exponent( scaloc )
1053 swork( ll, jj ) = min( bignum,
1054 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
1057 scamin = scamin / 2.d0**exponent( scaloc )
1058 scaloc = scaloc / 2.d0**exponent( scaloc )
1060 cnrm = cnrm * scaloc
1061 xnrm = xnrm * scaloc
1066 scal = ( scamin / swork( k, l ) ) * scaloc
1067 IF (scal .NE. one)
THEN
1069 CALL dscal( k2-k1, scal, c( k1, ll ), 1 )
1073 scal = ( scamin / swork( i, l ) ) * scaloc
1074 IF (scal .NE. one)
THEN
1076 CALL dscal( i2-i1, scal, c( i1, ll ), 1 )
1082 swork( k, l ) = scamin * scaloc
1083 swork( i, l ) = scamin * scaloc
1085 CALL dgemm(
'N',
'N', i2-i1, l2-l1, k2-k1, -one,
1086 $ a( i1, k1 ), lda, c( k1, l1 ), ldc,
1087 $ one, c( i1, l1 ), ldc )
1095 j1 = iwork( pc + j )
1096 j2 = iwork( pc + j + 1 )
1101 cnrm = dlange(
'I', k2-k1, j2-j1, c( k1, j1 ),
1103 scamin = min( swork( k, j ), swork( k, l ) )
1104 cnrm = cnrm * ( scamin / swork( k, j ) )
1105 xnrm = xnrm * ( scamin / swork( k, l ) )
1106 bnrm = swork( l, bwrk + j )
1107 scaloc = dlarmm( bnrm, xnrm, cnrm )
1108 IF( scaloc * scamin .EQ. zero )
THEN
1110 buf = buf*2.d0**exponent( scaloc )
1113 swork( ll, jj ) = min( bignum,
1114 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
1117 scamin = scamin / 2.d0**exponent( scaloc )
1118 scaloc = scaloc / 2.d0**exponent( scaloc )
1120 cnrm = cnrm * scaloc
1121 xnrm = xnrm * scaloc
1126 scal = ( scamin / swork( k, l ) ) * scaloc
1127 IF( scal .NE. one )
THEN
1129 CALL dscal( k2-k1, scal, c( k1, jj ), 1 )
1133 scal = ( scamin / swork( k, j ) ) * scaloc
1134 IF( scal .NE. one )
THEN
1136 CALL dscal( k2-k1, scal, c( k1, jj ), 1 )
1142 swork( k, l ) = scamin * scaloc
1143 swork( k, j ) = scamin * scaloc
1145 CALL dgemm(
'N',
'T', k2-k1, j2-j1, l2-l1, -sgn,
1146 $ c( k1, l1 ), ldc, b( j1, l1 ), ldb,
1147 $ one, c( k1, j1 ), ldc )
1156 scale = swork( 1, 1 )
1159 scale = min( scale, swork( k, l ) )
1163 IF( scale .EQ. zero )
THEN
1170 iwork(1) = nba + nbb + 2
1171 swork(1,1) = max( nba, nbb )
1172 swork(2,1) = 2 * nbb + nba
1182 l1 = iwork( pc + l )
1183 l2 = iwork( pc + l + 1 )
1184 scal = scale / swork( k, l )
1185 IF( scal .NE. one )
THEN
1187 CALL dscal( k2-k1, scal, c( k1, ll ), 1 )
1193 IF( buf .NE. one .AND. buf.GT.zero )
THEN
1197 scaloc = min( scale / smlnum, one / buf )
1199 scale = scale / scaloc
1202 IF( buf.NE.one .AND. buf.GT.zero )
THEN
1215 scal = max( scal, abs( c( k, l ) ) )
1221 scaloc = min( bignum / scal, one / buf )
1223 CALL dlascl(
'G', -1, -1, one, scaloc, m, n, c, ldc, iwork(1) )
1233 iwork(1) = nba + nbb + 2
1234 swork(1,1) = max( nba, nbb )
1235 swork(2,1) = 2 * nbb + nba
subroutine xerbla(srname, info)
subroutine dtrsyl3(trana, tranb, isgn, m, n, a, lda, b, ldb, c, ldc, scale, iwork, liwork, swork, ldswork, info)
DTRSYL3
subroutine dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
subroutine dlascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
DLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine dscal(n, da, dx, incx)
DSCAL
subroutine dtrsyl(trana, tranb, isgn, m, n, a, lda, b, ldb, c, ldc, scale, info)
DTRSYL