168 SUBROUTINE ztrsyl3( TRANA, TRANB, ISGN, M, N, A, LDA, B, LDB,
169 $ C, LDC, SCALE, SWORK, LDSWORK, INFO )
173 CHARACTER TRANA, TRANB
174 INTEGER INFO, ISGN, LDA, LDB, LDC, LDSWORK, M, N
175 DOUBLE PRECISION SCALE
178 COMPLEX*16 A( LDA, * ), B( LDB, * ), C( LDC, * )
179 DOUBLE PRECISION SWORK( LDSWORK, * )
182 DOUBLE PRECISION ZERO, ONE
183 parameter( zero = 0.0d0, one = 1.0d0 )
185 parameter( cone = ( 1.0d0, 0.0d0 ) )
188 LOGICAL NOTRNA, NOTRNB, LQUERY
189 INTEGER AWRK, BWRK, I, I1, I2, IINFO, J, J1, J2, JJ,
190 $ k, k1, k2, l, l1, l2, ll, nba, nb, nbb
191 DOUBLE PRECISION ANRM, BIGNUM, BNRM, CNRM, SCAL, SCALOC,
192 $ scamin, sgn, xnrm, buf, smlnum
196 DOUBLE PRECISION WNRM( MAX( M, N ) )
201 DOUBLE PRECISION DLAMCH, DLARMM, ZLANGE
202 EXTERNAL dlamch, dlarmm, ilaenv, lsame,
210 INTRINSIC abs, dble, dimag, exponent, max, min
216 notrna = lsame( trana,
'N' )
217 notrnb = lsame( tranb,
'N' )
221 nb = max( 8, ilaenv( 1,
'ZTRSYL',
'', m, n, -1, -1) )
225 nba = max( 1, (m + nb - 1) / nb )
226 nbb = max( 1, (n + nb - 1) / nb )
231 lquery = ( ldswork.EQ.-1 )
234 swork(1,1) = max( nba, nbb )
235 swork(2,1) = 2 * nbb + nba
240 IF( .NOT.notrna .AND. .NOT. lsame( trana,
'C' ) )
THEN
242 ELSE IF( .NOT.notrnb .AND. .NOT. lsame( tranb,
'C' ) )
THEN
244 ELSE IF( isgn.NE.1 .AND. isgn.NE.-1 )
THEN
246 ELSE IF( m.LT.0 )
THEN
248 ELSE IF( n.LT.0 )
THEN
250 ELSE IF( lda.LT.max( 1, m ) )
THEN
252 ELSE IF( ldb.LT.max( 1, n ) )
THEN
254 ELSE IF( ldc.LT.max( 1, m ) )
THEN
258 CALL xerbla(
'ZTRSYL3', -info )
260 ELSE IF( lquery )
THEN
267 IF( m.EQ.0 .OR. n.EQ.0 )
273 IF( min( nba, nbb ).EQ.1 .OR. ldswork.LT.max( nba, nbb ) )
THEN
274 CALL ztrsyl( trana, tranb, isgn, m, n, a, lda, b, ldb,
275 $ c, ldc, scale, info )
281 smlnum = dlamch(
'S' )
282 bignum = one / smlnum
301 k1 = (k - 1) * nb + 1
302 k2 = min( k * nb, m ) + 1
304 l1 = (l - 1) * nb + 1
305 l2 = min( l * nb, m ) + 1
307 swork( k, awrk + l ) = zlange(
'I', k2-k1, l2-l1,
308 $ a( k1, l1 ), lda, wnrm )
310 swork( l, awrk + k ) = zlange(
'1', k2-k1, l2-l1,
311 $ a( k1, l1 ), lda, wnrm )
317 k1 = (k - 1) * nb + 1
318 k2 = min( k * nb, n ) + 1
320 l1 = (l - 1) * nb + 1
321 l2 = min( l * nb, n ) + 1
323 swork( k, bwrk + l ) = zlange(
'I', k2-k1, l2-l1,
324 $ b( k1, l1 ), ldb, wnrm )
326 swork( l, bwrk + k ) = zlange(
'1', k2-k1, l2-l1,
327 $ b( k1, l1 ), ldb, wnrm )
333 csgn = dcmplx( sgn, zero )
335 IF( notrna .AND. notrnb )
THEN
357 k1 = (k - 1) * nb + 1
358 k2 = min( k * nb, m ) + 1
365 l1 = (l - 1) * nb + 1
366 l2 = min( l * nb, n ) + 1
368 CALL ztrsyl( trana, tranb, isgn, k2-k1, l2-l1,
371 $ c( k1, l1 ), ldc, scaloc, iinfo )
372 info = max( info, iinfo )
374 IF( scaloc * swork( k, l ) .EQ. zero )
THEN
375 IF( scaloc .EQ. zero )
THEN
382 buf = buf*2.d0**exponent( scaloc )
389 swork( ll, jj ) = min( bignum,
390 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
394 swork( k, l ) = scaloc * swork( k, l )
395 xnrm = zlange(
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
402 i1 = (i - 1) * nb + 1
403 i2 = min( i * nb, m ) + 1
408 cnrm = zlange(
'I', i2-i1, l2-l1, c( i1, l1 ),
410 scamin = min( swork( i, l ), swork( k, l ) )
411 cnrm = cnrm * ( scamin / swork( i, l ) )
412 xnrm = xnrm * ( scamin / swork( k, l ) )
413 anrm = swork( i, awrk + k )
414 scaloc = dlarmm( anrm, xnrm, cnrm )
415 IF( scaloc * scamin .EQ. zero )
THEN
417 buf = buf*2.d0**exponent( scaloc )
420 swork( ll, jj ) = min( bignum,
421 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
424 scamin = scamin / 2.d0**exponent( scaloc )
425 scaloc = scaloc / 2.d0**exponent( scaloc )
433 scal = ( scamin / swork( k, l ) ) * scaloc
434 IF( scal .NE. one )
THEN
436 CALL zdscal( k2-k1, scal, c( k1, jj ), 1)
440 scal = ( scamin / swork( i, l ) ) * scaloc
441 IF( scal .NE. one )
THEN
443 CALL zdscal( i2-i1, scal, c( i1, ll ), 1)
449 swork( k, l ) = scamin * scaloc
450 swork( i, l ) = scamin * scaloc
452 CALL zgemm(
'N',
'N', i2-i1, l2-l1, k2-k1, -cone,
453 $ a( i1, k1 ), lda, c( k1, l1 ), ldc,
454 $ cone, c( i1, l1 ), ldc )
462 j1 = (j - 1) * nb + 1
463 j2 = min( j * nb, n ) + 1
468 cnrm = zlange(
'I', k2-k1, j2-j1, c( k1, j1 ),
470 scamin = min( swork( k, j ), swork( k, l ) )
471 cnrm = cnrm * ( scamin / swork( k, j ) )
472 xnrm = xnrm * ( scamin / swork( k, l ) )
473 bnrm = swork(l, bwrk + j)
474 scaloc = dlarmm( bnrm, xnrm, cnrm )
475 IF( scaloc * scamin .EQ. zero )
THEN
477 buf = buf*2.d0**exponent( scaloc )
480 swork( ll, jj ) = min( bignum,
481 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
484 scamin = scamin / 2.d0**exponent( scaloc )
485 scaloc = scaloc / 2.d0**exponent( scaloc )
493 scal = ( scamin / swork( k, l ) ) * scaloc
494 IF( scal .NE. one )
THEN
496 CALL zdscal( k2-k1, scal, c( k1, ll ), 1 )
500 scal = ( scamin / swork( k, j ) ) * scaloc
501 IF( scal .NE. one )
THEN
503 CALL zdscal( k2-k1, scal, c( k1, jj ), 1 )
509 swork( k, l ) = scamin * scaloc
510 swork( k, j ) = scamin * scaloc
512 CALL zgemm(
'N',
'N', k2-k1, j2-j1, l2-l1, -csgn,
513 $ c( k1, l1 ), ldc, b( l1, j1 ), ldb,
514 $ cone, c( k1, j1 ), ldc )
518 ELSE IF( .NOT.notrna .AND. notrnb )
THEN
540 k1 = (k - 1) * nb + 1
541 k2 = min( k * nb, m ) + 1
548 l1 = (l - 1) * nb + 1
549 l2 = min( l * nb, n ) + 1
551 CALL ztrsyl( trana, tranb, isgn, k2-k1, l2-l1,
554 $ c( k1, l1 ), ldc, scaloc, iinfo )
555 info = max( info, iinfo )
557 IF( scaloc * swork( k, l ) .EQ. zero )
THEN
558 IF( scaloc .EQ. zero )
THEN
566 buf = buf*2.d0**exponent( scaloc )
573 swork( ll, jj ) = min( bignum,
574 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
578 swork( k, l ) = scaloc * swork( k, l )
579 xnrm = zlange(
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
586 i1 = (i - 1) * nb + 1
587 i2 = min( i * nb, m ) + 1
592 cnrm = zlange(
'I', i2-i1, l2-l1, c( i1, l1 ),
594 scamin = min( swork( i, l ), swork( k, l ) )
595 cnrm = cnrm * ( scamin / swork( i, l ) )
596 xnrm = xnrm * ( scamin / swork( k, l ) )
597 anrm = swork( i, awrk + k )
598 scaloc = dlarmm( anrm, xnrm, cnrm )
599 IF( scaloc * scamin .EQ. zero )
THEN
601 buf = buf*2.d0**exponent( scaloc )
604 swork( ll, jj ) = min( bignum,
605 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
608 scamin = scamin / 2.d0**exponent( scaloc )
609 scaloc = scaloc / 2.d0**exponent( scaloc )
617 scal = ( scamin / swork( k, l ) ) * scaloc
618 IF( scal .NE. one )
THEN
620 CALL zdscal( k2-k1, scal, c( k1, ll ), 1 )
624 scal = ( scamin / swork( i, l ) ) * scaloc
625 IF( scal .NE. one )
THEN
627 CALL zdscal( i2-i1, scal, c( i1, ll ), 1 )
633 swork( k, l ) = scamin * scaloc
634 swork( i, l ) = scamin * scaloc
636 CALL zgemm(
'C',
'N', i2-i1, l2-l1, k2-k1, -cone,
637 $ a( k1, i1 ), lda, c( k1, l1 ), ldc,
638 $ cone, c( i1, l1 ), ldc )
645 j1 = (j - 1) * nb + 1
646 j2 = min( j * nb, n ) + 1
651 cnrm = zlange(
'I', k2-k1, j2-j1, c( k1, j1 ),
653 scamin = min( swork( k, j ), swork( k, l ) )
654 cnrm = cnrm * ( scamin / swork( k, j ) )
655 xnrm = xnrm * ( scamin / swork( k, l ) )
656 bnrm = swork( l, bwrk + j )
657 scaloc = dlarmm( bnrm, xnrm, cnrm )
658 IF( scaloc * scamin .EQ. zero )
THEN
660 buf = buf*2.d0**exponent( scaloc )
663 swork( ll, jj ) = min( bignum,
664 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
667 scamin = scamin / 2.d0**exponent( scaloc )
668 scaloc = scaloc / 2.d0**exponent( scaloc )
676 scal = ( scamin / swork( k, l ) ) * scaloc
677 IF( scal .NE. one )
THEN
679 CALL zdscal( k2-k1, scal, c( k1, ll ), 1 )
683 scal = ( scamin / swork( k, j ) ) * scaloc
684 IF( scal .NE. one )
THEN
686 CALL zdscal( k2-k1, scal, c( k1, jj ), 1 )
692 swork( k, l ) = scamin * scaloc
693 swork( k, j ) = scamin * scaloc
695 CALL zgemm(
'N',
'N', k2-k1, j2-j1, l2-l1, -csgn,
696 $ c( k1, l1 ), ldc, b( l1, j1 ), ldb,
697 $ cone, c( k1, j1 ), ldc )
701 ELSE IF( .NOT.notrna .AND. .NOT.notrnb )
THEN
723 k1 = (k - 1) * nb + 1
724 k2 = min( k * nb, m ) + 1
731 l1 = (l - 1) * nb + 1
732 l2 = min( l * nb, n ) + 1
734 CALL ztrsyl( trana, tranb, isgn, k2-k1, l2-l1,
737 $ c( k1, l1 ), ldc, scaloc, iinfo )
738 info = max( info, iinfo )
740 IF( scaloc * swork( k, l ) .EQ. zero )
THEN
741 IF( scaloc .EQ. zero )
THEN
749 buf = buf*2.d0**exponent( scaloc )
756 swork( ll, jj ) = min( bignum,
757 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
761 swork( k, l ) = scaloc * swork( k, l )
762 xnrm = zlange(
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
769 i1 = (i - 1) * nb + 1
770 i2 = min( i * nb, m ) + 1
775 cnrm = zlange(
'I', i2-i1, l2-l1, c( i1, l1 ),
777 scamin = min( swork( i, l ), swork( k, l ) )
778 cnrm = cnrm * ( scamin / swork( i, l ) )
779 xnrm = xnrm * ( scamin / swork( k, l ) )
780 anrm = swork( i, awrk + k )
781 scaloc = dlarmm( anrm, xnrm, cnrm )
782 IF( scaloc * scamin .EQ. zero )
THEN
784 buf = buf*2.d0**exponent( scaloc )
787 swork( ll, jj ) = min( bignum,
788 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
791 scamin = scamin / 2.d0**exponent( scaloc )
792 scaloc = scaloc / 2.d0**exponent( scaloc )
800 scal = ( scamin / swork( k, l ) ) * scaloc
801 IF( scal .NE. one )
THEN
803 CALL zdscal( k2-k1, scal, c( k1, ll ), 1 )
807 scal = ( scamin / swork( i, l ) ) * scaloc
808 IF( scal .NE. one )
THEN
810 CALL zdscal( i2-i1, scal, c( i1, ll ), 1 )
816 swork( k, l ) = scamin * scaloc
817 swork( i, l ) = scamin * scaloc
819 CALL zgemm(
'C',
'N', i2-i1, l2-l1, k2-k1, -cone,
820 $ a( k1, i1 ), lda, c( k1, l1 ), ldc,
821 $ cone, c( i1, l1 ), ldc )
828 j1 = (j - 1) * nb + 1
829 j2 = min( j * nb, n ) + 1
834 cnrm = zlange(
'I', k2-k1, j2-j1, c( k1, j1 ),
836 scamin = min( swork( k, j ), swork( k, l ) )
837 cnrm = cnrm * ( scamin / swork( k, j ) )
838 xnrm = xnrm * ( scamin / swork( k, l ) )
839 bnrm = swork( l, bwrk + j )
840 scaloc = dlarmm( bnrm, xnrm, cnrm )
841 IF( scaloc * scamin .EQ. zero )
THEN
843 buf = buf*2.d0**exponent( scaloc )
846 swork( ll, jj ) = min( bignum,
847 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
850 scamin = scamin / 2.d0**exponent( scaloc )
851 scaloc = scaloc / 2.d0**exponent( scaloc )
859 scal = ( scamin / swork( k, l ) ) * scaloc
860 IF( scal .NE. one )
THEN
862 CALL zdscal( k2-k1, scal, c( k1, ll ), 1)
866 scal = ( scamin / swork( k, j ) ) * scaloc
867 IF( scal .NE. one )
THEN
869 CALL zdscal( k2-k1, scal, c( k1, jj ), 1 )
875 swork( k, l ) = scamin * scaloc
876 swork( k, j ) = scamin * scaloc
878 CALL zgemm(
'N',
'C', k2-k1, j2-j1, l2-l1, -csgn,
879 $ c( k1, l1 ), ldc, b( j1, l1 ), ldb,
880 $ cone, c( k1, j1 ), ldc )
884 ELSE IF( notrna .AND. .NOT.notrnb )
THEN
906 k1 = (k - 1) * nb + 1
907 k2 = min( k * nb, m ) + 1
914 l1 = (l - 1) * nb + 1
915 l2 = min( l * nb, n ) + 1
917 CALL ztrsyl( trana, tranb, isgn, k2-k1, l2-l1,
920 $ c( k1, l1 ), ldc, scaloc, iinfo )
921 info = max( info, iinfo )
923 IF( scaloc * swork( k, l ) .EQ. zero )
THEN
924 IF( scaloc .EQ. zero )
THEN
932 buf = buf*2.d0**exponent( scaloc )
939 swork( ll, jj ) = min( bignum,
940 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
944 swork( k, l ) = scaloc * swork( k, l )
945 xnrm = zlange(
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
952 i1 = (i - 1) * nb + 1
953 i2 = min( i * nb, m ) + 1
958 cnrm = zlange(
'I', i2-i1, l2-l1, c( i1, l1 ),
960 scamin = min( swork( i, l ), swork( k, l ) )
961 cnrm = cnrm * ( scamin / swork( i, l ) )
962 xnrm = xnrm * ( scamin / swork( k, l ) )
963 anrm = swork( i, awrk + k )
964 scaloc = dlarmm( anrm, xnrm, cnrm )
965 IF( scaloc * scamin .EQ. zero )
THEN
967 buf = buf*2.d0**exponent( scaloc )
970 swork( ll, jj ) = min( bignum,
971 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
974 scamin = scamin / 2.d0**exponent( scaloc )
975 scaloc = scaloc / 2.d0**exponent( scaloc )
983 scal = ( scamin / swork( k, l ) ) * scaloc
984 IF( scal .NE. one )
THEN
986 CALL zdscal( k2-k1, scal, c( k1, ll ), 1 )
990 scal = ( scamin / swork( i, l ) ) * scaloc
991 IF( scal .NE. one )
THEN
993 CALL zdscal( i2-i1, scal, c( i1, ll ), 1 )
999 swork( k, l ) = scamin * scaloc
1000 swork( i, l ) = scamin * scaloc
1002 CALL zgemm(
'N',
'N', i2-i1, l2-l1, k2-k1, -cone,
1003 $ a( i1, k1 ), lda, c( k1, l1 ), ldc,
1004 $ cone, c( i1, l1 ), ldc )
1012 j1 = (j - 1) * nb + 1
1013 j2 = min( j * nb, n ) + 1
1018 cnrm = zlange(
'I', k2-k1, j2-j1, c( k1, j1 ),
1020 scamin = min( swork( k, j ), swork( k, l ) )
1021 cnrm = cnrm * ( scamin / swork( k, j ) )
1022 xnrm = xnrm * ( scamin / swork( k, l ) )
1023 bnrm = swork( l, bwrk + j )
1024 scaloc = dlarmm( bnrm, xnrm, cnrm )
1025 IF( scaloc * scamin .EQ. zero )
THEN
1027 buf = buf*2.d0**exponent( scaloc )
1030 swork( ll, jj ) = min( bignum,
1031 $ swork( ll, jj ) / 2.d0**exponent( scaloc ) )
1034 scamin = scamin / 2.d0**exponent( scaloc )
1035 scaloc = scaloc / 2.d0**exponent( scaloc )
1037 cnrm = cnrm * scaloc
1038 xnrm = xnrm * scaloc
1043 scal = ( scamin / swork( k, l ) ) * scaloc
1044 IF( scal .NE. one )
THEN
1046 CALL zdscal( k2-k1, scal, c( k1, jj ), 1 )
1050 scal = ( scamin / swork( k, j ) ) * scaloc
1051 IF( scal .NE. one )
THEN
1053 CALL zdscal( k2-k1, scal, c( k1, jj ), 1 )
1059 swork( k, l ) = scamin * scaloc
1060 swork( k, j ) = scamin * scaloc
1062 CALL zgemm(
'N',
'C', k2-k1, j2-j1, l2-l1, -csgn,
1063 $ c( k1, l1 ), ldc, b( j1, l1 ), ldb,
1064 $ cone, c( k1, j1 ), ldc )
1073 scale = swork( 1, 1 )
1076 scale = min( scale, swork( k, l ) )
1079 IF( scale .EQ. zero )
THEN
1086 swork(1,1) = max( nba, nbb )
1087 swork(2,1) = 2 * nbb + nba
1094 k1 = (k - 1) * nb + 1
1095 k2 = min( k * nb, m ) + 1
1097 l1 = (l - 1) * nb + 1
1098 l2 = min( l * nb, n ) + 1
1099 scal = scale / swork( k, l )
1100 IF( scal .NE. one )
THEN
1102 CALL zdscal( k2-k1, scal, c( k1, ll ), 1 )
1108 IF( buf .NE. one .AND. buf.GT.zero )
THEN
1112 scaloc = min( scale / smlnum, one / buf )
1114 scale = scale / scaloc
1117 IF( buf.NE.one .AND. buf.GT.zero )
THEN
1127 scal = max( abs( dble( c( 1, 1 ) ) ),
1128 $ abs( dimag( c( 1, 1 ) ) ) )
1131 scal = max( scal, abs( dble( c( k, l ) ) ),
1132 $ abs( dimag( c( k, l ) ) ) )
1138 scaloc = min( bignum / scal, one / buf )
1140 CALL zlascl(
'G', -1, -1, one, scaloc, m, n, c, ldc, iinfo )
1150 swork(1,1) = max( nba, nbb )
1151 swork(2,1) = 2 * nbb + nba