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