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 ) )
211 REAL SLANGE, SLAMCH, SLARMM
212 EXTERNAL slange, slamch, slarmm, ilaenv, lsame
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 )
297 smlnum = slamch(
'S' )
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(1) )
1236 iwork(1) = nba + nbb + 2
1237 swork(1,1) = max( nba, nbb )
1238 swork(2,1) = 2 * nbb + nba
subroutine xerbla(srname, info)
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.
subroutine sscal(n, sa, sx, incx)
SSCAL
subroutine strsyl(trana, tranb, isgn, m, n, a, lda, b, ldb, c, ldc, scale, info)
STRSYL
subroutine strsyl3(trana, tranb, isgn, m, n, a, lda, b, ldb, c, ldc, scale, iwork, liwork, swork, ldswork, info)
STRSYL3