169      IMPLICIT NONE
  170
  171
  172      CHARACTER          TRANA, TRANB
  173      INTEGER            INFO, ISGN, LDA, LDB, LDC, LDSWORK, M, N
  174      REAL               SCALE
  175
  176
  177      COMPLEX            A( LDA, * ), B( LDB, * ), C( LDC, * )
  178      REAL               SWORK( LDSWORK, * )
  179
  180
  181      REAL               ZERO, ONE
  182      parameter( zero = 0.0e+0, one = 1.0e+0 )
  183      COMPLEX            CONE
  184      parameter( cone = ( 1.0e+0, 0.0e+0 ) )
  185
  186
  187      LOGICAL            NOTRNA, NOTRNB, LQUERY
  188      INTEGER            AWRK, BWRK, I, I1, I2, IINFO, J, J1, J2, JJ,
  189     $                   K, K1, K2, L, L1, L2, LL, NBA, NB, NBB
  190      REAL               ANRM, BIGNUM, BNRM, CNRM, SCAL, SCALOC,
  191     $                   SCAMIN, SGN, XNRM, BUF, SMLNUM
  192      COMPLEX            CSGN
  193
  194
  195      REAL               WNRM( MAX( M, N ) )
  196
  197
  198      LOGICAL            LSAME
  199      INTEGER            ILAENV
  200      REAL               CLANGE, SLAMCH, SLARMM
  203
  204
  207
  208
  209      INTRINSIC          abs, aimag, exponent, max, min, real
  210
  211
  212
  213
  214
  215      notrna = 
lsame( trana, 
'N' )
 
  216      notrnb = 
lsame( tranb, 
'N' )
 
  217
  218
  219
  220      nb = max( 8, 
ilaenv( 1, 
'CTRSYL', 
'', m, n, -1, -1) )
 
  221
  222
  223
  224      nba = max( 1, (m + nb - 1) / nb )
  225      nbb = max( 1, (n + nb - 1) / nb )
  226
  227
  228
  229      info = 0
  230      lquery = ( ldswork.EQ.-1 )
  231      IF( lquery ) THEN
  232         ldswork = 2
  233         swork(1,1) = real( max( nba, nbb ) )
  234         swork(2,1) = real( 2 * nbb + nba )
  235      END IF
  236
  237
  238
  239      IF( .NOT.notrna .AND. .NOT. 
lsame( trana, 
'C' ) ) 
THEN 
  240         info = -1
  241      ELSE IF( .NOT.notrnb .AND. .NOT. 
lsame( tranb, 
'C' ) ) 
THEN 
  242         info = -2
  243      ELSE IF( isgn.NE.1 .AND. isgn.NE.-1 ) THEN
  244         info = -3
  245      ELSE IF( m.LT.0 ) THEN
  246         info = -4
  247      ELSE IF( n.LT.0 ) THEN
  248         info = -5
  249      ELSE IF( lda.LT.max( 1, m ) ) THEN
  250         info = -7
  251      ELSE IF( ldb.LT.max( 1, n ) ) THEN
  252         info = -9
  253      ELSE IF( ldc.LT.max( 1, m ) ) THEN
  254         info = -11
  255      END IF
  256      IF( info.NE.0 ) THEN
  257         CALL xerbla( 
'CTRSYL3', -info )
 
  258         RETURN
  259      ELSE IF( lquery ) THEN
  260         RETURN
  261      END IF
  262
  263
  264
  265      scale = one
  266      IF( m.EQ.0 .OR. n.EQ.0 )
  267     $   RETURN
  268
  269
  270
  271
  272      IF( min( nba, nbb ).EQ.1 .OR. ldswork.LT.max( nba, nbb ) ) THEN
  273        CALL ctrsyl( trana, tranb, isgn, m, n, a, lda, b, ldb,
 
  274     $               c, ldc, scale, info )
  275        RETURN
  276      END IF
  277
  278
  279
  281      bignum = one / smlnum
  282
  283
  284
  285      DO l = 1, nbb
  286         DO k = 1, nba
  287            swork( k, l ) = one
  288         END DO
  289      END DO
  290
  291
  292
  293
  294      buf = one
  295
  296
  297
  298      awrk = nbb
  299      DO k = 1, nba
  300         k1 = (k - 1) * nb + 1
  301         k2 = min( k * nb, m ) + 1
  302         DO l = k, nba
  303            l1 = (l - 1) * nb + 1
  304            l2 = min( l * nb, m ) + 1
  305            IF( notrna ) THEN
  306               swork( k, awrk + l ) = 
