File:  [local] / rpl / lapack / lapack / zunbdb1.f
Revision 1.6: download - view: text, annotated - select for diffs - revision graph
Sat Jun 17 11:07:05 2017 UTC (6 years, 10 months ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_1_27, rpl-4_1_26, HEAD
Cohérence.

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

CVSweb interface <joel.bertrand@systella.fr>