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