clange( 
'I', k2-k1, l2-l1,
 
  307     $                                        a( k1, l1 ), lda, wnrm )
  308            ELSE
  309               swork( l, awrk + k ) = 
clange( 
'1', k2-k1, l2-l1,
 
  310     $                                        a( k1, l1 ), lda, wnrm )
  311            END IF
  312         END DO
  313      END DO
  314      bwrk = nbb + nba
  315      DO k = 1, nbb
  316         k1 = (k - 1) * nb + 1
  317         k2 = min( k * nb, n ) + 1
  318         DO l = k, nbb
  319            l1 = (l - 1) * nb + 1
  320            l2 = min( l * nb, n ) + 1
  321            IF( notrnb ) THEN
  322               swork( k, bwrk + l ) = 
clange( 
'I', k2-k1, l2-l1,
 
  323     $                                        b( k1, l1 ), ldb, wnrm )
  324            ELSE
  325               swork( l, bwrk + k ) = 
clange( 
'1', k2-k1, l2-l1,
 
  326     $                                        b( k1, l1 ), ldb, wnrm )
  327            END IF
  328         END DO
  329      END DO
  330
  331      sgn = real( isgn )
  332      csgn = cmplx( sgn, zero )
  333
  334      IF( notrna .AND. notrnb ) THEN
  335
  336
  337
  338
  339
  340
  341
  342
  343
  344
  345
  346
  347
  348
  349
  350         DO k = nba, 1, -1
  351
  352
  353
  354
  355
  356            k1 = (k - 1) * nb + 1
  357            k2 = min( k * nb, m ) + 1
  358            DO l = 1, nbb
  359
  360
  361
  362
  363
  364               l1 = (l - 1) * nb + 1
  365               l2 = min( l * nb, n ) + 1
  366
  367               CALL ctrsyl( trana, tranb, isgn, k2-k1, l2-l1,
 
  368     $                      a( k1, k1 ), lda,
  369     $                      b( l1, l1 ), ldb,
  370     $                      c( k1, l1 ), ldc, scaloc, iinfo )
  371               info = max( info, iinfo )
  372
  373               IF( scaloc * swork( k, l ) .EQ. zero ) THEN
  374                  IF( scaloc .EQ. zero ) THEN
  375
  376
  377
  378
  379                     buf = zero
  380                  ELSE
  381
  382                     buf = buf*2.e0**exponent( scaloc )
  383                  END IF
  384                  DO jj = 1, nbb
  385                     DO ll = 1, nba
  386
  387
  388
  389                        swork( ll, jj ) = min( bignum,
  390     $                     swork( ll, jj ) / 2.e0**exponent( scaloc ) )
  391                     END DO
  392                  END DO
  393               END IF
  394               swork( k, l ) = scaloc * swork( k, l )
  395               xnrm = 
clange( 
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
 
  396     $                        wnrm )
  397
  398               DO i = k - 1, 1, -1
  399
  400
  401
  402                  i1 = (i - 1) * nb + 1
  403                  i2 = min( i * nb, m ) + 1
  404
  405
  406
  407
  408                  cnrm = 
clange( 
'I', i2-i1, l2-l1, c( i1, l1 ),
 
  409     $                           ldc, wnrm )
  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 = 
