File:  [local] / rpl / lapack / lapack / dorbdb2.f
Revision 1.9: download - view: text, annotated - select for diffs - revision graph
Mon Aug 7 08:39:01 2023 UTC (8 months, 3 weeks 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 DORBDB2
    2: *
    3: *  =========== DOCUMENTATION ===========
    4: *
    5: * Online html documentation available at
    6: *            http://www.netlib.org/lapack/explore-html/
    7: *
    8: *> \htmlonly
    9: *> Download DORBDB2 + dependencies
   10: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorbdb2.f">
   11: *> [TGZ]</a>
   12: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorbdb2.f">
   13: *> [ZIP]</a>
   14: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorbdb2.f">
   15: *> [TXT]</a>
   16: *> \endhtmlonly
   17: *
   18: *  Definition:
   19: *  ===========
   20: *
   21: *       SUBROUTINE DORBDB2( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI,
   22: *                           TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO )
   23: *
   24: *       .. Scalar Arguments ..
   25: *       INTEGER            INFO, LWORK, M, P, Q, LDX11, LDX21
   26: *       ..
   27: *       .. Array Arguments ..
   28: *       DOUBLE PRECISION   PHI(*), THETA(*)
   29: *       DOUBLE PRECISION   TAUP1(*), TAUP2(*), TAUQ1(*), WORK(*),
   30: *      $                   X11(LDX11,*), X21(LDX21,*)
   31: *       ..
   32: *
   33: *
   34: *> \par Purpose:
   35: *  =============
   36: *>
   37: *>\verbatim
   38: *>
   39: *> DORBDB2 simultaneously bidiagonalizes the blocks of a tall and skinny
   40: *> matrix X with orthonomal columns:
   41: *>
   42: *>                            [ B11 ]
   43: *>      [ X11 ]   [ P1 |    ] [  0  ]
   44: *>      [-----] = [---------] [-----] Q1**T .
   45: *>      [ X21 ]   [    | P2 ] [ B21 ]
   46: *>                            [  0  ]
   47: *>
   48: *> X11 is P-by-Q, and X21 is (M-P)-by-Q. P must be no larger than M-P,
   49: *> Q, or M-Q. Routines DORBDB1, DORBDB3, and DORBDB4 handle cases in
   50: *> which P is not the minimum dimension.
   51: *>
   52: *> The orthogonal matrices P1, P2, and Q1 are P-by-P, (M-P)-by-(M-P),
   53: *> and (M-Q)-by-(M-Q), respectively. They are represented implicitly by
   54: *> Householder vectors.
   55: *>
   56: *> B11 and B12 are P-by-P bidiagonal matrices represented implicitly by
   57: *> angles THETA, PHI.
   58: *>
   59: *>\endverbatim
   60: *
   61: *  Arguments:
   62: *  ==========
   63: *
   64: *> \param[in] M
   65: *> \verbatim
   66: *>          M is INTEGER
   67: *>           The number of rows X11 plus the number of rows in X21.
   68: *> \endverbatim
   69: *>
   70: *> \param[in] P
   71: *> \verbatim
   72: *>          P is INTEGER
   73: *>           The number of rows in X11. 0 <= P <= min(M-P,Q,M-Q).
   74: *> \endverbatim
   75: *>
   76: *> \param[in] Q
   77: *> \verbatim
   78: *>          Q is INTEGER
   79: *>           The number of columns in X11 and X21. 0 <= Q <= M.
   80: *> \endverbatim
   81: *>
   82: *> \param[in,out] X11
   83: *> \verbatim
   84: *>          X11 is DOUBLE PRECISION array, dimension (LDX11,Q)
   85: *>           On entry, the top block of the matrix X to be reduced. On
   86: *>           exit, the columns of tril(X11) specify reflectors for P1 and
   87: *>           the rows of triu(X11,1) specify reflectors for Q1.
   88: *> \endverbatim
   89: *>
   90: *> \param[in] LDX11
   91: *> \verbatim
   92: *>          LDX11 is INTEGER
   93: *>           The leading dimension of X11. LDX11 >= P.
   94: *> \endverbatim
   95: *>
   96: *> \param[in,out] X21
   97: *> \verbatim
   98: *>          X21 is DOUBLE PRECISION array, dimension (LDX21,Q)
   99: *>           On entry, the bottom block of the matrix X to be reduced. On
  100: *>           exit, the columns of tril(X21) specify reflectors for P2.
  101: *> \endverbatim
  102: *>
  103: *> \param[in] LDX21
  104: *> \verbatim
  105: *>          LDX21 is INTEGER
  106: *>           The leading dimension of X21. LDX21 >= M-P.
  107: *> \endverbatim
  108: *>
  109: *> \param[out] THETA
  110: *> \verbatim
  111: *>          THETA is DOUBLE PRECISION array, dimension (Q)
  112: *>           The entries of the bidiagonal blocks B11, B21 are defined by
  113: *>           THETA and PHI. See Further Details.
  114: *> \endverbatim
  115: *>
  116: *> \param[out] PHI
  117: *> \verbatim
  118: *>          PHI is DOUBLE PRECISION array, dimension (Q-1)
  119: *>           The entries of the bidiagonal blocks B11, B21 are defined by
  120: *>           THETA and PHI. See Further Details.
  121: *> \endverbatim
  122: *>
  123: *> \param[out] TAUP1
  124: *> \verbatim
  125: *>          TAUP1 is DOUBLE PRECISION array, dimension (P-1)
  126: *>           The scalar factors of the elementary reflectors that define
  127: *>           P1.
  128: *> \endverbatim
  129: *>
  130: *> \param[out] TAUP2
  131: *> \verbatim
  132: *>          TAUP2 is DOUBLE PRECISION array, dimension (Q)
  133: *>           The scalar factors of the elementary reflectors that define
  134: *>           P2.
  135: *> \endverbatim
  136: *>
  137: *> \param[out] TAUQ1
  138: *> \verbatim
  139: *>          TAUQ1 is DOUBLE PRECISION array, dimension (Q)
  140: *>           The scalar factors of the elementary reflectors that define
  141: *>           Q1.
  142: *> \endverbatim
  143: *>
  144: *> \param[out] WORK
  145: *> \verbatim
  146: *>          WORK is DOUBLE PRECISION array, dimension (LWORK)
  147: *> \endverbatim
  148: *>
  149: *> \param[in] LWORK
  150: *> \verbatim
  151: *>          LWORK is INTEGER
  152: *>           The dimension of the array WORK. LWORK >= M-Q.
  153: *>
  154: *>           If LWORK = -1, then a workspace query is assumed; the routine
  155: *>           only calculates the optimal size of the WORK array, returns
  156: *>           this value as the first entry of the WORK array, and no error
  157: *>           message related to LWORK is issued by XERBLA.
  158: *> \endverbatim
  159: *>
  160: *> \param[out] INFO
  161: *> \verbatim
  162: *>          INFO is INTEGER
  163: *>           = 0:  successful exit.
  164: *>           < 0:  if INFO = -i, the i-th argument had an illegal value.
  165: *> \endverbatim
  166: *>
  167: *
  168: *  Authors:
  169: *  ========
  170: *
  171: *> \author Univ. of Tennessee
  172: *> \author Univ. of California Berkeley
  173: *> \author Univ. of Colorado Denver
  174: *> \author NAG Ltd.
  175: *
  176: *> \ingroup doubleOTHERcomputational
  177: *
  178: *> \par Further Details:
  179: *  =====================
  180: *>
  181: *> \verbatim
  182: *>
  183: *>  The upper-bidiagonal blocks B11, B21 are represented implicitly by
  184: *>  angles THETA(1), ..., THETA(Q) and PHI(1), ..., PHI(Q-1). Every entry
  185: *>  in each bidiagonal band is a product of a sine or cosine of a THETA
  186: *>  with a sine or cosine of a PHI. See [1] or DORCSD for details.
  187: *>
  188: *>  P1, P2, and Q1 are represented as products of elementary reflectors.
  189: *>  See DORCSD2BY1 for details on generating P1, P2, and Q1 using DORGQR
  190: *>  and DORGLQ.
  191: *> \endverbatim
  192: *
  193: *> \par References:
  194: *  ================
  195: *>
  196: *>  [1] Brian D. Sutton. Computing the complete CS decomposition. Numer.
  197: *>      Algorithms, 50(1):33-65, 2009.
  198: *>
  199: *  =====================================================================
  200:       SUBROUTINE DORBDB2( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI,
  201:      $                    TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO )
  202: *
  203: *  -- LAPACK computational routine --
  204: *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
  205: *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  206: *
  207: *     .. Scalar Arguments ..
  208:       INTEGER            INFO, LWORK, M, P, Q, LDX11, LDX21
  209: *     ..
  210: *     .. Array Arguments ..
  211:       DOUBLE PRECISION   PHI(*), THETA(*)
  212:       DOUBLE PRECISION   TAUP1(*), TAUP2(*), TAUQ1(*), WORK(*),
  213:      $                   X11(LDX11,*), X21(LDX21,*)
  214: *     ..
  215: *
  216: *  ====================================================================
  217: *
  218: *     .. Parameters ..
  219:       DOUBLE PRECISION   NEGONE, ONE
  220:       PARAMETER          ( NEGONE = -1.0D0, ONE = 1.0D0 )
  221: *     ..
  222: *     .. Local Scalars ..
  223:       DOUBLE PRECISION   C, S
  224:       INTEGER            CHILDINFO, I, ILARF, IORBDB5, LLARF, LORBDB5,
  225:      $                   LWORKMIN, LWORKOPT
  226:       LOGICAL            LQUERY
  227: *     ..
  228: *     .. External Subroutines ..
  229:       EXTERNAL           DLARF, DLARFGP, DORBDB5, DROT, DSCAL, XERBLA
  230: *     ..
  231: *     .. External Functions ..
  232:       DOUBLE PRECISION   DNRM2
  233:       EXTERNAL           DNRM2
  234: *     ..
  235: *     .. Intrinsic Function ..
  236:       INTRINSIC          ATAN2, COS, MAX, SIN, SQRT
  237: *     ..
  238: *     .. Executable Statements ..
  239: *
  240: *     Test input arguments
  241: *
  242:       INFO = 0
  243:       LQUERY = LWORK .EQ. -1
  244: *
  245:       IF( M .LT. 0 ) THEN
  246:          INFO = -1
  247:       ELSE IF( P .LT. 0 .OR. P .GT. M-P ) THEN
  248:          INFO = -2
  249:       ELSE IF( Q .LT. 0 .OR. Q .LT. P .OR. M-Q .LT. P ) THEN
  250:          INFO = -3
  251:       ELSE IF( LDX11 .LT. MAX( 1, P ) ) THEN
  252:          INFO = -5
  253:       ELSE IF( LDX21 .LT. MAX( 1, M-P ) ) THEN
  254:          INFO = -7
  255:       END IF
  256: *
  257: *     Compute workspace
  258: *
  259:       IF( INFO .EQ. 0 ) THEN
  260:          ILARF = 2
  261:          LLARF = MAX( P-1, M-P, Q-1 )
  262:          IORBDB5 = 2
  263:          LORBDB5 = Q-1
  264:          LWORKOPT = MAX( ILARF+LLARF-1, IORBDB5+LORBDB5-1 )
  265:          LWORKMIN = LWORKOPT
  266:          WORK(1) = LWORKOPT
  267:          IF( LWORK .LT. LWORKMIN .AND. .NOT.LQUERY ) THEN
  268:            INFO = -14
  269:          END IF
  270:       END IF
  271:       IF( INFO .NE. 0 ) THEN
  272:          CALL XERBLA( 'DORBDB2', -INFO )
  273:          RETURN
  274:       ELSE IF( LQUERY ) THEN
  275:          RETURN
  276:       END IF
  277: *
  278: *     Reduce rows 1, ..., P of X11 and X21
  279: *
  280:       DO I = 1, P
  281: *
  282:          IF( I .GT. 1 ) THEN
  283:             CALL DROT( Q-I+1, X11(I,I), LDX11, X21(I-1,I), LDX21, C, S )
  284:          END IF
  285:          CALL DLARFGP( Q-I+1, X11(I,I), X11(I,I+1), LDX11, TAUQ1(I) )
  286:          C = X11(I,I)
  287:          X11(I,I) = ONE
  288:          CALL DLARF( 'R', P-I, Q-I+1, X11(I,I), LDX11, TAUQ1(I),
  289:      $               X11(I+1,I), LDX11, WORK(ILARF) )
  290:          CALL DLARF( 'R', M-P-I+1, Q-I+1, X11(I,I), LDX11, TAUQ1(I),
  291:      $               X21(I,I), LDX21, WORK(ILARF) )
  292:          S = SQRT( DNRM2( P-I, X11(I+1,I), 1 )**2
  293:      $           + DNRM2( M-P-I+1, X21(I,I), 1 )**2 )
  294:          THETA(I) = ATAN2( S, C )
  295: *
  296:          CALL DORBDB5( P-I, M-P-I+1, Q-I, X11(I+1,I), 1, X21(I,I), 1,
  297:      $                 X11(I+1,I+1), LDX11, X21(I,I+1), LDX21,
  298:      $                 WORK(IORBDB5), LORBDB5, CHILDINFO )
  299:          CALL DSCAL( P-I, NEGONE, X11(I+1,I), 1 )
  300:          CALL DLARFGP( M-P-I+1, X21(I,I), X21(I+1,I), 1, TAUP2(I) )
  301:          IF( I .LT. P ) THEN
  302:             CALL DLARFGP( P-I, X11(I+1,I), X11(I+2,I), 1, TAUP1(I) )
  303:             PHI(I) = ATAN2( X11(I+1,I), X21(I,I) )
  304:             C = COS( PHI(I) )
  305:             S = SIN( PHI(I) )
  306:             X11(I+1,I) = ONE
  307:             CALL DLARF( 'L', P-I, Q-I, X11(I+1,I), 1, TAUP1(I),
  308:      $                  X11(I+1,I+1), LDX11, WORK(ILARF) )
  309:          END IF
  310:          X21(I,I) = ONE
  311:          CALL DLARF( 'L', M-P-I+1, Q-I, X21(I,I), 1, TAUP2(I),
  312:      $               X21(I,I+1), LDX21, WORK(ILARF) )
  313: *
  314:       END DO
  315: *
  316: *     Reduce the bottom-right portion of X21 to the identity matrix
  317: *
  318:       DO I = P + 1, Q
  319:          CALL DLARFGP( M-P-I+1, X21(I,I), X21(I+1,I), 1, TAUP2(I) )
  320:          X21(I,I) = ONE
  321:          CALL DLARF( 'L', M-P-I+1, Q-I, X21(I,I), 1, TAUP2(I),
  322:      $               X21(I,I+1), LDX21, WORK(ILARF) )
  323:       END DO
  324: *
  325:       RETURN
  326: *
  327: *     End of DORBDB2
  328: *
  329:       END
  330: 

CVSweb interface <joel.bertrand@systella.fr>