00001 /* slasd6.f -- translated by f2c (version 20061008). 00002 You must link the resulting object file with libf2c: 00003 on Microsoft Windows system, link with libf2c.lib; 00004 on Linux or Unix systems, link with .../path/to/libf2c.a -lm 00005 or, if you install libf2c.a in a standard place, with -lf2c -lm 00006 -- in that order, at the end of the command line, as in 00007 cc *.o -lf2c -lm 00008 Source for libf2c is in /netlib/f2c/libf2c.zip, e.g., 00009 00010 http://www.netlib.org/f2c/libf2c.zip 00011 */ 00012 00013 #include "f2c.h" 00014 #include "blaswrap.h" 00015 00016 /* Table of constant values */ 00017 00018 static integer c__0 = 0; 00019 static real c_b7 = 1.f; 00020 static integer c__1 = 1; 00021 static integer c_n1 = -1; 00022 00023 /* Subroutine */ int slasd6_(integer *icompq, integer *nl, integer *nr, 00024 integer *sqre, real *d__, real *vf, real *vl, real *alpha, real *beta, 00025 integer *idxq, integer *perm, integer *givptr, integer *givcol, 00026 integer *ldgcol, real *givnum, integer *ldgnum, real *poles, real * 00027 difl, real *difr, real *z__, integer *k, real *c__, real *s, real * 00028 work, integer *iwork, integer *info) 00029 { 00030 /* System generated locals */ 00031 integer givcol_dim1, givcol_offset, givnum_dim1, givnum_offset, 00032 poles_dim1, poles_offset, i__1; 00033 real r__1, r__2; 00034 00035 /* Local variables */ 00036 integer i__, m, n, n1, n2, iw, idx, idxc, idxp, ivfw, ivlw; 00037 extern /* Subroutine */ int scopy_(integer *, real *, integer *, real *, 00038 integer *), slasd7_(integer *, integer *, integer *, integer *, 00039 integer *, real *, real *, real *, real *, real *, real *, real *, 00040 real *, real *, real *, integer *, integer *, integer *, integer 00041 *, integer *, integer *, integer *, real *, integer *, real *, 00042 real *, integer *), slasd8_(integer *, integer *, real *, real *, 00043 real *, real *, real *, real *, integer *, real *, real *, 00044 integer *); 00045 integer isigma; 00046 extern /* Subroutine */ int xerbla_(char *, integer *), slascl_( 00047 char *, integer *, integer *, real *, real *, integer *, integer * 00048 , real *, integer *, integer *), slamrg_(integer *, 00049 integer *, real *, integer *, integer *, integer *); 00050 real orgnrm; 00051 00052 00053 /* -- LAPACK auxiliary routine (version 3.2) -- */ 00054 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ 00055 /* November 2006 */ 00056 00057 /* .. Scalar Arguments .. */ 00058 /* .. */ 00059 /* .. Array Arguments .. */ 00060 /* .. */ 00061 00062 /* Purpose */ 00063 /* ======= */ 00064 00065 /* SLASD6 computes the SVD of an updated upper bidiagonal matrix B */ 00066 /* obtained by merging two smaller ones by appending a row. This */ 00067 /* routine is used only for the problem which requires all singular */ 00068 /* values and optionally singular vector matrices in factored form. */ 00069 /* B is an N-by-M matrix with N = NL + NR + 1 and M = N + SQRE. */ 00070 /* A related subroutine, SLASD1, handles the case in which all singular */ 00071 /* values and singular vectors of the bidiagonal matrix are desired. */ 00072 00073 /* SLASD6 computes the SVD as follows: */ 00074 00075 /* ( D1(in) 0 0 0 ) */ 00076 /* B = U(in) * ( Z1' a Z2' b ) * VT(in) */ 00077 /* ( 0 0 D2(in) 0 ) */ 00078 00079 /* = U(out) * ( D(out) 0) * VT(out) */ 00080 00081 /* where Z' = (Z1' a Z2' b) = u' VT', and u is a vector of dimension M */ 00082 /* with ALPHA and BETA in the NL+1 and NL+2 th entries and zeros */ 00083 /* elsewhere; and the entry b is empty if SQRE = 0. */ 00084 00085 /* The singular values of B can be computed using D1, D2, the first */ 00086 /* components of all the right singular vectors of the lower block, and */ 00087 /* the last components of all the right singular vectors of the upper */ 00088 /* block. These components are stored and updated in VF and VL, */ 00089 /* respectively, in SLASD6. Hence U and VT are not explicitly */ 00090 /* referenced. */ 00091 00092 /* The singular values are stored in D. The algorithm consists of two */ 00093 /* stages: */ 00094 00095 /* The first stage consists of deflating the size of the problem */ 00096 /* when there are multiple singular values or if there is a zero */ 00097 /* in the Z vector. For each such occurence the dimension of the */ 00098 /* secular equation problem is reduced by one. This stage is */ 00099 /* performed by the routine SLASD7. */ 00100 00101 /* The second stage consists of calculating the updated */ 00102 /* singular values. This is done by finding the roots of the */ 00103 /* secular equation via the routine SLASD4 (as called by SLASD8). */ 00104 /* This routine also updates VF and VL and computes the distances */ 00105 /* between the updated singular values and the old singular */ 00106 /* values. */ 00107 00108 /* SLASD6 is called from SLASDA. */ 00109 00110 /* Arguments */ 00111 /* ========= */ 00112 00113 /* ICOMPQ (input) INTEGER */ 00114 /* Specifies whether singular vectors are to be computed in */ 00115 /* factored form: */ 00116 /* = 0: Compute singular values only. */ 00117 /* = 1: Compute singular vectors in factored form as well. */ 00118 00119 /* NL (input) INTEGER */ 00120 /* The row dimension of the upper block. NL >= 1. */ 00121 00122 /* NR (input) INTEGER */ 00123 /* The row dimension of the lower block. NR >= 1. */ 00124 00125 /* SQRE (input) INTEGER */ 00126 /* = 0: the lower block is an NR-by-NR square matrix. */ 00127 /* = 1: the lower block is an NR-by-(NR+1) rectangular matrix. */ 00128 00129 /* The bidiagonal matrix has row dimension N = NL + NR + 1, */ 00130 /* and column dimension M = N + SQRE. */ 00131 00132 /* D (input/output) REAL array, dimension (NL+NR+1). */ 00133 /* On entry D(1:NL,1:NL) contains the singular values of the */ 00134 /* upper block, and D(NL+2:N) contains the singular values */ 00135 /* of the lower block. On exit D(1:N) contains the singular */ 00136 /* values of the modified matrix. */ 00137 00138 /* VF (input/output) REAL array, dimension (M) */ 00139 /* On entry, VF(1:NL+1) contains the first components of all */ 00140 /* right singular vectors of the upper block; and VF(NL+2:M) */ 00141 /* contains the first components of all right singular vectors */ 00142 /* of the lower block. On exit, VF contains the first components */ 00143 /* of all right singular vectors of the bidiagonal matrix. */ 00144 00145 /* VL (input/output) REAL array, dimension (M) */ 00146 /* On entry, VL(1:NL+1) contains the last components of all */ 00147 /* right singular vectors of the upper block; and VL(NL+2:M) */ 00148 /* contains the last components of all right singular vectors of */ 00149 /* the lower block. On exit, VL contains the last components of */ 00150 /* all right singular vectors of the bidiagonal matrix. */ 00151 00152 /* ALPHA (input/output) REAL */ 00153 /* Contains the diagonal element associated with the added row. */ 00154 00155 /* BETA (input/output) REAL */ 00156 /* Contains the off-diagonal element associated with the added */ 00157 /* row. */ 00158 00159 /* IDXQ (output) INTEGER array, dimension (N) */ 00160 /* This contains the permutation which will reintegrate the */ 00161 /* subproblem just solved back into sorted order, i.e. */ 00162 /* D( IDXQ( I = 1, N ) ) will be in ascending order. */ 00163 00164 /* PERM (output) INTEGER array, dimension ( N ) */ 00165 /* The permutations (from deflation and sorting) to be applied */ 00166 /* to each block. Not referenced if ICOMPQ = 0. */ 00167 00168 /* GIVPTR (output) INTEGER */ 00169 /* The number of Givens rotations which took place in this */ 00170 /* subproblem. Not referenced if ICOMPQ = 0. */ 00171 00172 /* GIVCOL (output) INTEGER array, dimension ( LDGCOL, 2 ) */ 00173 /* Each pair of numbers indicates a pair of columns to take place */ 00174 /* in a Givens rotation. Not referenced if ICOMPQ = 0. */ 00175 00176 /* LDGCOL (input) INTEGER */ 00177 /* leading dimension of GIVCOL, must be at least N. */ 00178 00179 /* GIVNUM (output) REAL array, dimension ( LDGNUM, 2 ) */ 00180 /* Each number indicates the C or S value to be used in the */ 00181 /* corresponding Givens rotation. Not referenced if ICOMPQ = 0. */ 00182 00183 /* LDGNUM (input) INTEGER */ 00184 /* The leading dimension of GIVNUM and POLES, must be at least N. */ 00185 00186 /* POLES (output) REAL array, dimension ( LDGNUM, 2 ) */ 00187 /* On exit, POLES(1,*) is an array containing the new singular */ 00188 /* values obtained from solving the secular equation, and */ 00189 /* POLES(2,*) is an array containing the poles in the secular */ 00190 /* equation. Not referenced if ICOMPQ = 0. */ 00191 00192 /* DIFL (output) REAL array, dimension ( N ) */ 00193 /* On exit, DIFL(I) is the distance between I-th updated */ 00194 /* (undeflated) singular value and the I-th (undeflated) old */ 00195 /* singular value. */ 00196 00197 /* DIFR (output) REAL array, */ 00198 /* dimension ( LDGNUM, 2 ) if ICOMPQ = 1 and */ 00199 /* dimension ( N ) if ICOMPQ = 0. */ 00200 /* On exit, DIFR(I, 1) is the distance between I-th updated */ 00201 /* (undeflated) singular value and the I+1-th (undeflated) old */ 00202 /* singular value. */ 00203 00204 /* If ICOMPQ = 1, DIFR(1:K,2) is an array containing the */ 00205 /* normalizing factors for the right singular vector matrix. */ 00206 00207 /* See SLASD8 for details on DIFL and DIFR. */ 00208 00209 /* Z (output) REAL array, dimension ( M ) */ 00210 /* The first elements of this array contain the components */ 00211 /* of the deflation-adjusted updating row vector. */ 00212 00213 /* K (output) INTEGER */ 00214 /* Contains the dimension of the non-deflated matrix, */ 00215 /* This is the order of the related secular equation. 1 <= K <=N. */ 00216 00217 /* C (output) REAL */ 00218 /* C contains garbage if SQRE =0 and the C-value of a Givens */ 00219 /* rotation related to the right null space if SQRE = 1. */ 00220 00221 /* S (output) REAL */ 00222 /* S contains garbage if SQRE =0 and the S-value of a Givens */ 00223 /* rotation related to the right null space if SQRE = 1. */ 00224 00225 /* WORK (workspace) REAL array, dimension ( 4 * M ) */ 00226 00227 /* IWORK (workspace) INTEGER array, dimension ( 3 * N ) */ 00228 00229 /* INFO (output) INTEGER */ 00230 /* = 0: successful exit. */ 00231 /* < 0: if INFO = -i, the i-th argument had an illegal value. */ 00232 /* > 0: if INFO = 1, an singular value did not converge */ 00233 00234 /* Further Details */ 00235 /* =============== */ 00236 00237 /* Based on contributions by */ 00238 /* Ming Gu and Huan Ren, Computer Science Division, University of */ 00239 /* California at Berkeley, USA */ 00240 00241 /* ===================================================================== */ 00242 00243 /* .. Parameters .. */ 00244 /* .. */ 00245 /* .. Local Scalars .. */ 00246 /* .. */ 00247 /* .. External Subroutines .. */ 00248 /* .. */ 00249 /* .. Intrinsic Functions .. */ 00250 /* .. */ 00251 /* .. Executable Statements .. */ 00252 00253 /* Test the input parameters. */ 00254 00255 /* Parameter adjustments */ 00256 --d__; 00257 --vf; 00258 --vl; 00259 --idxq; 00260 --perm; 00261 givcol_dim1 = *ldgcol; 00262 givcol_offset = 1 + givcol_dim1; 00263 givcol -= givcol_offset; 00264 poles_dim1 = *ldgnum; 00265 poles_offset = 1 + poles_dim1; 00266 poles -= poles_offset; 00267 givnum_dim1 = *ldgnum; 00268 givnum_offset = 1 + givnum_dim1; 00269 givnum -= givnum_offset; 00270 --difl; 00271 --difr; 00272 --z__; 00273 --work; 00274 --iwork; 00275 00276 /* Function Body */ 00277 *info = 0; 00278 n = *nl + *nr + 1; 00279 m = n + *sqre; 00280 00281 if (*icompq < 0 || *icompq > 1) { 00282 *info = -1; 00283 } else if (*nl < 1) { 00284 *info = -2; 00285 } else if (*nr < 1) { 00286 *info = -3; 00287 } else if (*sqre < 0 || *sqre > 1) { 00288 *info = -4; 00289 } else if (*ldgcol < n) { 00290 *info = -14; 00291 } else if (*ldgnum < n) { 00292 *info = -16; 00293 } 00294 if (*info != 0) { 00295 i__1 = -(*info); 00296 xerbla_("SLASD6", &i__1); 00297 return 0; 00298 } 00299 00300 /* The following values are for bookkeeping purposes only. They are */ 00301 /* integer pointers which indicate the portion of the workspace */ 00302 /* used by a particular array in SLASD7 and SLASD8. */ 00303 00304 isigma = 1; 00305 iw = isigma + n; 00306 ivfw = iw + m; 00307 ivlw = ivfw + m; 00308 00309 idx = 1; 00310 idxc = idx + n; 00311 idxp = idxc + n; 00312 00313 /* Scale. */ 00314 00315 /* Computing MAX */ 00316 r__1 = dabs(*alpha), r__2 = dabs(*beta); 00317 orgnrm = dmax(r__1,r__2); 00318 d__[*nl + 1] = 0.f; 00319 i__1 = n; 00320 for (i__ = 1; i__ <= i__1; ++i__) { 00321 if ((r__1 = d__[i__], dabs(r__1)) > orgnrm) { 00322 orgnrm = (r__1 = d__[i__], dabs(r__1)); 00323 } 00324 /* L10: */ 00325 } 00326 slascl_("G", &c__0, &c__0, &orgnrm, &c_b7, &n, &c__1, &d__[1], &n, info); 00327 *alpha /= orgnrm; 00328 *beta /= orgnrm; 00329 00330 /* Sort and Deflate singular values. */ 00331 00332 slasd7_(icompq, nl, nr, sqre, k, &d__[1], &z__[1], &work[iw], &vf[1], & 00333 work[ivfw], &vl[1], &work[ivlw], alpha, beta, &work[isigma], & 00334 iwork[idx], &iwork[idxp], &idxq[1], &perm[1], givptr, &givcol[ 00335 givcol_offset], ldgcol, &givnum[givnum_offset], ldgnum, c__, s, 00336 info); 00337 00338 /* Solve Secular Equation, compute DIFL, DIFR, and update VF, VL. */ 00339 00340 slasd8_(icompq, k, &d__[1], &z__[1], &vf[1], &vl[1], &difl[1], &difr[1], 00341 ldgnum, &work[isigma], &work[iw], info); 00342 00343 /* Save the poles if ICOMPQ = 1. */ 00344 00345 if (*icompq == 1) { 00346 scopy_(k, &d__[1], &c__1, &poles[poles_dim1 + 1], &c__1); 00347 scopy_(k, &work[isigma], &c__1, &poles[(poles_dim1 << 1) + 1], &c__1); 00348 } 00349 00350 /* Unscale. */ 00351 00352 slascl_("G", &c__0, &c__0, &c_b7, &orgnrm, &n, &c__1, &d__[1], &n, info); 00353 00354 /* Prepare the IDXQ sorting permutation. */ 00355 00356 n1 = *k; 00357 n2 = n - *k; 00358 slamrg_(&n1, &n2, &d__[1], &c__1, &c_n1, &idxq[1]); 00359 00360 return 0; 00361 00362 /* End of SLASD6 */ 00363 00364 } /* slasd6_ */