slarmm( anrm, xnrm, cnrm )
 
  415                  IF( scaloc * scamin .EQ. zero ) THEN
  416
  417                     buf = buf*2.e0**exponent( scaloc )
  418                     DO jj = 1, nbb
  419                        DO ll = 1, nba
  420                        swork( ll, jj ) = min( bignum,
  421     $                     swork( ll, jj ) / 2.e0**exponent( scaloc ) )
  422                        END DO
  423                     END DO
  424                     scamin = scamin / 2.e0**exponent( scaloc )
  425                     scaloc = scaloc / 2.e0**exponent( scaloc )
  426                  END IF
  427                  cnrm = cnrm * scaloc
  428                  xnrm = xnrm * scaloc
  429
  430
  431
  432
  433                  scal = ( scamin / swork( k, l ) ) * scaloc
  434                  IF( scal.NE.one ) THEN
  435                      DO jj = l1, l2-1
  436                         CALL csscal( k2-k1, scal, c( k1, jj ), 1)
 
  437                      END DO
  438                  ENDIF
  439
  440                  scal = ( scamin / swork( i, l ) ) * scaloc
  441                  IF( scal.NE.one ) THEN
  442                      DO ll = l1, l2-1
  443                         CALL csscal( i2-i1, scal, c( i1, ll ), 1)
 
  444                      END DO
  445                  ENDIF
  446
  447
  448
  449                  swork( k, l ) = scamin * scaloc
  450                  swork( i, l ) = scamin * scaloc
  451
  452                  CALL cgemm( 
'N', 
'N', i2-i1, l2-l1, k2-k1, -cone,
 
  453     $                        a( i1, k1 ), lda, c( k1, l1 ), ldc,
  454     $                        cone, c( i1, l1 ), ldc )
  455
  456               END DO
  457
  458               DO j = l + 1, nbb
  459
  460
  461
  462                  j1 = (j - 1) * nb + 1
  463                  j2 = min( j * nb, n ) + 1
  464
  465
  466
  467
  468                  cnrm = 
clange( 
'I', k2-k1, j2-j1, c( k1, j1 ),
 
  469     $                           ldc, wnrm )
  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 = 
slarmm( bnrm, xnrm, cnrm )
 
  475                  IF( scaloc * scamin .EQ. zero ) THEN
  476
  477                     buf = buf*2.e0**exponent( scaloc )
  478                     DO jj = 1, nbb
  479                        DO ll = 1, nba
  480                        swork( ll, jj ) = min( bignum,
  481     $                     swork( ll, jj ) / 2.e0**exponent( scaloc ) )
  482                        END DO
  483                     END DO
  484                     scamin = scamin / 2.e0**exponent( scaloc )
  485                     scaloc = scaloc / 2.e0**exponent( scaloc )
  486                  END IF
  487                  cnrm = cnrm * scaloc
  488                  xnrm = xnrm * scaloc
  489
  490
  491
  492
  493                  scal = ( scamin / swork( k, l ) ) * scaloc
  494                  IF( scal .NE. one ) THEN
  495                     DO ll = l1, l2-1
  496                        CALL csscal( k2-k1, scal, c( k1, ll ), 1 )
 
  497                     END DO
  498                  ENDIF
  499
  500                  scal = ( scamin / swork( k, j ) ) * scaloc
  501                  IF( scal .NE. one ) THEN
  502                      DO jj = j1, j2-1
  503                         CALL csscal( k2-k1, scal, c( k1, jj ), 1 )
 
  504                      END DO
  505                  ENDIF
  506
  507
  508
  509                  swork( k, l ) = scamin * scaloc
  510                  swork( k, j ) = scamin * scaloc
  511
  512                  CALL cgemm( 
'N', 
'N', k2-k1, j2-j1, l2-l1, -csgn,
 
  513     $                        c( k1, l1 ), ldc, b( l1, j1 ), ldb,
  514     $                        cone, c( k1, j1 ), ldc )
  515               END DO
  516            END DO
  517         END DO
  518      ELSE IF( .NOT.notrna .AND. notrnb ) THEN
  519
  520
  521
  522
  523
  524
  525
  526
  527
  528
  529
  530
  531
  532
  533
  534         DO k = 1, nba
  535
  536
  537
  538
  539
  540            k1 = (k - 1) * nb + 1
  541            k2 = min( k * nb, m ) + 1
  542            DO l = 1, nbb
  543
  544
  545
  546
  547
  548               l1 = (l - 1) * nb + 1
  549               l2 = min( l * nb, n ) + 1
  550
  551               CALL ctrsyl( trana, tranb, isgn, k2-k1, l2-l1,
 
  552     $                      a( k1, k1 ), lda,
  553     $                      b( l1, l1 ), ldb,
  554     $                      c( k1, l1 ), ldc, scaloc, iinfo )
  555               info = max( info, iinfo )
  556
  557               IF( scaloc * swork( k, l ) .EQ. zero ) THEN
  558                  IF( scaloc .EQ. zero ) THEN
  559
  560
  561
  562
  563                     buf = zero
  564                  ELSE
  565
  566                     buf = buf*2.e0**exponent( scaloc )
  567                  END IF
  568                  DO jj = 1, nbb
  569                     DO ll = 1, nba
  570
  571
  572
  573                        swork( ll, jj ) = min( bignum,
  574     $                     swork( ll, jj ) / 2.e0**exponent( scaloc ) )
  575                     END DO
  576                  END DO
  577               END IF
  578               swork( k, l ) = scaloc * swork( k, l )
  579               xnrm = 
