197 SUBROUTINE dtrsyl3( TRANA, TRANB, ISGN, M, N, A, LDA, B, LDB,
198 $ C, LDC, SCALE, IWORK, LIWORK, SWORK,
203 CHARACTER TRANA, TRANB
204 INTEGER INFO, ISGN, LDA, LDB, LDC, M, N,
206 DOUBLE PRECISION SCALE
210 DOUBLE PRECISION A( LDA, * ), B( LDB, * ), C( LDC, * ),
211 $ swork( ldswork, * )
214 DOUBLE PRECISION ZERO, ONE
215 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0 )
218 LOGICAL NOTRNA, NOTRNB, LQUERY, SKIP
219 INTEGER AWRK, BWRK, I, I1, I2, IINFO, J, J1, J2, JJ,
220 $ k, k1, k2, l, l1, l2, ll, nba, nb, nbb, pc
221 DOUBLE PRECISION ANRM, BIGNUM, BNRM, CNRM, SCAL, SCALOC,
222 $ SCAMIN, SGN, XNRM, BUF, SMLNUM
225 DOUBLE PRECISION WNRM( MAX( M, N ) )
230 DOUBLE PRECISION DLANGE, DLAMCH, DLARMM
231 EXTERNAL dlange, dlamch, dlarmm, ilaenv,
239 INTRINSIC abs, dble, exponent, max, min
245 notrna = lsame( trana,
'N' )
246 notrnb = lsame( tranb,
'N' )
250 nb = max(8, ilaenv( 1,
'DTRSYL',
'', m, n, -1, -1) )
254 nba = max( 1, (m + nb - 1) / nb )
255 nbb = max( 1, (n + nb - 1) / nb )
260 lquery = ( liwork.EQ.-1 .OR. ldswork.EQ.-1 )
261 iwork( 1 ) = nba + nbb + 2
264 swork( 1, 1 ) = max( nba, nbb )
265 swork( 2, 1 ) = 2 * nbb + nba
270 IF( .NOT.notrna .AND. .NOT.lsame( trana,
'T' ) .AND. .NOT.
271 $ lsame( trana,
'C' ) )
THEN
273 ELSE IF( .NOT.notrnb .AND. .NOT.lsame( tranb,
'T' ) .AND. .NOT.
274 $ lsame( tranb,
'C' ) )
THEN
276 ELSE IF( isgn.NE.1 .AND. isgn.NE.-1 )
THEN
278 ELSE IF( m.LT.0 )
THEN
280 ELSE IF( n.LT.0 )
THEN
282 ELSE IF( lda.LT.max( 1, m ) )
THEN
284 ELSE IF( ldb.LT.max( 1, n ) )
THEN
286 ELSE IF( ldc.LT.max( 1, m ) )
THEN
290 CALL xerbla(
'DTRSYL3', -info )
292 ELSE IF( lquery )
THEN
299 IF( m.EQ.0 .OR. n.EQ.0 )
305 IF( min( nba, nbb ).EQ.1 .OR. ldswork.LT.max( nba, nbb ) .OR.
306 $ liwork.LT.iwork(1) )
THEN
307 CALL dtrsyl( trana, tranb, isgn, m, n, a, lda, b, ldb,
308 $ c, ldc, scale, info )
314 smlnum = dlamch(
'S' )
315 bignum = one / smlnum
321 iwork( i ) = ( i - 1 ) * nb + 1
323 iwork( nba + 1 ) = m + 1
326 l2 = iwork( k + 1 ) - 1
336 IF( a( l, l+1 ).NE.zero .AND. a( l+1, l ).NE.zero )
THEN
338 IF( l + 1 .EQ. iwork( k + 1 ) )
THEN
339 iwork( k + 1 ) = iwork( k + 1 ) + 1
346 iwork( nba + 1 ) = m + 1
347 IF( iwork( nba ).GE.iwork( nba + 1 ) )
THEN
348 iwork( nba ) = iwork( nba + 1 )
357 iwork( pc + i ) = ( i - 1 ) * nb + 1
359 iwork( pc + nbb + 1 ) = n + 1
362 l2 = iwork( pc + k + 1 ) - 1
372 IF( b( l, l+1 ).NE.zero .AND. b( l+1, l ).NE.zero )
THEN
374 IF( l + 1 .EQ. iwork( pc + k + 1 ) )
THEN
375 iwork( pc + k + 1 ) = iwork( pc + k + 1 ) + 1
382 iwork( pc + nbb + 1 ) = n + 1
383 IF( iwork( pc + nbb ).GE.iwork( pc + nbb + 1 ) )
THEN
384 iwork( pc + nbb ) = iwork( pc + nbb + 1 )
411 swork( k, awrk + l ) = dlange(
'I', k2-k1, l2-l1,
412 $ a( k1, l1 ), lda, wnrm )
414 swork( l, awrk + k ) = dlange(
'1', k2-k1, l2-l1,
415 $ a( k1, l1 ), lda, wnrm )
422 k2 = iwork( pc + k + 1 )
425 l2 = iwork( pc + l + 1 )
427 swork( k, bwrk + l ) = dlange(
'I', k2-k1, l2-l1,
428 $ b( k1, l1 ), ldb, wnrm )
430 swork( l, bwrk + k ) = dlange(
'1', k2-k1, l2-l1,
431 $ b( k1, l1 ), ldb, wnrm )
438 IF( notrna .AND. notrnb )
THEN
469 l2 = iwork( pc + l + 1 )
471 CALL dtrsyl( trana, tranb, isgn, k2-k1, l2-l1,
474 $ c( k1, l1 ), ldc, scaloc, iinfo )
475 info = max( info, iinfo )
477 IF ( scaloc * swork( k, l ) .EQ. zero )
THEN
478 IF( scaloc .EQ. zero )
THEN
486 buf = buf*2.d0**exponent( scaloc )
493 swork( ll, jj ) = min( bignum,
494 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
498 swork( k, l ) = scaloc * swork( k, l )
499 xnrm = dlange(
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
512 cnrm = dlange(
'I', i2-i1, l2-l1, c( i1, l1 ),
514 scamin = min( swork( i, l ), swork( k, l ) )
515 cnrm = cnrm * ( scamin / swork( i, l ) )
516 xnrm = xnrm * ( scamin / swork( k, l ) )
517 anrm = swork( i, awrk + k )
518 scaloc = dlarmm( anrm, xnrm, cnrm )
519 IF( scaloc * scamin .EQ. zero )
THEN
521 buf = buf*2.d0**exponent( scaloc )
524 swork( ll, jj ) = min( bignum,
525 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
528 scamin = scamin / 2.d0**exponent( scaloc )
529 scaloc = scaloc / 2.d0**exponent( scaloc )
537 scal = ( scamin / swork( k, l ) ) * scaloc
538 IF (scal .NE. one)
THEN
540 CALL dscal( k2-k1, scal, c( k1, jj ), 1)
544 scal = ( scamin / swork( i, l ) ) * scaloc
545 IF (scal .NE. one)
THEN
547 CALL dscal( i2-i1, scal, c( i1, ll ), 1)
553 swork( k, l ) = scamin * scaloc
554 swork( i, l ) = scamin * scaloc
556 CALL dgemm(
'N',
'N', i2-i1, l2-l1, k2-k1, -one,
557 $ a( i1, k1 ), lda, c( k1, l1 ), ldc,
558 $ one, c( i1, l1 ), ldc )
567 j2 = iwork( pc + j + 1 )
572 cnrm = dlange(
'I', k2-k1, j2-j1, c( k1, j1 ),
574 scamin = min( swork( k, j ), swork( k, l ) )
575 cnrm = cnrm * ( scamin / swork( k, j ) )
576 xnrm = xnrm * ( scamin / swork( k, l ) )
577 bnrm = swork(l, bwrk + j)
578 scaloc = dlarmm( bnrm, xnrm, cnrm )
579 IF( scaloc * scamin .EQ. zero )
THEN
581 buf = buf*2.d0**exponent( scaloc )
584 swork( ll, jj ) = min( bignum,
585 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
588 scamin = scamin / 2.d0**exponent( scaloc )
589 scaloc = scaloc / 2.d0**exponent( scaloc )
597 scal = ( scamin / swork( k, l ) ) * scaloc
598 IF( scal .NE. one )
THEN
600 CALL dscal( k2-k1, scal, c( k1, ll ), 1 )
604 scal = ( scamin / swork( k, j ) ) * scaloc
605 IF( scal .NE. one )
THEN
607 CALL dscal( k2-k1, scal, c( k1, jj ), 1 )
613 swork( k, l ) = scamin * scaloc
614 swork( k, j ) = scamin * scaloc
616 CALL dgemm(
'N',
'N', k2-k1, j2-j1, l2-l1, -sgn,
617 $ c( k1, l1 ), ldc, b( l1, j1 ), ldb,
618 $ one, c( k1, j1 ), ldc )
622 ELSE IF( .NOT.notrna .AND. notrnb )
THEN
653 l2 = iwork( pc + l + 1 )
655 CALL dtrsyl( trana, tranb, isgn, k2-k1, l2-l1,
658 $ c( k1, l1 ), ldc, scaloc, iinfo )
659 info = max( info, iinfo )
661 IF( scaloc * swork( k, l ) .EQ. zero )
THEN
662 IF( scaloc .EQ. zero )
THEN
670 buf = buf*2.d0**exponent( scaloc )
677 swork( ll, jj ) = min( bignum,
678 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
682 swork( k, l ) = scaloc * swork( k, l )
683 xnrm = dlange(
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
696 cnrm = dlange(
'I', i2-i1, l2-l1, c( i1, l1 ),
698 scamin = min( swork( i, l ), swork( k, l ) )
699 cnrm = cnrm * ( scamin / swork( i, l ) )
700 xnrm = xnrm * ( scamin / swork( k, l ) )
701 anrm = swork( i, awrk + k )
702 scaloc = dlarmm( anrm, xnrm, cnrm )
703 IF( scaloc * scamin .EQ. zero )
THEN
705 buf = buf*2.d0**exponent( scaloc )
708 swork( ll, jj ) = min( bignum,
709 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
712 scamin = scamin / 2.d0**exponent( scaloc )
713 scaloc = scaloc / 2.d0**exponent( scaloc )
721 scal = ( scamin / swork( k, l ) ) * scaloc
722 IF (scal .NE. one)
THEN
724 CALL dscal( k2-k1, scal, c( k1, ll ), 1 )
728 scal = ( scamin / swork( i, l ) ) * scaloc
729 IF (scal .NE. one)
THEN
731 CALL dscal( i2-i1, scal, c( i1, ll ), 1 )
737 swork( k, l ) = scamin * scaloc
738 swork( i, l ) = scamin * scaloc
740 CALL dgemm(
'T',
'N', i2-i1, l2-l1, k2-k1, -one,
741 $ a( k1, i1 ), lda, c( k1, l1 ), ldc,
742 $ one, c( i1, l1 ), ldc )
750 j2 = iwork( pc + j + 1 )
755 cnrm = dlange(
'I', k2-k1, j2-j1, c( k1, j1 ),
757 scamin = min( swork( k, j ), swork( k, l ) )
758 cnrm = cnrm * ( scamin / swork( k, j ) )
759 xnrm = xnrm * ( scamin / swork( k, l ) )
760 bnrm = swork( l, bwrk + j )
761 scaloc = dlarmm( bnrm, xnrm, cnrm )
762 IF( scaloc * scamin .EQ. zero )
THEN
764 buf = buf*2.d0**exponent( scaloc )
767 swork( ll, jj ) = min( bignum,
768 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
771 scamin = scamin / 2.d0**exponent( scaloc )
772 scaloc = scaloc / 2.d0**exponent( scaloc )
780 scal = ( scamin / swork( k, l ) ) * scaloc
781 IF( scal .NE. one )
THEN
783 CALL dscal( k2-k1, scal, c( k1, ll ), 1 )
787 scal = ( scamin / swork( k, j ) ) * scaloc
788 IF( scal .NE. one )
THEN
790 CALL dscal( k2-k1, scal, c( k1, jj ), 1 )
796 swork( k, l ) = scamin * scaloc
797 swork( k, j ) = scamin * scaloc
799 CALL dgemm(
'N',
'N', k2-k1, j2-j1, l2-l1, -sgn,
800 $ c( k1, l1 ), ldc, b( l1, j1 ), ldb,
801 $ one, c( k1, j1 ), ldc )
805 ELSE IF( .NOT.notrna .AND. .NOT.notrnb )
THEN
836 l2 = iwork( pc + l + 1 )
838 CALL dtrsyl( trana, tranb, isgn, k2-k1, l2-l1,
841 $ c( k1, l1 ), ldc, scaloc, iinfo )
842 info = max( info, iinfo )
844 swork( k, l ) = scaloc * swork( k, l )
845 IF( scaloc * swork( k, l ) .EQ. zero )
THEN
846 IF( scaloc .EQ. zero )
THEN
854 buf = buf*2.d0**exponent( scaloc )
861 swork( ll, jj ) = min( bignum,
862 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
866 xnrm = dlange(
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
879 cnrm = dlange(
'I', i2-i1, l2-l1, c( i1, l1 ),
881 scamin = min( swork( i, l ), swork( k, l ) )
882 cnrm = cnrm * ( scamin / swork( i, l ) )
883 xnrm = xnrm * ( scamin / swork( k, l ) )
884 anrm = swork( i, awrk + k )
885 scaloc = dlarmm( anrm, xnrm, cnrm )
886 IF( scaloc * scamin .EQ. zero )
THEN
888 buf = buf*2.d0**exponent( scaloc )
891 swork( ll, jj ) = min( bignum,
892 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
895 scamin = scamin / 2.d0**exponent( scaloc )
896 scaloc = scaloc / 2.d0**exponent( scaloc )
904 scal = ( scamin / swork( k, l ) ) * scaloc
905 IF (scal .NE. one)
THEN
907 CALL dscal( k2-k1, scal, c( k1, ll ), 1 )
911 scal = ( scamin / swork( i, l ) ) * scaloc
912 IF (scal .NE. one)
THEN
914 CALL dscal( i2-i1, scal, c( i1, ll ), 1 )
920 swork( k, l ) = scamin * scaloc
921 swork( i, l ) = scamin * scaloc
923 CALL dgemm(
'T',
'N', i2-i1, l2-l1, k2-k1, -one,
924 $ a( k1, i1 ), lda, c( k1, l1 ), ldc,
925 $ one, c( i1, l1 ), ldc )
933 j2 = iwork( pc + j + 1 )
938 cnrm = dlange(
'I', k2-k1, j2-j1, c( k1, j1 ),
940 scamin = min( swork( k, j ), swork( k, l ) )
941 cnrm = cnrm * ( scamin / swork( k, j ) )
942 xnrm = xnrm * ( scamin / swork( k, l ) )
943 bnrm = swork( l, bwrk + j )
944 scaloc = dlarmm( bnrm, xnrm, cnrm )
945 IF( scaloc * scamin .EQ. zero )
THEN
947 buf = buf*2.d0**exponent( scaloc )
950 swork( ll, jj ) = min( bignum,
951 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
954 scamin = scamin / 2.d0**exponent( scaloc )
955 scaloc = scaloc / 2.d0**exponent( scaloc )
963 scal = ( scamin / swork( k, l ) ) * scaloc
964 IF( scal .NE. one )
THEN
966 CALL dscal( k2-k1, scal, c( k1, ll ), 1)
970 scal = ( scamin / swork( k, j ) ) * scaloc
971 IF( scal .NE. one )
THEN
973 CALL dscal( k2-k1, scal, c( k1, jj ), 1 )
979 swork( k, l ) = scamin * scaloc
980 swork( k, j ) = scamin * scaloc
982 CALL dgemm(
'N',
'T', k2-k1, j2-j1, l2-l1, -sgn,
983 $ c( k1, l1 ), ldc, b( j1, l1 ), ldb,
984 $ one, c( k1, j1 ), ldc )
988 ELSE IF( notrna .AND. .NOT.notrnb )
THEN
1018 l1 = iwork( pc + l )
1019 l2 = iwork( pc + l + 1 )
1021 CALL dtrsyl( trana, tranb, isgn, k2-k1, l2-l1,
1024 $ c( k1, l1 ), ldc, scaloc, iinfo )
1025 info = max( info, iinfo )
1027 IF( scaloc * swork( k, l ) .EQ. zero )
THEN
1028 IF( scaloc .EQ. zero )
THEN
1036 buf = buf*2.d0**exponent( scaloc )
1043 swork( ll, jj ) = min( bignum,
1044 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
1048 swork( k, l ) = scaloc * swork( k, l )
1049 xnrm = dlange(
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
1062 cnrm = dlange(
'I', i2-i1, l2-l1, c( i1, l1 ),
1064 scamin = min( swork( i, l ), swork( k, l ) )
1065 cnrm = cnrm * ( scamin / swork( i, l ) )
1066 xnrm = xnrm * ( scamin / swork( k, l ) )
1067 anrm = swork( i, awrk + k )
1068 scaloc = dlarmm( anrm, xnrm, cnrm )
1069 IF( scaloc * scamin .EQ. zero )
THEN
1071 buf = buf*2.d0**exponent( scaloc )
1074 swork( ll, jj ) = min( bignum,
1075 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
1078 scamin = scamin / 2.d0**exponent( scaloc )
1079 scaloc = scaloc / 2.d0**exponent( scaloc )
1081 cnrm = cnrm * scaloc
1082 xnrm = xnrm * scaloc
1087 scal = ( scamin / swork( k, l ) ) * scaloc
1088 IF (scal .NE. one)
THEN
1090 CALL dscal( k2-k1, scal, c( k1, ll ), 1 )
1094 scal = ( scamin / swork( i, l ) ) * scaloc
1095 IF (scal .NE. one)
THEN
1097 CALL dscal( i2-i1, scal, c( i1, ll ), 1 )
1103 swork( k, l ) = scamin * scaloc
1104 swork( i, l ) = scamin * scaloc
1106 CALL dgemm(
'N',
'N', i2-i1, l2-l1, k2-k1, -one,
1107 $ a( i1, k1 ), lda, c( k1, l1 ), ldc,
1108 $ one, c( i1, l1 ), ldc )
1116 j1 = iwork( pc + j )
1117 j2 = iwork( pc + j + 1 )
1122 cnrm = dlange(
'I', k2-k1, j2-j1, c( k1, j1 ),
1124 scamin = min( swork( k, j ), swork( k, l ) )
1125 cnrm = cnrm * ( scamin / swork( k, j ) )
1126 xnrm = xnrm * ( scamin / swork( k, l ) )
1127 bnrm = swork( l, bwrk + j )
1128 scaloc = dlarmm( bnrm, xnrm, cnrm )
1129 IF( scaloc * scamin .EQ. zero )
THEN
1131 buf = buf*2.d0**exponent( scaloc )
1134 swork( ll, jj ) = min( bignum,
1135 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
1138 scamin = scamin / 2.d0**exponent( scaloc )
1139 scaloc = scaloc / 2.d0**exponent( scaloc )
1141 cnrm = cnrm * scaloc
1142 xnrm = xnrm * scaloc
1147 scal = ( scamin / swork( k, l ) ) * scaloc
1148 IF( scal .NE. one )
THEN
1150 CALL dscal( k2-k1, scal, c( k1, jj ), 1 )
1154 scal = ( scamin / swork( k, j ) ) * scaloc
1155 IF( scal .NE. one )
THEN
1157 CALL dscal( k2-k1, scal, c( k1, jj ), 1 )
1163 swork( k, l ) = scamin * scaloc
1164 swork( k, j ) = scamin * scaloc
1166 CALL dgemm(
'N',
'T', k2-k1, j2-j1, l2-l1, -sgn,
1167 $ c( k1, l1 ), ldc, b( j1, l1 ), ldb,
1168 $ one, c( k1, j1 ), ldc )
1177 scale = swork( 1, 1 )
1180 scale = min( scale, swork( k, l ) )
1184 IF( scale .EQ. zero )
THEN
1191 iwork(1) = nba + nbb + 2
1192 swork(1,1) = max( nba, nbb )
1193 swork(2,1) = 2 * nbb + nba
1203 l1 = iwork( pc + l )
1204 l2 = iwork( pc + l + 1 )
1205 scal = scale / swork( k, l )
1206 IF( scal .NE. one )
THEN
1208 CALL dscal( k2-k1, scal, c( k1, ll ), 1 )
1214 IF( buf .NE. one .AND. buf.GT.zero )
THEN
1218 scaloc = min( scale / smlnum, one / buf )
1220 scale = scale / scaloc
1223 IF( buf.NE.one .AND. buf.GT.zero )
THEN
1236 scal = max( scal, abs( c( k, l ) ) )
1242 scaloc = min( bignum / scal, one / buf )
1244 CALL dlascl(
'G', -1, -1, one, scaloc, m, n, c, ldc,
1255 iwork(1) = nba + nbb + 2
1256 swork(1,1) = max( nba, nbb )
1257 swork(2,1) = 2 * nbb + nba