File:  [local] / rpl / lapack / lapack / zlals0.f
Revision 1.6: download - view: text, annotated - select for diffs - revision graph
Fri Aug 13 21:04:09 2010 UTC (13 years, 9 months ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_0_19, rpl-4_0_18, HEAD
Patches pour OS/2

    1:       SUBROUTINE ZLALS0( ICOMPQ, NL, NR, SQRE, NRHS, B, LDB, BX, LDBX,
    2:      $                   PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM, LDGNUM,
    3:      $                   POLES, DIFL, DIFR, Z, K, C, S, RWORK, INFO )
    4: *
    5: *  -- LAPACK routine (version 3.2) --
    6: *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
    7: *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
    8: *     November 2006
    9: *
   10: *     .. Scalar Arguments ..
   11:       INTEGER            GIVPTR, ICOMPQ, INFO, K, LDB, LDBX, LDGCOL,
   12:      $                   LDGNUM, NL, NR, NRHS, SQRE
   13:       DOUBLE PRECISION   C, S
   14: *     ..
   15: *     .. Array Arguments ..
   16:       INTEGER            GIVCOL( LDGCOL, * ), PERM( * )
   17:       DOUBLE PRECISION   DIFL( * ), DIFR( LDGNUM, * ),
   18:      $                   GIVNUM( LDGNUM, * ), POLES( LDGNUM, * ),
   19:      $                   RWORK( * ), Z( * )
   20:       COMPLEX*16         B( LDB, * ), BX( LDBX, * )
   21: *     ..
   22: *
   23: *  Purpose
   24: *  =======
   25: *
   26: *  ZLALS0 applies back the multiplying factors of either the left or the
   27: *  right singular vector matrix of a diagonal matrix appended by a row
   28: *  to the right hand side matrix B in solving the least squares problem
   29: *  using the divide-and-conquer SVD approach.
   30: *
   31: *  For the left singular vector matrix, three types of orthogonal
   32: *  matrices are involved:
   33: *
   34: *  (1L) Givens rotations: the number of such rotations is GIVPTR; the
   35: *       pairs of columns/rows they were applied to are stored in GIVCOL;
   36: *       and the C- and S-values of these rotations are stored in GIVNUM.
   37: *
   38: *  (2L) Permutation. The (NL+1)-st row of B is to be moved to the first
   39: *       row, and for J=2:N, PERM(J)-th row of B is to be moved to the
   40: *       J-th row.
   41: *
   42: *  (3L) The left singular vector matrix of the remaining matrix.
   43: *
   44: *  For the right singular vector matrix, four types of orthogonal
   45: *  matrices are involved:
   46: *
   47: *  (1R) The right singular vector matrix of the remaining matrix.
   48: *
   49: *  (2R) If SQRE = 1, one extra Givens rotation to generate the right
   50: *       null space.
   51: *
   52: *  (3R) The inverse transformation of (2L).
   53: *
   54: *  (4R) The inverse transformation of (1L).
   55: *
   56: *  Arguments
   57: *  =========
   58: *
   59: *  ICOMPQ (input) INTEGER
   60: *         Specifies whether singular vectors are to be computed in
   61: *         factored form:
   62: *         = 0: Left singular vector matrix.
   63: *         = 1: Right singular vector matrix.
   64: *
   65: *  NL     (input) INTEGER
   66: *         The row dimension of the upper block. NL >= 1.
   67: *
   68: *  NR     (input) INTEGER
   69: *         The row dimension of the lower block. NR >= 1.
   70: *
   71: *  SQRE   (input) INTEGER
   72: *         = 0: the lower block is an NR-by-NR square matrix.
   73: *         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
   74: *
   75: *         The bidiagonal matrix has row dimension N = NL + NR + 1,
   76: *         and column dimension M = N + SQRE.
   77: *
   78: *  NRHS   (input) INTEGER
   79: *         The number of columns of B and BX. NRHS must be at least 1.
   80: *
   81: *  B      (input/output) COMPLEX*16 array, dimension ( LDB, NRHS )
   82: *         On input, B contains the right hand sides of the least
   83: *         squares problem in rows 1 through M. On output, B contains
   84: *         the solution X in rows 1 through N.
   85: *
   86: *  LDB    (input) INTEGER
   87: *         The leading dimension of B. LDB must be at least
   88: *         max(1,MAX( M, N ) ).
   89: *
   90: *  BX     (workspace) COMPLEX*16 array, dimension ( LDBX, NRHS )
   91: *
   92: *  LDBX   (input) INTEGER
   93: *         The leading dimension of BX.
   94: *
   95: *  PERM   (input) INTEGER array, dimension ( N )
   96: *         The permutations (from deflation and sorting) applied
   97: *         to the two blocks.
   98: *
   99: *  GIVPTR (input) INTEGER
  100: *         The number of Givens rotations which took place in this
  101: *         subproblem.
  102: *
  103: *  GIVCOL (input) INTEGER array, dimension ( LDGCOL, 2 )
  104: *         Each pair of numbers indicates a pair of rows/columns
  105: *         involved in a Givens rotation.
  106: *
  107: *  LDGCOL (input) INTEGER
  108: *         The leading dimension of GIVCOL, must be at least N.
  109: *
  110: *  GIVNUM (input) DOUBLE PRECISION array, dimension ( LDGNUM, 2 )
  111: *         Each number indicates the C or S value used in the
  112: *         corresponding Givens rotation.
  113: *
  114: *  LDGNUM (input) INTEGER
  115: *         The leading dimension of arrays DIFR, POLES and
  116: *         GIVNUM, must be at least K.
  117: *
  118: *  POLES  (input) DOUBLE PRECISION array, dimension ( LDGNUM, 2 )
  119: *         On entry, POLES(1:K, 1) contains the new singular
  120: *         values obtained from solving the secular equation, and
  121: *         POLES(1:K, 2) is an array containing the poles in the secular
  122: *         equation.
  123: *
  124: *  DIFL   (input) DOUBLE PRECISION array, dimension ( K ).
  125: *         On entry, DIFL(I) is the distance between I-th updated
  126: *         (undeflated) singular value and the I-th (undeflated) old
  127: *         singular value.
  128: *
  129: *  DIFR   (input) DOUBLE PRECISION array, dimension ( LDGNUM, 2 ).
  130: *         On entry, DIFR(I, 1) contains the distances between I-th
  131: *         updated (undeflated) singular value and the I+1-th
  132: *         (undeflated) old singular value. And DIFR(I, 2) is the
  133: *         normalizing factor for the I-th right singular vector.
  134: *
  135: *  Z      (input) DOUBLE PRECISION array, dimension ( K )
  136: *         Contain the components of the deflation-adjusted updating row
  137: *         vector.
  138: *
  139: *  K      (input) INTEGER
  140: *         Contains the dimension of the non-deflated matrix,
  141: *         This is the order of the related secular equation. 1 <= K <=N.
  142: *
  143: *  C      (input) DOUBLE PRECISION
  144: *         C contains garbage if SQRE =0 and the C-value of a Givens
  145: *         rotation related to the right null space if SQRE = 1.
  146: *
  147: *  S      (input) DOUBLE PRECISION
  148: *         S contains garbage if SQRE =0 and the S-value of a Givens
  149: *         rotation related to the right null space if SQRE = 1.
  150: *
  151: *  RWORK  (workspace) DOUBLE PRECISION array, dimension
  152: *         ( K*(1+NRHS) + 2*NRHS )
  153: *
  154: *  INFO   (output) INTEGER
  155: *          = 0:  successful exit.
  156: *          < 0:  if INFO = -i, the i-th argument had an illegal value.
  157: *
  158: *  Further Details
  159: *  ===============
  160: *
  161: *  Based on contributions by
  162: *     Ming Gu and Ren-Cang Li, Computer Science Division, University of
  163: *       California at Berkeley, USA
  164: *     Osni Marques, LBNL/NERSC, USA
  165: *
  166: *  =====================================================================
  167: *
  168: *     .. Parameters ..
  169:       DOUBLE PRECISION   ONE, ZERO, NEGONE
  170:       PARAMETER          ( ONE = 1.0D0, ZERO = 0.0D0, NEGONE = -1.0D0 )
  171: *     ..
  172: *     .. Local Scalars ..
  173:       INTEGER            I, J, JCOL, JROW, M, N, NLP1
  174:       DOUBLE PRECISION   DIFLJ, DIFRJ, DJ, DSIGJ, DSIGJP, TEMP
  175: *     ..
  176: *     .. External Subroutines ..
  177:       EXTERNAL           DGEMV, XERBLA, ZCOPY, ZDROT, ZDSCAL, ZLACPY,
  178:      $                   ZLASCL
  179: *     ..
  180: *     .. External Functions ..
  181:       DOUBLE PRECISION   DLAMC3, DNRM2
  182:       EXTERNAL           DLAMC3, DNRM2
  183: *     ..
  184: *     .. Intrinsic Functions ..
  185:       INTRINSIC          DBLE, DCMPLX, DIMAG, MAX
  186: *     ..
  187: *     .. Executable Statements ..
  188: *
  189: *     Test the input parameters.
  190: *
  191:       INFO = 0
  192: *
  193:       IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THEN
  194:          INFO = -1
  195:       ELSE IF( NL.LT.1 ) THEN
  196:          INFO = -2
  197:       ELSE IF( NR.LT.1 ) THEN
  198:          INFO = -3
  199:       ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THEN
  200:          INFO = -4
  201:       END IF
  202: *
  203:       N = NL + NR + 1
  204: *
  205:       IF( NRHS.LT.1 ) THEN
  206:          INFO = -5
  207:       ELSE IF( LDB.LT.N ) THEN
  208:          INFO = -7
  209:       ELSE IF( LDBX.LT.N ) THEN
  210:          INFO = -9
  211:       ELSE IF( GIVPTR.LT.0 ) THEN
  212:          INFO = -11
  213:       ELSE IF( LDGCOL.LT.N ) THEN
  214:          INFO = -13
  215:       ELSE IF( LDGNUM.LT.N ) THEN
  216:          INFO = -15
  217:       ELSE IF( K.LT.1 ) THEN
  218:          INFO = -20
  219:       END IF
  220:       IF( INFO.NE.0 ) THEN
  221:          CALL XERBLA( 'ZLALS0', -INFO )
  222:          RETURN
  223:       END IF
  224: *
  225:       M = N + SQRE
  226:       NLP1 = NL + 1
  227: *
  228:       IF( ICOMPQ.EQ.0 ) THEN
  229: *
  230: *        Apply back orthogonal transformations from the left.
  231: *
  232: *        Step (1L): apply back the Givens rotations performed.
  233: *
  234:          DO 10 I = 1, GIVPTR
  235:             CALL ZDROT( NRHS, B( GIVCOL( I, 2 ), 1 ), LDB,
  236:      $                  B( GIVCOL( I, 1 ), 1 ), LDB, GIVNUM( I, 2 ),
  237:      $                  GIVNUM( I, 1 ) )
  238:    10    CONTINUE
  239: *
  240: *        Step (2L): permute rows of B.
  241: *
  242:          CALL ZCOPY( NRHS, B( NLP1, 1 ), LDB, BX( 1, 1 ), LDBX )
  243:          DO 20 I = 2, N
  244:             CALL ZCOPY( NRHS, B( PERM( I ), 1 ), LDB, BX( I, 1 ), LDBX )
  245:    20    CONTINUE
  246: *
  247: *        Step (3L): apply the inverse of the left singular vector
  248: *        matrix to BX.
  249: *
  250:          IF( K.EQ.1 ) THEN
  251:             CALL ZCOPY( NRHS, BX, LDBX, B, LDB )
  252:             IF( Z( 1 ).LT.ZERO ) THEN
  253:                CALL ZDSCAL( NRHS, NEGONE, B, LDB )
  254:             END IF
  255:          ELSE
  256:             DO 100 J = 1, K
  257:                DIFLJ = DIFL( J )
  258:                DJ = POLES( J, 1 )
  259:                DSIGJ = -POLES( J, 2 )
  260:                IF( J.LT.K ) THEN
  261:                   DIFRJ = -DIFR( J, 1 )
  262:                   DSIGJP = -POLES( J+1, 2 )
  263:                END IF
  264:                IF( ( Z( J ).EQ.ZERO ) .OR. ( POLES( J, 2 ).EQ.ZERO ) )
  265:      $              THEN
  266:                   RWORK( J ) = ZERO
  267:                ELSE
  268:                   RWORK( J ) = -POLES( J, 2 )*Z( J ) / DIFLJ /
  269:      $                         ( POLES( J, 2 )+DJ )
  270:                END IF
  271:                DO 30 I = 1, J - 1
  272:                   IF( ( Z( I ).EQ.ZERO ) .OR.
  273:      $                ( POLES( I, 2 ).EQ.ZERO ) ) THEN
  274:                      RWORK( I ) = ZERO
  275:                   ELSE
  276:                      RWORK( I ) = POLES( I, 2 )*Z( I ) /
  277:      $                            ( DLAMC3( POLES( I, 2 ), DSIGJ )-
  278:      $                            DIFLJ ) / ( POLES( I, 2 )+DJ )
  279:                   END IF
  280:    30          CONTINUE
  281:                DO 40 I = J + 1, K
  282:                   IF( ( Z( I ).EQ.ZERO ) .OR.
  283:      $                ( POLES( I, 2 ).EQ.ZERO ) ) THEN
  284:                      RWORK( I ) = ZERO
  285:                   ELSE
  286:                      RWORK( I ) = POLES( I, 2 )*Z( I ) /
  287:      $                            ( DLAMC3( POLES( I, 2 ), DSIGJP )+
  288:      $                            DIFRJ ) / ( POLES( I, 2 )+DJ )
  289:                   END IF
  290:    40          CONTINUE
  291:                RWORK( 1 ) = NEGONE
  292:                TEMP = DNRM2( K, RWORK, 1 )
  293: *
  294: *              Since B and BX are complex, the following call to DGEMV
  295: *              is performed in two steps (real and imaginary parts).
  296: *
  297: *              CALL DGEMV( 'T', K, NRHS, ONE, BX, LDBX, WORK, 1, ZERO,
  298: *    $                     B( J, 1 ), LDB )
  299: *
  300:                I = K + NRHS*2
  301:                DO 60 JCOL = 1, NRHS
  302:                   DO 50 JROW = 1, K
  303:                      I = I + 1
  304:                      RWORK( I ) = DBLE( BX( JROW, JCOL ) )
  305:    50             CONTINUE
  306:    60          CONTINUE
  307:                CALL DGEMV( 'T', K, NRHS, ONE, RWORK( 1+K+NRHS*2 ), K,
  308:      $                     RWORK( 1 ), 1, ZERO, RWORK( 1+K ), 1 )
  309:                I = K + NRHS*2
  310:                DO 80 JCOL = 1, NRHS
  311:                   DO 70 JROW = 1, K
  312:                      I = I + 1
  313:                      RWORK( I ) = DIMAG( BX( JROW, JCOL ) )
  314:    70             CONTINUE
  315:    80          CONTINUE
  316:                CALL DGEMV( 'T', K, NRHS, ONE, RWORK( 1+K+NRHS*2 ), K,
  317:      $                     RWORK( 1 ), 1, ZERO, RWORK( 1+K+NRHS ), 1 )
  318:                DO 90 JCOL = 1, NRHS
  319:                   B( J, JCOL ) = DCMPLX( RWORK( JCOL+K ),
  320:      $                           RWORK( JCOL+K+NRHS ) )
  321:    90          CONTINUE
  322:                CALL ZLASCL( 'G', 0, 0, TEMP, ONE, 1, NRHS, B( J, 1 ),
  323:      $                      LDB, INFO )
  324:   100       CONTINUE
  325:          END IF
  326: *
  327: *        Move the deflated rows of BX to B also.
  328: *
  329:          IF( K.LT.MAX( M, N ) )
  330:      $      CALL ZLACPY( 'A', N-K, NRHS, BX( K+1, 1 ), LDBX,
  331:      $                   B( K+1, 1 ), LDB )
  332:       ELSE
  333: *
  334: *        Apply back the right orthogonal transformations.
  335: *
  336: *        Step (1R): apply back the new right singular vector matrix
  337: *        to B.
  338: *
  339:          IF( K.EQ.1 ) THEN
  340:             CALL ZCOPY( NRHS, B, LDB, BX, LDBX )
  341:          ELSE
  342:             DO 180 J = 1, K
  343:                DSIGJ = POLES( J, 2 )
  344:                IF( Z( J ).EQ.ZERO ) THEN
  345:                   RWORK( J ) = ZERO
  346:                ELSE
  347:                   RWORK( J ) = -Z( J ) / DIFL( J ) /
  348:      $                         ( DSIGJ+POLES( J, 1 ) ) / DIFR( J, 2 )
  349:                END IF
  350:                DO 110 I = 1, J - 1
  351:                   IF( Z( J ).EQ.ZERO ) THEN
  352:                      RWORK( I ) = ZERO
  353:                   ELSE
  354:                      RWORK( I ) = Z( J ) / ( DLAMC3( DSIGJ, -POLES( I+1,
  355:      $                            2 ) )-DIFR( I, 1 ) ) /
  356:      $                            ( DSIGJ+POLES( I, 1 ) ) / DIFR( I, 2 )
  357:                   END IF
  358:   110          CONTINUE
  359:                DO 120 I = J + 1, K
  360:                   IF( Z( J ).EQ.ZERO ) THEN
  361:                      RWORK( I ) = ZERO
  362:                   ELSE
  363:                      RWORK( I ) = Z( J ) / ( DLAMC3( DSIGJ, -POLES( I,
  364:      $                            2 ) )-DIFL( I ) ) /
  365:      $                            ( DSIGJ+POLES( I, 1 ) ) / DIFR( I, 2 )
  366:                   END IF
  367:   120          CONTINUE
  368: *
  369: *              Since B and BX are complex, the following call to DGEMV
  370: *              is performed in two steps (real and imaginary parts).
  371: *
  372: *              CALL DGEMV( 'T', K, NRHS, ONE, B, LDB, WORK, 1, ZERO,
  373: *    $                     BX( J, 1 ), LDBX )
  374: *
  375:                I = K + NRHS*2
  376:                DO 140 JCOL = 1, NRHS
  377:                   DO 130 JROW = 1, K
  378:                      I = I + 1
  379:                      RWORK( I ) = DBLE( B( JROW, JCOL ) )
  380:   130             CONTINUE
  381:   140          CONTINUE
  382:                CALL DGEMV( 'T', K, NRHS, ONE, RWORK( 1+K+NRHS*2 ), K,
  383:      $                     RWORK( 1 ), 1, ZERO, RWORK( 1+K ), 1 )
  384:                I = K + NRHS*2
  385:                DO 160 JCOL = 1, NRHS
  386:                   DO 150 JROW = 1, K
  387:                      I = I + 1
  388:                      RWORK( I ) = DIMAG( B( JROW, JCOL ) )
  389:   150             CONTINUE
  390:   160          CONTINUE
  391:                CALL DGEMV( 'T', K, NRHS, ONE, RWORK( 1+K+NRHS*2 ), K,
  392:      $                     RWORK( 1 ), 1, ZERO, RWORK( 1+K+NRHS ), 1 )
  393:                DO 170 JCOL = 1, NRHS
  394:                   BX( J, JCOL ) = DCMPLX( RWORK( JCOL+K ),
  395:      $                            RWORK( JCOL+K+NRHS ) )
  396:   170          CONTINUE
  397:   180       CONTINUE
  398:          END IF
  399: *
  400: *        Step (2R): if SQRE = 1, apply back the rotation that is
  401: *        related to the right null space of the subproblem.
  402: *
  403:          IF( SQRE.EQ.1 ) THEN
  404:             CALL ZCOPY( NRHS, B( M, 1 ), LDB, BX( M, 1 ), LDBX )
  405:             CALL ZDROT( NRHS, BX( 1, 1 ), LDBX, BX( M, 1 ), LDBX, C, S )
  406:          END IF
  407:          IF( K.LT.MAX( M, N ) )
  408:      $      CALL ZLACPY( 'A', N-K, NRHS, B( K+1, 1 ), LDB, BX( K+1, 1 ),
  409:      $                   LDBX )
  410: *
  411: *        Step (3R): permute rows of B.
  412: *
  413:          CALL ZCOPY( NRHS, BX( 1, 1 ), LDBX, B( NLP1, 1 ), LDB )
  414:          IF( SQRE.EQ.1 ) THEN
  415:             CALL ZCOPY( NRHS, BX( M, 1 ), LDBX, B( M, 1 ), LDB )
  416:          END IF
  417:          DO 190 I = 2, N
  418:             CALL ZCOPY( NRHS, BX( I, 1 ), LDBX, B( PERM( I ), 1 ), LDB )
  419:   190    CONTINUE
  420: *
  421: *        Step (4R): apply back the Givens rotations performed.
  422: *
  423:          DO 200 I = GIVPTR, 1, -1
  424:             CALL ZDROT( NRHS, B( GIVCOL( I, 2 ), 1 ), LDB,
  425:      $                  B( GIVCOL( I, 1 ), 1 ), LDB, GIVNUM( I, 2 ),
  426:      $                  -GIVNUM( I, 1 ) )
  427:   200    CONTINUE
  428:       END IF
  429: *
  430:       RETURN
  431: *
  432: *     End of ZLALS0
  433: *
  434:       END

CVSweb interface <joel.bertrand@systella.fr>