156 IMPLICIT NONE
157
158
159 CHARACTER TRANA, TRANB
160 INTEGER INFO, ISGN, LDA, LDB, LDC, LDSWORK, M, N
161 REAL SCALE
162
163
164 COMPLEX A( LDA, * ), B( LDB, * ), C( LDC, * )
165 REAL SWORK( LDSWORK, * )
166
167
168 REAL ZERO, ONE
169 parameter( zero = 0.0e+0, one = 1.0e+0 )
170 COMPLEX CONE
171 parameter( cone = ( 1.0e+0, 0.0e+0 ) )
172
173
174 LOGICAL NOTRNA, NOTRNB, LQUERY
175 INTEGER AWRK, BWRK, I, I1, I2, IINFO, J, J1, J2, JJ,
176 $ K, K1, K2, L, L1, L2, LL, NBA, NB, NBB
177 REAL ANRM, BIGNUM, BNRM, CNRM, SCAL, SCALOC,
178 $ SCAMIN, SGN, XNRM, BUF, SMLNUM
179 COMPLEX CSGN
180
181
182 REAL WNRM( MAX( M, N ) )
183
184
185 LOGICAL LSAME
186 INTEGER ILAENV
187 REAL CLANGE, SLAMCH, SLARMM
189
190
192
193
194 INTRINSIC abs, aimag, exponent, max, min, real
195
196
197
198
199
200 notrna =
lsame( trana,
'N' )
201 notrnb =
lsame( tranb,
'N' )
202
203
204
205 nb = max( 8,
ilaenv( 1,
'CTRSYL',
'', m, n, -1, -1) )
206
207
208
209 nba = max( 1, (m + nb - 1) / nb )
210 nbb = max( 1, (n + nb - 1) / nb )
211
212
213
214 info = 0
215 lquery = ( ldswork.EQ.-1 )
216 IF( lquery ) THEN
217 ldswork = 2
218 swork(1,1) = max( nba, nbb )
219 swork(2,1) = 2 * nbb + nba
220 END IF
221
222
223
224 IF( .NOT.notrna .AND. .NOT.
lsame( trana,
'C' ) )
THEN
225 info = -1
226 ELSE IF( .NOT.notrnb .AND. .NOT.
lsame( tranb,
'C' ) )
THEN
227 info = -2
228 ELSE IF( isgn.NE.1 .AND. isgn.NE.-1 ) THEN
229 info = -3
230 ELSE IF( m.LT.0 ) THEN
231 info = -4
232 ELSE IF( n.LT.0 ) THEN
233 info = -5
234 ELSE IF( lda.LT.max( 1, m ) ) THEN
235 info = -7
236 ELSE IF( ldb.LT.max( 1, n ) ) THEN
237 info = -9
238 ELSE IF( ldc.LT.max( 1, m ) ) THEN
239 info = -11
240 END IF
241 IF( info.NE.0 ) THEN
242 CALL xerbla(
'CTRSYL3', -info )
243 RETURN
244 ELSE IF( lquery ) THEN
245 RETURN
246 END IF
247
248
249
250 scale = one
251 IF( m.EQ.0 .OR. n.EQ.0 )
252 $ RETURN
253
254
255
256
257 IF( min( nba, nbb ).EQ.1 .OR. ldswork.LT.max( nba, nbb ) ) THEN
258 CALL ctrsyl( trana, tranb, isgn, m, n, a, lda, b, ldb,
259 $ c, ldc, scale, info )
260 RETURN
261 END IF
262
263
264
266 bignum = one / smlnum
267
268
269
270 DO l = 1, nbb
271 DO k = 1, nba
272 swork( k, l ) = one
273 END DO
274 END DO
275
276
277
278
279 buf = one
280
281
282
283 awrk = nbb
284 DO k = 1, nba
285 k1 = (k - 1) * nb + 1
286 k2 = min( k * nb, m ) + 1
287 DO l = k, nba
288 l1 = (l - 1) * nb + 1
289 l2 = min( l * nb, m ) + 1
290 IF( notrna ) THEN
291 swork( k, awrk + l ) =
clange(
'I', k2-k1, l2-l1,
292 $ a( k1, l1 ), lda, wnrm )
293 ELSE
294 swork( l, awrk + k ) =
clange(
'1', k2-k1, l2-l1,
295 $ a( k1, l1 ), lda, wnrm )
296 END IF
297 END DO
298 END DO
299 bwrk = nbb + nba
300 DO k = 1, nbb
301 k1 = (k - 1) * nb + 1
302 k2 = min( k * nb, n ) + 1
303 DO l = k, nbb
304 l1 = (l - 1) * nb + 1
305 l2 = min( l * nb, n ) + 1
306 IF( notrnb ) THEN
307 swork( k, bwrk + l ) =
clange(
'I', k2-k1, l2-l1,
308 $ b( k1, l1 ), ldb, wnrm )
309 ELSE
310 swork( l, bwrk + k ) =
clange(
'1', k2-k1, l2-l1,
311 $ b( k1, l1 ), ldb, wnrm )
312 END IF
313 END DO
314 END DO
315
316 sgn = real( isgn )
317 csgn = cmplx( sgn, zero )
318
319 IF( notrna .AND. notrnb ) THEN
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335 DO k = nba, 1, -1
336
337
338
339
340
341 k1 = (k - 1) * nb + 1
342 k2 = min( k * nb, m ) + 1
343 DO l = 1, nbb
344
345
346
347
348
349 l1 = (l - 1) * nb + 1
350 l2 = min( l * nb, n ) + 1
351
352 CALL ctrsyl( trana, tranb, isgn, k2-k1, l2-l1,
353 $ a( k1, k1 ), lda,
354 $ b( l1, l1 ), ldb,
355 $ c( k1, l1 ), ldc, scaloc, iinfo )
356 info = max( info, iinfo )
357
358 IF( scaloc * swork( k, l ) .EQ. zero ) THEN
359 IF( scaloc .EQ. zero ) THEN
360
361
362
363
364 buf = zero
365 ELSE
366
367 buf = buf*2.e0**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.e0**exponent( scaloc ) )
376 END DO
377 END DO
378 END IF
379 swork( k, l ) = scaloc * swork( k, l )
380 xnrm =
clange(
'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 =
clange(
'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 =
slarmm( anrm, xnrm, cnrm )
400 IF( scaloc * scamin .EQ. zero ) THEN
401
402 buf = buf*2.e0**exponent( scaloc )
403 DO jj = 1, nbb
404 DO ll = 1, nba
405 swork( ll, jj ) = min( bignum,
406 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
407 END DO
408 END DO
409 scamin = scamin / 2.e0**exponent( scaloc )
410 scaloc = scaloc / 2.e0**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 csscal( 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 csscal( 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 cgemm(
'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 =
clange(
'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 =
slarmm( bnrm, xnrm, cnrm )
460 IF( scaloc * scamin .EQ. zero ) THEN
461
462 buf = buf*2.e0**exponent( scaloc )
463 DO jj = 1, nbb
464 DO ll = 1, nba
465 swork( ll, jj ) = min( bignum,
466 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
467 END DO
468 END DO
469 scamin = scamin / 2.e0**exponent( scaloc )
470 scaloc = scaloc / 2.e0**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 csscal( 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 csscal( 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 cgemm(
'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 ctrsyl( 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.e0**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.e0**exponent( scaloc ) )
560 END DO
561 END DO
562 END IF
563 swork( k, l ) = scaloc * swork( k, l )
564 xnrm =
clange(
'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 =
clange(
'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 =
slarmm( anrm, xnrm, cnrm )
584 IF( scaloc * scamin .EQ. zero ) THEN
585
586 buf = buf*2.e0**exponent( scaloc )
587 DO jj = 1, nbb
588 DO ll = 1, nba
589 swork( ll, jj ) = min( bignum,
590 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
591 END DO
592 END DO
593 scamin = scamin / 2.e0**exponent( scaloc )
594 scaloc = scaloc / 2.e0**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 csscal( 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 csscal( 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 cgemm(
'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 =
clange(
'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 =
slarmm( bnrm, xnrm, cnrm )
643 IF( scaloc * scamin .EQ. zero ) THEN
644
645 buf = buf*2.e0**exponent( scaloc )
646 DO jj = 1, nbb
647 DO ll = 1, nba
648 swork( ll, jj ) = min( bignum,
649 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
650 END DO
651 END DO
652 scamin = scamin / 2.e0**exponent( scaloc )
653 scaloc = scaloc / 2.e0**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 csscal( 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 csscal( 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 cgemm(
'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 ctrsyl( 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.e0**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.e0**exponent( scaloc ) )
743 END DO
744 END DO
745 END IF
746 swork( k, l ) = scaloc * swork( k, l )
747 xnrm =
clange(
'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 =
clange(
'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 =
slarmm( anrm, xnrm, cnrm )
767 IF( scaloc * scamin .EQ. zero ) THEN
768
769 buf = buf*2.e0**exponent( scaloc )
770 DO jj = 1, nbb
771 DO ll = 1, nba
772 swork( ll, jj ) = min( bignum,
773 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
774 END DO
775 END DO
776 scamin = scamin / 2.e0**exponent( scaloc )
777 scaloc = scaloc / 2.e0**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 csscal( 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 csscal( 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 cgemm(
'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 =
clange(
'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 =
slarmm( bnrm, xnrm, cnrm )
826 IF( scaloc * scamin .EQ. zero ) THEN
827
828 buf = buf*2.e0**exponent( scaloc )
829 DO jj = 1, nbb
830 DO ll = 1, nba
831 swork( ll, jj ) = min( bignum,
832 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
833 END DO
834 END DO
835 scamin = scamin / 2.e0**exponent( scaloc )
836 scaloc = scaloc / 2.e0**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 csscal( 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 csscal( 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 cgemm(
'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 ctrsyl( 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.e0**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.e0**exponent( scaloc ) )
926 END DO
927 END DO
928 END IF
929 swork( k, l ) = scaloc * swork( k, l )
930 xnrm =
clange(
'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 =
clange(
'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 =
slarmm( anrm, xnrm, cnrm )
950 IF( scaloc * scamin .EQ. zero ) THEN
951
952 buf = buf*2.e0**exponent( scaloc )
953 DO jj = 1, nbb
954 DO ll = 1, nba
955 swork( ll, jj ) = min( bignum,
956 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
957 END DO
958 END DO
959 scamin = scamin / 2.e0**exponent( scaloc )
960 scaloc = scaloc / 2.e0**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 csscal( 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 csscal( 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 cgemm(
'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 =
clange(
'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 =
slarmm( bnrm, xnrm, cnrm )
1010 IF( scaloc * scamin .EQ. zero ) THEN
1011
1012 buf = buf*2.e0**exponent( scaloc )
1013 DO jj = 1, nbb
1014 DO ll = 1, nba
1015 swork( ll, jj ) = min( bignum,
1016 $ swork( ll, jj ) / 2.e0**exponent( scaloc ) )
1017 END DO
1018 END DO
1019 scamin = scamin / 2.e0**exponent( scaloc )
1020 scaloc = scaloc / 2.e0**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 csscal( 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 csscal( 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 cgemm(
'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 csscal( 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( real( c( 1, 1 ) ) ),
1113 $ abs( aimag( c( 1, 1 ) ) ) )
1114 DO k = 1, m
1115 DO l = 1, n
1116 scal = max( scal, abs( real( c( k, l ) ) ),
1117 $ abs( aimag( 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 clascl(
'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 cgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
CGEMM
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
real function slamch(cmach)
SLAMCH
real function clange(norm, m, n, a, lda, work)
CLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
real function slarmm(anorm, bnorm, cnorm)
SLARMM
subroutine clascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
CLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
logical function lsame(ca, cb)
LSAME
subroutine csscal(n, sa, cx, incx)
CSSCAL
subroutine ctrsyl(trana, tranb, isgn, m, n, a, lda, b, ldb, c, ldc, scale, info)
CTRSYL