Annotation of rpl/lapack/lapack/zlals0.f, revision 1.1

1.1     ! bertrand    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>