File:  [local] / rpl / lapack / lapack / dtfsm.f
Revision 1.17: download - view: text, annotated - select for diffs - revision graph
Mon Aug 7 08:39:12 2023 UTC (9 months ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_1_35, rpl-4_1_34, HEAD
Première mise à jour de lapack et blas.

    1: *> \brief \b DTFSM solves a matrix equation (one operand is a triangular matrix in RFP format).
    2: *
    3: *  =========== DOCUMENTATION ===========
    4: *
    5: * Online html documentation available at
    6: *            http://www.netlib.org/lapack/explore-html/
    7: *
    8: *> \htmlonly
    9: *> Download DTFSM + dependencies
   10: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtfsm.f">
   11: *> [TGZ]</a>
   12: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtfsm.f">
   13: *> [ZIP]</a>
   14: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtfsm.f">
   15: *> [TXT]</a>
   16: *> \endhtmlonly
   17: *
   18: *  Definition:
   19: *  ===========
   20: *
   21: *       SUBROUTINE DTFSM( TRANSR, SIDE, UPLO, TRANS, DIAG, M, N, ALPHA, A,
   22: *                         B, LDB )
   23: *
   24: *       .. Scalar Arguments ..
   25: *       CHARACTER          TRANSR, DIAG, SIDE, TRANS, UPLO
   26: *       INTEGER            LDB, M, N
   27: *       DOUBLE PRECISION   ALPHA
   28: *       ..
   29: *       .. Array Arguments ..
   30: *       DOUBLE PRECISION   A( 0: * ), B( 0: LDB-1, 0: * )
   31: *       ..
   32: *
   33: *
   34: *> \par Purpose:
   35: *  =============
   36: *>
   37: *> \verbatim
   38: *>
   39: *> Level 3 BLAS like routine for A in RFP Format.
   40: *>
   41: *> DTFSM  solves the matrix equation
   42: *>
   43: *>    op( A )*X = alpha*B  or  X*op( A ) = alpha*B
   44: *>
   45: *> where alpha is a scalar, X and B are m by n matrices, A is a unit, or
   46: *> non-unit,  upper or lower triangular matrix  and  op( A )  is one  of
   47: *>
   48: *>    op( A ) = A   or   op( A ) = A**T.
   49: *>
   50: *> A is in Rectangular Full Packed (RFP) Format.
   51: *>
   52: *> The matrix X is overwritten on B.
   53: *> \endverbatim
   54: *
   55: *  Arguments:
   56: *  ==========
   57: *
   58: *> \param[in] TRANSR
   59: *> \verbatim
   60: *>          TRANSR is CHARACTER*1
   61: *>          = 'N':  The Normal Form of RFP A is stored;
   62: *>          = 'T':  The Transpose Form of RFP A is stored.
   63: *> \endverbatim
   64: *>
   65: *> \param[in] SIDE
   66: *> \verbatim
   67: *>          SIDE is CHARACTER*1
   68: *>           On entry, SIDE specifies whether op( A ) appears on the left
   69: *>           or right of X as follows:
   70: *>
   71: *>              SIDE = 'L' or 'l'   op( A )*X = alpha*B.
   72: *>
   73: *>              SIDE = 'R' or 'r'   X*op( A ) = alpha*B.
   74: *>
   75: *>           Unchanged on exit.
   76: *> \endverbatim
   77: *>
   78: *> \param[in] UPLO
   79: *> \verbatim
   80: *>          UPLO is CHARACTER*1
   81: *>           On entry, UPLO specifies whether the RFP matrix A came from
   82: *>           an upper or lower triangular matrix as follows:
   83: *>           UPLO = 'U' or 'u' RFP A came from an upper triangular matrix
   84: *>           UPLO = 'L' or 'l' RFP A came from a  lower triangular matrix
   85: *>
   86: *>           Unchanged on exit.
   87: *> \endverbatim
   88: *>
   89: *> \param[in] TRANS
   90: *> \verbatim
   91: *>          TRANS is CHARACTER*1
   92: *>           On entry, TRANS  specifies the form of op( A ) to be used
   93: *>           in the matrix multiplication as follows:
   94: *>
   95: *>              TRANS  = 'N' or 'n'   op( A ) = A.
   96: *>
   97: *>              TRANS  = 'T' or 't'   op( A ) = A'.
   98: *>
   99: *>           Unchanged on exit.
  100: *> \endverbatim
  101: *>
  102: *> \param[in] DIAG
  103: *> \verbatim
  104: *>          DIAG is CHARACTER*1
  105: *>           On entry, DIAG specifies whether or not RFP A is unit
  106: *>           triangular as follows:
  107: *>
  108: *>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
  109: *>
  110: *>              DIAG = 'N' or 'n'   A is not assumed to be unit
  111: *>                                  triangular.
  112: *>
  113: *>           Unchanged on exit.
  114: *> \endverbatim
  115: *>
  116: *> \param[in] M
  117: *> \verbatim
  118: *>          M is INTEGER
  119: *>           On entry, M specifies the number of rows of B. M must be at
  120: *>           least zero.
  121: *>           Unchanged on exit.
  122: *> \endverbatim
  123: *>
  124: *> \param[in] N
  125: *> \verbatim
  126: *>          N is INTEGER
  127: *>           On entry, N specifies the number of columns of B.  N must be
  128: *>           at least zero.
  129: *>           Unchanged on exit.
  130: *> \endverbatim
  131: *>
  132: *> \param[in] ALPHA
  133: *> \verbatim
  134: *>          ALPHA is DOUBLE PRECISION
  135: *>           On entry,  ALPHA specifies the scalar  alpha. When  alpha is
  136: *>           zero then  A is not referenced and  B need not be set before
  137: *>           entry.
  138: *>           Unchanged on exit.
  139: *> \endverbatim
  140: *>
  141: *> \param[in] A
  142: *> \verbatim
  143: *>          A is DOUBLE PRECISION array, dimension (NT)
  144: *>           NT = N*(N+1)/2. On entry, the matrix A in RFP Format.
  145: *>           RFP Format is described by TRANSR, UPLO and N as follows:
  146: *>           If TRANSR='N' then RFP A is (0:N,0:K-1) when N is even;
  147: *>           K=N/2. RFP A is (0:N-1,0:K) when N is odd; K=N/2. If
  148: *>           TRANSR = 'T' then RFP is the transpose of RFP A as
  149: *>           defined when TRANSR = 'N'. The contents of RFP A are defined
  150: *>           by UPLO as follows: If UPLO = 'U' the RFP A contains the NT
  151: *>           elements of upper packed A either in normal or
  152: *>           transpose Format. If UPLO = 'L' the RFP A contains
  153: *>           the NT elements of lower packed A either in normal or
  154: *>           transpose Format. The LDA of RFP A is (N+1)/2 when
  155: *>           TRANSR = 'T'. When TRANSR is 'N' the LDA is N+1 when N is
  156: *>           even and is N when is odd.
  157: *>           See the Note below for more details. Unchanged on exit.
  158: *> \endverbatim
  159: *>
  160: *> \param[in,out] B
  161: *> \verbatim
  162: *>          B is DOUBLE PRECISION array, dimension (LDB,N)
  163: *>           Before entry,  the leading  m by n part of the array  B must
  164: *>           contain  the  right-hand  side  matrix  B,  and  on exit  is
  165: *>           overwritten by the solution matrix  X.
  166: *> \endverbatim
  167: *>
  168: *> \param[in] LDB
  169: *> \verbatim
  170: *>          LDB is INTEGER
  171: *>           On entry, LDB specifies the first dimension of B as declared
  172: *>           in  the  calling  (sub)  program.   LDB  must  be  at  least
  173: *>           max( 1, m ).
  174: *>           Unchanged on exit.
  175: *> \endverbatim
  176: *
  177: *  Authors:
  178: *  ========
  179: *
  180: *> \author Univ. of Tennessee
  181: *> \author Univ. of California Berkeley
  182: *> \author Univ. of Colorado Denver
  183: *> \author NAG Ltd.
  184: *
  185: *> \ingroup doubleOTHERcomputational
  186: *
  187: *> \par Further Details:
  188: *  =====================
  189: *>
  190: *> \verbatim
  191: *>
  192: *>  We first consider Rectangular Full Packed (RFP) Format when N is
  193: *>  even. We give an example where N = 6.
  194: *>
  195: *>      AP is Upper             AP is Lower
  196: *>
  197: *>   00 01 02 03 04 05       00
  198: *>      11 12 13 14 15       10 11
  199: *>         22 23 24 25       20 21 22
  200: *>            33 34 35       30 31 32 33
  201: *>               44 45       40 41 42 43 44
  202: *>                  55       50 51 52 53 54 55
  203: *>
  204: *>
  205: *>  Let TRANSR = 'N'. RFP holds AP as follows:
  206: *>  For UPLO = 'U' the upper trapezoid A(0:5,0:2) consists of the last
  207: *>  three columns of AP upper. The lower triangle A(4:6,0:2) consists of
  208: *>  the transpose of the first three columns of AP upper.
  209: *>  For UPLO = 'L' the lower trapezoid A(1:6,0:2) consists of the first
  210: *>  three columns of AP lower. The upper triangle A(0:2,0:2) consists of
  211: *>  the transpose of the last three columns of AP lower.
  212: *>  This covers the case N even and TRANSR = 'N'.
  213: *>
  214: *>         RFP A                   RFP A
  215: *>
  216: *>        03 04 05                33 43 53
  217: *>        13 14 15                00 44 54
  218: *>        23 24 25                10 11 55
  219: *>        33 34 35                20 21 22
  220: *>        00 44 45                30 31 32
  221: *>        01 11 55                40 41 42
  222: *>        02 12 22                50 51 52
  223: *>
  224: *>  Now let TRANSR = 'T'. RFP A in both UPLO cases is just the
  225: *>  transpose of RFP A above. One therefore gets:
  226: *>
  227: *>
  228: *>           RFP A                   RFP A
  229: *>
  230: *>     03 13 23 33 00 01 02    33 00 10 20 30 40 50
  231: *>     04 14 24 34 44 11 12    43 44 11 21 31 41 51
  232: *>     05 15 25 35 45 55 22    53 54 55 22 32 42 52
  233: *>
  234: *>
  235: *>  We then consider Rectangular Full Packed (RFP) Format when N is
  236: *>  odd. We give an example where N = 5.
  237: *>
  238: *>     AP is Upper                 AP is Lower
  239: *>
  240: *>   00 01 02 03 04              00
  241: *>      11 12 13 14              10 11
  242: *>         22 23 24              20 21 22
  243: *>            33 34              30 31 32 33
  244: *>               44              40 41 42 43 44
  245: *>
  246: *>
  247: *>  Let TRANSR = 'N'. RFP holds AP as follows:
  248: *>  For UPLO = 'U' the upper trapezoid A(0:4,0:2) consists of the last
  249: *>  three columns of AP upper. The lower triangle A(3:4,0:1) consists of
  250: *>  the transpose of the first two columns of AP upper.
  251: *>  For UPLO = 'L' the lower trapezoid A(0:4,0:2) consists of the first
  252: *>  three columns of AP lower. The upper triangle A(0:1,1:2) consists of
  253: *>  the transpose of the last two columns of AP lower.
  254: *>  This covers the case N odd and TRANSR = 'N'.
  255: *>
  256: *>         RFP A                   RFP A
  257: *>
  258: *>        02 03 04                00 33 43
  259: *>        12 13 14                10 11 44
  260: *>        22 23 24                20 21 22
  261: *>        00 33 34                30 31 32
  262: *>        01 11 44                40 41 42
  263: *>
  264: *>  Now let TRANSR = 'T'. RFP A in both UPLO cases is just the
  265: *>  transpose of RFP A above. One therefore gets:
  266: *>
  267: *>           RFP A                   RFP A
  268: *>
  269: *>     02 12 22 00 01             00 10 20 30 40 50
  270: *>     03 13 23 33 11             33 11 21 31 41 51
  271: *>     04 14 24 34 44             43 44 22 32 42 52
  272: *> \endverbatim
  273: *
  274: *  =====================================================================
  275:       SUBROUTINE DTFSM( TRANSR, SIDE, UPLO, TRANS, DIAG, M, N, ALPHA, A,
  276:      $                  B, LDB )
  277: *
  278: *  -- LAPACK computational routine --
  279: *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
  280: *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  281: *
  282: *     .. Scalar Arguments ..
  283:       CHARACTER          TRANSR, DIAG, SIDE, TRANS, UPLO
  284:       INTEGER            LDB, M, N
  285:       DOUBLE PRECISION   ALPHA
  286: *     ..
  287: *     .. Array Arguments ..
  288:       DOUBLE PRECISION   A( 0: * ), B( 0: LDB-1, 0: * )
  289: *     ..
  290: *
  291: *  =====================================================================
  292: *
  293: *     ..
  294: *     .. Parameters ..
  295:       DOUBLE PRECISION   ONE, ZERO
  296:       PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
  297: *     ..
  298: *     .. Local Scalars ..
  299:       LOGICAL            LOWER, LSIDE, MISODD, NISODD, NORMALTRANSR,
  300:      $                   NOTRANS
  301:       INTEGER            M1, M2, N1, N2, K, INFO, I, J
  302: *     ..
  303: *     .. External Functions ..
  304:       LOGICAL            LSAME
  305:       EXTERNAL           LSAME
  306: *     ..
  307: *     .. External Subroutines ..
  308:       EXTERNAL           XERBLA, DGEMM, DTRSM
  309: *     ..
  310: *     .. Intrinsic Functions ..
  311:       INTRINSIC          MAX, MOD
  312: *     ..
  313: *     .. Executable Statements ..
  314: *
  315: *     Test the input parameters.
  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. .NOT.LSAME( DIAG, 'U' ) )
  331:      $         THEN
  332:          INFO = -5
  333:       ELSE IF( M.LT.0 ) THEN
  334:          INFO = -6
  335:       ELSE IF( N.LT.0 ) THEN
  336:          INFO = -7
  337:       ELSE IF( LDB.LT.MAX( 1, M ) ) THEN
  338:          INFO = -11
  339:       END IF
  340:       IF( INFO.NE.0 ) THEN
  341:          CALL XERBLA( 'DTFSM ', -INFO )
  342:          RETURN
  343:       END IF
  344: *
  345: *     Quick return when ( (N.EQ.0).OR.(M.EQ.0) )
  346: *
  347:       IF( ( M.EQ.0 ) .OR. ( N.EQ.0 ) )
  348:      $   RETURN
  349: *
  350: *     Quick return when ALPHA.EQ.(0D+0)
  351: *
  352:       IF( ALPHA.EQ.ZERO ) THEN
  353:          DO 20 J = 0, N - 1
  354:             DO 10 I = 0, M - 1
  355:                B( I, J ) = ZERO
  356:    10       CONTINUE
  357:    20    CONTINUE
  358:          RETURN
  359:       END IF
  360: *
  361:       IF( LSIDE ) THEN
  362: *
  363: *        SIDE = 'L'
  364: *
  365: *        A is M-by-M.
  366: *        If M is odd, set NISODD = .TRUE., and M1 and M2.
  367: *        If M is even, NISODD = .FALSE., and M.
  368: *
  369:          IF( MOD( M, 2 ).EQ.0 ) THEN
  370:             MISODD = .FALSE.
  371:             K = M / 2
  372:          ELSE
  373:             MISODD = .TRUE.
  374:             IF( LOWER ) THEN
  375:                M2 = M / 2
  376:                M1 = M - M2
  377:             ELSE
  378:                M1 = M / 2
  379:                M2 = M - M1
  380:             END IF
  381:          END IF
  382: *
  383: *
  384:          IF( MISODD ) THEN
  385: *
  386: *           SIDE = 'L' and N is odd
  387: *
  388:             IF( NORMALTRANSR ) THEN
  389: *
  390: *              SIDE = 'L', N is odd, and TRANSR = 'N'
  391: *
  392:                IF( LOWER ) THEN
  393: *
  394: *                 SIDE  ='L', N is odd, TRANSR = 'N', and UPLO = 'L'
  395: *
  396:                   IF( NOTRANS ) THEN
  397: *
  398: *                    SIDE  ='L', N is odd, TRANSR = 'N', UPLO = 'L', and
  399: *                    TRANS = 'N'
  400: *
  401:                      IF( M.EQ.1 ) THEN
  402:                         CALL DTRSM( 'L', 'L', 'N', DIAG, M1, N, ALPHA,
  403:      $                              A, M, B, LDB )
  404:                      ELSE
  405:                         CALL DTRSM( 'L', 'L', 'N', DIAG, M1, N, ALPHA,
  406:      $                              A( 0 ), M, B, LDB )
  407:                         CALL DGEMM( 'N', 'N', M2, N, M1, -ONE, A( M1 ),
  408:      $                              M, B, LDB, ALPHA, B( M1, 0 ), LDB )
  409:                         CALL DTRSM( 'L', 'U', 'T', DIAG, M2, N, ONE,
  410:      $                              A( M ), M, B( M1, 0 ), LDB )
  411:                      END IF
  412: *
  413:                   ELSE
  414: *
  415: *                    SIDE  ='L', N is odd, TRANSR = 'N', UPLO = 'L', and
  416: *                    TRANS = 'T'
  417: *
  418:                      IF( M.EQ.1 ) THEN
  419:                         CALL DTRSM( 'L', 'L', 'T', DIAG, M1, N, ALPHA,
  420:      $                              A( 0 ), M, B, LDB )
  421:                      ELSE
  422:                         CALL DTRSM( 'L', 'U', 'N', DIAG, M2, N, ALPHA,
  423:      $                              A( M ), M, B( M1, 0 ), LDB )
  424:                         CALL DGEMM( 'T', 'N', M1, N, M2, -ONE, A( M1 ),
  425:      $                              M, B( M1, 0 ), LDB, ALPHA, B, LDB )
  426:                         CALL DTRSM( 'L', 'L', 'T', DIAG, M1, N, ONE,
  427:      $                              A( 0 ), M, B, LDB )
  428:                      END IF
  429: *
  430:                   END IF
  431: *
  432:                ELSE
  433: *
  434: *                 SIDE  ='L', N is odd, TRANSR = 'N', and UPLO = 'U'
  435: *
  436:                   IF( .NOT.NOTRANS ) THEN
  437: *
  438: *                    SIDE  ='L', N is odd, TRANSR = 'N', UPLO = 'U', and
  439: *                    TRANS = 'N'
  440: *
  441:                      CALL DTRSM( 'L', 'L', 'N', DIAG, M1, N, ALPHA,
  442:      $                           A( M2 ), M, B, LDB )
  443:                      CALL DGEMM( 'T', 'N', M2, N, M1, -ONE, A( 0 ), M,
  444:      $                           B, LDB, ALPHA, B( M1, 0 ), LDB )
  445:                      CALL DTRSM( 'L', 'U', 'T', DIAG, M2, N, ONE,
  446:      $                           A( M1 ), M, B( M1, 0 ), LDB )
  447: *
  448:                   ELSE
  449: *
  450: *                    SIDE  ='L', N is odd, TRANSR = 'N', UPLO = 'U', and
  451: *                    TRANS = 'T'
  452: *
  453:                      CALL DTRSM( 'L', 'U', 'N', DIAG, M2, N, ALPHA,
  454:      $                           A( M1 ), M, B( M1, 0 ), LDB )
  455:                      CALL DGEMM( 'N', 'N', M1, N, M2, -ONE, A( 0 ), M,
  456:      $                           B( M1, 0 ), LDB, ALPHA, B, LDB )
  457:                      CALL DTRSM( 'L', 'L', 'T', DIAG, M1, N, ONE,
  458:      $                           A( M2 ), M, B, LDB )
  459: *
  460:                   END IF
  461: *
  462:                END IF
  463: *
  464:             ELSE
  465: *
  466: *              SIDE = 'L', N is odd, and TRANSR = 'T'
  467: *
  468:                IF( LOWER ) THEN
  469: *
  470: *                 SIDE  ='L', N is odd, TRANSR = 'T', and UPLO = 'L'
  471: *
  472:                   IF( NOTRANS ) THEN
  473: *
  474: *                    SIDE  ='L', N is odd, TRANSR = 'T', UPLO = 'L', and
  475: *                    TRANS = 'N'
  476: *
  477:                      IF( M.EQ.1 ) THEN
  478:                         CALL DTRSM( 'L', 'U', 'T', DIAG, M1, N, ALPHA,
  479:      $                              A( 0 ), M1, B, LDB )
  480:                      ELSE
  481:                         CALL DTRSM( 'L', 'U', 'T', DIAG, M1, N, ALPHA,
  482:      $                              A( 0 ), M1, B, LDB )
  483:                         CALL DGEMM( 'T', 'N', M2, N, M1, -ONE,
  484:      $                              A( M1*M1 ), M1, B, LDB, ALPHA,
  485:      $                              B( M1, 0 ), LDB )
  486:                         CALL DTRSM( 'L', 'L', 'N', DIAG, M2, N, ONE,
  487:      $                              A( 1 ), M1, B( M1, 0 ), LDB )
  488:                      END IF
  489: *
  490:                   ELSE
  491: *
  492: *                    SIDE  ='L', N is odd, TRANSR = 'T', UPLO = 'L', and
  493: *                    TRANS = 'T'
  494: *
  495:                      IF( M.EQ.1 ) THEN
  496:                         CALL DTRSM( 'L', 'U', 'N', DIAG, M1, N, ALPHA,
  497:      $                              A( 0 ), M1, B, LDB )
  498:                      ELSE
  499:                         CALL DTRSM( 'L', 'L', 'T', DIAG, M2, N, ALPHA,
  500:      $                              A( 1 ), M1, B( M1, 0 ), LDB )
  501:                         CALL DGEMM( 'N', 'N', M1, N, M2, -ONE,
  502:      $                              A( M1*M1 ), M1, B( M1, 0 ), LDB,
  503:      $                              ALPHA, B, LDB )
  504:                         CALL DTRSM( 'L', 'U', 'N', DIAG, M1, N, ONE,
  505:      $                              A( 0 ), M1, B, LDB )
  506:                      END IF
  507: *
  508:                   END IF
  509: *
  510:                ELSE
  511: *
  512: *                 SIDE  ='L', N is odd, TRANSR = 'T', and UPLO = 'U'
  513: *
  514:                   IF( .NOT.NOTRANS ) THEN
  515: *
  516: *                    SIDE  ='L', N is odd, TRANSR = 'T', UPLO = 'U', and
  517: *                    TRANS = 'N'
  518: *
  519:                      CALL DTRSM( 'L', 'U', 'T', DIAG, M1, N, ALPHA,
  520:      $                           A( M2*M2 ), M2, B, LDB )
  521:                      CALL DGEMM( 'N', 'N', M2, N, M1, -ONE, A( 0 ), M2,
  522:      $                           B, LDB, ALPHA, B( M1, 0 ), LDB )
  523:                      CALL DTRSM( 'L', 'L', 'N', DIAG, M2, N, ONE,
  524:      $                           A( M1*M2 ), M2, B( M1, 0 ), LDB )
  525: *
  526:                   ELSE
  527: *
  528: *                    SIDE  ='L', N is odd, TRANSR = 'T', UPLO = 'U', and
  529: *                    TRANS = 'T'
  530: *
  531:                      CALL DTRSM( 'L', 'L', 'T', DIAG, M2, N, ALPHA,
  532:      $                           A( M1*M2 ), M2, B( M1, 0 ), LDB )
  533:                      CALL DGEMM( 'T', 'N', M1, N, M2, -ONE, A( 0 ), M2,
  534:      $                           B( M1, 0 ), LDB, ALPHA, B, LDB )
  535:                      CALL DTRSM( 'L', 'U', 'N', DIAG, M1, N, ONE,
  536:      $                           A( M2*M2 ), M2, B, LDB )
  537: *
  538:                   END IF
  539: *
  540:                END IF
  541: *
  542:             END IF
  543: *
  544:          ELSE
  545: *
  546: *           SIDE = 'L' and N is even
  547: *
  548:             IF( NORMALTRANSR ) THEN
  549: *
  550: *              SIDE = 'L', N is even, and TRANSR = 'N'
  551: *
  552:                IF( LOWER ) THEN
  553: *
  554: *                 SIDE  ='L', N is even, TRANSR = 'N', and UPLO = 'L'
  555: *
  556:                   IF( NOTRANS ) THEN
  557: *
  558: *                    SIDE  ='L', N is even, TRANSR = 'N', UPLO = 'L',
  559: *                    and TRANS = 'N'
  560: *
  561:                      CALL DTRSM( 'L', 'L', 'N', DIAG, K, N, ALPHA,
  562:      $                           A( 1 ), M+1, B, LDB )
  563:                      CALL DGEMM( 'N', 'N', K, N, K, -ONE, A( K+1 ),
  564:      $                           M+1, B, LDB, ALPHA, B( K, 0 ), LDB )
  565:                      CALL DTRSM( 'L', 'U', 'T', DIAG, K, N, ONE,
  566:      $                           A( 0 ), M+1, B( K, 0 ), LDB )
  567: *
  568:                   ELSE
  569: *
  570: *                    SIDE  ='L', N is even, TRANSR = 'N', UPLO = 'L',
  571: *                    and TRANS = 'T'
  572: *
  573:                      CALL DTRSM( 'L', 'U', 'N', DIAG, K, N, ALPHA,
  574:      $                           A( 0 ), M+1, B( K, 0 ), LDB )
  575:                      CALL DGEMM( 'T', 'N', K, N, K, -ONE, A( K+1 ),
  576:      $                           M+1, B( K, 0 ), LDB, ALPHA, B, LDB )
  577:                      CALL DTRSM( 'L', 'L', 'T', DIAG, K, N, ONE,
  578:      $                           A( 1 ), M+1, B, LDB )
  579: *
  580:                   END IF
  581: *
  582:                ELSE
  583: *
  584: *                 SIDE  ='L', N is even, TRANSR = 'N', and UPLO = 'U'
  585: *
  586:                   IF( .NOT.NOTRANS ) THEN
  587: *
  588: *                    SIDE  ='L', N is even, TRANSR = 'N', UPLO = 'U',
  589: *                    and TRANS = 'N'
  590: *
  591:                      CALL DTRSM( 'L', 'L', 'N', DIAG, K, N, ALPHA,
  592:      $                           A( K+1 ), M+1, B, LDB )
  593:                      CALL DGEMM( 'T', 'N', K, N, K, -ONE, A( 0 ), M+1,
  594:      $                           B, LDB, ALPHA, B( K, 0 ), LDB )
  595:                      CALL DTRSM( 'L', 'U', 'T', DIAG, K, N, ONE,
  596:      $                           A( K ), M+1, B( K, 0 ), LDB )
  597: *
  598:                   ELSE
  599: *
  600: *                    SIDE  ='L', N is even, TRANSR = 'N', UPLO = 'U',
  601: *                    and TRANS = 'T'
  602:                      CALL DTRSM( 'L', 'U', 'N', DIAG, K, N, ALPHA,
  603:      $                           A( K ), M+1, B( K, 0 ), LDB )
  604:                      CALL DGEMM( 'N', 'N', K, N, K, -ONE, A( 0 ), M+1,
  605:      $                           B( K, 0 ), LDB, ALPHA, B, LDB )
  606:                      CALL DTRSM( 'L', 'L', 'T', DIAG, K, N, ONE,
  607:      $                           A( K+1 ), M+1, B, LDB )
  608: *
  609:                   END IF
  610: *
  611:                END IF
  612: *
  613:             ELSE
  614: *
  615: *              SIDE = 'L', N is even, and TRANSR = 'T'
  616: *
  617:                IF( LOWER ) THEN
  618: *
  619: *                 SIDE  ='L', N is even, TRANSR = 'T', and UPLO = 'L'
  620: *
  621:                   IF( NOTRANS ) THEN
  622: *
  623: *                    SIDE  ='L', N is even, TRANSR = 'T', UPLO = 'L',
  624: *                    and TRANS = 'N'
  625: *
  626:                      CALL DTRSM( 'L', 'U', 'T', DIAG, K, N, ALPHA,
  627:      $                           A( K ), K, B, LDB )
  628:                      CALL DGEMM( 'T', 'N', K, N, K, -ONE,
  629:      $                           A( K*( K+1 ) ), K, B, LDB, ALPHA,
  630:      $                           B( K, 0 ), LDB )
  631:                      CALL DTRSM( 'L', 'L', 'N', DIAG, K, N, ONE,
  632:      $                           A( 0 ), K, B( K, 0 ), LDB )
  633: *
  634:                   ELSE
  635: *
  636: *                    SIDE  ='L', N is even, TRANSR = 'T', UPLO = 'L',
  637: *                    and TRANS = 'T'
  638: *
  639:                      CALL DTRSM( 'L', 'L', 'T', DIAG, K, N, ALPHA,
  640:      $                           A( 0 ), K, B( K, 0 ), LDB )
  641:                      CALL DGEMM( 'N', 'N', K, N, K, -ONE,
  642:      $                           A( K*( K+1 ) ), K, B( K, 0 ), LDB,
  643:      $                           ALPHA, B, LDB )
  644:                      CALL DTRSM( 'L', 'U', 'N', DIAG, K, N, ONE,
  645:      $                           A( K ), K, B, LDB )
  646: *
  647:                   END IF
  648: *
  649:                ELSE
  650: *
  651: *                 SIDE  ='L', N is even, TRANSR = 'T', and UPLO = 'U'
  652: *
  653:                   IF( .NOT.NOTRANS ) THEN
  654: *
  655: *                    SIDE  ='L', N is even, TRANSR = 'T', UPLO = 'U',
  656: *                    and TRANS = 'N'
  657: *
  658:                      CALL DTRSM( 'L', 'U', 'T', DIAG, K, N, ALPHA,
  659:      $                           A( K*( K+1 ) ), K, B, LDB )
  660:                      CALL DGEMM( 'N', 'N', K, N, K, -ONE, A( 0 ), K, B,
  661:      $                           LDB, ALPHA, B( K, 0 ), LDB )
  662:                      CALL DTRSM( 'L', 'L', 'N', DIAG, K, N, ONE,
  663:      $                           A( K*K ), K, B( K, 0 ), LDB )
  664: *
  665:                   ELSE
  666: *
  667: *                    SIDE  ='L', N is even, TRANSR = 'T', UPLO = 'U',
  668: *                    and TRANS = 'T'
  669: *
  670:                      CALL DTRSM( 'L', 'L', 'T', DIAG, K, N, ALPHA,
  671:      $                           A( K*K ), K, B( K, 0 ), LDB )
  672:                      CALL DGEMM( 'T', 'N', K, N, K, -ONE, A( 0 ), K,
  673:      $                           B( K, 0 ), LDB, ALPHA, B, LDB )
  674:                      CALL DTRSM( 'L', 'U', 'N', DIAG, K, N, ONE,
  675:      $                           A( K*( K+1 ) ), K, B, LDB )
  676: *
  677:                   END IF
  678: *
  679:                END IF
  680: *
  681:             END IF
  682: *
  683:          END IF
  684: *
  685:       ELSE
  686: *
  687: *        SIDE = 'R'
  688: *
  689: *        A is N-by-N.
  690: *        If N is odd, set NISODD = .TRUE., and N1 and N2.
  691: *        If N is even, NISODD = .FALSE., and K.
  692: *
  693:          IF( MOD( N, 2 ).EQ.0 ) THEN
  694:             NISODD = .FALSE.
  695:             K = N / 2
  696:          ELSE
  697:             NISODD = .TRUE.
  698:             IF( LOWER ) THEN
  699:                N2 = N / 2
  700:                N1 = N - N2
  701:             ELSE
  702:                N1 = N / 2
  703:                N2 = N - N1
  704:             END IF
  705:          END IF
  706: *
  707:          IF( NISODD ) THEN
  708: *
  709: *           SIDE = 'R' and N is odd
  710: *
  711:             IF( NORMALTRANSR ) THEN
  712: *
  713: *              SIDE = 'R', N is odd, and TRANSR = 'N'
  714: *
  715:                IF( LOWER ) THEN
  716: *
  717: *                 SIDE  ='R', N is odd, TRANSR = 'N', and UPLO = 'L'
  718: *
  719:                   IF( NOTRANS ) THEN
  720: *
  721: *                    SIDE  ='R', N is odd, TRANSR = 'N', UPLO = 'L', and
  722: *                    TRANS = 'N'
  723: *
  724:                      CALL DTRSM( 'R', 'U', 'T', DIAG, M, N2, ALPHA,
  725:      $                           A( N ), N, B( 0, N1 ), LDB )
  726:                      CALL DGEMM( 'N', 'N', M, N1, N2, -ONE, B( 0, N1 ),
  727:      $                           LDB, A( N1 ), N, ALPHA, B( 0, 0 ),
  728:      $                           LDB )
  729:                      CALL DTRSM( 'R', 'L', 'N', DIAG, M, N1, ONE,
  730:      $                           A( 0 ), N, B( 0, 0 ), LDB )
  731: *
  732:                   ELSE
  733: *
  734: *                    SIDE  ='R', N is odd, TRANSR = 'N', UPLO = 'L', and
  735: *                    TRANS = 'T'
  736: *
  737:                      CALL DTRSM( 'R', 'L', 'T', DIAG, M, N1, ALPHA,
  738:      $                           A( 0 ), N, B( 0, 0 ), LDB )
  739:                      CALL DGEMM( 'N', 'T', M, N2, N1, -ONE, B( 0, 0 ),
  740:      $                           LDB, A( N1 ), N, ALPHA, B( 0, N1 ),
  741:      $                           LDB )
  742:                      CALL DTRSM( 'R', 'U', 'N', DIAG, M, N2, ONE,
  743:      $                           A( N ), N, B( 0, N1 ), LDB )
  744: *
  745:                   END IF
  746: *
  747:                ELSE
  748: *
  749: *                 SIDE  ='R', N is odd, TRANSR = 'N', and UPLO = 'U'
  750: *
  751:                   IF( NOTRANS ) THEN
  752: *
  753: *                    SIDE  ='R', N is odd, TRANSR = 'N', UPLO = 'U', and
  754: *                    TRANS = 'N'
  755: *
  756:                      CALL DTRSM( 'R', 'L', 'T', DIAG, M, N1, ALPHA,
  757:      $                           A( N2 ), N, B( 0, 0 ), LDB )
  758:                      CALL DGEMM( 'N', 'N', M, N2, N1, -ONE, B( 0, 0 ),
  759:      $                           LDB, A( 0 ), N, ALPHA, B( 0, N1 ),
  760:      $                           LDB )
  761:                      CALL DTRSM( 'R', 'U', 'N', DIAG, M, N2, ONE,
  762:      $                           A( N1 ), N, B( 0, N1 ), LDB )
  763: *
  764:                   ELSE
  765: *
  766: *                    SIDE  ='R', N is odd, TRANSR = 'N', UPLO = 'U', and
  767: *                    TRANS = 'T'
  768: *
  769:                      CALL DTRSM( 'R', 'U', 'T', DIAG, M, N2, ALPHA,
  770:      $                           A( N1 ), N, B( 0, N1 ), LDB )
  771:                      CALL DGEMM( 'N', 'T', M, N1, N2, -ONE, B( 0, N1 ),
  772:      $                           LDB, A( 0 ), N, ALPHA, B( 0, 0 ), LDB )
  773:                      CALL DTRSM( 'R', 'L', 'N', DIAG, M, N1, ONE,
  774:      $                           A( N2 ), N, B( 0, 0 ), LDB )
  775: *
  776:                   END IF
  777: *
  778:                END IF
  779: *
  780:             ELSE
  781: *
  782: *              SIDE = 'R', N is odd, and TRANSR = 'T'
  783: *
  784:                IF( LOWER ) THEN
  785: *
  786: *                 SIDE  ='R', N is odd, TRANSR = 'T', and UPLO = 'L'
  787: *
  788:                   IF( NOTRANS ) THEN
  789: *
  790: *                    SIDE  ='R', N is odd, TRANSR = 'T', UPLO = 'L', and
  791: *                    TRANS = 'N'
  792: *
  793:                      CALL DTRSM( 'R', 'L', 'N', DIAG, M, N2, ALPHA,
  794:      $                           A( 1 ), N1, B( 0, N1 ), LDB )
  795:                      CALL DGEMM( 'N', 'T', M, N1, N2, -ONE, B( 0, N1 ),
  796:      $                           LDB, A( N1*N1 ), N1, ALPHA, B( 0, 0 ),
  797:      $                           LDB )
  798:                      CALL DTRSM( 'R', 'U', 'T', DIAG, M, N1, ONE,
  799:      $                           A( 0 ), N1, B( 0, 0 ), LDB )
  800: *
  801:                   ELSE
  802: *
  803: *                    SIDE  ='R', N is odd, TRANSR = 'T', UPLO = 'L', and
  804: *                    TRANS = 'T'
  805: *
  806:                      CALL DTRSM( 'R', 'U', 'N', DIAG, M, N1, ALPHA,
  807:      $                           A( 0 ), N1, B( 0, 0 ), LDB )
  808:                      CALL DGEMM( 'N', 'N', M, N2, N1, -ONE, B( 0, 0 ),
  809:      $                           LDB, A( N1*N1 ), N1, ALPHA, B( 0, N1 ),
  810:      $                           LDB )
  811:                      CALL DTRSM( 'R', 'L', 'T', DIAG, M, N2, ONE,
  812:      $                           A( 1 ), N1, B( 0, N1 ), LDB )
  813: *
  814:                   END IF
  815: *
  816:                ELSE
  817: *
  818: *                 SIDE  ='R', N is odd, TRANSR = 'T', and UPLO = 'U'
  819: *
  820:                   IF( NOTRANS ) THEN
  821: *
  822: *                    SIDE  ='R', N is odd, TRANSR = 'T', UPLO = 'U', and
  823: *                    TRANS = 'N'
  824: *
  825:                      CALL DTRSM( 'R', 'U', 'N', DIAG, M, N1, ALPHA,
  826:      $                           A( N2*N2 ), N2, B( 0, 0 ), LDB )
  827:                      CALL DGEMM( 'N', 'T', M, N2, N1, -ONE, B( 0, 0 ),
  828:      $                           LDB, A( 0 ), N2, ALPHA, B( 0, N1 ),
  829:      $                           LDB )
  830:                      CALL DTRSM( 'R', 'L', 'T', DIAG, M, N2, ONE,
  831:      $                           A( N1*N2 ), N2, B( 0, N1 ), LDB )
  832: *
  833:                   ELSE
  834: *
  835: *                    SIDE  ='R', N is odd, TRANSR = 'T', UPLO = 'U', and
  836: *                    TRANS = 'T'
  837: *
  838:                      CALL DTRSM( 'R', 'L', 'N', DIAG, M, N2, ALPHA,
  839:      $                           A( N1*N2 ), N2, B( 0, N1 ), LDB )
  840:                      CALL DGEMM( 'N', 'N', M, N1, N2, -ONE, B( 0, N1 ),
  841:      $                           LDB, A( 0 ), N2, ALPHA, B( 0, 0 ),
  842:      $                           LDB )
  843:                      CALL DTRSM( 'R', 'U', 'T', DIAG, M, N1, ONE,
  844:      $                           A( N2*N2 ), N2, B( 0, 0 ), LDB )
  845: *
  846:                   END IF
  847: *
  848:                END IF
  849: *
  850:             END IF
  851: *
  852:          ELSE
  853: *
  854: *           SIDE = 'R' and N is even
  855: *
  856:             IF( NORMALTRANSR ) THEN
  857: *
  858: *              SIDE = 'R', N is even, and TRANSR = 'N'
  859: *
  860:                IF( LOWER ) THEN
  861: *
  862: *                 SIDE  ='R', N is even, TRANSR = 'N', and UPLO = 'L'
  863: *
  864:                   IF( NOTRANS ) THEN
  865: *
  866: *                    SIDE  ='R', N is even, TRANSR = 'N', UPLO = 'L',
  867: *                    and TRANS = 'N'
  868: *
  869:                      CALL DTRSM( 'R', 'U', 'T', DIAG, M, K, ALPHA,
  870:      $                           A( 0 ), N+1, B( 0, K ), LDB )
  871:                      CALL DGEMM( 'N', 'N', M, K, K, -ONE, B( 0, K ),
  872:      $                           LDB, A( K+1 ), N+1, ALPHA, B( 0, 0 ),
  873:      $                           LDB )
  874:                      CALL DTRSM( 'R', 'L', 'N', DIAG, M, K, ONE,
  875:      $                           A( 1 ), N+1, B( 0, 0 ), LDB )
  876: *
  877:                   ELSE
  878: *
  879: *                    SIDE  ='R', N is even, TRANSR = 'N', UPLO = 'L',
  880: *                    and TRANS = 'T'
  881: *
  882:                      CALL DTRSM( 'R', 'L', 'T', DIAG, M, K, ALPHA,
  883:      $                           A( 1 ), N+1, B( 0, 0 ), LDB )
  884:                      CALL DGEMM( 'N', 'T', M, K, K, -ONE, B( 0, 0 ),
  885:      $                           LDB, A( K+1 ), N+1, ALPHA, B( 0, K ),
  886:      $                           LDB )
  887:                      CALL DTRSM( 'R', 'U', 'N', DIAG, M, K, ONE,
  888:      $                           A( 0 ), N+1, B( 0, K ), LDB )
  889: *
  890:                   END IF
  891: *
  892:                ELSE
  893: *
  894: *                 SIDE  ='R', N is even, TRANSR = 'N', and UPLO = 'U'
  895: *
  896:                   IF( NOTRANS ) THEN
  897: *
  898: *                    SIDE  ='R', N is even, TRANSR = 'N', UPLO = 'U',
  899: *                    and TRANS = 'N'
  900: *
  901:                      CALL DTRSM( 'R', 'L', 'T', DIAG, M, K, ALPHA,
  902:      $                           A( K+1 ), N+1, B( 0, 0 ), LDB )
  903:                      CALL DGEMM( 'N', 'N', M, K, K, -ONE, B( 0, 0 ),
  904:      $                           LDB, A( 0 ), N+1, ALPHA, B( 0, K ),
  905:      $                           LDB )
  906:                      CALL DTRSM( 'R', 'U', 'N', DIAG, M, K, ONE,
  907:      $                           A( K ), N+1, B( 0, K ), LDB )
  908: *
  909:                   ELSE
  910: *
  911: *                    SIDE  ='R', N is even, TRANSR = 'N', UPLO = 'U',
  912: *                    and TRANS = 'T'
  913: *
  914:                      CALL DTRSM( 'R', 'U', 'T', DIAG, M, K, ALPHA,
  915:      $                           A( K ), N+1, B( 0, K ), LDB )
  916:                      CALL DGEMM( 'N', 'T', M, K, K, -ONE, B( 0, K ),
  917:      $                           LDB, A( 0 ), N+1, ALPHA, B( 0, 0 ),
  918:      $                           LDB )
  919:                      CALL DTRSM( 'R', 'L', 'N', DIAG, M, K, ONE,
  920:      $                           A( K+1 ), N+1, B( 0, 0 ), LDB )
  921: *
  922:                   END IF
  923: *
  924:                END IF
  925: *
  926:             ELSE
  927: *
  928: *              SIDE = 'R', N is even, and TRANSR = 'T'
  929: *
  930:                IF( LOWER ) THEN
  931: *
  932: *                 SIDE  ='R', N is even, TRANSR = 'T', and UPLO = 'L'
  933: *
  934:                   IF( NOTRANS ) THEN
  935: *
  936: *                    SIDE  ='R', N is even, TRANSR = 'T', UPLO = 'L',
  937: *                    and TRANS = 'N'
  938: *
  939:                      CALL DTRSM( 'R', 'L', 'N', DIAG, M, K, ALPHA,
  940:      $                           A( 0 ), K, B( 0, K ), LDB )
  941:                      CALL DGEMM( 'N', 'T', M, K, K, -ONE, B( 0, K ),
  942:      $                           LDB, A( ( K+1 )*K ), K, ALPHA,
  943:      $                           B( 0, 0 ), LDB )
  944:                      CALL DTRSM( 'R', 'U', 'T', DIAG, M, K, ONE,
  945:      $                           A( K ), K, B( 0, 0 ), LDB )
  946: *
  947:                   ELSE
  948: *
  949: *                    SIDE  ='R', N is even, TRANSR = 'T', UPLO = 'L',
  950: *                    and TRANS = 'T'
  951: *
  952:                      CALL DTRSM( 'R', 'U', 'N', DIAG, M, K, ALPHA,
  953:      $                           A( K ), K, B( 0, 0 ), LDB )
  954:                      CALL DGEMM( 'N', 'N', M, K, K, -ONE, B( 0, 0 ),
  955:      $                           LDB, A( ( K+1 )*K ), K, ALPHA,
  956:      $                           B( 0, K ), LDB )
  957:                      CALL DTRSM( 'R', 'L', 'T', DIAG, M, K, ONE,
  958:      $                           A( 0 ), K, B( 0, K ), LDB )
  959: *
  960:                   END IF
  961: *
  962:                ELSE
  963: *
  964: *                 SIDE  ='R', N is even, TRANSR = 'T', and UPLO = 'U'
  965: *
  966:                   IF( NOTRANS ) THEN
  967: *
  968: *                    SIDE  ='R', N is even, TRANSR = 'T', UPLO = 'U',
  969: *                    and TRANS = 'N'
  970: *
  971:                      CALL DTRSM( 'R', 'U', 'N', DIAG, M, K, ALPHA,
  972:      $                           A( ( K+1 )*K ), K, B( 0, 0 ), LDB )
  973:                      CALL DGEMM( 'N', 'T', M, K, K, -ONE, B( 0, 0 ),
  974:      $                           LDB, A( 0 ), K, ALPHA, B( 0, K ), LDB )
  975:                      CALL DTRSM( 'R', 'L', 'T', DIAG, M, K, ONE,
  976:      $                           A( K*K ), K, B( 0, K ), LDB )
  977: *
  978:                   ELSE
  979: *
  980: *                    SIDE  ='R', N is even, TRANSR = 'T', UPLO = 'U',
  981: *                    and TRANS = 'T'
  982: *
  983:                      CALL DTRSM( 'R', 'L', 'N', DIAG, M, K, ALPHA,
  984:      $                           A( K*K ), K, B( 0, K ), LDB )
  985:                      CALL DGEMM( 'N', 'N', M, K, K, -ONE, B( 0, K ),
  986:      $                           LDB, A( 0 ), K, ALPHA, B( 0, 0 ), LDB )
  987:                      CALL DTRSM( 'R', 'U', 'T', DIAG, M, K, ONE,
  988:      $                           A( ( K+1 )*K ), K, B( 0, 0 ), LDB )
  989: *
  990:                   END IF
  991: *
  992:                END IF
  993: *
  994:             END IF
  995: *
  996:          END IF
  997:       END IF
  998: *
  999:       RETURN
 1000: *
 1001: *     End of DTFSM
 1002: *
 1003:       END

CVSweb interface <joel.bertrand@systella.fr>