clange( 
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
 
  580     $                        wnrm )
  581
  582               DO i = k + 1, nba
  583
  584
  585
  586                  i1 = (i - 1) * nb + 1
  587                  i2 = min( i * nb, m ) + 1
  588
  589
  590
  591
  592                  cnrm = 
clange( 
'I', i2-i1, l2-l1, c( i1, l1 ),
 
  593     $                           ldc, wnrm )
  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 = 
slarmm( anrm, xnrm, cnrm )
 
  599                  IF( scaloc * scamin .EQ. zero ) THEN
  600
  601                     buf = buf*2.e0**exponent( scaloc )
  602                     DO jj = 1, nbb
  603                        DO ll = 1, nba
  604                        swork( ll, jj ) = min( bignum,
  605     $                     swork( ll, jj ) / 2.e0**exponent( scaloc ) )
  606                        END DO
  607                     END DO
  608                     scamin = scamin / 2.e0**exponent( scaloc )
  609                     scaloc = scaloc / 2.e0**exponent( scaloc )
  610                  END IF
  611                  cnrm = cnrm * scaloc
  612                  xnrm = xnrm * scaloc
  613
  614
  615
  616
  617                  scal = ( scamin / swork( k, l ) ) * scaloc
  618                  IF( scal .NE. one ) THEN
  619                     DO ll = l1, l2-1
  620                        CALL csscal( k2-k1, scal, c( k1, ll ), 1 )
 
  621                     END DO
  622                  ENDIF
  623
  624                  scal = ( scamin / swork( i, l ) ) * scaloc
  625                  IF( scal .NE. one ) THEN
  626                     DO ll = l1, l2-1
  627                        CALL csscal( i2-i1, scal, c( i1, ll ), 1 )
 
  628                     END DO
  629                  ENDIF
  630
  631
  632
  633                  swork( k, l ) = scamin * scaloc
  634                  swork( i, l ) = scamin * scaloc
  635
  636                  CALL cgemm( 
'C', 
'N', i2-i1, l2-l1, k2-k1, -cone,
 
  637     $                        a( k1, i1 ), lda, c( k1, l1 ), ldc,
  638     $                        cone, c( i1, l1 ), ldc )
  639               END DO
  640
  641               DO j = l + 1, nbb
  642
  643
  644
  645                  j1 = (j - 1) * nb + 1
  646                  j2 = min( j * nb, n ) + 1
  647
  648
  649
  650
  651                  cnrm = 
clange( 
'I', k2-k1, j2-j1, c( k1, j1 ),
 
  652     $                           ldc, wnrm )
  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 = 
