277
278
279
280
281
282
283 CHARACTER TRANSR, DIAG, SIDE, TRANS, UPLO
284 INTEGER LDB, M, N
285 REAL ALPHA
286
287
288 REAL A( 0: * ), B( 0: LDB-1, 0: * )
289
290
291
292
293
294
295 REAL ONE, ZERO
296 parameter( one = 1.0e+0, zero = 0.0e+0 )
297
298
299 LOGICAL LOWER, LSIDE, MISODD, NISODD, NORMALTRANSR,
300 $ NOTRANS
301 INTEGER M1, M2, N1, N2, K, INFO, I, J
302
303
304 LOGICAL LSAME
306
307
309
310
311 INTRINSIC max, mod
312
313
314
315
316
317 info = 0
318 normaltransr =
lsame( transr,
'N' )
319 lside =
lsame( side,
'L' )
320 lower =
lsame( uplo,
'L' )
321 notrans =
lsame( trans,
'N' )
322 IF( .NOT.normaltransr .AND. .NOT.
lsame( transr,
'T' ) )
THEN
323 info = -1
324 ELSE IF( .NOT.lside .AND. .NOT.
lsame( side,
'R' ) )
THEN
325 info = -2
326 ELSE IF( .NOT.lower .AND. .NOT.
lsame( uplo,
'U' ) )
THEN
327 info = -3
328 ELSE IF( .NOT.notrans .AND. .NOT.
lsame( trans,
'T' ) )
THEN
329 info = -4
330 ELSE IF( .NOT.
lsame( diag,
'N' ) .AND.
331 $ .NOT.
lsame( diag,
'U' ) )
332 $ THEN
333 info = -5
334 ELSE IF( m.LT.0 ) THEN
335 info = -6
336 ELSE IF( n.LT.0 ) THEN
337 info = -7
338 ELSE IF( ldb.LT.max( 1, m ) ) THEN
339 info = -11
340 END IF
341 IF( info.NE.0 ) THEN
342 CALL xerbla(
'STFSM ', -info )
343 RETURN
344 END IF
345
346
347
348 IF( ( m.EQ.0 ) .OR. ( n.EQ.0 ) )
349 $ RETURN
350
351
352
353 IF( alpha.EQ.zero ) THEN
354 DO 20 j = 0, n - 1
355 DO 10 i = 0, m - 1
356 b( i, j ) = zero
357 10 CONTINUE
358 20 CONTINUE
359 RETURN
360 END IF
361
362 IF( lside ) THEN
363
364
365
366
367
368
369
370 IF( mod( m, 2 ).EQ.0 ) THEN
371 misodd = .false.
372 k = m / 2
373 ELSE
374 misodd = .true.
375 IF( lower ) THEN
376 m2 = m / 2
377 m1 = m - m2
378 ELSE
379 m1 = m / 2
380 m2 = m - m1
381 END IF
382 END IF
383
384 IF( misodd ) THEN
385
386
387
388 IF( normaltransr ) THEN
389
390
391
392 IF( lower ) THEN
393
394
395
396 IF( notrans ) THEN
397
398
399
400
401 IF( m.EQ.1 ) THEN
402 CALL strsm(
'L',
'L',
'N', diag, m1, n,
403 $ alpha,
404 $ a, m, b, ldb )
405 ELSE
406 CALL strsm(
'L',
'L',
'N', diag, m1, n,
407 $ alpha,
408 $ a( 0 ), m, b, ldb )
409 CALL sgemm(
'N',
'N', m2, n, m1, -one,
410 $ a( m1 ),
411 $ m, b, ldb, alpha, b( m1, 0 ), ldb )
412 CALL strsm(
'L',
'U',
'T', diag, m2, n, one,
413 $ a( m ), m, b( m1, 0 ), ldb )
414 END IF
415
416 ELSE
417
418
419
420
421 IF( m.EQ.1 ) THEN
422 CALL strsm(
'L',
'L',
'T', diag, m1, n,
423 $ alpha,
424 $ a( 0 ), m, b, ldb )
425 ELSE
426 CALL strsm(
'L',
'U',
'N', diag, m2, n,
427 $ alpha,
428 $ a( m ), m, b( m1, 0 ), ldb )
429 CALL sgemm(
'T',
'N', m1, n, m2, -one,
430 $ a( m1 ),
431 $ m, b( m1, 0 ), ldb, alpha, b, ldb )
432 CALL strsm(
'L',
'L',
'T', diag, m1, n, one,
433 $ a( 0 ), m, b, ldb )
434 END IF
435
436 END IF
437
438 ELSE
439
440
441
442 IF( .NOT.notrans ) THEN
443
444
445
446
447 CALL strsm(
'L',
'L',
'N', diag, m1, n, alpha,
448 $ a( m2 ), m, b, ldb )
449 CALL sgemm(
'T',
'N', m2, n, m1, -one, a( 0 ),
450 $ m,
451 $ b, ldb, alpha, b( m1, 0 ), ldb )
452 CALL strsm(
'L',
'U',
'T', diag, m2, n, one,
453 $ a( m1 ), m, b( m1, 0 ), ldb )
454
455 ELSE
456
457
458
459
460 CALL strsm(
'L',
'U',
'N', diag, m2, n, alpha,
461 $ a( m1 ), m, b( m1, 0 ), ldb )
462 CALL sgemm(
'N',
'N', m1, n, m2, -one, a( 0 ),
463 $ m,
464 $ b( m1, 0 ), ldb, alpha, b, ldb )
465 CALL strsm(
'L',
'L',
'T', diag, m1, n, one,
466 $ a( m2 ), m, b, ldb )
467
468 END IF
469
470 END IF
471
472 ELSE
473
474
475
476 IF( lower ) THEN
477
478
479
480 IF( notrans ) THEN
481
482
483
484
485 IF( m.EQ.1 ) THEN
486 CALL strsm(
'L',
'U',
'T', diag, m1, n,
487 $ alpha,
488 $ a( 0 ), m1, b, ldb )
489 ELSE
490 CALL strsm(
'L',
'U',
'T', diag, m1, n,
491 $ alpha,
492 $ a( 0 ), m1, b, ldb )
493 CALL sgemm(
'T',
'N', m2, n, m1, -one,
494 $ a( m1*m1 ), m1, b, ldb, alpha,
495 $ b( m1, 0 ), ldb )
496 CALL strsm(
'L',
'L',
'N', diag, m2, n, one,
497 $ a( 1 ), m1, b( m1, 0 ), ldb )
498 END IF
499
500 ELSE
501
502
503
504
505 IF( m.EQ.1 ) THEN
506 CALL strsm(
'L',
'U',
'N', diag, m1, n,
507 $ alpha,
508 $ a( 0 ), m1, b, ldb )
509 ELSE
510 CALL strsm(
'L',
'L',
'T', diag, m2, n,
511 $ alpha,
512 $ a( 1 ), m1, b( m1, 0 ), ldb )
513 CALL sgemm(
'N',
'N', m1, n, m2, -one,
514 $ a( m1*m1 ), m1, b( m1, 0 ), ldb,
515 $ alpha, b, ldb )
516 CALL strsm(
'L',
'U',
'N', diag, m1, n, one,
517 $ a( 0 ), m1, b, ldb )
518 END IF
519
520 END IF
521
522 ELSE
523
524
525
526 IF( .NOT.notrans ) THEN
527
528
529
530
531 CALL strsm(
'L',
'U',
'T', diag, m1, n, alpha,
532 $ a( m2*m2 ), m2, b, ldb )
533 CALL sgemm(
'N',
'N', m2, n, m1, -one, a( 0 ),
534 $ m2,
535 $ b, ldb, alpha, b( m1, 0 ), ldb )
536 CALL strsm(
'L',
'L',
'N', diag, m2, n, one,
537 $ a( m1*m2 ), m2, b( m1, 0 ), ldb )
538
539 ELSE
540
541
542
543
544 CALL strsm(
'L',
'L',
'T', diag, m2, n, alpha,
545 $ a( m1*m2 ), m2, b( m1, 0 ), ldb )
546 CALL sgemm(
'T',
'N', m1, n, m2, -one, a( 0 ),
547 $ m2,
548 $ b( m1, 0 ), ldb, alpha, b, ldb )
549 CALL strsm(
'L',
'U',
'N', diag, m1, n, one,
550 $ a( m2*m2 ), m2, b, ldb )
551
552 END IF
553
554 END IF
555
556 END IF
557
558 ELSE
559
560
561
562 IF( normaltransr ) THEN
563
564
565
566 IF( lower ) THEN
567
568
569
570 IF( notrans ) THEN
571
572
573
574
575 CALL strsm(
'L',
'L',
'N', diag, k, n, alpha,
576 $ a( 1 ), m+1, b, ldb )
577 CALL sgemm(
'N',
'N', k, n, k, -one, a( k+1 ),
578 $ m+1, b, ldb, alpha, b( k, 0 ), ldb )
579 CALL strsm(
'L',
'U',
'T', diag, k, n, one,
580 $ a( 0 ), m+1, b( k, 0 ), ldb )
581
582 ELSE
583
584
585
586
587 CALL strsm(
'L',
'U',
'N', diag, k, n, alpha,
588 $ a( 0 ), m+1, b( k, 0 ), ldb )
589 CALL sgemm(
'T',
'N', k, n, k, -one, a( k+1 ),
590 $ m+1, b( k, 0 ), ldb, alpha, b, ldb )
591 CALL strsm(
'L',
'L',
'T', diag, k, n, one,
592 $ a( 1 ), m+1, b, ldb )
593
594 END IF
595
596 ELSE
597
598
599
600 IF( .NOT.notrans ) THEN
601
602
603
604
605 CALL strsm(
'L',
'L',
'N', diag, k, n, alpha,
606 $ a( k+1 ), m+1, b, ldb )
607 CALL sgemm(
'T',
'N', k, n, k, -one, a( 0 ),
608 $ m+1,
609 $ b, ldb, alpha, b( k, 0 ), ldb )
610 CALL strsm(
'L',
'U',
'T', diag, k, n, one,
611 $ a( k ), m+1, b( k, 0 ), ldb )
612
613 ELSE
614
615
616
617 CALL strsm(
'L',
'U',
'N', diag, k, n, alpha,
618 $ a( k ), m+1, b( k, 0 ), ldb )
619 CALL sgemm(
'N',
'N', k, n, k, -one, a( 0 ),
620 $ m+1,
621 $ b( k, 0 ), ldb, alpha, b, ldb )
622 CALL strsm(
'L',
'L',
'T', diag, k, n, one,
623 $ a( k+1 ), m+1, b, ldb )
624
625 END IF
626
627 END IF
628
629 ELSE
630
631
632
633 IF( lower ) THEN
634
635
636
637 IF( notrans ) THEN
638
639
640
641
642 CALL strsm(
'L',
'U',
'T', diag, k, n, alpha,
643 $ a( k ), k, b, ldb )
644 CALL sgemm(
'T',
'N', k, n, k, -one,
645 $ a( k*( k+1 ) ), k, b, ldb, alpha,
646 $ b( k, 0 ), ldb )
647 CALL strsm(
'L',
'L',
'N', diag, k, n, one,
648 $ a( 0 ), k, b( k, 0 ), ldb )
649
650 ELSE
651
652
653
654
655 CALL strsm(
'L',
'L',
'T', diag, k, n, alpha,
656 $ a( 0 ), k, b( k, 0 ), ldb )
657 CALL sgemm(
'N',
'N', k, n, k, -one,
658 $ a( k*( k+1 ) ), k, b( k, 0 ), ldb,
659 $ alpha, b, ldb )
660 CALL strsm(
'L',
'U',
'N', diag, k, n, one,
661 $ a( k ), k, b, ldb )
662
663 END IF
664
665 ELSE
666
667
668
669 IF( .NOT.notrans ) THEN
670
671
672
673
674 CALL strsm(
'L',
'U',
'T', diag, k, n, alpha,
675 $ a( k*( k+1 ) ), k, b, ldb )
676 CALL sgemm(
'N',
'N', k, n, k, -one, a( 0 ), k,
677 $ b,
678 $ ldb, alpha, b( k, 0 ), ldb )
679 CALL strsm(
'L',
'L',
'N', diag, k, n, one,
680 $ a( k*k ), k, b( k, 0 ), ldb )
681
682 ELSE
683
684
685
686
687 CALL strsm(
'L',
'L',
'T', diag, k, n, alpha,
688 $ a( k*k ), k, b( k, 0 ), ldb )
689 CALL sgemm(
'T',
'N', k, n, k, -one, a( 0 ), k,
690 $ b( k, 0 ), ldb, alpha, b, ldb )
691 CALL strsm(
'L',
'U',
'N', diag, k, n, one,
692 $ a( k*( k+1 ) ), k, b, ldb )
693
694 END IF
695
696 END IF
697
698 END IF
699
700 END IF
701
702 ELSE
703
704
705
706
707
708
709
710 IF( mod( n, 2 ).EQ.0 ) THEN
711 nisodd = .false.
712 k = n / 2
713 ELSE
714 nisodd = .true.
715 IF( lower ) THEN
716 n2 = n / 2
717 n1 = n - n2
718 ELSE
719 n1 = n / 2
720 n2 = n - n1
721 END IF
722 END IF
723
724 IF( nisodd ) THEN
725
726
727
728 IF( normaltransr ) THEN
729
730
731
732 IF( lower ) THEN
733
734
735
736 IF( notrans ) THEN
737
738
739
740
741 CALL strsm(
'R',
'U',
'T', diag, m, n2, alpha,
742 $ a( n ), n, b( 0, n1 ), ldb )
743 CALL sgemm(
'N',
'N', m, n1, n2, -one, b( 0,
744 $ n1 ),
745 $ ldb, a( n1 ), n, alpha, b( 0, 0 ),
746 $ ldb )
747 CALL strsm(
'R',
'L',
'N', diag, m, n1, one,
748 $ a( 0 ), n, b( 0, 0 ), ldb )
749
750 ELSE
751
752
753
754
755 CALL strsm(
'R',
'L',
'T', diag, m, n1, alpha,
756 $ a( 0 ), n, b( 0, 0 ), ldb )
757 CALL sgemm(
'N',
'T', m, n2, n1, -one, b( 0,
758 $ 0 ),
759 $ ldb, a( n1 ), n, alpha, b( 0, n1 ),
760 $ ldb )
761 CALL strsm(
'R',
'U',
'N', diag, m, n2, one,
762 $ a( n ), n, b( 0, n1 ), ldb )
763
764 END IF
765
766 ELSE
767
768
769
770 IF( notrans ) THEN
771
772
773
774
775 CALL strsm(
'R',
'L',
'T', diag, m, n1, alpha,
776 $ a( n2 ), n, b( 0, 0 ), ldb )
777 CALL sgemm(
'N',
'N', m, n2, n1, -one, b( 0,
778 $ 0 ),
779 $ ldb, a( 0 ), n, alpha, b( 0, n1 ),
780 $ ldb )
781 CALL strsm(
'R',
'U',
'N', diag, m, n2, one,
782 $ a( n1 ), n, b( 0, n1 ), ldb )
783
784 ELSE
785
786
787
788
789 CALL strsm(
'R',
'U',
'T', diag, m, n2, alpha,
790 $ a( n1 ), n, b( 0, n1 ), ldb )
791 CALL sgemm(
'N',
'T', m, n1, n2, -one, b( 0,
792 $ n1 ),
793 $ ldb, a( 0 ), n, alpha, b( 0, 0 ), ldb )
794 CALL strsm(
'R',
'L',
'N', diag, m, n1, one,
795 $ a( n2 ), n, b( 0, 0 ), ldb )
796
797 END IF
798
799 END IF
800
801 ELSE
802
803
804
805 IF( lower ) THEN
806
807
808
809 IF( notrans ) THEN
810
811
812
813
814 CALL strsm(
'R',
'L',
'N', diag, m, n2, alpha,
815 $ a( 1 ), n1, b( 0, n1 ), ldb )
816 CALL sgemm(
'N',
'T', m, n1, n2, -one, b( 0,
817 $ n1 ),
818 $ ldb, a( n1*n1 ), n1, alpha, b( 0, 0 ),
819 $ ldb )
820 CALL strsm(
'R',
'U',
'T', diag, m, n1, one,
821 $ a( 0 ), n1, b( 0, 0 ), ldb )
822
823 ELSE
824
825
826
827
828 CALL strsm(
'R',
'U',
'N', diag, m, n1, alpha,
829 $ a( 0 ), n1, b( 0, 0 ), ldb )
830 CALL sgemm(
'N',
'N', m, n2, n1, -one, b( 0,
831 $ 0 ),
832 $ ldb, a( n1*n1 ), n1, alpha, b( 0, n1 ),
833 $ ldb )
834 CALL strsm(
'R',
'L',
'T', diag, m, n2, one,
835 $ a( 1 ), n1, b( 0, n1 ), ldb )
836
837 END IF
838
839 ELSE
840
841
842
843 IF( notrans ) THEN
844
845
846
847
848 CALL strsm(
'R',
'U',
'N', diag, m, n1, alpha,
849 $ a( n2*n2 ), n2, b( 0, 0 ), ldb )
850 CALL sgemm(
'N',
'T', m, n2, n1, -one, b( 0,
851 $ 0 ),
852 $ ldb, a( 0 ), n2, alpha, b( 0, n1 ),
853 $ ldb )
854 CALL strsm(
'R',
'L',
'T', diag, m, n2, one,
855 $ a( n1*n2 ), n2, b( 0, n1 ), ldb )
856
857 ELSE
858
859
860
861
862 CALL strsm(
'R',
'L',
'N', diag, m, n2, alpha,
863 $ a( n1*n2 ), n2, b( 0, n1 ), ldb )
864 CALL sgemm(
'N',
'N', m, n1, n2, -one, b( 0,
865 $ n1 ),
866 $ ldb, a( 0 ), n2, alpha, b( 0, 0 ),
867 $ ldb )
868 CALL strsm(
'R',
'U',
'T', diag, m, n1, one,
869 $ a( n2*n2 ), n2, b( 0, 0 ), ldb )
870
871 END IF
872
873 END IF
874
875 END IF
876
877 ELSE
878
879
880
881 IF( normaltransr ) THEN
882
883
884
885 IF( lower ) THEN
886
887
888
889 IF( notrans ) THEN
890
891
892
893
894 CALL strsm(
'R',
'U',
'T', diag, m, k, alpha,
895 $ a( 0 ), n+1, b( 0, k ), ldb )
896 CALL sgemm(
'N',
'N', m, k, k, -one, b( 0, k ),
897 $ ldb, a( k+1 ), n+1, alpha, b( 0, 0 ),
898 $ ldb )
899 CALL strsm(
'R',
'L',
'N', diag, m, k, one,
900 $ a( 1 ), n+1, b( 0, 0 ), ldb )
901
902 ELSE
903
904
905
906
907 CALL strsm(
'R',
'L',
'T', diag, m, k, alpha,
908 $ a( 1 ), n+1, b( 0, 0 ), ldb )
909 CALL sgemm(
'N',
'T', m, k, k, -one, b( 0, 0 ),
910 $ ldb, a( k+1 ), n+1, alpha, b( 0, k ),
911 $ ldb )
912 CALL strsm(
'R',
'U',
'N', diag, m, k, one,
913 $ a( 0 ), n+1, b( 0, k ), ldb )
914
915 END IF
916
917 ELSE
918
919
920
921 IF( notrans ) THEN
922
923
924
925
926 CALL strsm(
'R',
'L',
'T', diag, m, k, alpha,
927 $ a( k+1 ), n+1, b( 0, 0 ), ldb )
928 CALL sgemm(
'N',
'N', m, k, k, -one, b( 0, 0 ),
929 $ ldb, a( 0 ), n+1, alpha, b( 0, k ),
930 $ ldb )
931 CALL strsm(
'R',
'U',
'N', diag, m, k, one,
932 $ a( k ), n+1, b( 0, k ), ldb )
933
934 ELSE
935
936
937
938
939 CALL strsm(
'R',
'U',
'T', diag, m, k, alpha,
940 $ a( k ), n+1, b( 0, k ), ldb )
941 CALL sgemm(
'N',
'T', m, k, k, -one, b( 0, k ),
942 $ ldb, a( 0 ), n+1, alpha, b( 0, 0 ),
943 $ ldb )
944 CALL strsm(
'R',
'L',
'N', diag, m, k, one,
945 $ a( k+1 ), n+1, b( 0, 0 ), ldb )
946
947 END IF
948
949 END IF
950
951 ELSE
952
953
954
955 IF( lower ) THEN
956
957
958
959 IF( notrans ) THEN
960
961
962
963
964 CALL strsm(
'R',
'L',
'N', diag, m, k, alpha,
965 $ a( 0 ), k, b( 0, k ), ldb )
966 CALL sgemm(
'N',
'T', m, k, k, -one, b( 0, k ),
967 $ ldb, a( ( k+1 )*k ), k, alpha,
968 $ b( 0, 0 ), ldb )
969 CALL strsm(
'R',
'U',
'T', diag, m, k, one,
970 $ a( k ), k, b( 0, 0 ), ldb )
971
972 ELSE
973
974
975
976
977 CALL strsm(
'R',
'U',
'N', diag, m, k, alpha,
978 $ a( k ), k, b( 0, 0 ), ldb )
979 CALL sgemm(
'N',
'N', m, k, k, -one, b( 0, 0 ),
980 $ ldb, a( ( k+1 )*k ), k, alpha,
981 $ b( 0, k ), ldb )
982 CALL strsm(
'R',
'L',
'T', diag, m, k, one,
983 $ a( 0 ), k, b( 0, k ), ldb )
984
985 END IF
986
987 ELSE
988
989
990
991 IF( notrans ) THEN
992
993
994
995
996 CALL strsm(
'R',
'U',
'N', diag, m, k, alpha,
997 $ a( ( k+1 )*k ), k, b( 0, 0 ), ldb )
998 CALL sgemm(
'N',
'T', m, k, k, -one, b( 0, 0 ),
999 $ ldb, a( 0 ), k, alpha, b( 0, k ), ldb )
1000 CALL strsm(
'R',
'L',
'T', diag, m, k, one,
1001 $ a( k*k ), k, b( 0, k ), ldb )
1002
1003 ELSE
1004
1005
1006
1007
1008 CALL strsm(
'R',
'L',
'N', diag, m, k, alpha,
1009 $ a( k*k ), k, b( 0, k ), ldb )
1010 CALL sgemm(
'N',
'N', m, k, k, -one, b( 0, k ),
1011 $ ldb, a( 0 ), k, alpha, b( 0, 0 ), ldb )
1012 CALL strsm(
'R',
'U',
'T', diag, m, k, one,
1013 $ a( ( k+1 )*k ), k, b( 0, 0 ), ldb )
1014
1015 END IF
1016
1017 END IF
1018
1019 END IF
1020
1021 END IF
1022 END IF
1023
1024 RETURN
1025
1026
1027
subroutine xerbla(srname, info)
subroutine sgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
SGEMM
logical function lsame(ca, cb)
LSAME
subroutine strsm(side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb)
STRSM