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