slarmm( bnrm, xnrm, cnrm )
 
  658                  IF( scaloc * scamin .EQ. zero ) THEN
  659
  660                     buf = buf*2.e0**exponent( scaloc )
  661                     DO jj = 1, nbb
  662                        DO ll = 1, nba
  663                        swork( ll, jj ) = min( bignum,
  664     $                     swork( ll, jj ) / 2.e0**exponent( scaloc ) )
  665                        END DO
  666                     END DO
  667                     scamin = scamin / 2.e0**exponent( scaloc )
  668                     scaloc = scaloc / 2.e0**exponent( scaloc )
  669                  END IF
  670                  cnrm = cnrm * scaloc
  671                  xnrm = xnrm * scaloc
  672
  673
  674
  675
  676                  scal = ( scamin / swork( k, l ) ) * scaloc
  677                  IF( scal .NE. one ) THEN
  678                      DO ll = l1, l2-1
  679                         CALL csscal( k2-k1, scal, c( k1, ll ), 1 )
 
  680                      END DO
  681                  ENDIF
  682
  683                  scal = ( scamin / swork( k, j ) ) * scaloc
  684                  IF( scal .NE. one ) THEN
  685                     DO jj = j1, j2-1
  686                        CALL csscal( k2-k1, scal, c( k1, jj ), 1 )
 
  687                     END DO
  688                  ENDIF
  689
  690
  691
  692                  swork( k, l ) = scamin * scaloc
  693                  swork( k, j ) = scamin * scaloc
  694
  695                  CALL cgemm( 
'N', 
'N', k2-k1, j2-j1, l2-l1, -csgn,
 
  696     $                        c( k1, l1 ), ldc, b( l1, j1 ), ldb,
  697     $                        cone, c( k1, j1 ), ldc )
  698               END DO
  699            END DO
  700         END DO
  701      ELSE IF( .NOT.notrna .AND. .NOT.notrnb ) THEN
  702
  703
  704
  705
  706
  707
  708
  709
  710
  711
  712
  713
  714
  715
  716
  717         DO k = 1, nba
  718
  719
  720
  721
  722
  723            k1 = (k - 1) * nb + 1
  724            k2 = min( k * nb, m ) + 1
  725            DO l = nbb, 1, -1
  726
  727
  728
  729
  730
  731               l1 = (l - 1) * nb + 1
  732               l2 = min( l * nb, n ) + 1
  733
  734               CALL ctrsyl( trana, tranb, isgn, k2-k1, l2-l1,
 
  735     $                      a( k1, k1 ), lda,
  736     $                      b( l1, l1 ), ldb,
  737     $                      c( k1, l1 ), ldc, scaloc, iinfo )
  738               info = max( info, iinfo )
  739
  740               IF( scaloc * swork( k, l ) .EQ. zero ) THEN
  741                  IF( scaloc .EQ. zero ) THEN
  742
  743
  744
  745
  746                     buf = zero
  747                  ELSE
  748
  749                     buf = buf*2.e0**exponent( scaloc )
  750                  END IF
  751                  DO jj = 1, nbb
  752                     DO ll = 1, nba
  753
  754
  755
  756                        swork( ll, jj ) = min( bignum,
  757     $                     swork( ll, jj ) / 2.e0**exponent( scaloc ) )
  758                     END DO
  759                  END DO
  760               END IF
  761               swork( k, l ) = scaloc * swork( k, l )
  762               xnrm = 
clange( 
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
 
  763     $                        wnrm )
  764
  765               DO i = k + 1, nba
  766
  767
  768
  769                  i1 = (i - 1) * nb + 1
  770                  i2 = min( i * nb, m ) + 1
  771
  772
  773
  774
  775                  cnrm = 
clange( 
'I', i2-i1, l2-l1, c( i1, l1 ),
 
  776     $                           ldc, wnrm )
  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 = 
