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