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