slarmm( anrm, xnrm, cnrm )
 
  782                  IF( scaloc * scamin .EQ. zero ) THEN
  783
  784                     buf = buf*2.e0**exponent( scaloc )
  785                     DO jj = 1, nbb
  786                        DO ll = 1, nba
  787                        swork( ll, jj ) = min( bignum,
  788     $                     swork( ll, jj ) / 2.e0**exponent( scaloc ) )
  789                        END DO
  790                     END DO
  791                     scamin = scamin / 2.e0**exponent( scaloc )
  792                     scaloc = scaloc / 2.e0**exponent( scaloc )
  793                  END IF
  794                  cnrm = cnrm * scaloc
  795                  xnrm = xnrm * scaloc
  796
  797
  798
  799
  800                  scal = ( scamin / swork( k, l ) ) * scaloc
  801                  IF( scal .NE. one ) THEN
  802                     DO ll = l1, l2-1
  803                        CALL csscal( k2-k1, scal, c( k1, ll ), 1 )
 
  804                     END DO
  805                  ENDIF
  806
  807                  scal = ( scamin / swork( i, l ) ) * scaloc
  808                  IF( scal .NE. one ) THEN
  809                     DO ll = l1, l2-1
  810                        CALL csscal( i2-i1, scal, c( i1, ll ), 1 )
 
  811                     END DO
  812                  ENDIF
  813
  814
  815
  816                  swork( k, l ) = scamin * scaloc
  817                  swork( i, l ) = scamin * scaloc
  818
  819                  CALL cgemm( 
'C', 
'N', i2-i1, l2-l1, k2-k1, -cone,
 
  820     $                        a( k1, i1 ), lda, c( k1, l1 ), ldc,
  821     $                        cone, c( i1, l1 ), ldc )
  822               END DO
  823
  824               DO j = 1, l - 1
  825
  826
  827
  828                  j1 = (j - 1) * nb + 1
  829                  j2 = min( j * nb, n ) + 1
  830
  831
  832
  833
  834                  cnrm = 
clange( 
'I', k2-k1, j2-j1, c( k1, j1 ),
 
  835     $                           ldc, wnrm )
  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 = 
slarmm( bnrm, xnrm, cnrm )
 
  841                  IF( scaloc * scamin .EQ. zero ) THEN
  842
  843                     buf = buf*2.e0**exponent( scaloc )
  844                     DO jj = 1, nbb
  845                        DO ll = 1, nba
  846                        swork( ll, jj ) = min( bignum,
  847     $                     swork( ll, jj ) / 2.e0**exponent( scaloc ) )
  848                        END DO
  849                     END DO
  850                     scamin = scamin / 2.e0**exponent( scaloc )
  851                     scaloc = scaloc / 2.e0**exponent( scaloc )
  852                  END IF
  853                  cnrm = cnrm * scaloc
  854                  xnrm = xnrm * scaloc
  855
  856
  857
  858
  859                  scal = ( scamin / swork( k, l ) ) * scaloc
  860                  IF( scal .NE. one ) THEN
  861                     DO ll = l1, l2-1
  862                        CALL csscal( k2-k1, scal, c( k1, ll ), 1)
 
  863                     END DO
  864                  ENDIF
  865
  866                  scal = ( scamin / swork( k, j ) ) * scaloc
  867                  IF( scal .NE. one ) THEN
  868                     DO jj = j1, j2-1
  869                        CALL csscal( k2-k1, scal, c( k1, jj ), 1 )
 
  870                     END DO
  871                  ENDIF
  872
  873
  874
  875                  swork( k, l ) = scamin * scaloc
  876                  swork( k, j ) = scamin * scaloc
  877
  878                  CALL cgemm( 
'N', 
'C', k2-k1, j2-j1, l2-l1, -csgn,
 
  879     $                        c( k1, l1 ), ldc, b( j1, l1 ), ldb,
  880     $                        cone, c( k1, j1 ), ldc )
  881               END DO
  882            END DO
  883         END DO
  884      ELSE IF( notrna .AND. .NOT.notrnb ) THEN
  885
  886
  887
  888
  889
  890
  891
  892
  893
  894
  895
  896
  897
  898
  899
  900         DO k = nba, 1, -1
  901
  902
  903
  904
  905
  906            k1 = (k - 1) * nb + 1
  907            k2 = min( k * nb, m ) + 1
  908            DO l = nbb, 1, -1
  909
  910
  911
  912
  913
  914               l1 = (l - 1) * nb + 1
  915               l2 = min( l * nb, n ) + 1
  916
  917               CALL ctrsyl( trana, tranb, isgn, k2-k1, l2-l1,
 
  918     $                      a( k1, k1 ), lda,
  919     $                      b( l1, l1 ), ldb,
  920     $                      c( k1, l1 ), ldc, scaloc, iinfo )
  921               info = max( info, iinfo )
  922
  923               IF( scaloc * swork( k, l ) .EQ. zero ) THEN
  924                  IF( scaloc .EQ. zero ) THEN
  925
  926
  927
  928
  929                     buf = zero
  930                  ELSE
  931
  932                     buf = buf*2.e0**exponent( scaloc )
  933                  END IF
  934                  DO jj = 1, nbb
  935                     DO ll = 1, nba
  936
  937
  938
  939                        swork( ll, jj ) = min( bignum,
  940     $                     swork( ll, jj ) / 2.e0**exponent( scaloc ) )
  941                     END DO
  942                  END DO
  943               END IF
  944               swork( k, l ) = scaloc * swork( k, l )
  945               xnrm = 
