249
250
251
252
253
254
255 CHARACTER DIRECT, SIDE, STOREV, TRANS
256 INTEGER K, L, LDA, LDB, LDT, LDV, LDWORK, M, N
257
258
259 REAL A( LDA, * ), B( LDB, * ), T( LDT, * ),
260 $ V( LDV, * ), WORK( LDWORK, * )
261
262
263
264
265
266 REAL ONE, ZERO
267 parameter( one = 1.0, zero = 0.0 )
268
269
270 INTEGER I, J, MP, NP, KP
271 LOGICAL LEFT, FORWARD, COLUMN, RIGHT, BACKWARD, ROW
272
273
274 LOGICAL LSAME
276
277
279
280
281
282
283
284 IF( m.LE.0 .OR. n.LE.0 .OR. k.LE.0 .OR. l.LT.0 ) RETURN
285
286 IF(
lsame( storev,
'C' ) )
THEN
287 column = .true.
288 row = .false.
289 ELSE IF (
lsame( storev,
'R' ) )
THEN
290 column = .false.
291 row = .true.
292 ELSE
293 column = .false.
294 row = .false.
295 END IF
296
297 IF(
lsame( side,
'L' ) )
THEN
298 left = .true.
299 right = .false.
300 ELSE IF(
lsame( side,
'R' ) )
THEN
301 left = .false.
302 right = .true.
303 ELSE
304 left = .false.
305 right = .false.
306 END IF
307
308 IF(
lsame( direct,
'F' ) )
THEN
309 forward = .true.
310 backward = .false.
311 ELSE IF(
lsame( direct,
'B' ) )
THEN
312 forward = .false.
313 backward = .true.
314 ELSE
315 forward = .false.
316 backward = .false.
317 END IF
318
319
320
321 IF( column .AND. forward .AND. left ) THEN
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338 mp = min( m-l+1, m )
339 kp = min( l+1, k )
340
341 DO j = 1, n
342 DO i = 1, l
343 work( i, j ) = b( m-l+i, j )
344 END DO
345 END DO
346 CALL strmm(
'L',
'U',
'T',
'N', l, n, one, v( mp, 1 ), ldv,
347 $ work, ldwork )
348 CALL sgemm(
'T',
'N', l, n, m-l, one, v, ldv, b, ldb,
349 $ one, work, ldwork )
350 CALL sgemm(
'T',
'N', k-l, n, m, one, v( 1, kp ), ldv,
351 $ b, ldb, zero, work( kp, 1 ), ldwork )
352
353 DO j = 1, n
354 DO i = 1, k
355 work( i, j ) = work( i, j ) + a( i, j )
356 END DO
357 END DO
358
359 CALL strmm(
'L',
'U', trans,
'N', k, n, one, t, ldt,
360 $ work, ldwork )
361
362 DO j = 1, n
363 DO i = 1, k
364 a( i, j ) = a( i, j ) - work( i, j )
365 END DO
366 END DO
367
368 CALL sgemm(
'N',
'N', m-l, n, k, -one, v, ldv, work, ldwork,
369 $ one, b, ldb )
370 CALL sgemm(
'N',
'N', l, n, k-l, -one, v( mp, kp ), ldv,
371 $ work( kp, 1 ), ldwork, one, b( mp, 1 ), ldb )
372 CALL strmm(
'L',
'U',
'N',
'N', l, n, one, v( mp, 1 ), ldv,
373 $ work, ldwork )
374 DO j = 1, n
375 DO i = 1, l
376 b( m-l+i, j ) = b( m-l+i, j ) - work( i, j )
377 END DO
378 END DO
379
380
381
382 ELSE IF( column .AND. forward .AND. right ) THEN
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398 np = min( n-l+1, n )
399 kp = min( l+1, k )
400
401 DO j = 1, l
402 DO i = 1, m
403 work( i, j ) = b( i, n-l+j )
404 END DO
405 END DO
406 CALL strmm(
'R',
'U',
'N',
'N', m, l, one, v( np, 1 ), ldv,
407 $ work, ldwork )
408 CALL sgemm(
'N',
'N', m, l, n-l, one, b, ldb,
409 $ v, ldv, one, work, ldwork )
410 CALL sgemm(
'N',
'N', m, k-l, n, one, b, ldb,
411 $ v( 1, kp ), ldv, zero, work( 1, kp ), ldwork )
412
413 DO j = 1, k
414 DO i = 1, m
415 work( i, j ) = work( i, j ) + a( i, j )
416 END DO
417 END DO
418
419 CALL strmm(
'R',
'U', trans,
'N', m, k, one, t, ldt,
420 $ work, ldwork )
421
422 DO j = 1, k
423 DO i = 1, m
424 a( i, j ) = a( i, j ) - work( i, j )
425 END DO
426 END DO
427
428 CALL sgemm(
'N',
'T', m, n-l, k, -one, work, ldwork,
429 $ v, ldv, one, b, ldb )
430 CALL sgemm(
'N',
'T', m, l, k-l, -one, work( 1, kp ),
431 $ ldwork,
432 $ v( np, kp ), ldv, one, b( 1, np ), ldb )
433 CALL strmm(
'R',
'U',
'T',
'N', m, l, one, v( np, 1 ), ldv,
434 $ work, ldwork )
435 DO j = 1, l
436 DO i = 1, m
437 b( i, n-l+j ) = b( i, n-l+j ) - work( i, j )
438 END DO
439 END DO
440
441
442
443 ELSE IF( column .AND. backward .AND. left ) THEN
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460 mp = min( l+1, m )
461 kp = min( k-l+1, k )
462
463 DO j = 1, n
464 DO i = 1, l
465 work( k-l+i, j ) = b( i, j )
466 END DO
467 END DO
468
469 CALL strmm(
'L',
'L',
'T',
'N', l, n, one, v( 1, kp ), ldv,
470 $ work( kp, 1 ), ldwork )
471 CALL sgemm(
'T',
'N', l, n, m-l, one, v( mp, kp ), ldv,
472 $ b( mp, 1 ), ldb, one, work( kp, 1 ), ldwork )
473 CALL sgemm(
'T',
'N', k-l, n, m, one, v, ldv,
474 $ b, ldb, zero, work, ldwork )
475
476 DO j = 1, n
477 DO i = 1, k
478 work( i, j ) = work( i, j ) + a( i, j )
479 END DO
480 END DO
481
482 CALL strmm(
'L',
'L', trans,
'N', k, n, one, t, ldt,
483 $ work, ldwork )
484
485 DO j = 1, n
486 DO i = 1, k
487 a( i, j ) = a( i, j ) - work( i, j )
488 END DO
489 END DO
490
491 CALL sgemm(
'N',
'N', m-l, n, k, -one, v( mp, 1 ), ldv,
492 $ work, ldwork, one, b( mp, 1 ), ldb )
493 CALL sgemm(
'N',
'N', l, n, k-l, -one, v, ldv,
494 $ work, ldwork, one, b, ldb )
495 CALL strmm(
'L',
'L',
'N',
'N', l, n, one, v( 1, kp ), ldv,
496 $ work( kp, 1 ), ldwork )
497 DO j = 1, n
498 DO i = 1, l
499 b( i, j ) = b( i, j ) - work( k-l+i, j )
500 END DO
501 END DO
502
503
504
505 ELSE IF( column .AND. backward .AND. right ) THEN
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521 np = min( l+1, n )
522 kp = min( k-l+1, k )
523
524 DO j = 1, l
525 DO i = 1, m
526 work( i, k-l+j ) = b( i, j )
527 END DO
528 END DO
529 CALL strmm(
'R',
'L',
'N',
'N', m, l, one, v( 1, kp ), ldv,
530 $ work( 1, kp ), ldwork )
531 CALL sgemm(
'N',
'N', m, l, n-l, one, b( 1, np ), ldb,
532 $ v( np, kp ), ldv, one, work( 1, kp ), ldwork )
533 CALL sgemm(
'N',
'N', m, k-l, n, one, b, ldb,
534 $ v, ldv, zero, work, ldwork )
535
536 DO j = 1, k
537 DO i = 1, m
538 work( i, j ) = work( i, j ) + a( i, j )
539 END DO
540 END DO
541
542 CALL strmm(
'R',
'L', trans,
'N', m, k, one, t, ldt,
543 $ work, ldwork )
544
545 DO j = 1, k
546 DO i = 1, m
547 a( i, j ) = a( i, j ) - work( i, j )
548 END DO
549 END DO
550
551 CALL sgemm(
'N',
'T', m, n-l, k, -one, work, ldwork,
552 $ v( np, 1 ), ldv, one, b( 1, np ), ldb )
553 CALL sgemm(
'N',
'T', m, l, k-l, -one, work, ldwork,
554 $ v, ldv, one, b, ldb )
555 CALL strmm(
'R',
'L',
'T',
'N', m, l, one, v( 1, kp ), ldv,
556 $ work( 1, kp ), ldwork )
557 DO j = 1, l
558 DO i = 1, m
559 b( i, j ) = b( i, j ) - work( i, k-l+j )
560 END DO
561 END DO
562
563
564
565 ELSE IF( row .AND. forward .AND. left ) THEN
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581 mp = min( m-l+1, m )
582 kp = min( l+1, k )
583
584 DO j = 1, n
585 DO i = 1, l
586 work( i, j ) = b( m-l+i, j )
587 END DO
588 END DO
589 CALL strmm(
'L',
'L',
'N',
'N', l, n, one, v( 1, mp ), ldv,
590 $ work, ldb )
591 CALL sgemm(
'N',
'N', l, n, m-l, one, v, ldv,b, ldb,
592 $ one, work, ldwork )
593 CALL sgemm(
'N',
'N', k-l, n, m, one, v( kp, 1 ), ldv,
594 $ b, ldb, zero, work( kp, 1 ), ldwork )
595
596 DO j = 1, n
597 DO i = 1, k
598 work( i, j ) = work( i, j ) + a( i, j )
599 END DO
600 END DO
601
602 CALL strmm(
'L',
'U', trans,
'N', k, n, one, t, ldt,
603 $ work, ldwork )
604
605 DO j = 1, n
606 DO i = 1, k
607 a( i, j ) = a( i, j ) - work( i, j )
608 END DO
609 END DO
610
611 CALL sgemm(
'T',
'N', m-l, n, k, -one, v, ldv, work, ldwork,
612 $ one, b, ldb )
613 CALL sgemm(
'T',
'N', l, n, k-l, -one, v( kp, mp ), ldv,
614 $ work( kp, 1 ), ldwork, one, b( mp, 1 ), ldb )
615 CALL strmm(
'L',
'L',
'T',
'N', l, n, one, v( 1, mp ), ldv,
616 $ work, ldwork )
617 DO j = 1, n
618 DO i = 1, l
619 b( m-l+i, j ) = b( m-l+i, j ) - work( i, j )
620 END DO
621 END DO
622
623
624
625 ELSE IF( row .AND. forward .AND. right ) THEN
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640 np = min( n-l+1, n )
641 kp = min( l+1, k )
642
643 DO j = 1, l
644 DO i = 1, m
645 work( i, j ) = b( i, n-l+j )
646 END DO
647 END DO
648 CALL strmm(
'R',
'L',
'T',
'N', m, l, one, v( 1, np ), ldv,
649 $ work, ldwork )
650 CALL sgemm(
'N',
'T', m, l, n-l, one, b, ldb, v, ldv,
651 $ one, work, ldwork )
652 CALL sgemm(
'N',
'T', m, k-l, n, one, b, ldb,
653 $ v( kp, 1 ), ldv, zero, work( 1, kp ), ldwork )
654
655 DO j = 1, k
656 DO i = 1, m
657 work( i, j ) = work( i, j ) + a( i, j )
658 END DO
659 END DO
660
661 CALL strmm(
'R',
'U', trans,
'N', m, k, one, t, ldt,
662 $ work, ldwork )
663
664 DO j = 1, k
665 DO i = 1, m
666 a( i, j ) = a( i, j ) - work( i, j )
667 END DO
668 END DO
669
670 CALL sgemm(
'N',
'N', m, n-l, k, -one, work, ldwork,
671 $ v, ldv, one, b, ldb )
672 CALL sgemm(
'N',
'N', m, l, k-l, -one, work( 1, kp ),
673 $ ldwork,
674 $ v( kp, np ), ldv, one, b( 1, np ), ldb )
675 CALL strmm(
'R',
'L',
'N',
'N', m, l, one, v( 1, np ), ldv,
676 $ work, ldwork )
677 DO j = 1, l
678 DO i = 1, m
679 b( i, n-l+j ) = b( i, n-l+j ) - work( i, j )
680 END DO
681 END DO
682
683
684
685 ELSE IF( row .AND. backward .AND. left ) THEN
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701 mp = min( l+1, m )
702 kp = min( k-l+1, k )
703
704 DO j = 1, n
705 DO i = 1, l
706 work( k-l+i, j ) = b( i, j )
707 END DO
708 END DO
709 CALL strmm(
'L',
'U',
'N',
'N', l, n, one, v( kp, 1 ), ldv,
710 $ work( kp, 1 ), ldwork )
711 CALL sgemm(
'N',
'N', l, n, m-l, one, v( kp, mp ), ldv,
712 $ b( mp, 1 ), ldb, one, work( kp, 1 ), ldwork )
713 CALL sgemm(
'N',
'N', k-l, n, m, one, v, ldv, b, ldb,
714 $ zero, work, ldwork )
715
716 DO j = 1, n
717 DO i = 1, k
718 work( i, j ) = work( i, j ) + a( i, j )
719 END DO
720 END DO
721
722 CALL strmm(
'L',
'L ', trans,
'N', k, n, one, t, ldt,
723 $ work, ldwork )
724
725 DO j = 1, n
726 DO i = 1, k
727 a( i, j ) = a( i, j ) - work( i, j )
728 END DO
729 END DO
730
731 CALL sgemm(
'T',
'N', m-l, n, k, -one, v( 1, mp ), ldv,
732 $ work, ldwork, one, b( mp, 1 ), ldb )
733 CALL sgemm(
'T',
'N', l, n, k-l, -one, v, ldv,
734 $ work, ldwork, one, b, ldb )
735 CALL strmm(
'L',
'U',
'T',
'N', l, n, one, v( kp, 1 ), ldv,
736 $ work( kp, 1 ), ldwork )
737 DO j = 1, n
738 DO i = 1, l
739 b( i, j ) = b( i, j ) - work( k-l+i, j )
740 END DO
741 END DO
742
743
744
745 ELSE IF( row .AND. backward .AND. right ) THEN
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760 np = min( l+1, n )
761 kp = min( k-l+1, k )
762
763 DO j = 1, l
764 DO i = 1, m
765 work( i, k-l+j ) = b( i, j )
766 END DO
767 END DO
768 CALL strmm(
'R',
'U',
'T',
'N', m, l, one, v( kp, 1 ), ldv,
769 $ work( 1, kp ), ldwork )
770 CALL sgemm(
'N',
'T', m, l, n-l, one, b( 1, np ), ldb,
771 $ v( kp, np ), ldv, one, work( 1, kp ), ldwork )
772 CALL sgemm(
'N',
'T', m, k-l, n, one, b, ldb, v, ldv,
773 $ zero, work, ldwork )
774
775 DO j = 1, k
776 DO i = 1, m
777 work( i, j ) = work( i, j ) + a( i, j )
778 END DO
779 END DO
780
781 CALL strmm(
'R',
'L', trans,
'N', m, k, one, t, ldt,
782 $ work, ldwork )
783
784 DO j = 1, k
785 DO i = 1, m
786 a( i, j ) = a( i, j ) - work( i, j )
787 END DO
788 END DO
789
790 CALL sgemm(
'N',
'N', m, n-l, k, -one, work, ldwork,
791 $ v( 1, np ), ldv, one, b( 1, np ), ldb )
792 CALL sgemm(
'N',
'N', m, l, k-l , -one, work, ldwork,
793 $ v, ldv, one, b, ldb )
794 CALL strmm(
'R',
'U',
'N',
'N', m, l, one, v( kp, 1 ), ldv,
795 $ work( 1, kp ), ldwork )
796 DO j = 1, l
797 DO i = 1, m
798 b( i, j ) = b( i, j ) - work( i, k-l+j )
799 END DO
800 END DO
801
802 END IF
803
804 RETURN
805
806
807
subroutine sgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
SGEMM
logical function lsame(ca, cb)
LSAME
subroutine strmm(side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb)
STRMM