LAPACK 3.3.1
Linear Algebra PACKage

clals0.f

Go to the documentation of this file.
00001       SUBROUTINE CLALS0( ICOMPQ, NL, NR, SQRE, NRHS, B, LDB, BX, LDBX,
00002      $                   PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM, LDGNUM,
00003      $                   POLES, DIFL, DIFR, Z, K, C, S, RWORK, INFO )
00004 *
00005 *  -- LAPACK routine (version 3.2) --
00006 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00007 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00008 *     November 2006
00009 *
00010 *     .. Scalar Arguments ..
00011       INTEGER            GIVPTR, ICOMPQ, INFO, K, LDB, LDBX, LDGCOL,
00012      $                   LDGNUM, NL, NR, NRHS, SQRE
00013       REAL               C, S
00014 *     ..
00015 *     .. Array Arguments ..
00016       INTEGER            GIVCOL( LDGCOL, * ), PERM( * )
00017       REAL               DIFL( * ), DIFR( LDGNUM, * ),
00018      $                   GIVNUM( LDGNUM, * ), POLES( LDGNUM, * ),
00019      $                   RWORK( * ), Z( * )
00020       COMPLEX            B( LDB, * ), BX( LDBX, * )
00021 *     ..
00022 *
00023 *  Purpose
00024 *  =======
00025 *
00026 *  CLALS0 applies back the multiplying factors of either the left or the
00027 *  right singular vector matrix of a diagonal matrix appended by a row
00028 *  to the right hand side matrix B in solving the least squares problem
00029 *  using the divide-and-conquer SVD approach.
00030 *
00031 *  For the left singular vector matrix, three types of orthogonal
00032 *  matrices are involved:
00033 *
00034 *  (1L) Givens rotations: the number of such rotations is GIVPTR; the
00035 *       pairs of columns/rows they were applied to are stored in GIVCOL;
00036 *       and the C- and S-values of these rotations are stored in GIVNUM.
00037 *
00038 *  (2L) Permutation. The (NL+1)-st row of B is to be moved to the first
00039 *       row, and for J=2:N, PERM(J)-th row of B is to be moved to the
00040 *       J-th row.
00041 *
00042 *  (3L) The left singular vector matrix of the remaining matrix.
00043 *
00044 *  For the right singular vector matrix, four types of orthogonal
00045 *  matrices are involved:
00046 *
00047 *  (1R) The right singular vector matrix of the remaining matrix.
00048 *
00049 *  (2R) If SQRE = 1, one extra Givens rotation to generate the right
00050 *       null space.
00051 *
00052 *  (3R) The inverse transformation of (2L).
00053 *
00054 *  (4R) The inverse transformation of (1L).
00055 *
00056 *  Arguments
00057 *  =========
00058 *
00059 *  ICOMPQ (input) INTEGER
00060 *         Specifies whether singular vectors are to be computed in
00061 *         factored form:
00062 *         = 0: Left singular vector matrix.
00063 *         = 1: Right singular vector matrix.
00064 *
00065 *  NL     (input) INTEGER
00066 *         The row dimension of the upper block. NL >= 1.
00067 *
00068 *  NR     (input) INTEGER
00069 *         The row dimension of the lower block. NR >= 1.
00070 *
00071 *  SQRE   (input) INTEGER
00072 *         = 0: the lower block is an NR-by-NR square matrix.
00073 *         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
00074 *
00075 *         The bidiagonal matrix has row dimension N = NL + NR + 1,
00076 *         and column dimension M = N + SQRE.
00077 *
00078 *  NRHS   (input) INTEGER
00079 *         The number of columns of B and BX. NRHS must be at least 1.
00080 *
00081 *  B      (input/output) COMPLEX array, dimension ( LDB, NRHS )
00082 *         On input, B contains the right hand sides of the least
00083 *         squares problem in rows 1 through M. On output, B contains
00084 *         the solution X in rows 1 through N.
00085 *
00086 *  LDB    (input) INTEGER
00087 *         The leading dimension of B. LDB must be at least
00088 *         max(1,MAX( M, N ) ).
00089 *
00090 *  BX     (workspace) COMPLEX array, dimension ( LDBX, NRHS )
00091 *
00092 *  LDBX   (input) INTEGER
00093 *         The leading dimension of BX.
00094 *
00095 *  PERM   (input) INTEGER array, dimension ( N )
00096 *         The permutations (from deflation and sorting) applied
00097 *         to the two blocks.
00098 *
00099 *  GIVPTR (input) INTEGER
00100 *         The number of Givens rotations which took place in this
00101 *         subproblem.
00102 *
00103 *  GIVCOL (input) INTEGER array, dimension ( LDGCOL, 2 )
00104 *         Each pair of numbers indicates a pair of rows/columns
00105 *         involved in a Givens rotation.
00106 *
00107 *  LDGCOL (input) INTEGER
00108 *         The leading dimension of GIVCOL, must be at least N.
00109 *
00110 *  GIVNUM (input) REAL array, dimension ( LDGNUM, 2 )
00111 *         Each number indicates the C or S value used in the
00112 *         corresponding Givens rotation.
00113 *
00114 *  LDGNUM (input) INTEGER
00115 *         The leading dimension of arrays DIFR, POLES and
00116 *         GIVNUM, must be at least K.
00117 *
00118 *  POLES  (input) REAL array, dimension ( LDGNUM, 2 )
00119 *         On entry, POLES(1:K, 1) contains the new singular
00120 *         values obtained from solving the secular equation, and
00121 *         POLES(1:K, 2) is an array containing the poles in the secular
00122 *         equation.
00123 *
00124 *  DIFL   (input) REAL array, dimension ( K ).
00125 *         On entry, DIFL(I) is the distance between I-th updated
00126 *         (undeflated) singular value and the I-th (undeflated) old
00127 *         singular value.
00128 *
00129 *  DIFR   (input) REAL array, dimension ( LDGNUM, 2 ).
00130 *         On entry, DIFR(I, 1) contains the distances between I-th
00131 *         updated (undeflated) singular value and the I+1-th
00132 *         (undeflated) old singular value. And DIFR(I, 2) is the
00133 *         normalizing factor for the I-th right singular vector.
00134 *
00135 *  Z      (input) REAL array, dimension ( K )
00136 *         Contain the components of the deflation-adjusted updating row
00137 *         vector.
00138 *
00139 *  K      (input) INTEGER
00140 *         Contains the dimension of the non-deflated matrix,
00141 *         This is the order of the related secular equation. 1 <= K <=N.
00142 *
00143 *  C      (input) REAL
00144 *         C contains garbage if SQRE =0 and the C-value of a Givens
00145 *         rotation related to the right null space if SQRE = 1.
00146 *
00147 *  S      (input) REAL
00148 *         S contains garbage if SQRE =0 and the S-value of a Givens
00149 *         rotation related to the right null space if SQRE = 1.
00150 *
00151 *  RWORK  (workspace) REAL array, dimension
00152 *         ( K*(1+NRHS) + 2*NRHS )
00153 *
00154 *  INFO   (output) INTEGER
00155 *          = 0:  successful exit.
00156 *          < 0:  if INFO = -i, the i-th argument had an illegal value.
00157 *
00158 *  Further Details
00159 *  ===============
00160 *
00161 *  Based on contributions by
00162 *     Ming Gu and Ren-Cang Li, Computer Science Division, University of
00163 *       California at Berkeley, USA
00164 *     Osni Marques, LBNL/NERSC, USA
00165 *
00166 *  =====================================================================
00167 *
00168 *     .. Parameters ..
00169       REAL               ONE, ZERO, NEGONE
00170       PARAMETER          ( ONE = 1.0E0, ZERO = 0.0E0, NEGONE = -1.0E0 )
00171 *     ..
00172 *     .. Local Scalars ..
00173       INTEGER            I, J, JCOL, JROW, M, N, NLP1
00174       REAL               DIFLJ, DIFRJ, DJ, DSIGJ, DSIGJP, TEMP
00175 *     ..
00176 *     .. External Subroutines ..
00177       EXTERNAL           CCOPY, CLACPY, CLASCL, CSROT, CSSCAL, SGEMV,
00178      $                   XERBLA
00179 *     ..
00180 *     .. External Functions ..
00181       REAL               SLAMC3, SNRM2
00182       EXTERNAL           SLAMC3, SNRM2
00183 *     ..
00184 *     .. Intrinsic Functions ..
00185       INTRINSIC          AIMAG, CMPLX, MAX, REAL
00186 *     ..
00187 *     .. Executable Statements ..
00188 *
00189 *     Test the input parameters.
00190 *
00191       INFO = 0
00192 *
00193       IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THEN
00194          INFO = -1
00195       ELSE IF( NL.LT.1 ) THEN
00196          INFO = -2
00197       ELSE IF( NR.LT.1 ) THEN
00198          INFO = -3
00199       ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THEN
00200          INFO = -4
00201       END IF
00202 *
00203       N = NL + NR + 1
00204 *
00205       IF( NRHS.LT.1 ) THEN
00206          INFO = -5
00207       ELSE IF( LDB.LT.N ) THEN
00208          INFO = -7
00209       ELSE IF( LDBX.LT.N ) THEN
00210          INFO = -9
00211       ELSE IF( GIVPTR.LT.0 ) THEN
00212          INFO = -11
00213       ELSE IF( LDGCOL.LT.N ) THEN
00214          INFO = -13
00215       ELSE IF( LDGNUM.LT.N ) THEN
00216          INFO = -15
00217       ELSE IF( K.LT.1 ) THEN
00218          INFO = -20
00219       END IF
00220       IF( INFO.NE.0 ) THEN
00221          CALL XERBLA( 'CLALS0', -INFO )
00222          RETURN
00223       END IF
00224 *
00225       M = N + SQRE
00226       NLP1 = NL + 1
00227 *
00228       IF( ICOMPQ.EQ.0 ) THEN
00229 *
00230 *        Apply back orthogonal transformations from the left.
00231 *
00232 *        Step (1L): apply back the Givens rotations performed.
00233 *
00234          DO 10 I = 1, GIVPTR
00235             CALL CSROT( NRHS, B( GIVCOL( I, 2 ), 1 ), LDB,
00236      $                  B( GIVCOL( I, 1 ), 1 ), LDB, GIVNUM( I, 2 ),
00237      $                  GIVNUM( I, 1 ) )
00238    10    CONTINUE
00239 *
00240 *        Step (2L): permute rows of B.
00241 *
00242          CALL CCOPY( NRHS, B( NLP1, 1 ), LDB, BX( 1, 1 ), LDBX )
00243          DO 20 I = 2, N
00244             CALL CCOPY( NRHS, B( PERM( I ), 1 ), LDB, BX( I, 1 ), LDBX )
00245    20    CONTINUE
00246 *
00247 *        Step (3L): apply the inverse of the left singular vector
00248 *        matrix to BX.
00249 *
00250          IF( K.EQ.1 ) THEN
00251             CALL CCOPY( NRHS, BX, LDBX, B, LDB )
00252             IF( Z( 1 ).LT.ZERO ) THEN
00253                CALL CSSCAL( NRHS, NEGONE, B, LDB )
00254             END IF
00255          ELSE
00256             DO 100 J = 1, K
00257                DIFLJ = DIFL( J )
00258                DJ = POLES( J, 1 )
00259                DSIGJ = -POLES( J, 2 )
00260                IF( J.LT.K ) THEN
00261                   DIFRJ = -DIFR( J, 1 )
00262                   DSIGJP = -POLES( J+1, 2 )
00263                END IF
00264                IF( ( Z( J ).EQ.ZERO ) .OR. ( POLES( J, 2 ).EQ.ZERO ) )
00265      $              THEN
00266                   RWORK( J ) = ZERO
00267                ELSE
00268                   RWORK( J ) = -POLES( J, 2 )*Z( J ) / DIFLJ /
00269      $                         ( POLES( J, 2 )+DJ )
00270                END IF
00271                DO 30 I = 1, J - 1
00272                   IF( ( Z( I ).EQ.ZERO ) .OR.
00273      $                ( POLES( I, 2 ).EQ.ZERO ) ) THEN
00274                      RWORK( I ) = ZERO
00275                   ELSE
00276                      RWORK( I ) = POLES( I, 2 )*Z( I ) /
00277      $                            ( SLAMC3( POLES( I, 2 ), DSIGJ )-
00278      $                            DIFLJ ) / ( POLES( I, 2 )+DJ )
00279                   END IF
00280    30          CONTINUE
00281                DO 40 I = J + 1, K
00282                   IF( ( Z( I ).EQ.ZERO ) .OR.
00283      $                ( POLES( I, 2 ).EQ.ZERO ) ) THEN
00284                      RWORK( I ) = ZERO
00285                   ELSE
00286                      RWORK( I ) = POLES( I, 2 )*Z( I ) /
00287      $                            ( SLAMC3( POLES( I, 2 ), DSIGJP )+
00288      $                            DIFRJ ) / ( POLES( I, 2 )+DJ )
00289                   END IF
00290    40          CONTINUE
00291                RWORK( 1 ) = NEGONE
00292                TEMP = SNRM2( K, RWORK, 1 )
00293 *
00294 *              Since B and BX are complex, the following call to SGEMV
00295 *              is performed in two steps (real and imaginary parts).
00296 *
00297 *              CALL SGEMV( 'T', K, NRHS, ONE, BX, LDBX, WORK, 1, ZERO,
00298 *    $                     B( J, 1 ), LDB )
00299 *
00300                I = K + NRHS*2
00301                DO 60 JCOL = 1, NRHS
00302                   DO 50 JROW = 1, K
00303                      I = I + 1
00304                      RWORK( I ) = REAL( BX( JROW, JCOL ) )
00305    50             CONTINUE
00306    60          CONTINUE
00307                CALL SGEMV( 'T', K, NRHS, ONE, RWORK( 1+K+NRHS*2 ), K,
00308      $                     RWORK( 1 ), 1, ZERO, RWORK( 1+K ), 1 )
00309                I = K + NRHS*2
00310                DO 80 JCOL = 1, NRHS
00311                   DO 70 JROW = 1, K
00312                      I = I + 1
00313                      RWORK( I ) = AIMAG( BX( JROW, JCOL ) )
00314    70             CONTINUE
00315    80          CONTINUE
00316                CALL SGEMV( 'T', K, NRHS, ONE, RWORK( 1+K+NRHS*2 ), K,
00317      $                     RWORK( 1 ), 1, ZERO, RWORK( 1+K+NRHS ), 1 )
00318                DO 90 JCOL = 1, NRHS
00319                   B( J, JCOL ) = CMPLX( RWORK( JCOL+K ),
00320      $                           RWORK( JCOL+K+NRHS ) )
00321    90          CONTINUE
00322                CALL CLASCL( 'G', 0, 0, TEMP, ONE, 1, NRHS, B( J, 1 ),
00323      $                      LDB, INFO )
00324   100       CONTINUE
00325          END IF
00326 *
00327 *        Move the deflated rows of BX to B also.
00328 *
00329          IF( K.LT.MAX( M, N ) )
00330      $      CALL CLACPY( 'A', N-K, NRHS, BX( K+1, 1 ), LDBX,
00331      $                   B( K+1, 1 ), LDB )
00332       ELSE
00333 *
00334 *        Apply back the right orthogonal transformations.
00335 *
00336 *        Step (1R): apply back the new right singular vector matrix
00337 *        to B.
00338 *
00339          IF( K.EQ.1 ) THEN
00340             CALL CCOPY( NRHS, B, LDB, BX, LDBX )
00341          ELSE
00342             DO 180 J = 1, K
00343                DSIGJ = POLES( J, 2 )
00344                IF( Z( J ).EQ.ZERO ) THEN
00345                   RWORK( J ) = ZERO
00346                ELSE
00347                   RWORK( J ) = -Z( J ) / DIFL( J ) /
00348      $                         ( DSIGJ+POLES( J, 1 ) ) / DIFR( J, 2 )
00349                END IF
00350                DO 110 I = 1, J - 1
00351                   IF( Z( J ).EQ.ZERO ) THEN
00352                      RWORK( I ) = ZERO
00353                   ELSE
00354                      RWORK( I ) = Z( J ) / ( SLAMC3( DSIGJ, -POLES( I+1,
00355      $                            2 ) )-DIFR( I, 1 ) ) /
00356      $                            ( DSIGJ+POLES( I, 1 ) ) / DIFR( I, 2 )
00357                   END IF
00358   110          CONTINUE
00359                DO 120 I = J + 1, K
00360                   IF( Z( J ).EQ.ZERO ) THEN
00361                      RWORK( I ) = ZERO
00362                   ELSE
00363                      RWORK( I ) = Z( J ) / ( SLAMC3( DSIGJ, -POLES( I,
00364      $                            2 ) )-DIFL( I ) ) /
00365      $                            ( DSIGJ+POLES( I, 1 ) ) / DIFR( I, 2 )
00366                   END IF
00367   120          CONTINUE
00368 *
00369 *              Since B and BX are complex, the following call to SGEMV
00370 *              is performed in two steps (real and imaginary parts).
00371 *
00372 *              CALL SGEMV( 'T', K, NRHS, ONE, B, LDB, WORK, 1, ZERO,
00373 *    $                     BX( J, 1 ), LDBX )
00374 *
00375                I = K + NRHS*2
00376                DO 140 JCOL = 1, NRHS
00377                   DO 130 JROW = 1, K
00378                      I = I + 1
00379                      RWORK( I ) = REAL( B( JROW, JCOL ) )
00380   130             CONTINUE
00381   140          CONTINUE
00382                CALL SGEMV( 'T', K, NRHS, ONE, RWORK( 1+K+NRHS*2 ), K,
00383      $                     RWORK( 1 ), 1, ZERO, RWORK( 1+K ), 1 )
00384                I = K + NRHS*2
00385                DO 160 JCOL = 1, NRHS
00386                   DO 150 JROW = 1, K
00387                      I = I + 1
00388                      RWORK( I ) = AIMAG( B( JROW, JCOL ) )
00389   150             CONTINUE
00390   160          CONTINUE
00391                CALL SGEMV( 'T', K, NRHS, ONE, RWORK( 1+K+NRHS*2 ), K,
00392      $                     RWORK( 1 ), 1, ZERO, RWORK( 1+K+NRHS ), 1 )
00393                DO 170 JCOL = 1, NRHS
00394                   BX( J, JCOL ) = CMPLX( RWORK( JCOL+K ),
00395      $                            RWORK( JCOL+K+NRHS ) )
00396   170          CONTINUE
00397   180       CONTINUE
00398          END IF
00399 *
00400 *        Step (2R): if SQRE = 1, apply back the rotation that is
00401 *        related to the right null space of the subproblem.
00402 *
00403          IF( SQRE.EQ.1 ) THEN
00404             CALL CCOPY( NRHS, B( M, 1 ), LDB, BX( M, 1 ), LDBX )
00405             CALL CSROT( NRHS, BX( 1, 1 ), LDBX, BX( M, 1 ), LDBX, C, S )
00406          END IF
00407          IF( K.LT.MAX( M, N ) )
00408      $      CALL CLACPY( 'A', N-K, NRHS, B( K+1, 1 ), LDB,
00409      $                   BX( K+1, 1 ), LDBX )
00410 *
00411 *        Step (3R): permute rows of B.
00412 *
00413          CALL CCOPY( NRHS, BX( 1, 1 ), LDBX, B( NLP1, 1 ), LDB )
00414          IF( SQRE.EQ.1 ) THEN
00415             CALL CCOPY( NRHS, BX( M, 1 ), LDBX, B( M, 1 ), LDB )
00416          END IF
00417          DO 190 I = 2, N
00418             CALL CCOPY( NRHS, BX( I, 1 ), LDBX, B( PERM( I ), 1 ), LDB )
00419   190    CONTINUE
00420 *
00421 *        Step (4R): apply back the Givens rotations performed.
00422 *
00423          DO 200 I = GIVPTR, 1, -1
00424             CALL CSROT( NRHS, B( GIVCOL( I, 2 ), 1 ), LDB,
00425      $                  B( GIVCOL( I, 1 ), 1 ), LDB, GIVNUM( I, 2 ),
00426      $                  -GIVNUM( I, 1 ) )
00427   200    CONTINUE
00428       END IF
00429 *
00430       RETURN
00431 *
00432 *     End of CLALS0
00433 *
00434       END
 All Files Functions