clange( 
'I', k2-k1, l2-l1, c( k1, l1 ), ldc,
 
  946     $                        wnrm )
  947
  948               DO i = 1, k - 1
  949
  950
  951
  952                  i1 = (i - 1) * nb + 1
  953                  i2 = min( i * nb, m ) + 1
  954
  955
  956
  957
  958                  cnrm = 
clange( 
'I', i2-i1, l2-l1, c( i1, l1 ),
 
  959     $                           ldc, wnrm )
  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 = 
slarmm( anrm, xnrm, cnrm )
 
  965                  IF( scaloc * scamin .EQ. zero ) THEN
  966
  967                     buf = buf*2.e0**exponent( scaloc )
  968                     DO jj = 1, nbb
  969                        DO ll = 1, nba
  970                        swork( ll, jj ) = min( bignum,
  971     $                     swork( ll, jj ) / 2.e0**exponent( scaloc ) )
  972                        END DO
  973                     END DO
  974                     scamin = scamin / 2.e0**exponent( scaloc )
  975                     scaloc = scaloc / 2.e0**exponent( scaloc )
  976                  END IF
  977                  cnrm = cnrm * scaloc
  978                  xnrm = xnrm * scaloc
  979
  980
  981
  982
  983                  scal = ( scamin / swork( k, l ) ) * scaloc
  984                  IF( scal .NE. one ) THEN
  985                     DO ll = l1, l2-1
  986                        CALL csscal( k2-k1, scal, c( k1, ll ), 1 )
 
  987                     END DO
  988                  ENDIF
  989
  990                  scal = ( scamin / swork( i, l ) ) * scaloc
  991                  IF( scal .NE. one ) THEN
  992                     DO ll = l1, l2-1
  993                        CALL csscal( i2-i1, scal, c( i1, ll ), 1 )
 
  994                     END DO
  995                  ENDIF
  996
  997
  998
  999                  swork( k, l ) = scamin * scaloc
 1000                  swork( i, l ) = scamin * scaloc
 1001
 1002                  CALL cgemm( 
'N', 
'N', i2-i1, l2-l1, k2-k1, -cone,
 
 1003     $                        a( i1, k1 ), lda, c( k1, l1 ), ldc,
 1004     $                        cone, c( i1, l1 ), ldc )
 1005
 1006               END DO
 1007
 1008               DO j = 1, l - 1
 1009
 1010
 1011
 1012                  j1 = (j - 1) * nb + 1
 1013                  j2 = min( j * nb, n ) + 1
 1014
 1015
 1016
 1017
 1018                  cnrm = 
clange( 
'I', k2-k1, j2-j1, c( k1, j1 ),
 
 1019     $                           ldc, wnrm )
 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 = 
