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