LAPACK 3.3.0

slals0.f

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