slarmm( bnrm, xnrm, cnrm )
 
 1025                  IF( scaloc * scamin .EQ. zero ) THEN
 1026
 1027                     buf = buf*2.e0**exponent( scaloc )
 1028                     DO jj = 1, nbb
 1029                        DO ll = 1, nba
 1030                        swork( ll, jj ) = min( bignum,
 1031     $                     swork( ll, jj ) / 2.e0**exponent( scaloc ) )
 1032                        END DO
 1033                     END DO
 1034                     scamin = scamin / 2.e0**exponent( scaloc )
 1035                     scaloc = scaloc / 2.e0**exponent( scaloc )
 1036                  END IF
 1037                  cnrm = cnrm * scaloc 
 1038                  xnrm = xnrm * scaloc
 1039
 1040
 1041
 1042
 1043                  scal = ( scamin / swork( k, l ) ) * scaloc
 1044                  IF( scal .NE. one ) THEN
 1045                     DO jj = l1, l2-1
 1046                        CALL csscal( k2-k1, scal, c( k1, jj ), 1 )
 
 1047                     END DO
 1048                  ENDIF
 1049
 1050                  scal = ( scamin / swork( k, j ) ) * scaloc
 1051                  IF( scal .NE. one ) THEN
 1052                     DO jj = j1, j2-1
 1053                        CALL csscal( k2-k1, scal, c( k1, jj ), 1 )
 
 1054                     END DO
 1055                  ENDIF
 1056
 1057
 1058
 1059                  swork( k, l ) = scamin * scaloc
 1060                  swork( k, j ) = scamin * scaloc
 1061
 1062                  CALL cgemm( 
'N', 
'C', k2-k1, j2-j1, l2-l1, -csgn,
 
 1063     $                        c( k1, l1 ), ldc, b( j1, l1 ), ldb,
 1064     $                        cone, c( k1, j1 ), ldc )
 1065               END DO
 1066            END DO
 1067         END DO
 1068
 1069      END IF
 1070
 1071
 1072
 1073      scale = swork( 1, 1 )
 1074      DO k = 1, nba
 1075         DO l = 1, nbb
 1076            scale = min( scale, swork( k, l ) )
 1077         END DO
 1078      END DO
 1079      IF( scale .EQ. zero ) THEN
 1080
 1081
 1082
 1083
 1084
 1085
 1086         swork(1,1) = real( max( nba, nbb ) )
 1087         swork(2,1) = real( 2 * nbb + nba )
 1088         RETURN
 1089      END IF
 1090
 1091
 1092
 1093      DO k = 1, nba
 1094         k1 = (k - 1) * nb + 1
 1095         k2 = min( k * nb, m ) + 1
 1096         DO l = 1, nbb
 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
 1101               DO ll = l1, l2-1
 1102                  CALL csscal( k2-k1, scal, c( k1, ll ), 1 )
 
 1103               END DO
 1104            ENDIF
 1105         END DO
 1106      END DO
 1107
 1108      IF( buf .NE. one .AND. buf.GT.zero ) THEN
 1109
 1110
 1111
 1112         scaloc = min( scale / smlnum, one / buf )
 1113         buf = buf * scaloc
 1114         scale = scale / scaloc
 1115      END IF
 1116
 1117      IF( buf.NE.one .AND. buf.GT.zero ) THEN
 1118
 1119
 1120
 1121
 1122
 1123
 1124
 1125
 1126
 1127         scal = max( abs( real( c( 1, 1 ) ) ),
 1128     $               abs( aimag( c( 1, 1 ) ) ) )
 1129         DO k = 1, m
 1130            DO l = 1, n
 1131               scal = max( scal, abs( real( c( k, l ) ) ),
 1132     $                     abs( aimag( c( k, l ) ) ) )
 1133            END DO
 1134         END DO
 1135
 1136
 1137
 1138         scaloc = min( bignum / scal, one / buf )
 1139         buf = buf * scaloc
 1140         CALL clascl( 
'G', -1, -1, one, scaloc, m, n, c, ldc, iinfo )
 
 1141      END IF
 1142
 1143
 1144
 1145
 1146      scale = scale * buf
 1147
 1148
 1149
 1150      swork(1,1) = real( max( nba, nbb ) )
 1151      swork(2,1) = real( 2 * nbb + nba )
 1152
 1153      RETURN
 1154
 1155
 1156
subroutine xerbla(srname, info)
 
subroutine cgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
CGEMM
 
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
 
real function slamch(cmach)
SLAMCH
 
real function clange(norm, m, n, a, lda, work)
CLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
 
real function slarmm(anorm, bnorm, cnorm)
SLARMM
 
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.
 
logical function lsame(ca, cb)
LSAME
 
subroutine csscal(n, sa, cx, incx)
CSSCAL
 
subroutine ctrsyl(trana, tranb, isgn, m, n, a, lda, b, ldb, c, ldc, scale, info)
CTRSYL