154 SUBROUTINE ctrsyl3( TRANA, TRANB, ISGN, M, N, A, LDA, B, LDB, C,
155 $ LDC, SCALE, SWORK, LDSWORK, INFO )
159 CHARACTER TRANA, TRANB
160 INTEGER INFO, ISGN, LDA, LDB, LDC, LDSWORK, M, N
164 COMPLEX A( LDA, * ), B( LDB, * ), C( LDC, * )
165 REAL SWORK( LDSWORK, * )
169 parameter( zero = 0.0e+0, one = 1.0e+0 )
171 parameter( cone = ( 1.0e+0, 0.0e+0 ) )
174 LOGICAL NOTRNA, NOTRNB, LQUERY
175 INTEGER AWRK, BWRK, I, I1, I2, IINFO, J, J1, J2, JJ,
176 $ k, k1, k2, l, l1, l2, ll, nba, nb, nbb
177 REAL ANRM, BIGNUM, BNRM, CNRM, SCAL, SCALOC,
178 $ scamin, sgn, xnrm, buf, smlnum
182 REAL WNRM( MAX( M, N ) )
187 REAL CLANGE, SLAMCH, SLARMM
188 EXTERNAL clange, ilaenv, lsame, slamch, slarmm
194 INTRINSIC abs, aimag, exponent, max, min, real
200 notrna = lsame( trana,
'N' )
201 notrnb = lsame( tranb,
'N' )
205 nb = max( 8, ilaenv( 1,
'CTRSYL',
'', m, n, -1, -1) )
209 nba = max( 1, (m + nb - 1) / nb )
210 nbb = max( 1, (n + nb - 1) / nb )
215 lquery = ( ldswork.EQ.-1 )
218 swork(1,1) = max( nba, nbb )
219 swork(2,1) = 2 * nbb + nba
224 IF( .NOT.notrna .AND. .NOT. lsame( trana,
'C' ) )
THEN
226 ELSE IF( .NOT.notrnb .AND. .NOT. lsame( tranb,
'C' ) )
THEN
228 ELSE IF( isgn.NE.1 .AND. isgn.NE.-1 )
THEN
230 ELSE IF( m.LT.0 )
THEN
232 ELSE IF( n.LT.0 )
THEN
234 ELSE IF( lda.LT.max( 1, m ) )
THEN
236 ELSE IF( ldb.LT.max( 1, n ) )
THEN
238 ELSE IF( ldc.LT.max( 1, m ) )
THEN
242 CALL xerbla(
'CTRSYL3', -info )
244 ELSE IF( lquery )
THEN
251 IF( m.EQ.0 .OR. n.EQ.0 )
257 IF( min( nba, nbb ).EQ.1 .OR. ldswork.LT.max( nba, nbb ) )
THEN
258 CALL ctrsyl( trana, tranb, isgn, m, n, a, lda, b, ldb,
259 $ c, ldc, scale, info )
265 smlnum = slamch(
'S' )
266 bignum = one / smlnum
285 k1 = (k - 1) * nb + 1
286 k2 = min( k * nb, m ) + 1
288 l1 = (l - 1) * nb + 1
289 l2 = min( l * nb, m ) + 1
291 swork( k, awrk + l ) = clange(
'I', k2-k1, l2-l1,
292 $ a( k1, l1 ), lda, wnrm )
294 swork( l, awrk + k ) = clange(
'1', k2-k1, l2-l1,
295 $ a( k1, l1 ), lda, wnrm )
301 k1 = (k - 1) * nb + 1
302 k2 = min( k * nb, n ) + 1
304 l1 = (l - 1) * nb + 1
305 l2 = min( l * nb, n ) + 1
307 swork( k, bwrk + l ) = clange(
'I', k2-k1, l2-l1,
308 $ b( k1, l1 ), ldb, wnrm )
310 swork( l, bwrk + k ) = clange(
'1', k2-k1, l2-l1,
311 $ b( k1, l1 ), ldb, wnrm )
317 csgn = cmplx( sgn, zero )
319 IF( notrna .AND. notrnb )
THEN
341 k1 = (k - 1) * nb + 1
342 k2 = min( k * nb, m ) + 1
349 l1 = (l - 1) * nb + 1
350 l2 = min( l * nb, n ) + 1
352 CALL ctrsyl( trana, tranb, isgn, k2-k1, l2-l1,
355 $ c( k1, l1 ), ldc, scaloc, iinfo )
356 info = max( info, iinfo )
358 IF( scaloc * swork( k, l ) .EQ. zero )
THEN
359 IF( scaloc .EQ. zero )
THEN
367 buf = buf*2.e0**exponent( scaloc )
374 swork( ll, jj ) = min( bignum,
375 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
379 swork( k, l ) = scaloc * swork( k, l )
380 xnrm = clange(
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
387 i1 = (i - 1) * nb + 1
388 i2 = min( i * nb, m ) + 1
393 cnrm = clange(
'I', i2-i1, l2-l1, c( i1, l1 ),
395 scamin = min( swork( i, l ), swork( k, l ) )
396 cnrm = cnrm * ( scamin / swork( i, l ) )
397 xnrm = xnrm * ( scamin / swork( k, l ) )
398 anrm = swork( i, awrk + k )
399 scaloc = slarmm( anrm, xnrm, cnrm )
400 IF( scaloc * scamin .EQ. zero )
THEN
402 buf = buf*2.e0**exponent( scaloc )
405 swork( ll, jj ) = min( bignum,
406 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
409 scamin = scamin / 2.e0**exponent( scaloc )
410 scaloc = scaloc / 2.e0**exponent( scaloc )
418 scal = ( scamin / swork( k, l ) ) * scaloc
419 IF( scal.NE.one )
THEN
421 CALL csscal( k2-k1, scal, c( k1, jj ), 1)
425 scal = ( scamin / swork( i, l ) ) * scaloc
426 IF( scal.NE.one )
THEN
428 CALL csscal( i2-i1, scal, c( i1, ll ), 1)
434 swork( k, l ) = scamin * scaloc
435 swork( i, l ) = scamin * scaloc
437 CALL cgemm(
'N',
'N', i2-i1, l2-l1, k2-k1, -cone,
438 $ a( i1, k1 ), lda, c( k1, l1 ), ldc,
439 $ cone, c( i1, l1 ), ldc )
447 j1 = (j - 1) * nb + 1
448 j2 = min( j * nb, n ) + 1
453 cnrm = clange(
'I', k2-k1, j2-j1, c( k1, j1 ),
455 scamin = min( swork( k, j ), swork( k, l ) )
456 cnrm = cnrm * ( scamin / swork( k, j ) )
457 xnrm = xnrm * ( scamin / swork( k, l ) )
458 bnrm = swork(l, bwrk + j)
459 scaloc = slarmm( bnrm, xnrm, cnrm )
460 IF( scaloc * scamin .EQ. zero )
THEN
462 buf = buf*2.e0**exponent( scaloc )
465 swork( ll, jj ) = min( bignum,
466 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
469 scamin = scamin / 2.e0**exponent( scaloc )
470 scaloc = scaloc / 2.e0**exponent( scaloc )
478 scal = ( scamin / swork( k, l ) ) * scaloc
479 IF( scal .NE. one )
THEN
481 CALL csscal( k2-k1, scal, c( k1, ll ), 1 )
485 scal = ( scamin / swork( k, j ) ) * scaloc
486 IF( scal .NE. one )
THEN
488 CALL csscal( k2-k1, scal, c( k1, jj ), 1 )
494 swork( k, l ) = scamin * scaloc
495 swork( k, j ) = scamin * scaloc
497 CALL cgemm(
'N',
'N', k2-k1, j2-j1, l2-l1, -csgn,
498 $ c( k1, l1 ), ldc, b( l1, j1 ), ldb,
499 $ cone, c( k1, j1 ), ldc )
503 ELSE IF( .NOT.notrna .AND. notrnb )
THEN
525 k1 = (k - 1) * nb + 1
526 k2 = min( k * nb, m ) + 1
533 l1 = (l - 1) * nb + 1
534 l2 = min( l * nb, n ) + 1
536 CALL ctrsyl( trana, tranb, isgn, k2-k1, l2-l1,
539 $ c( k1, l1 ), ldc, scaloc, iinfo )
540 info = max( info, iinfo )
542 IF( scaloc * swork( k, l ) .EQ. zero )
THEN
543 IF( scaloc .EQ. zero )
THEN
551 buf = buf*2.e0**exponent( scaloc )
558 swork( ll, jj ) = min( bignum,
559 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
563 swork( k, l ) = scaloc * swork( k, l )
564 xnrm = clange(
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
571 i1 = (i - 1) * nb + 1
572 i2 = min( i * nb, m ) + 1
577 cnrm = clange(
'I', i2-i1, l2-l1, c( i1, l1 ),
579 scamin = min( swork( i, l ), swork( k, l ) )
580 cnrm = cnrm * ( scamin / swork( i, l ) )
581 xnrm = xnrm * ( scamin / swork( k, l ) )
582 anrm = swork( i, awrk + k )
583 scaloc = slarmm( anrm, xnrm, cnrm )
584 IF( scaloc * scamin .EQ. zero )
THEN
586 buf = buf*2.e0**exponent( scaloc )
589 swork( ll, jj ) = min( bignum,
590 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
593 scamin = scamin / 2.e0**exponent( scaloc )
594 scaloc = scaloc / 2.e0**exponent( scaloc )
602 scal = ( scamin / swork( k, l ) ) * scaloc
603 IF( scal .NE. one )
THEN
605 CALL csscal( k2-k1, scal, c( k1, ll ), 1 )
609 scal = ( scamin / swork( i, l ) ) * scaloc
610 IF( scal .NE. one )
THEN
612 CALL csscal( i2-i1, scal, c( i1, ll ), 1 )
618 swork( k, l ) = scamin * scaloc
619 swork( i, l ) = scamin * scaloc
621 CALL cgemm(
'C',
'N', i2-i1, l2-l1, k2-k1, -cone,
622 $ a( k1, i1 ), lda, c( k1, l1 ), ldc,
623 $ cone, c( i1, l1 ), ldc )
630 j1 = (j - 1) * nb + 1
631 j2 = min( j * nb, n ) + 1
636 cnrm = clange(
'I', k2-k1, j2-j1, c( k1, j1 ),
638 scamin = min( swork( k, j ), swork( k, l ) )
639 cnrm = cnrm * ( scamin / swork( k, j ) )
640 xnrm = xnrm * ( scamin / swork( k, l ) )
641 bnrm = swork( l, bwrk + j )
642 scaloc = slarmm( bnrm, xnrm, cnrm )
643 IF( scaloc * scamin .EQ. zero )
THEN
645 buf = buf*2.e0**exponent( scaloc )
648 swork( ll, jj ) = min( bignum,
649 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
652 scamin = scamin / 2.e0**exponent( scaloc )
653 scaloc = scaloc / 2.e0**exponent( scaloc )
661 scal = ( scamin / swork( k, l ) ) * scaloc
662 IF( scal .NE. one )
THEN
664 CALL csscal( k2-k1, scal, c( k1, ll ), 1 )
668 scal = ( scamin / swork( k, j ) ) * scaloc
669 IF( scal .NE. one )
THEN
671 CALL csscal( k2-k1, scal, c( k1, jj ), 1 )
677 swork( k, l ) = scamin * scaloc
678 swork( k, j ) = scamin * scaloc
680 CALL cgemm(
'N',
'N', k2-k1, j2-j1, l2-l1, -csgn,
681 $ c( k1, l1 ), ldc, b( l1, j1 ), ldb,
682 $ cone, c( k1, j1 ), ldc )
686 ELSE IF( .NOT.notrna .AND. .NOT.notrnb )
THEN
708 k1 = (k - 1) * nb + 1
709 k2 = min( k * nb, m ) + 1
716 l1 = (l - 1) * nb + 1
717 l2 = min( l * nb, n ) + 1
719 CALL ctrsyl( trana, tranb, isgn, k2-k1, l2-l1,
722 $ c( k1, l1 ), ldc, scaloc, iinfo )
723 info = max( info, iinfo )
725 IF( scaloc * swork( k, l ) .EQ. zero )
THEN
726 IF( scaloc .EQ. zero )
THEN
734 buf = buf*2.e0**exponent( scaloc )
741 swork( ll, jj ) = min( bignum,
742 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
746 swork( k, l ) = scaloc * swork( k, l )
747 xnrm = clange(
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
754 i1 = (i - 1) * nb + 1
755 i2 = min( i * nb, m ) + 1
760 cnrm = clange(
'I', i2-i1, l2-l1, c( i1, l1 ),
762 scamin = min( swork( i, l ), swork( k, l ) )
763 cnrm = cnrm * ( scamin / swork( i, l ) )
764 xnrm = xnrm * ( scamin / swork( k, l ) )
765 anrm = swork( i, awrk + k )
766 scaloc = slarmm( anrm, xnrm, cnrm )
767 IF( scaloc * scamin .EQ. zero )
THEN
769 buf = buf*2.e0**exponent( scaloc )
772 swork( ll, jj ) = min( bignum,
773 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
776 scamin = scamin / 2.e0**exponent( scaloc )
777 scaloc = scaloc / 2.e0**exponent( scaloc )
785 scal = ( scamin / swork( k, l ) ) * scaloc
786 IF( scal .NE. one )
THEN
788 CALL csscal( k2-k1, scal, c( k1, ll ), 1 )
792 scal = ( scamin / swork( i, l ) ) * scaloc
793 IF( scal .NE. one )
THEN
795 CALL csscal( i2-i1, scal, c( i1, ll ), 1 )
801 swork( k, l ) = scamin * scaloc
802 swork( i, l ) = scamin * scaloc
804 CALL cgemm(
'C',
'N', i2-i1, l2-l1, k2-k1, -cone,
805 $ a( k1, i1 ), lda, c( k1, l1 ), ldc,
806 $ cone, c( i1, l1 ), ldc )
813 j1 = (j - 1) * nb + 1
814 j2 = min( j * nb, n ) + 1
819 cnrm = clange(
'I', k2-k1, j2-j1, c( k1, j1 ),
821 scamin = min( swork( k, j ), swork( k, l ) )
822 cnrm = cnrm * ( scamin / swork( k, j ) )
823 xnrm = xnrm * ( scamin / swork( k, l ) )
824 bnrm = swork( l, bwrk + j )
825 scaloc = slarmm( bnrm, xnrm, cnrm )
826 IF( scaloc * scamin .EQ. zero )
THEN
828 buf = buf*2.e0**exponent( scaloc )
831 swork( ll, jj ) = min( bignum,
832 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
835 scamin = scamin / 2.e0**exponent( scaloc )
836 scaloc = scaloc / 2.e0**exponent( scaloc )
844 scal = ( scamin / swork( k, l ) ) * scaloc
845 IF( scal .NE. one )
THEN
847 CALL csscal( k2-k1, scal, c( k1, ll ), 1)
851 scal = ( scamin / swork( k, j ) ) * scaloc
852 IF( scal .NE. one )
THEN
854 CALL csscal( k2-k1, scal, c( k1, jj ), 1 )
860 swork( k, l ) = scamin * scaloc
861 swork( k, j ) = scamin * scaloc
863 CALL cgemm(
'N',
'C', k2-k1, j2-j1, l2-l1, -csgn,
864 $ c( k1, l1 ), ldc, b( j1, l1 ), ldb,
865 $ cone, c( k1, j1 ), ldc )
869 ELSE IF( notrna .AND. .NOT.notrnb )
THEN
891 k1 = (k - 1) * nb + 1
892 k2 = min( k * nb, m ) + 1
899 l1 = (l - 1) * nb + 1
900 l2 = min( l * nb, n ) + 1
902 CALL ctrsyl( trana, tranb, isgn, k2-k1, l2-l1,
905 $ c( k1, l1 ), ldc, scaloc, iinfo )
906 info = max( info, iinfo )
908 IF( scaloc * swork( k, l ) .EQ. zero )
THEN
909 IF( scaloc .EQ. zero )
THEN
917 buf = buf*2.e0**exponent( scaloc )
924 swork( ll, jj ) = min( bignum,
925 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
929 swork( k, l ) = scaloc * swork( k, l )
930 xnrm = clange(
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
937 i1 = (i - 1) * nb + 1
938 i2 = min( i * nb, m ) + 1
943 cnrm = clange(
'I', i2-i1, l2-l1, c( i1, l1 ),
945 scamin = min( swork( i, l ), swork( k, l ) )
946 cnrm = cnrm * ( scamin / swork( i, l ) )
947 xnrm = xnrm * ( scamin / swork( k, l ) )
948 anrm = swork( i, awrk + k )
949 scaloc = slarmm( anrm, xnrm, cnrm )
950 IF( scaloc * scamin .EQ. zero )
THEN
952 buf = buf*2.e0**exponent( scaloc )
955 swork( ll, jj ) = min( bignum,
956 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
959 scamin = scamin / 2.e0**exponent( scaloc )
960 scaloc = scaloc / 2.e0**exponent( scaloc )
968 scal = ( scamin / swork( k, l ) ) * scaloc
969 IF( scal .NE. one )
THEN
971 CALL csscal( k2-k1, scal, c( k1, ll ), 1 )
975 scal = ( scamin / swork( i, l ) ) * scaloc
976 IF( scal .NE. one )
THEN
978 CALL csscal( i2-i1, scal, c( i1, ll ), 1 )
984 swork( k, l ) = scamin * scaloc
985 swork( i, l ) = scamin * scaloc
987 CALL cgemm(
'N',
'N', i2-i1, l2-l1, k2-k1, -cone,
988 $ a( i1, k1 ), lda, c( k1, l1 ), ldc,
989 $ cone, c( i1, l1 ), ldc )
997 j1 = (j - 1) * nb + 1
998 j2 = min( j * nb, n ) + 1
1003 cnrm = clange(
'I', k2-k1, j2-j1, c( k1, j1 ),
1005 scamin = min( swork( k, j ), swork( k, l ) )
1006 cnrm = cnrm * ( scamin / swork( k, j ) )
1007 xnrm = xnrm * ( scamin / swork( k, l ) )
1008 bnrm = swork( l, bwrk + j )
1009 scaloc = slarmm( bnrm, xnrm, cnrm )
1010 IF( scaloc * scamin .EQ. zero )
THEN
1012 buf = buf*2.e0**exponent( scaloc )
1015 swork( ll, jj ) = min( bignum,
1016 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
1019 scamin = scamin / 2.e0**exponent( scaloc )
1020 scaloc = scaloc / 2.e0**exponent( scaloc )
1022 cnrm = cnrm * scaloc
1023 xnrm = xnrm * scaloc
1028 scal = ( scamin / swork( k, l ) ) * scaloc
1029 IF( scal .NE. one )
THEN
1031 CALL csscal( k2-k1, scal, c( k1, jj ), 1 )
1035 scal = ( scamin / swork( k, j ) ) * scaloc
1036 IF( scal .NE. one )
THEN
1038 CALL csscal( k2-k1, scal, c( k1, jj ), 1 )
1044 swork( k, l ) = scamin * scaloc
1045 swork( k, j ) = scamin * scaloc
1047 CALL cgemm(
'N',
'C', k2-k1, j2-j1, l2-l1, -csgn,
1048 $ c( k1, l1 ), ldc, b( j1, l1 ), ldb,
1049 $ cone, c( k1, j1 ), ldc )
1058 scale = swork( 1, 1 )
1061 scale = min( scale, swork( k, l ) )
1064 IF( scale .EQ. zero )
THEN
1071 swork(1,1) = max( nba, nbb )
1072 swork(2,1) = 2 * nbb + nba
1079 k1 = (k - 1) * nb + 1
1080 k2 = min( k * nb, m ) + 1
1082 l1 = (l - 1) * nb + 1
1083 l2 = min( l * nb, n ) + 1
1084 scal = scale / swork( k, l )
1085 IF( scal .NE. one )
THEN
1087 CALL csscal( k2-k1, scal, c( k1, ll ), 1 )
1093 IF( buf .NE. one .AND. buf.GT.zero )
THEN
1097 scaloc = min( scale / smlnum, one / buf )
1099 scale = scale / scaloc
1102 IF( buf.NE.one .AND. buf.GT.zero )
THEN
1112 scal = max( abs( real( c( 1, 1 ) ) ),
1113 $ abs( aimag( c( 1, 1 ) ) ) )
1116 scal = max( scal, abs( real( c( k, l ) ) ),
1117 $ abs( aimag( c( k, l ) ) ) )
1123 scaloc = min( bignum / scal, one / buf )
1125 CALL clascl(
'G', -1, -1, one, scaloc, m, n, c, ldc, iinfo )
1135 swork(1,1) = max( nba, nbb )
1136 swork(2,1) = 2 * nbb + nba
subroutine xerbla(srname, info)
subroutine cgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
CGEMM
subroutine clascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
CLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine csscal(n, sa, cx, incx)
CSSCAL
subroutine ctrsyl3(trana, tranb, isgn, m, n, a, lda, b, ldb, c, ldc, scale, swork, ldswork, info)
CTRSYL3
subroutine ctrsyl(trana, tranb, isgn, m, n, a, lda, b, ldb, c, ldc, scale, info)
CTRSYL