File:  [local] / rpl / lapack / lapack / dtprfb.f
Revision 1.5: download - view: text, annotated - select for diffs - revision graph
Mon Jan 27 09:28:29 2014 UTC (10 years, 3 months ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_1_24, rpl-4_1_23, rpl-4_1_22, rpl-4_1_21, rpl-4_1_20, rpl-4_1_19, rpl-4_1_18, rpl-4_1_17, HEAD
Cohérence.

    1: *> \brief \b DTPRFB applies a real or complex "triangular-pentagonal" blocked reflector to a real or complex matrix, which is composed of two blocks.
    2: *
    3: *  =========== DOCUMENTATION ===========
    4: *
    5: * Online html documentation available at 
    6: *            http://www.netlib.org/lapack/explore-html/ 
    7: *
    8: *> \htmlonly
    9: *> Download DTPRFB + dependencies 
   10: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtprfb.f"> 
   11: *> [TGZ]</a> 
   12: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtprfb.f"> 
   13: *> [ZIP]</a> 
   14: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtprfb.f"> 
   15: *> [TXT]</a>
   16: *> \endhtmlonly 
   17: *
   18: *  Definition:
   19: *  ===========
   20: *
   21: *       SUBROUTINE DTPRFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, L, 
   22: *                          V, LDV, T, LDT, A, LDA, B, LDB, WORK, LDWORK )
   23:    24: *       .. Scalar Arguments ..
   25: *       CHARACTER DIRECT, SIDE, STOREV, TRANS
   26: *       INTEGER   K, L, LDA, LDB, LDT, LDV, LDWORK, M, N
   27: *       ..
   28: *       .. Array Arguments ..
   29: *       DOUBLE PRECISION   A( LDA, * ), B( LDB, * ), T( LDT, * ), 
   30: *      $          V( LDV, * ), WORK( LDWORK, * )
   31: *       ..
   32: *  
   33: *
   34: *> \par Purpose:
   35: *  =============
   36: *>
   37: *> \verbatim
   38: *>
   39: *> DTPRFB applies a real "triangular-pentagonal" block reflector H or its 
   40: *> transpose H**T to a real matrix C, which is composed of two 
   41: *> blocks A and B, either from the left or right.
   42: *> 
   43: *> \endverbatim
   44: *
   45: *  Arguments:
   46: *  ==========
   47: *
   48: *> \param[in] SIDE
   49: *> \verbatim
   50: *>          SIDE is CHARACTER*1
   51: *>          = 'L': apply H or H**T from the Left
   52: *>          = 'R': apply H or H**T from the Right
   53: *> \endverbatim
   54: *>
   55: *> \param[in] TRANS
   56: *> \verbatim
   57: *>          TRANS is CHARACTER*1
   58: *>          = 'N': apply H (No transpose)
   59: *>          = 'T': apply H**T (Transpose)
   60: *> \endverbatim
   61: *>
   62: *> \param[in] DIRECT
   63: *> \verbatim
   64: *>          DIRECT is CHARACTER*1
   65: *>          Indicates how H is formed from a product of elementary
   66: *>          reflectors
   67: *>          = 'F': H = H(1) H(2) . . . H(k) (Forward)
   68: *>          = 'B': H = H(k) . . . H(2) H(1) (Backward)
   69: *> \endverbatim
   70: *>
   71: *> \param[in] STOREV
   72: *> \verbatim
   73: *>          STOREV is CHARACTER*1
   74: *>          Indicates how the vectors which define the elementary
   75: *>          reflectors are stored:
   76: *>          = 'C': Columns
   77: *>          = 'R': Rows
   78: *> \endverbatim
   79: *>
   80: *> \param[in] M
   81: *> \verbatim
   82: *>          M is INTEGER
   83: *>          The number of rows of the matrix B.  
   84: *>          M >= 0.
   85: *> \endverbatim
   86: *>
   87: *> \param[in] N
   88: *> \verbatim
   89: *>          N is INTEGER
   90: *>          The number of columns of the matrix B.  
   91: *>          N >= 0.
   92: *> \endverbatim
   93: *>
   94: *> \param[in] K
   95: *> \verbatim
   96: *>          K is INTEGER
   97: *>          The order of the matrix T, i.e. the number of elementary
   98: *>          reflectors whose product defines the block reflector.  
   99: *>          K >= 0.
  100: *> \endverbatim
  101: *>
  102: *> \param[in] L
  103: *> \verbatim
  104: *>          L is INTEGER
  105: *>          The order of the trapezoidal part of V.  
  106: *>          K >= L >= 0.  See Further Details.
  107: *> \endverbatim
  108: *>
  109: *> \param[in] V
  110: *> \verbatim
  111: *>          V is DOUBLE PRECISION array, dimension
  112: *>                                (LDV,K) if STOREV = 'C'
  113: *>                                (LDV,M) if STOREV = 'R' and SIDE = 'L'
  114: *>                                (LDV,N) if STOREV = 'R' and SIDE = 'R'
  115: *>          The pentagonal matrix V, which contains the elementary reflectors
  116: *>          H(1), H(2), ..., H(K).  See Further Details.
  117: *> \endverbatim
  118: *>
  119: *> \param[in] LDV
  120: *> \verbatim
  121: *>          LDV is INTEGER
  122: *>          The leading dimension of the array V.
  123: *>          If STOREV = 'C' and SIDE = 'L', LDV >= max(1,M);
  124: *>          if STOREV = 'C' and SIDE = 'R', LDV >= max(1,N);
  125: *>          if STOREV = 'R', LDV >= K.
  126: *> \endverbatim
  127: *>
  128: *> \param[in] T
  129: *> \verbatim
  130: *>          T is DOUBLE PRECISION array, dimension (LDT,K)
  131: *>          The triangular K-by-K matrix T in the representation of the
  132: *>          block reflector.  
  133: *> \endverbatim
  134: *>
  135: *> \param[in] LDT
  136: *> \verbatim
  137: *>          LDT is INTEGER
  138: *>          The leading dimension of the array T. 
  139: *>          LDT >= K.
  140: *> \endverbatim
  141: *>
  142: *> \param[in,out] A
  143: *> \verbatim
  144: *>          A is DOUBLE PRECISION array, dimension
  145: *>          (LDA,N) if SIDE = 'L' or (LDA,K) if SIDE = 'R'
  146: *>          On entry, the K-by-N or M-by-K matrix A.
  147: *>          On exit, A is overwritten by the corresponding block of 
  148: *>          H*C or H**T*C or C*H or C*H**T.  See Futher Details.
  149: *> \endverbatim
  150: *>
  151: *> \param[in] LDA
  152: *> \verbatim
  153: *>          LDA is INTEGER
  154: *>          The leading dimension of the array A. 
  155: *>          If SIDE = 'L', LDC >= max(1,K);
  156: *>          If SIDE = 'R', LDC >= max(1,M). 
  157: *> \endverbatim
  158: *>
  159: *> \param[in,out] B
  160: *> \verbatim
  161: *>          B is DOUBLE PRECISION array, dimension (LDB,N)
  162: *>          On entry, the M-by-N matrix B.
  163: *>          On exit, B is overwritten by the corresponding block of
  164: *>          H*C or H**T*C or C*H or C*H**T.  See Further Details.
  165: *> \endverbatim
  166: *>
  167: *> \param[in] LDB
  168: *> \verbatim
  169: *>          LDB is INTEGER
  170: *>          The leading dimension of the array B. 
  171: *>          LDB >= max(1,M).
  172: *> \endverbatim
  173: *>
  174: *> \param[out] WORK
  175: *> \verbatim
  176: *>          WORK is DOUBLE PRECISION array, dimension
  177: *>          (LDWORK,N) if SIDE = 'L',
  178: *>          (LDWORK,K) if SIDE = 'R'.
  179: *> \endverbatim
  180: *>
  181: *> \param[in] LDWORK
  182: *> \verbatim
  183: *>          LDWORK is INTEGER
  184: *>          The leading dimension of the array WORK.
  185: *>          If SIDE = 'L', LDWORK >= K; 
  186: *>          if SIDE = 'R', LDWORK >= M.
  187: *> \endverbatim
  188: *
  189: *  Authors:
  190: *  ========
  191: *
  192: *> \author Univ. of Tennessee 
  193: *> \author Univ. of California Berkeley 
  194: *> \author Univ. of Colorado Denver 
  195: *> \author NAG Ltd. 
  196: *
  197: *> \date September 2012
  198: *
  199: *> \ingroup doubleOTHERauxiliary
  200: *
  201: *> \par Further Details:
  202: *  =====================
  203: *>
  204: *> \verbatim
  205: *>
  206: *>  The matrix C is a composite matrix formed from blocks A and B.
  207: *>  The block B is of size M-by-N; if SIDE = 'R', A is of size M-by-K, 
  208: *>  and if SIDE = 'L', A is of size K-by-N.
  209: *>
  210: *>  If SIDE = 'R' and DIRECT = 'F', C = [A B].
  211: *>
  212: *>  If SIDE = 'L' and DIRECT = 'F', C = [A] 
  213: *>                                      [B].
  214: *>
  215: *>  If SIDE = 'R' and DIRECT = 'B', C = [B A].
  216: *>
  217: *>  If SIDE = 'L' and DIRECT = 'B', C = [B]
  218: *>                                      [A]. 
  219: *>
  220: *>  The pentagonal matrix V is composed of a rectangular block V1 and a 
  221: *>  trapezoidal block V2.  The size of the trapezoidal block is determined by 
  222: *>  the parameter L, where 0<=L<=K.  If L=K, the V2 block of V is triangular;
  223: *>  if L=0, there is no trapezoidal block, thus V = V1 is rectangular.
  224: *>
  225: *>  If DIRECT = 'F' and STOREV = 'C':  V = [V1]
  226: *>                                         [V2]
  227: *>     - V2 is upper trapezoidal (first L rows of K-by-K upper triangular)
  228: *>
  229: *>  If DIRECT = 'F' and STOREV = 'R':  V = [V1 V2]
  230: *>
  231: *>     - V2 is lower trapezoidal (first L columns of K-by-K lower triangular)
  232: *>
  233: *>  If DIRECT = 'B' and STOREV = 'C':  V = [V2]
  234: *>                                         [V1]
  235: *>     - V2 is lower trapezoidal (last L rows of K-by-K lower triangular)
  236: *>
  237: *>  If DIRECT = 'B' and STOREV = 'R':  V = [V2 V1]
  238: *>    
  239: *>     - V2 is upper trapezoidal (last L columns of K-by-K upper triangular)
  240: *>
  241: *>  If STOREV = 'C' and SIDE = 'L', V is M-by-K with V2 L-by-K.
  242: *>
  243: *>  If STOREV = 'C' and SIDE = 'R', V is N-by-K with V2 L-by-K.
  244: *>
  245: *>  If STOREV = 'R' and SIDE = 'L', V is K-by-M with V2 K-by-L.
  246: *>
  247: *>  If STOREV = 'R' and SIDE = 'R', V is K-by-N with V2 K-by-L.
  248: *> \endverbatim
  249: *>
  250: *  =====================================================================
  251:       SUBROUTINE DTPRFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, L, 
  252:      $                   V, LDV, T, LDT, A, LDA, B, LDB, WORK, LDWORK )
  253: *
  254: *  -- LAPACK auxiliary routine (version 3.4.2) --
  255: *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
  256: *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  257: *     September 2012
  258: *
  259: *     .. Scalar Arguments ..
  260:       CHARACTER DIRECT, SIDE, STOREV, TRANS
  261:       INTEGER   K, L, LDA, LDB, LDT, LDV, LDWORK, M, N
  262: *     ..
  263: *     .. Array Arguments ..
  264:       DOUBLE PRECISION   A( LDA, * ), B( LDB, * ), T( LDT, * ), 
  265:      $          V( LDV, * ), WORK( LDWORK, * )
  266: *     ..
  267: *
  268: *  ==========================================================================
  269: *
  270: *     .. Parameters ..
  271:       DOUBLE PRECISION   ONE, ZERO
  272:       PARAMETER ( ONE = 1.0, ZERO = 0.0 )
  273: *     ..
  274: *     .. Local Scalars ..
  275:       INTEGER   I, J, MP, NP, KP
  276:       LOGICAL   LEFT, FORWARD, COLUMN, RIGHT, BACKWARD, ROW
  277: *     ..
  278: *     .. External Functions ..
  279:       LOGICAL   LSAME
  280:       EXTERNAL  LSAME
  281: *     ..
  282: *     .. External Subroutines ..
  283:       EXTERNAL  DGEMM, DTRMM
  284: *     ..
  285: *     .. Executable Statements ..
  286: *
  287: *     Quick return if possible
  288: *
  289:       IF( M.LE.0 .OR. N.LE.0 .OR. K.LE.0 .OR. L.LT.0 ) RETURN
  290: *
  291:       IF( LSAME( STOREV, 'C' ) ) THEN
  292:          COLUMN = .TRUE.
  293:          ROW = .FALSE.
  294:       ELSE IF ( LSAME( STOREV, 'R' ) ) THEN
  295:          COLUMN = .FALSE.
  296:          ROW = .TRUE.
  297:       ELSE
  298:          COLUMN = .FALSE.
  299:          ROW = .FALSE.
  300:       END IF
  301: *
  302:       IF( LSAME( SIDE, 'L' ) ) THEN
  303:          LEFT = .TRUE.
  304:          RIGHT = .FALSE.
  305:       ELSE IF( LSAME( SIDE, 'R' ) ) THEN
  306:          LEFT = .FALSE.
  307:          RIGHT = .TRUE.
  308:       ELSE
  309:          LEFT = .FALSE.
  310:          RIGHT = .FALSE.
  311:       END IF
  312: *
  313:       IF( LSAME( DIRECT, 'F' ) ) THEN
  314:          FORWARD = .TRUE.
  315:          BACKWARD = .FALSE.
  316:       ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
  317:          FORWARD = .FALSE.
  318:          BACKWARD = .TRUE.
  319:       ELSE
  320:          FORWARD = .FALSE.
  321:          BACKWARD = .FALSE.
  322:       END IF
  323: *
  324: * ---------------------------------------------------------------------------
  325: *      
  326:       IF( COLUMN .AND. FORWARD .AND. LEFT  ) THEN
  327: *
  328: * ---------------------------------------------------------------------------
  329: *
  330: *        Let  W =  [ I ]    (K-by-K)
  331: *                  [ V ]    (M-by-K)
  332: *
  333: *        Form  H C  or  H**T C  where  C = [ A ]  (K-by-N)
  334: *                                          [ B ]  (M-by-N)
  335: *
  336: *        H = I - W T W**T          or  H**T = I - W T**T W**T
  337: *
  338: *        A = A -   T (A + V**T B)  or  A = A -   T**T (A + V**T B)
  339: *        B = B - V T (A + V**T B)  or  B = B - V T**T (A + V**T B) 
  340: *
  341: * ---------------------------------------------------------------------------
  342: *
  343:          MP = MIN( M-L+1, M )
  344:          KP = MIN( L+1, K )
  345: *         
  346:          DO J = 1, N
  347:             DO I = 1, L
  348:                WORK( I, J ) = B( M-L+I, J )
  349:             END DO
  350:          END DO
  351:          CALL DTRMM( 'L', 'U', 'T', 'N', L, N, ONE, V( MP, 1 ), LDV,
  352:      $               WORK, LDWORK )         
  353:          CALL DGEMM( 'T', 'N', L, N, M-L, ONE, V, LDV, B, LDB, 
  354:      $               ONE, WORK, LDWORK )
  355:          CALL DGEMM( 'T', 'N', K-L, N, M, ONE, V( 1, KP ), LDV, 
  356:      $               B, LDB, ZERO, WORK( KP, 1 ), LDWORK )
  357: *     
  358:          DO J = 1, N
  359:             DO I = 1, K
  360:                WORK( I, J ) = WORK( I, J ) + A( I, J )
  361:             END DO
  362:          END DO
  363: *
  364:          CALL DTRMM( 'L', 'U', TRANS, 'N', K, N, ONE, T, LDT, 
  365:      $               WORK, LDWORK )
  366: *     
  367:          DO J = 1, N
  368:             DO I = 1, K
  369:                A( I, J ) = A( I, J ) - WORK( I, J )
  370:             END DO
  371:          END DO
  372: *
  373:          CALL DGEMM( 'N', 'N', M-L, N, K, -ONE, V, LDV, WORK, LDWORK,
  374:      $               ONE, B, LDB )
  375:          CALL DGEMM( 'N', 'N', L, N, K-L, -ONE, V( MP, KP ), LDV,
  376:      $               WORK( KP, 1 ), LDWORK, ONE, B( MP, 1 ),  LDB )    
  377:          CALL DTRMM( 'L', 'U', 'N', 'N', L, N, ONE, V( MP, 1 ), LDV,
  378:      $               WORK, LDWORK )
  379:          DO J = 1, N
  380:             DO I = 1, L
  381:                B( M-L+I, J ) = B( M-L+I, J ) - WORK( I, J )
  382:             END DO
  383:          END DO
  384: *
  385: * ---------------------------------------------------------------------------
  386: *      
  387:       ELSE IF( COLUMN .AND. FORWARD .AND. RIGHT ) THEN
  388: *
  389: * ---------------------------------------------------------------------------
  390: *
  391: *        Let  W =  [ I ]    (K-by-K)
  392: *                  [ V ]    (N-by-K)
  393: *
  394: *        Form  C H or  C H**T  where  C = [ A B ] (A is M-by-K, B is M-by-N)
  395: *
  396: *        H = I - W T W**T          or  H**T = I - W T**T W**T
  397: *
  398: *        A = A - (A + B V) T      or  A = A - (A + B V) T**T
  399: *        B = B - (A + B V) T V**T  or  B = B - (A + B V) T**T V**T
  400: *
  401: * ---------------------------------------------------------------------------
  402: *
  403:          NP = MIN( N-L+1, N )
  404:          KP = MIN( L+1, K )
  405: *         
  406:          DO J = 1, L
  407:             DO I = 1, M
  408:                WORK( I, J ) = B( I, N-L+J )
  409:             END DO
  410:          END DO
  411:          CALL DTRMM( 'R', 'U', 'N', 'N', M, L, ONE, V( NP, 1 ), LDV,
  412:      $               WORK, LDWORK )
  413:          CALL DGEMM( 'N', 'N', M, L, N-L, ONE, B, LDB, 
  414:      $               V, LDV, ONE, WORK, LDWORK )
  415:          CALL DGEMM( 'N', 'N', M, K-L, N, ONE, B, LDB, 
  416:      $               V( 1, KP ), LDV, ZERO, WORK( 1, KP ), LDWORK )
  417: *     
  418:          DO J = 1, K
  419:             DO I = 1, M
  420:                WORK( I, J ) = WORK( I, J ) + A( I, J )
  421:             END DO
  422:          END DO
  423: *
  424:          CALL DTRMM( 'R', 'U', TRANS, 'N', M, K, ONE, T, LDT, 
  425:      $               WORK, LDWORK )
  426: *     
  427:          DO J = 1, K
  428:             DO I = 1, M
  429:                A( I, J ) = A( I, J ) - WORK( I, J )
  430:             END DO
  431:          END DO
  432: *
  433:          CALL DGEMM( 'N', 'T', M, N-L, K, -ONE, WORK, LDWORK,
  434:      $               V, LDV, ONE, B, LDB )
  435:          CALL DGEMM( 'N', 'T', M, L, K-L, -ONE, WORK( 1, KP ), LDWORK,
  436:      $               V( NP, KP ), LDV, ONE, B( 1, NP ), LDB )
  437:          CALL DTRMM( 'R', 'U', 'T', 'N', M, L, ONE, V( NP, 1 ), LDV,
  438:      $               WORK, LDWORK )
  439:          DO J = 1, L
  440:             DO I = 1, M
  441:                B( I, N-L+J ) = B( I, N-L+J ) - WORK( I, J )
  442:             END DO
  443:          END DO
  444: *
  445: * ---------------------------------------------------------------------------
  446: *      
  447:       ELSE IF( COLUMN .AND. BACKWARD .AND. LEFT ) THEN
  448: *
  449: * ---------------------------------------------------------------------------
  450: *
  451: *        Let  W =  [ V ]    (M-by-K)
  452: *                  [ I ]    (K-by-K)
  453: *
  454: *        Form  H C  or  H**T C  where  C = [ B ]  (M-by-N)
  455: *                                          [ A ]  (K-by-N)
  456: *
  457: *        H = I - W T W**T          or  H**T = I - W T**T W**T
  458: *
  459: *        A = A -   T (A + V**T B)  or  A = A -   T**T (A + V**T B)
  460: *        B = B - V T (A + V**T B)  or  B = B - V T**T (A + V**T B) 
  461: *
  462: * ---------------------------------------------------------------------------
  463: *
  464:          MP = MIN( L+1, M )
  465:          KP = MIN( K-L+1, K )
  466: *
  467:          DO J = 1, N
  468:             DO I = 1, L
  469:                WORK( K-L+I, J ) = B( I, J )
  470:             END DO
  471:          END DO
  472: *
  473:          CALL DTRMM( 'L', 'L', 'T', 'N', L, N, ONE, V( 1, KP ), LDV,
  474:      $               WORK( KP, 1 ), LDWORK )
  475:          CALL DGEMM( 'T', 'N', L, N, M-L, ONE, V( MP, KP ), LDV, 
  476:      $               B( MP, 1 ), LDB, ONE, WORK( KP, 1 ), LDWORK )
  477:          CALL DGEMM( 'T', 'N', K-L, N, M, ONE, V, LDV,
  478:      $               B, LDB, ZERO, WORK, LDWORK )         
  479: *
  480:          DO J = 1, N
  481:             DO I = 1, K
  482:                WORK( I, J ) = WORK( I, J ) + A( I, J )
  483:             END DO
  484:          END DO
  485: *
  486:          CALL DTRMM( 'L', 'L', TRANS, 'N', K, N, ONE, T, LDT, 
  487:      $               WORK, LDWORK )
  488: *     
  489:          DO J = 1, N
  490:             DO I = 1, K
  491:                A( I, J ) = A( I, J ) - WORK( I, J )
  492:             END DO
  493:          END DO
  494: *
  495:          CALL DGEMM( 'N', 'N', M-L, N, K, -ONE, V( MP, 1 ), LDV, 
  496:      $               WORK, LDWORK, ONE, B( MP, 1 ), LDB )
  497:          CALL DGEMM( 'N', 'N', L, N, K-L, -ONE, V, LDV,
  498:      $               WORK, LDWORK, ONE, B,  LDB )
  499:          CALL DTRMM( 'L', 'L', 'N', 'N', L, N, ONE, V( 1, KP ), LDV,
  500:      $               WORK( KP, 1 ), LDWORK )
  501:          DO J = 1, N
  502:             DO I = 1, L
  503:                B( I, J ) = B( I, J ) - WORK( K-L+I, J )
  504:             END DO
  505:          END DO
  506: *
  507: * ---------------------------------------------------------------------------
  508: *      
  509:       ELSE IF( COLUMN .AND. BACKWARD .AND. RIGHT ) THEN
  510: *
  511: * ---------------------------------------------------------------------------
  512: *
  513: *        Let  W =  [ V ]    (N-by-K)
  514: *                  [ I ]    (K-by-K)
  515: *
  516: *        Form  C H  or  C H**T  where  C = [ B A ] (B is M-by-N, A is M-by-K)
  517: *
  518: *        H = I - W T W**T          or  H**T = I - W T**T W**T
  519: *
  520: *        A = A - (A + B V) T      or  A = A - (A + B V) T**T
  521: *        B = B - (A + B V) T V**T  or  B = B - (A + B V) T**T V**T
  522: *
  523: * ---------------------------------------------------------------------------
  524: *
  525:          NP = MIN( L+1, N )
  526:          KP = MIN( K-L+1, K )
  527: *         
  528:          DO J = 1, L
  529:             DO I = 1, M
  530:                WORK( I, K-L+J ) = B( I, J )
  531:             END DO
  532:          END DO
  533:          CALL DTRMM( 'R', 'L', 'N', 'N', M, L, ONE, V( 1, KP ), LDV,
  534:      $               WORK( 1, KP ), LDWORK )
  535:          CALL DGEMM( 'N', 'N', M, L, N-L, ONE, B( 1, NP ), LDB, 
  536:      $               V( NP, KP ), LDV, ONE, WORK( 1, KP ), LDWORK )
  537:          CALL DGEMM( 'N', 'N', M, K-L, N, ONE, B, LDB, 
  538:      $               V, LDV, ZERO, WORK, LDWORK )
  539: *     
  540:          DO J = 1, K
  541:             DO I = 1, M
  542:                WORK( I, J ) = WORK( I, J ) + A( I, J )
  543:             END DO
  544:          END DO
  545: *
  546:          CALL DTRMM( 'R', 'L', TRANS, 'N', M, K, ONE, T, LDT, 
  547:      $               WORK, LDWORK )
  548: *     
  549:          DO J = 1, K
  550:             DO I = 1, M
  551:                A( I, J ) = A( I, J ) - WORK( I, J )
  552:             END DO
  553:          END DO
  554: *
  555:          CALL DGEMM( 'N', 'T', M, N-L, K, -ONE, WORK, LDWORK,
  556:      $               V( NP, 1 ), LDV, ONE, B( 1, NP ), LDB )
  557:          CALL DGEMM( 'N', 'T', M, L, K-L, -ONE, WORK, LDWORK,
  558:      $               V, LDV, ONE, B, LDB )
  559:          CALL DTRMM( 'R', 'L', 'T', 'N', M, L, ONE, V( 1, KP ), LDV,
  560:      $               WORK( 1, KP ), LDWORK )
  561:          DO J = 1, L
  562:             DO I = 1, M
  563:                B( I, J ) = B( I, J ) - WORK( I, K-L+J )
  564:             END DO
  565:          END DO
  566: *
  567: * ---------------------------------------------------------------------------
  568: *      
  569:       ELSE IF( ROW .AND. FORWARD .AND. LEFT ) THEN
  570: *
  571: * ---------------------------------------------------------------------------
  572: *
  573: *        Let  W =  [ I V ] ( I is K-by-K, V is K-by-M )
  574: *
  575: *        Form  H C  or  H**T C  where  C = [ A ]  (K-by-N)
  576: *                                          [ B ]  (M-by-N)
  577: *
  578: *        H = I - W**T T W          or  H**T = I - W**T T**T W
  579: *
  580: *        A = A -     T (A + V B)  or  A = A -     T**T (A + V B)
  581: *        B = B - V**T T (A + V B)  or  B = B - V**T T**T (A + V B) 
  582: *
  583: * ---------------------------------------------------------------------------
  584: *
  585:          MP = MIN( M-L+1, M )
  586:          KP = MIN( L+1, K )
  587: *
  588:          DO J = 1, N
  589:             DO I = 1, L
  590:                WORK( I, J ) = B( M-L+I, J )
  591:             END DO
  592:          END DO 
  593:          CALL DTRMM( 'L', 'L', 'N', 'N', L, N, ONE, V( 1, MP ), LDV,
  594:      $               WORK, LDB )
  595:          CALL DGEMM( 'N', 'N', L, N, M-L, ONE, V, LDV,B, LDB, 
  596:      $               ONE, WORK, LDWORK )
  597:          CALL DGEMM( 'N', 'N', K-L, N, M, ONE, V( KP, 1 ), LDV, 
  598:      $               B, LDB, ZERO, WORK( KP, 1 ), LDWORK )
  599: *
  600:          DO J = 1, N
  601:             DO I = 1, K
  602:                WORK( I, J ) = WORK( I, J ) + A( I, J )
  603:             END DO
  604:          END DO
  605: *
  606:          CALL DTRMM( 'L', 'U', TRANS, 'N', K, N, ONE, T, LDT, 
  607:      $               WORK, LDWORK )
  608: *
  609:          DO J = 1, N
  610:             DO I = 1, K
  611:                A( I, J ) = A( I, J ) - WORK( I, J )
  612:             END DO
  613:          END DO
  614: *
  615:          CALL DGEMM( 'T', 'N', M-L, N, K, -ONE, V, LDV, WORK, LDWORK,
  616:      $               ONE, B, LDB )
  617:          CALL DGEMM( 'T', 'N', L, N, K-L, -ONE, V( KP, MP ), LDV, 
  618:      $               WORK( KP, 1 ), LDWORK, ONE, B( MP, 1 ), LDB )
  619:          CALL DTRMM( 'L', 'L', 'T', 'N', L, N, ONE, V( 1, MP ), LDV,
  620:      $               WORK, LDWORK )
  621:          DO J = 1, N
  622:             DO I = 1, L
  623:                B( M-L+I, J ) = B( M-L+I, J ) - WORK( I, J )
  624:             END DO
  625:          END DO
  626: *
  627: * ---------------------------------------------------------------------------
  628: *      
  629:       ELSE IF( ROW .AND. FORWARD .AND. RIGHT ) THEN
  630: *
  631: * ---------------------------------------------------------------------------
  632: *
  633: *        Let  W =  [ I V ] ( I is K-by-K, V is K-by-N )
  634: *
  635: *        Form  C H  or  C H**T  where  C = [ A B ] (A is M-by-K, B is M-by-N)
  636: *
  637: *        H = I - W**T T W            or  H**T = I - W**T T**T W
  638: *
  639: *        A = A - (A + B V**T) T      or  A = A - (A + B V**T) T**T
  640: *        B = B - (A + B V**T) T V    or  B = B - (A + B V**T) T**T V
  641: *
  642: * ---------------------------------------------------------------------------
  643: *
  644:          NP = MIN( N-L+1, N )
  645:          KP = MIN( L+1, K )
  646: *
  647:          DO J = 1, L
  648:             DO I = 1, M
  649:                WORK( I, J ) = B( I, N-L+J )
  650:             END DO
  651:          END DO
  652:          CALL DTRMM( 'R', 'L', 'T', 'N', M, L, ONE, V( 1, NP ), LDV,
  653:      $               WORK, LDWORK )
  654:          CALL DGEMM( 'N', 'T', M, L, N-L, ONE, B, LDB, V, LDV,
  655:      $               ONE, WORK, LDWORK )
  656:          CALL DGEMM( 'N', 'T', M, K-L, N, ONE, B, LDB, 
  657:      $               V( KP, 1 ), LDV, ZERO, WORK( 1, KP ), LDWORK )
  658: *
  659:          DO J = 1, K
  660:             DO I = 1, M
  661:                WORK( I, J ) = WORK( I, J ) + A( I, J )
  662:             END DO
  663:          END DO
  664: *
  665:          CALL DTRMM( 'R', 'U', TRANS, 'N', M, K, ONE, T, LDT, 
  666:      $               WORK, LDWORK )
  667: *
  668:          DO J = 1, K
  669:             DO I = 1, M
  670:                A( I, J ) = A( I, J ) - WORK( I, J )
  671:             END DO
  672:          END DO
  673: *
  674:          CALL DGEMM( 'N', 'N', M, N-L, K, -ONE, WORK, LDWORK, 
  675:      $               V, LDV, ONE, B, LDB )
  676:          CALL DGEMM( 'N', 'N', M, L, K-L, -ONE, WORK( 1, KP ), LDWORK,
  677:      $               V( KP, NP ), LDV, ONE, B( 1, NP ), LDB )   
  678:          CALL DTRMM( '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: *        Let  W =  [ V I ] ( I is K-by-K, V is K-by-M )
  693: *
  694: *        Form  H C  or  H**T C  where  C = [ B ]  (M-by-N)
  695: *                                          [ A ]  (K-by-N)
  696: *
  697: *        H = I - W**T T W          or  H**T = I - W**T T**T W
  698: *
  699: *        A = A -     T (A + V B)  or  A = A -     T**T (A + V B)
  700: *        B = B - V**T T (A + V B)  or  B = B - V**T T**T (A + V B) 
  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 DTRMM( 'L', 'U', 'N', 'N', L, N, ONE, V( KP, 1 ), LDV,
  713:      $               WORK( KP, 1 ), LDWORK )
  714:          CALL DGEMM( 'N', 'N', L, N, M-L, ONE, V( KP, MP ), LDV,
  715:      $               B( MP, 1 ), LDB, ONE, WORK( KP, 1 ), LDWORK )
  716:          CALL DGEMM( '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 DTRMM( '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 DGEMM( 'T', 'N', M-L, N, K, -ONE, V( 1, MP ), LDV,
  735:      $               WORK, LDWORK, ONE, B( MP, 1 ), LDB )
  736:          CALL DGEMM( 'T', 'N', L, N, K-L, -ONE, V, LDV, 
  737:      $               WORK, LDWORK, ONE, B, LDB )
  738:          CALL DTRMM( 'L', 'U', 'T', '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: *        Let  W =  [ V I ] ( I is K-by-K, V is K-by-N )
  753: *
  754: *        Form  C H  or  C H**T  where  C = [ B A ] (A is M-by-K, B is M-by-N)
  755: *
  756: *        H = I - W**T T W            or  H**T = I - W**T T**T W
  757: *
  758: *        A = A - (A + B V**T) T      or  A = A - (A + B V**T) T**T
  759: *        B = B - (A + B V**T) T V    or  B = B - (A + B V**T) T**T V
  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 DTRMM( 'R', 'U', 'T', 'N', M, L, ONE, V( KP, 1 ), LDV,
  772:      $               WORK( 1, KP ), LDWORK )
  773:          CALL DGEMM( 'N', 'T', M, L, N-L, ONE, B( 1, NP ), LDB,
  774:      $               V( KP, NP ), LDV, ONE, WORK( 1, KP ), LDWORK )
  775:          CALL DGEMM( 'N', 'T', 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 DTRMM( '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 DGEMM( 'N', 'N', M, N-L, K, -ONE, WORK, LDWORK, 
  794:      $               V( 1, NP ), LDV, ONE, B( 1, NP ), LDB )
  795:          CALL DGEMM( 'N', 'N', M, L, K-L , -ONE, WORK, LDWORK,    
  796:      $               V, LDV, ONE, B, LDB )
  797:          CALL DTRMM( '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: *     End of DTPRFB
  810: *
  811:       END

CVSweb interface <joel.bertrand@systella.fr>