178 SUBROUTINE strsyl3( 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,
191 REAL a( lda, * ), b( ldb, * ), c( ldc, * ),
192 $ swork( ldswork, * )
196 parameter( zero = 0.0e+0, one = 1.0e+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 REAL anrm, bignum, bnrm, cnrm, scal, scaloc,
203 $ scamin, sgn, xnrm, buf, smlnum
206 REAL wnrm( max( m, n ) )
218 INTRINSIC abs, exponent, max, min, real
224 notrna =
lsame( trana,
'N' )
225 notrnb =
lsame( tranb,
'N' )
229 nb = max(8,
ilaenv( 1,
'STRSYL',
'', 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 267 ELSE IF( .NOT.lquery .AND. liwork.LT.iwork(1) )
THEN 269 ELSE IF( .NOT.lquery .AND. ldswork.LT.max( nba, nbb ) )
THEN 273 CALL xerbla(
'STRSYL3', -info )
275 ELSE IF( lquery )
THEN 282 IF( m.EQ.0 .OR. n.EQ.0 )
288 IF( min( nba, nbb ).EQ.1 .OR. ldswork.LT.max( nba, nbb ) .OR.
289 $ liwork.LT.iwork(1) )
THEN 290 CALL strsyl( trana, tranb, isgn, m, n, a, lda, b, ldb,
291 $ c, ldc, scale, info )
298 bignum = one / smlnum
304 iwork( i ) = ( i - 1 ) * nb + 1
306 iwork( nba + 1 ) = m + 1
309 l2 = iwork( k + 1 ) - 1
319 IF( a( l, l+1 ).NE.zero .AND. a( l+1, l ).NE.zero )
THEN 321 IF( l + 1 .EQ. iwork( k + 1 ) )
THEN 322 iwork( k + 1 ) = iwork( k + 1 ) + 1
329 iwork( nba + 1 ) = m + 1
330 IF( iwork( nba ).GE.iwork( nba + 1 ) )
THEN 331 iwork( nba ) = iwork( nba + 1 )
340 iwork( pc + i ) = ( i - 1 ) * nb + 1
342 iwork( pc + nbb + 1 ) = n + 1
345 l2 = iwork( pc + k + 1 ) - 1
355 IF( b( l, l+1 ).NE.zero .AND. b( l+1, l ).NE.zero )
THEN 357 IF( l + 1 .EQ. iwork( pc + k + 1 ) )
THEN 358 iwork( pc + k + 1 ) = iwork( pc + k + 1 ) + 1
365 iwork( pc + nbb + 1 ) = n + 1
366 IF( iwork( pc + nbb ).GE.iwork( pc + nbb + 1 ) )
THEN 367 iwork( pc + nbb ) = iwork( pc + nbb + 1 )
394 swork( k, awrk + l ) =
slange(
'I', k2-k1, l2-l1,
395 $ a( k1, l1 ), lda, wnrm )
397 swork( l, awrk + k ) =
slange(
'1', k2-k1, l2-l1,
398 $ a( k1, l1 ), lda, wnrm )
405 k2 = iwork( pc + k + 1 )
408 l2 = iwork( pc + l + 1 )
410 swork( k, bwrk + l ) =
slange(
'I', k2-k1, l2-l1,
411 $ b( k1, l1 ), ldb, wnrm )
413 swork( l, bwrk + k ) =
slange(
'1', k2-k1, l2-l1,
414 $ b( k1, l1 ), ldb, wnrm )
421 IF( notrna .AND. notrnb )
THEN 452 l2 = iwork( pc + l + 1 )
454 CALL strsyl( trana, tranb, isgn, k2-k1, l2-l1,
457 $ c( k1, l1 ), ldc, scaloc, iinfo )
458 info = max( info, iinfo )
460 IF ( scaloc * swork( k, l ) .EQ. zero )
THEN 461 IF( scaloc .EQ. zero )
THEN 469 buf = buf*2.e0**exponent( scaloc )
476 swork( ll, jj ) = min( bignum,
477 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
481 swork( k, l ) = scaloc * swork( k, l )
482 xnrm =
slange(
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
495 cnrm =
slange(
'I', i2-i1, l2-l1, c( i1, l1 ),
497 scamin = min( swork( i, l ), swork( k, l ) )
498 cnrm = cnrm * ( scamin / swork( i, l ) )
499 xnrm = xnrm * ( scamin / swork( k, l ) )
500 anrm = swork( i, awrk + k )
501 scaloc =
slarmm( anrm, xnrm, cnrm )
502 IF( scaloc * scamin .EQ. zero )
THEN 504 buf = buf*2.e0**exponent( scaloc )
507 swork( ll, jj ) = min( bignum,
508 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
511 scamin = scamin / 2.e0**exponent( scaloc )
512 scaloc = scaloc / 2.e0**exponent( scaloc )
520 scal = ( scamin / swork( k, l ) ) * scaloc
521 IF (scal .NE. one)
THEN 523 CALL sscal( k2-k1, scal, c( k1, jj ), 1)
527 scal = ( scamin / swork( i, l ) ) * scaloc
528 IF (scal .NE. one)
THEN 530 CALL sscal( i2-i1, scal, c( i1, ll ), 1)
536 swork( k, l ) = scamin * scaloc
537 swork( i, l ) = scamin * scaloc
539 CALL sgemm(
'N',
'N', i2-i1, l2-l1, k2-k1, -one,
540 $ a( i1, k1 ), lda, c( k1, l1 ), ldc,
541 $ one, c( i1, l1 ), ldc )
550 j2 = iwork( pc + j + 1 )
555 cnrm =
slange(
'I', k2-k1, j2-j1, c( k1, j1 ),
557 scamin = min( swork( k, j ), swork( k, l ) )
558 cnrm = cnrm * ( scamin / swork( k, j ) )
559 xnrm = xnrm * ( scamin / swork( k, l ) )
560 bnrm = swork(l, bwrk + j)
561 scaloc =
slarmm( bnrm, xnrm, cnrm )
562 IF( scaloc * scamin .EQ. zero )
THEN 564 buf = buf*2.e0**exponent( scaloc )
567 swork( ll, jj ) = min( bignum,
568 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
571 scamin = scamin / 2.e0**exponent( scaloc )
572 scaloc = scaloc / 2.e0**exponent( scaloc )
580 scal = ( scamin / swork( k, l ) ) * scaloc
581 IF( scal .NE. one )
THEN 583 CALL sscal( k2-k1, scal, c( k1, ll ), 1 )
587 scal = ( scamin / swork( k, j ) ) * scaloc
588 IF( scal .NE. one )
THEN 590 CALL sscal( k2-k1, scal, c( k1, jj ), 1 )
596 swork( k, l ) = scamin * scaloc
597 swork( k, j ) = scamin * scaloc
599 CALL sgemm(
'N',
'N', k2-k1, j2-j1, l2-l1, -sgn,
600 $ c( k1, l1 ), ldc, b( l1, j1 ), ldb,
601 $ one, c( k1, j1 ), ldc )
605 ELSE IF( .NOT.notrna .AND. notrnb )
THEN 636 l2 = iwork( pc + l + 1 )
638 CALL strsyl( trana, tranb, isgn, k2-k1, l2-l1,
641 $ c( k1, l1 ), ldc, scaloc, iinfo )
642 info = max( info, iinfo )
644 IF( scaloc * swork( k, l ) .EQ. zero )
THEN 645 IF( scaloc .EQ. zero )
THEN 653 buf = buf*2.e0**exponent( scaloc )
660 swork( ll, jj ) = min( bignum,
661 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
665 swork( k, l ) = scaloc * swork( k, l )
666 xnrm =
slange(
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
679 cnrm =
slange(
'I', i2-i1, l2-l1, c( i1, l1 ),
681 scamin = min( swork( i, l ), swork( k, l ) )
682 cnrm = cnrm * ( scamin / swork( i, l ) )
683 xnrm = xnrm * ( scamin / swork( k, l ) )
684 anrm = swork( i, awrk + k )
685 scaloc =
slarmm( anrm, xnrm, cnrm )
686 IF( scaloc * scamin .EQ. zero )
THEN 688 buf = buf*2.e0**exponent( scaloc )
691 swork( ll, jj ) = min( bignum,
692 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
695 scamin = scamin / 2.e0**exponent( scaloc )
696 scaloc = scaloc / 2.e0**exponent( scaloc )
704 scal = ( scamin / swork( k, l ) ) * scaloc
705 IF (scal .NE. one)
THEN 707 CALL sscal( k2-k1, scal, c( k1, ll ), 1 )
711 scal = ( scamin / swork( i, l ) ) * scaloc
712 IF (scal .NE. one)
THEN 714 CALL sscal( i2-i1, scal, c( i1, ll ), 1 )
720 swork( k, l ) = scamin * scaloc
721 swork( i, l ) = scamin * scaloc
723 CALL sgemm(
'T',
'N', i2-i1, l2-l1, k2-k1, -one,
724 $ a( k1, i1 ), lda, c( k1, l1 ), ldc,
725 $ one, c( i1, l1 ), ldc )
733 j2 = iwork( pc + j + 1 )
738 cnrm =
slange(
'I', k2-k1, j2-j1, c( k1, j1 ),
740 scamin = min( swork( k, j ), swork( k, l ) )
741 cnrm = cnrm * ( scamin / swork( k, j ) )
742 xnrm = xnrm * ( scamin / swork( k, l ) )
743 bnrm = swork( l, bwrk + j )
744 scaloc =
slarmm( bnrm, xnrm, cnrm )
745 IF( scaloc * scamin .EQ. zero )
THEN 747 buf = buf*2.e0**exponent( scaloc )
750 swork( ll, jj ) = min( bignum,
751 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
754 scamin = scamin / 2.e0**exponent( scaloc )
755 scaloc = scaloc / 2.e0**exponent( scaloc )
763 scal = ( scamin / swork( k, l ) ) * scaloc
764 IF( scal .NE. one )
THEN 766 CALL sscal( k2-k1, scal, c( k1, ll ), 1 )
770 scal = ( scamin / swork( k, j ) ) * scaloc
771 IF( scal .NE. one )
THEN 773 CALL sscal( k2-k1, scal, c( k1, jj ), 1 )
779 swork( k, l ) = scamin * scaloc
780 swork( k, j ) = scamin * scaloc
782 CALL sgemm(
'N',
'N', k2-k1, j2-j1, l2-l1, -sgn,
783 $ c( k1, l1 ), ldc, b( l1, j1 ), ldb,
784 $ one, c( k1, j1 ), ldc )
788 ELSE IF( .NOT.notrna .AND. .NOT.notrnb )
THEN 819 l2 = iwork( pc + l + 1 )
821 CALL strsyl( trana, tranb, isgn, k2-k1, l2-l1,
824 $ c( k1, l1 ), ldc, scaloc, iinfo )
825 info = max( info, iinfo )
827 IF( scaloc * swork( k, l ) .EQ. zero )
THEN 828 IF( scaloc .EQ. zero )
THEN 836 buf = buf*2.e0**exponent( scaloc )
843 swork( ll, jj ) = min( bignum,
844 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
848 swork( k, l ) = scaloc * swork( k, l )
849 xnrm =
slange(
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
862 cnrm =
slange(
'I', i2-i1, l2-l1, c( i1, l1 ),
864 scamin = min( swork( i, l ), swork( k, l ) )
865 cnrm = cnrm * ( scamin / swork( i, l ) )
866 xnrm = xnrm * ( scamin / swork( k, l ) )
867 anrm = swork( i, awrk + k )
868 scaloc =
slarmm( anrm, xnrm, cnrm )
869 IF( scaloc * scamin .EQ. zero )
THEN 871 buf = buf*2.e0**exponent( scaloc )
874 swork( ll, jj ) = min( bignum,
875 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
878 scamin = scamin / 2.e0**exponent( scaloc )
879 scaloc = scaloc / 2.e0**exponent( scaloc )
887 scal = ( scamin / swork( k, l ) ) * scaloc
888 IF (scal .NE. one)
THEN 890 CALL sscal( k2-k1, scal, c( k1, ll ), 1 )
894 scal = ( scamin / swork( i, l ) ) * scaloc
895 IF (scal .NE. one)
THEN 897 CALL sscal( i2-i1, scal, c( i1, ll ), 1 )
903 swork( k, l ) = scamin * scaloc
904 swork( i, l ) = scamin * scaloc
906 CALL sgemm(
'T',
'N', i2-i1, l2-l1, k2-k1, -one,
907 $ a( k1, i1 ), lda, c( k1, l1 ), ldc,
908 $ one, c( i1, l1 ), ldc )
916 j2 = iwork( pc + j + 1 )
921 cnrm =
slange(
'I', k2-k1, j2-j1, c( k1, j1 ),
923 scamin = min( swork( k, j ), swork( k, l ) )
924 cnrm = cnrm * ( scamin / swork( k, j ) )
925 xnrm = xnrm * ( scamin / swork( k, l ) )
926 bnrm = swork( l, bwrk + j )
927 scaloc =
slarmm( bnrm, xnrm, cnrm )
928 IF( scaloc * scamin .EQ. zero )
THEN 930 buf = buf*2.e0**exponent( scaloc )
933 swork( ll, jj ) = min( bignum,
934 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
937 scamin = scamin / 2.e0**exponent( scaloc )
938 scaloc = scaloc / 2.e0**exponent( scaloc )
946 scal = ( scamin / swork( k, l ) ) * scaloc
947 IF( scal .NE. one )
THEN 949 CALL sscal( k2-k1, scal, c( k1, ll ), 1)
953 scal = ( scamin / swork( k, j ) ) * scaloc
954 IF( scal .NE. one )
THEN 956 CALL sscal( k2-k1, scal, c( k1, jj ), 1 )
962 swork( k, l ) = scamin * scaloc
963 swork( k, j ) = scamin * scaloc
965 CALL sgemm(
'N',
'T', k2-k1, j2-j1, l2-l1, -sgn,
966 $ c( k1, l1 ), ldc, b( j1, l1 ), ldb,
967 $ one, c( k1, j1 ), ldc )
971 ELSE IF( notrna .AND. .NOT.notrnb )
THEN 1001 l1 = iwork( pc + l )
1002 l2 = iwork( pc + l + 1 )
1004 CALL strsyl( trana, tranb, isgn, k2-k1, l2-l1,
1007 $ c( k1, l1 ), ldc, scaloc, iinfo )
1008 info = max( info, iinfo )
1010 IF( scaloc * swork( k, l ) .EQ. zero )
THEN 1011 IF( scaloc .EQ. zero )
THEN 1019 buf = buf*2.e0**exponent( scaloc )
1026 swork( ll, jj ) = min( bignum,
1027 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
1031 swork( k, l ) = scaloc * swork( k, l )
1032 xnrm =
slange(
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
1045 cnrm =
slange(
'I', i2-i1, l2-l1, c( i1, l1 ),
1047 scamin = min( swork( i, l ), swork( k, l ) )
1048 cnrm = cnrm * ( scamin / swork( i, l ) )
1049 xnrm = xnrm * ( scamin / swork( k, l ) )
1050 anrm = swork( i, awrk + k )
1051 scaloc =
slarmm( anrm, xnrm, cnrm )
1052 IF( scaloc * scamin .EQ. zero )
THEN 1054 buf = buf*2.e0**exponent( scaloc )
1057 swork( ll, jj ) = min( bignum,
1058 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
1061 scamin = scamin / 2.e0**exponent( scaloc )
1062 scaloc = scaloc / 2.e0**exponent( scaloc )
1064 cnrm = cnrm * scaloc
1065 xnrm = xnrm * scaloc
1070 scal = ( scamin / swork( k, l ) ) * scaloc
1071 IF (scal .NE. one)
THEN 1073 CALL sscal( k2-k1, scal, c( k1, ll ), 1 )
1077 scal = ( scamin / swork( i, l ) ) * scaloc
1078 IF (scal .NE. one)
THEN 1080 CALL sscal( i2-i1, scal, c( i1, ll ), 1 )
1086 swork( k, l ) = scamin * scaloc
1087 swork( i, l ) = scamin * scaloc
1089 CALL sgemm(
'N',
'N', i2-i1, l2-l1, k2-k1, -one,
1090 $ a( i1, k1 ), lda, c( k1, l1 ), ldc,
1091 $ one, c( i1, l1 ), ldc )
1099 j1 = iwork( pc + j )
1100 j2 = iwork( pc + j + 1 )
1105 cnrm =
slange(
'I', k2-k1, j2-j1, c( k1, j1 ),
1107 scamin = min( swork( k, j ), swork( k, l ) )
1108 cnrm = cnrm * ( scamin / swork( k, j ) )
1109 xnrm = xnrm * ( scamin / swork( k, l ) )
1110 bnrm = swork( l, bwrk + j )
1111 scaloc =
slarmm( bnrm, xnrm, cnrm )
1112 IF( scaloc * scamin .EQ. zero )
THEN 1114 buf = buf*2.e0**exponent( scaloc )
1117 swork( ll, jj ) = min( bignum,
1118 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
1121 scamin = scamin / 2.e0**exponent( scaloc )
1122 scaloc = scaloc / 2.e0**exponent( scaloc )
1124 cnrm = cnrm * scaloc
1125 xnrm = xnrm * scaloc
1130 scal = ( scamin / swork( k, l ) ) * scaloc
1131 IF( scal .NE. one )
THEN 1133 CALL sscal( k2-k1, scal, c( k1, jj ), 1 )
1137 scal = ( scamin / swork( k, j ) ) * scaloc
1138 IF( scal .NE. one )
THEN 1140 CALL sscal( k2-k1, scal, c( k1, jj ), 1 )
1146 swork( k, l ) = scamin * scaloc
1147 swork( k, j ) = scamin * scaloc
1149 CALL sgemm(
'N',
'T', k2-k1, j2-j1, l2-l1, -sgn,
1150 $ c( k1, l1 ), ldc, b( j1, l1 ), ldb,
1151 $ one, c( k1, j1 ), ldc )
1160 scale = swork( 1, 1 )
1163 scale = min( scale, swork( k, l ) )
1167 IF( scale .EQ. zero )
THEN 1173 iwork(1) = nba + nbb + 2
1174 swork(1,1) = max( nba, nbb )
1175 swork(2,1) = 2 * nbb + nba
1185 l1 = iwork( pc + l )
1186 l2 = iwork( pc + l + 1 )
1187 scal = scale / swork( k, l )
1188 IF( scal .NE. one )
THEN 1190 CALL sscal( k2-k1, scal, c( k1, ll ), 1 )
1196 IF( buf .NE. one .AND. buf.GT.zero )
THEN 1200 scaloc = min( scale / smlnum, one / buf )
1202 scale = scale / scaloc
1205 IF( buf.NE.one .AND. buf.GT.zero )
THEN 1218 scal = max( scal, abs( c( k, l ) ) )
1224 scaloc = min( bignum / scal, one / buf )
1226 CALL slascl(
'G', -1, -1, one, scaloc, m, n, c, ldc, iwork )
1236 iwork(1) = nba + nbb + 2
1237 swork(1,1) = max( nba, nbb )
1238 swork(2,1) = 2 * nbb + nba
integer function ilaenv(ISPEC, NAME, OPTS, N1, N2, N3, N4)
ILAENV
logical function lsame(CA, CB)
LSAME
real function slarmm(ANORM, BNORM, CNORM)
SLARMM
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine sgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
SGEMM
subroutine slascl(TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO)
SLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
real function slange(NORM, M, N, A, LDA, WORK)
SLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
subroutine strsyl(TRANA, TRANB, ISGN, M, N, A, LDA, B, LDB, C, LDC, SCALE, INFO)
STRSYL
subroutine sscal(N, SA, SX, INCX)
SSCAL
real function slamch(CMACH)
SLAMCH