251
252
253
254
255
256
257 CHARACTER DIRECT, SIDE, STOREV, TRANS
258 INTEGER K, L, LDA, LDB, LDT, LDV, LDWORK, M, N
259
260
261 DOUBLE PRECISION A( LDA, * ), B( LDB, * ), T( LDT, * ),
262 $ V( LDV, * ), WORK( LDWORK, * )
263
264
265
266
267
268 DOUBLE PRECISION ONE, ZERO
269 parameter( one = 1.0, zero = 0.0 )
270
271
272 INTEGER I, J, MP, NP, KP
273 LOGICAL LEFT, FORWARD, COLUMN, RIGHT, BACKWARD, ROW
274
275
276 LOGICAL LSAME
278
279
281
282
283
284
285
286 IF( m.LE.0 .OR. n.LE.0 .OR. k.LE.0 .OR. l.LT.0 ) RETURN
287
288 IF(
lsame( storev,
'C' ) )
THEN
289 column = .true.
290 row = .false.
291 ELSE IF (
lsame( storev,
'R' ) )
THEN
292 column = .false.
293 row = .true.
294 ELSE
295 column = .false.
296 row = .false.
297 END IF
298
299 IF(
lsame( side,
'L' ) )
THEN
300 left = .true.
301 right = .false.
302 ELSE IF(
lsame( side,
'R' ) )
THEN
303 left = .false.
304 right = .true.
305 ELSE
306 left = .false.
307 right = .false.
308 END IF
309
310 IF(
lsame( direct,
'F' ) )
THEN
311 forward = .true.
312 backward = .false.
313 ELSE IF(
lsame( direct,
'B' ) )
THEN
314 forward = .false.
315 backward = .true.
316 ELSE
317 forward = .false.
318 backward = .false.
319 END IF
320
321
322
323 IF( column .AND. forward .AND. left ) THEN
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340 mp = min( m-l+1, m )
341 kp = min( l+1, k )
342
343 DO j = 1, n
344 DO i = 1, l
345 work( i, j ) = b( m-l+i, j )
346 END DO
347 END DO
348 CALL dtrmm(
'L',
'U',
'T',
'N', l, n, one, v( mp, 1 ), ldv,
349 $ work, ldwork )
350 CALL dgemm(
'T',
'N', l, n, m-l, one, v, ldv, b, ldb,
351 $ one, work, ldwork )
352 CALL dgemm(
'T',
'N', k-l, n, m, one, v( 1, kp ), ldv,
353 $ b, ldb, zero, work( kp, 1 ), ldwork )
354
355 DO j = 1, n
356 DO i = 1, k
357 work( i, j ) = work( i, j ) + a( i, j )
358 END DO
359 END DO
360
361 CALL dtrmm(
'L',
'U', trans,
'N', k, n, one, t, ldt,
362 $ work, ldwork )
363
364 DO j = 1, n
365 DO i = 1, k
366 a( i, j ) = a( i, j ) - work( i, j )
367 END DO
368 END DO
369
370 CALL dgemm(
'N',
'N', m-l, n, k, -one, v, ldv, work, ldwork,
371 $ one, b, ldb )
372 CALL dgemm(
'N',
'N', l, n, k-l, -one, v( mp, kp ), ldv,
373 $ work( kp, 1 ), ldwork, one, b( mp, 1 ), ldb )
374 CALL dtrmm(
'L',
'U',
'N',
'N', l, n, one, v( mp, 1 ), ldv,
375 $ work, ldwork )
376 DO j = 1, n
377 DO i = 1, l
378 b( m-l+i, j ) = b( m-l+i, j ) - work( i, j )
379 END DO
380 END DO
381
382
383
384 ELSE IF( column .AND. forward .AND. right ) THEN
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400 np = min( n-l+1, n )
401 kp = min( l+1, k )
402
403 DO j = 1, l
404 DO i = 1, m
405 work( i, j ) = b( i, n-l+j )
406 END DO
407 END DO
408 CALL dtrmm(
'R',
'U',
'N',
'N', m, l, one, v( np, 1 ), ldv,
409 $ work, ldwork )
410 CALL dgemm(
'N',
'N', m, l, n-l, one, b, ldb,
411 $ v, ldv, one, work, ldwork )
412 CALL dgemm(
'N',
'N', m, k-l, n, one, b, ldb,
413 $ v( 1, kp ), ldv, zero, work( 1, kp ), ldwork )
414
415 DO j = 1, k
416 DO i = 1, m
417 work( i, j ) = work( i, j ) + a( i, j )
418 END DO
419 END DO
420
421 CALL dtrmm(
'R',
'U', trans,
'N', m, k, one, t, ldt,
422 $ work, ldwork )
423
424 DO j = 1, k
425 DO i = 1, m
426 a( i, j ) = a( i, j ) - work( i, j )
427 END DO
428 END DO
429
430 CALL dgemm(
'N',
'T', m, n-l, k, -one, work, ldwork,
431 $ v, ldv, one, b, ldb )
432 CALL dgemm(
'N',
'T', m, l, k-l, -one, work( 1, kp ), ldwork,
433 $ v( np, kp ), ldv, one, b( 1, np ), ldb )
434 CALL dtrmm(
'R',
'U',
'T',
'N', m, l, one, v( np, 1 ), ldv,
435 $ work, ldwork )
436 DO j = 1, l
437 DO i = 1, m
438 b( i, n-l+j ) = b( i, n-l+j ) - work( i, j )
439 END DO
440 END DO
441
442
443
444 ELSE IF( column .AND. backward .AND. left ) THEN
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461 mp = min( l+1, m )
462 kp = min( k-l+1, k )
463
464 DO j = 1, n
465 DO i = 1, l
466 work( k-l+i, j ) = b( i, j )
467 END DO
468 END DO
469
470 CALL dtrmm(
'L',
'L',
'T',
'N', l, n, one, v( 1, kp ), ldv,
471 $ work( kp, 1 ), ldwork )
472 CALL dgemm(
'T',
'N', l, n, m-l, one, v( mp, kp ), ldv,
473 $ b( mp, 1 ), ldb, one, work( kp, 1 ), ldwork )
474 CALL dgemm(
'T',
'N', k-l, n, m, one, v, ldv,
475 $ b, ldb, zero, work, ldwork )
476
477 DO j = 1, n
478 DO i = 1, k
479 work( i, j ) = work( i, j ) + a( i, j )
480 END DO
481 END DO
482
483 CALL dtrmm(
'L',
'L', trans,
'N', k, n, one, t, ldt,
484 $ work, ldwork )
485
486 DO j = 1, n
487 DO i = 1, k
488 a( i, j ) = a( i, j ) - work( i, j )
489 END DO
490 END DO
491
492 CALL dgemm(
'N',
'N', m-l, n, k, -one, v( mp, 1 ), ldv,
493 $ work, ldwork, one, b( mp, 1 ), ldb )
494 CALL dgemm(
'N',
'N', l, n, k-l, -one, v, ldv,
495 $ work, ldwork, one, b, ldb )
496 CALL dtrmm(
'L',
'L',
'N',
'N', l, n, one, v( 1, kp ), ldv,
497 $ work( kp, 1 ), ldwork )
498 DO j = 1, n
499 DO i = 1, l
500 b( i, j ) = b( i, j ) - work( k-l+i, j )
501 END DO
502 END DO
503
504
505
506 ELSE IF( column .AND. backward .AND. right ) THEN
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522 np = min( l+1, n )
523 kp = min( k-l+1, k )
524
525 DO j = 1, l
526 DO i = 1, m
527 work( i, k-l+j ) = b( i, j )
528 END DO
529 END DO
530 CALL dtrmm(
'R',
'L',
'N',
'N', m, l, one, v( 1, kp ), ldv,
531 $ work( 1, kp ), ldwork )
532 CALL dgemm(
'N',
'N', m, l, n-l, one, b( 1, np ), ldb,
533 $ v( np, kp ), ldv, one, work( 1, kp ), ldwork )
534 CALL dgemm(
'N',
'N', m, k-l, n, one, b, ldb,
535 $ v, ldv, zero, work, ldwork )
536
537 DO j = 1, k
538 DO i = 1, m
539 work( i, j ) = work( i, j ) + a( i, j )
540 END DO
541 END DO
542
543 CALL dtrmm(
'R',
'L', trans,
'N', m, k, one, t, ldt,
544 $ work, ldwork )
545
546 DO j = 1, k
547 DO i = 1, m
548 a( i, j ) = a( i, j ) - work( i, j )
549 END DO
550 END DO
551
552 CALL dgemm(
'N',
'T', m, n-l, k, -one, work, ldwork,
553 $ v( np, 1 ), ldv, one, b( 1, np ), ldb )
554 CALL dgemm(
'N',
'T', m, l, k-l, -one, work, ldwork,
555 $ v, ldv, one, b, ldb )
556 CALL dtrmm(
'R',
'L',
'T',
'N', m, l, one, v( 1, kp ), ldv,
557 $ work( 1, kp ), ldwork )
558 DO j = 1, l
559 DO i = 1, m
560 b( i, j ) = b( i, j ) - work( i, k-l+j )
561 END DO
562 END DO
563
564
565
566 ELSE IF( row .AND. forward .AND. left ) THEN
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582 mp = min( m-l+1, m )
583 kp = min( l+1, k )
584
585 DO j = 1, n
586 DO i = 1, l
587 work( i, j ) = b( m-l+i, j )
588 END DO
589 END DO
590 CALL dtrmm(
'L',
'L',
'N',
'N', l, n, one, v( 1, mp ), ldv,
591 $ work, ldb )
592 CALL dgemm(
'N',
'N', l, n, m-l, one, v, ldv,b, ldb,
593 $ one, work, ldwork )
594 CALL dgemm(
'N',
'N', k-l, n, m, one, v( kp, 1 ), ldv,
595 $ b, ldb, zero, work( kp, 1 ), ldwork )
596
597 DO j = 1, n
598 DO i = 1, k
599 work( i, j ) = work( i, j ) + a( i, j )
600 END DO
601 END DO
602
603 CALL dtrmm(
'L',
'U', trans,
'N', k, n, one, t, ldt,
604 $ work, ldwork )
605
606 DO j = 1, n
607 DO i = 1, k
608 a( i, j ) = a( i, j ) - work( i, j )
609 END DO
610 END DO
611
612 CALL dgemm(
'T',
'N', m-l, n, k, -one, v, ldv, work, ldwork,
613 $ one, b, ldb )
614 CALL dgemm(
'T',
'N', l, n, k-l, -one, v( kp, mp ), ldv,
615 $ work( kp, 1 ), ldwork, one, b( mp, 1 ), ldb )
616 CALL dtrmm(
'L',
'L',
'T',
'N', l, n, one, v( 1, mp ), ldv,
617 $ work, ldwork )
618 DO j = 1, n
619 DO i = 1, l
620 b( m-l+i, j ) = b( m-l+i, j ) - work( i, j )
621 END DO
622 END DO
623
624
625
626 ELSE IF( row .AND. forward .AND. right ) THEN
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641 np = min( n-l+1, n )
642 kp = min( l+1, k )
643
644 DO j = 1, l
645 DO i = 1, m
646 work( i, j ) = b( i, n-l+j )
647 END DO
648 END DO
649 CALL dtrmm(
'R',
'L',
'T',
'N', m, l, one, v( 1, np ), ldv,
650 $ work, ldwork )
651 CALL dgemm(
'N',
'T', m, l, n-l, one, b, ldb, v, ldv,
652 $ one, work, ldwork )
653 CALL dgemm(
'N',
'T', m, k-l, n, one, b, ldb,
654 $ v( kp, 1 ), ldv, zero, work( 1, kp ), ldwork )
655
656 DO j = 1, k
657 DO i = 1, m
658 work( i, j ) = work( i, j ) + a( i, j )
659 END DO
660 END DO
661
662 CALL dtrmm(
'R',
'U', trans,
'N', m, k, one, t, ldt,
663 $ work, ldwork )
664
665 DO j = 1, k
666 DO i = 1, m
667 a( i, j ) = a( i, j ) - work( i, j )
668 END DO
669 END DO
670
671 CALL dgemm(
'N',
'N', m, n-l, k, -one, work, ldwork,
672 $ v, ldv, one, b, ldb )
673 CALL dgemm(
'N',
'N', m, l, k-l, -one, work( 1, kp ), ldwork,
674 $ v( kp, np ), ldv, one, b( 1, np ), ldb )
675 CALL dtrmm(
'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 dtrmm(
'L',
'U',
'N',
'N', l, n, one, v( kp, 1 ), ldv,
710 $ work( kp, 1 ), ldwork )
711 CALL dgemm(
'N',
'N', l, n, m-l, one, v( kp, mp ), ldv,
712 $ b( mp, 1 ), ldb, one, work( kp, 1 ), ldwork )
713 CALL dgemm(
'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 dtrmm(
'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 dgemm(
'T',
'N', m-l, n, k, -one, v( 1, mp ), ldv,
732 $ work, ldwork, one, b( mp, 1 ), ldb )
733 CALL dgemm(
'T',
'N', l, n, k-l, -one, v, ldv,
734 $ work, ldwork, one, b, ldb )
735 CALL dtrmm(
'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 dtrmm(
'R',
'U',
'T',
'N', m, l, one, v( kp, 1 ), ldv,
769 $ work( 1, kp ), ldwork )
770 CALL dgemm(
'N',
'T', m, l, n-l, one, b( 1, np ), ldb,
771 $ v( kp, np ), ldv, one, work( 1, kp ), ldwork )
772 CALL dgemm(
'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 dtrmm(
'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 dgemm(
'N',
'N', m, n-l, k, -one, work, ldwork,
791 $ v( 1, np ), ldv, one, b( 1, np ), ldb )
792 CALL dgemm(
'N',
'N', m, l, k-l , -one, work, ldwork,
793 $ v, ldv, one, b, ldb )
794 CALL dtrmm(
'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 dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
logical function lsame(ca, cb)
LSAME
subroutine dtrmm(side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb)
DTRMM