cbdsqr.c
Go to the documentation of this file.
00001 /* cbdsqr.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 doublereal c_b15 = -.125;
00019 static integer c__1 = 1;
00020 static real c_b49 = 1.f;
00021 static real c_b72 = -1.f;
00022 
00023 /* Subroutine */ int cbdsqr_(char *uplo, integer *n, integer *ncvt, integer *
00024         nru, integer *ncc, real *d__, real *e, complex *vt, integer *ldvt, 
00025         complex *u, integer *ldu, complex *c__, integer *ldc, real *rwork, 
00026         integer *info)
00027 {
00028     /* System generated locals */
00029     integer c_dim1, c_offset, u_dim1, u_offset, vt_dim1, vt_offset, i__1, 
00030             i__2;
00031     real r__1, r__2, r__3, r__4;
00032     doublereal d__1;
00033 
00034     /* Builtin functions */
00035     double pow_dd(doublereal *, doublereal *), sqrt(doublereal), r_sign(real *
00036             , real *);
00037 
00038     /* Local variables */
00039     real f, g, h__;
00040     integer i__, j, m;
00041     real r__, cs;
00042     integer ll;
00043     real sn, mu;
00044     integer nm1, nm12, nm13, lll;
00045     real eps, sll, tol, abse;
00046     integer idir;
00047     real abss;
00048     integer oldm;
00049     real cosl;
00050     integer isub, iter;
00051     real unfl, sinl, cosr, smin, smax, sinr;
00052     extern /* Subroutine */ int slas2_(real *, real *, real *, real *, real *)
00053             ;
00054     extern logical lsame_(char *, char *);
00055     real oldcs;
00056     extern /* Subroutine */ int clasr_(char *, char *, char *, integer *, 
00057             integer *, real *, real *, complex *, integer *);
00058     integer oldll;
00059     real shift, sigmn, oldsn;
00060     extern /* Subroutine */ int cswap_(integer *, complex *, integer *, 
00061             complex *, integer *);
00062     integer maxit;
00063     real sminl, sigmx;
00064     logical lower;
00065     extern /* Subroutine */ int csrot_(integer *, complex *, integer *, 
00066             complex *, integer *, real *, real *), slasq1_(integer *, real *, 
00067             real *, real *, integer *), slasv2_(real *, real *, real *, real *
00068 , real *, real *, real *, real *, real *);
00069     extern doublereal slamch_(char *);
00070     extern /* Subroutine */ int csscal_(integer *, real *, complex *, integer 
00071             *), xerbla_(char *, integer *);
00072     real sminoa;
00073     extern /* Subroutine */ int slartg_(real *, real *, real *, real *, real *
00074 );
00075     real thresh;
00076     logical rotate;
00077     real tolmul;
00078 
00079 
00080 /*  -- LAPACK routine (version 3.2) -- */
00081 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00082 /*     November 2006 */
00083 
00084 /*     .. Scalar Arguments .. */
00085 /*     .. */
00086 /*     .. Array Arguments .. */
00087 /*     .. */
00088 
00089 /*  Purpose */
00090 /*  ======= */
00091 
00092 /*  CBDSQR computes the singular values and, optionally, the right and/or */
00093 /*  left singular vectors from the singular value decomposition (SVD) of */
00094 /*  a real N-by-N (upper or lower) bidiagonal matrix B using the implicit */
00095 /*  zero-shift QR algorithm.  The SVD of B has the form */
00096 
00097 /*     B = Q * S * P**H */
00098 
00099 /*  where S is the diagonal matrix of singular values, Q is an orthogonal */
00100 /*  matrix of left singular vectors, and P is an orthogonal matrix of */
00101 /*  right singular vectors.  If left singular vectors are requested, this */
00102 /*  subroutine actually returns U*Q instead of Q, and, if right singular */
00103 /*  vectors are requested, this subroutine returns P**H*VT instead of */
00104 /*  P**H, for given complex input matrices U and VT.  When U and VT are */
00105 /*  the unitary matrices that reduce a general matrix A to bidiagonal */
00106 /*  form: A = U*B*VT, as computed by CGEBRD, then */
00107 
00108 /*     A = (U*Q) * S * (P**H*VT) */
00109 
00110 /*  is the SVD of A.  Optionally, the subroutine may also compute Q**H*C */
00111 /*  for a given complex input matrix C. */
00112 
00113 /*  See "Computing  Small Singular Values of Bidiagonal Matrices With */
00114 /*  Guaranteed High Relative Accuracy," by J. Demmel and W. Kahan, */
00115 /*  LAPACK Working Note #3 (or SIAM J. Sci. Statist. Comput. vol. 11, */
00116 /*  no. 5, pp. 873-912, Sept 1990) and */
00117 /*  "Accurate singular values and differential qd algorithms," by */
00118 /*  B. Parlett and V. Fernando, Technical Report CPAM-554, Mathematics */
00119 /*  Department, University of California at Berkeley, July 1992 */
00120 /*  for a detailed description of the algorithm. */
00121 
00122 /*  Arguments */
00123 /*  ========= */
00124 
00125 /*  UPLO    (input) CHARACTER*1 */
00126 /*          = 'U':  B is upper bidiagonal; */
00127 /*          = 'L':  B is lower bidiagonal. */
00128 
00129 /*  N       (input) INTEGER */
00130 /*          The order of the matrix B.  N >= 0. */
00131 
00132 /*  NCVT    (input) INTEGER */
00133 /*          The number of columns of the matrix VT. NCVT >= 0. */
00134 
00135 /*  NRU     (input) INTEGER */
00136 /*          The number of rows of the matrix U. NRU >= 0. */
00137 
00138 /*  NCC     (input) INTEGER */
00139 /*          The number of columns of the matrix C. NCC >= 0. */
00140 
00141 /*  D       (input/output) REAL array, dimension (N) */
00142 /*          On entry, the n diagonal elements of the bidiagonal matrix B. */
00143 /*          On exit, if INFO=0, the singular values of B in decreasing */
00144 /*          order. */
00145 
00146 /*  E       (input/output) REAL array, dimension (N-1) */
00147 /*          On entry, the N-1 offdiagonal elements of the bidiagonal */
00148 /*          matrix B. */
00149 /*          On exit, if INFO = 0, E is destroyed; if INFO > 0, D and E */
00150 /*          will contain the diagonal and superdiagonal elements of a */
00151 /*          bidiagonal matrix orthogonally equivalent to the one given */
00152 /*          as input. */
00153 
00154 /*  VT      (input/output) COMPLEX array, dimension (LDVT, NCVT) */
00155 /*          On entry, an N-by-NCVT matrix VT. */
00156 /*          On exit, VT is overwritten by P**H * VT. */
00157 /*          Not referenced if NCVT = 0. */
00158 
00159 /*  LDVT    (input) INTEGER */
00160 /*          The leading dimension of the array VT. */
00161 /*          LDVT >= max(1,N) if NCVT > 0; LDVT >= 1 if NCVT = 0. */
00162 
00163 /*  U       (input/output) COMPLEX array, dimension (LDU, N) */
00164 /*          On entry, an NRU-by-N matrix U. */
00165 /*          On exit, U is overwritten by U * Q. */
00166 /*          Not referenced if NRU = 0. */
00167 
00168 /*  LDU     (input) INTEGER */
00169 /*          The leading dimension of the array U.  LDU >= max(1,NRU). */
00170 
00171 /*  C       (input/output) COMPLEX array, dimension (LDC, NCC) */
00172 /*          On entry, an N-by-NCC matrix C. */
00173 /*          On exit, C is overwritten by Q**H * C. */
00174 /*          Not referenced if NCC = 0. */
00175 
00176 /*  LDC     (input) INTEGER */
00177 /*          The leading dimension of the array C. */
00178 /*          LDC >= max(1,N) if NCC > 0; LDC >=1 if NCC = 0. */
00179 
00180 /*  RWORK   (workspace) REAL array, dimension (2*N) */
00181 /*          if NCVT = NRU = NCC = 0, (max(1, 4*N-4)) otherwise */
00182 
00183 /*  INFO    (output) INTEGER */
00184 /*          = 0:  successful exit */
00185 /*          < 0:  If INFO = -i, the i-th argument had an illegal value */
00186 /*          > 0:  the algorithm did not converge; D and E contain the */
00187 /*                elements of a bidiagonal matrix which is orthogonally */
00188 /*                similar to the input matrix B;  if INFO = i, i */
00189 /*                elements of E have not converged to zero. */
00190 
00191 /*  Internal Parameters */
00192 /*  =================== */
00193 
00194 /*  TOLMUL  REAL, default = max(10,min(100,EPS**(-1/8))) */
00195 /*          TOLMUL controls the convergence criterion of the QR loop. */
00196 /*          If it is positive, TOLMUL*EPS is the desired relative */
00197 /*             precision in the computed singular values. */
00198 /*          If it is negative, abs(TOLMUL*EPS*sigma_max) is the */
00199 /*             desired absolute accuracy in the computed singular */
00200 /*             values (corresponds to relative accuracy */
00201 /*             abs(TOLMUL*EPS) in the largest singular value. */
00202 /*          abs(TOLMUL) should be between 1 and 1/EPS, and preferably */
00203 /*             between 10 (for fast convergence) and .1/EPS */
00204 /*             (for there to be some accuracy in the results). */
00205 /*          Default is to lose at either one eighth or 2 of the */
00206 /*             available decimal digits in each computed singular value */
00207 /*             (whichever is smaller). */
00208 
00209 /*  MAXITR  INTEGER, default = 6 */
00210 /*          MAXITR controls the maximum number of passes of the */
00211 /*          algorithm through its inner loop. The algorithms stops */
00212 /*          (and so fails to converge) if the number of passes */
00213 /*          through the inner loop exceeds MAXITR*N**2. */
00214 
00215 /*  ===================================================================== */
00216 
00217 /*     .. Parameters .. */
00218 /*     .. */
00219 /*     .. Local Scalars .. */
00220 /*     .. */
00221 /*     .. External Functions .. */
00222 /*     .. */
00223 /*     .. External Subroutines .. */
00224 /*     .. */
00225 /*     .. Intrinsic Functions .. */
00226 /*     .. */
00227 /*     .. Executable Statements .. */
00228 
00229 /*     Test the input parameters. */
00230 
00231     /* Parameter adjustments */
00232     --d__;
00233     --e;
00234     vt_dim1 = *ldvt;
00235     vt_offset = 1 + vt_dim1;
00236     vt -= vt_offset;
00237     u_dim1 = *ldu;
00238     u_offset = 1 + u_dim1;
00239     u -= u_offset;
00240     c_dim1 = *ldc;
00241     c_offset = 1 + c_dim1;
00242     c__ -= c_offset;
00243     --rwork;
00244 
00245     /* Function Body */
00246     *info = 0;
00247     lower = lsame_(uplo, "L");
00248     if (! lsame_(uplo, "U") && ! lower) {
00249         *info = -1;
00250     } else if (*n < 0) {
00251         *info = -2;
00252     } else if (*ncvt < 0) {
00253         *info = -3;
00254     } else if (*nru < 0) {
00255         *info = -4;
00256     } else if (*ncc < 0) {
00257         *info = -5;
00258     } else if (*ncvt == 0 && *ldvt < 1 || *ncvt > 0 && *ldvt < max(1,*n)) {
00259         *info = -9;
00260     } else if (*ldu < max(1,*nru)) {
00261         *info = -11;
00262     } else if (*ncc == 0 && *ldc < 1 || *ncc > 0 && *ldc < max(1,*n)) {
00263         *info = -13;
00264     }
00265     if (*info != 0) {
00266         i__1 = -(*info);
00267         xerbla_("CBDSQR", &i__1);
00268         return 0;
00269     }
00270     if (*n == 0) {
00271         return 0;
00272     }
00273     if (*n == 1) {
00274         goto L160;
00275     }
00276 
00277 /*     ROTATE is true if any singular vectors desired, false otherwise */
00278 
00279     rotate = *ncvt > 0 || *nru > 0 || *ncc > 0;
00280 
00281 /*     If no singular vectors desired, use qd algorithm */
00282 
00283     if (! rotate) {
00284         slasq1_(n, &d__[1], &e[1], &rwork[1], info);
00285         return 0;
00286     }
00287 
00288     nm1 = *n - 1;
00289     nm12 = nm1 + nm1;
00290     nm13 = nm12 + nm1;
00291     idir = 0;
00292 
00293 /*     Get machine constants */
00294 
00295     eps = slamch_("Epsilon");
00296     unfl = slamch_("Safe minimum");
00297 
00298 /*     If matrix lower bidiagonal, rotate to be upper bidiagonal */
00299 /*     by applying Givens rotations on the left */
00300 
00301     if (lower) {
00302         i__1 = *n - 1;
00303         for (i__ = 1; i__ <= i__1; ++i__) {
00304             slartg_(&d__[i__], &e[i__], &cs, &sn, &r__);
00305             d__[i__] = r__;
00306             e[i__] = sn * d__[i__ + 1];
00307             d__[i__ + 1] = cs * d__[i__ + 1];
00308             rwork[i__] = cs;
00309             rwork[nm1 + i__] = sn;
00310 /* L10: */
00311         }
00312 
00313 /*        Update singular vectors if desired */
00314 
00315         if (*nru > 0) {
00316             clasr_("R", "V", "F", nru, n, &rwork[1], &rwork[*n], &u[u_offset], 
00317                      ldu);
00318         }
00319         if (*ncc > 0) {
00320             clasr_("L", "V", "F", n, ncc, &rwork[1], &rwork[*n], &c__[
00321                     c_offset], ldc);
00322         }
00323     }
00324 
00325 /*     Compute singular values to relative accuracy TOL */
00326 /*     (By setting TOL to be negative, algorithm will compute */
00327 /*     singular values to absolute accuracy ABS(TOL)*norm(input matrix)) */
00328 
00329 /* Computing MAX */
00330 /* Computing MIN */
00331     d__1 = (doublereal) eps;
00332     r__3 = 100.f, r__4 = pow_dd(&d__1, &c_b15);
00333     r__1 = 10.f, r__2 = dmin(r__3,r__4);
00334     tolmul = dmax(r__1,r__2);
00335     tol = tolmul * eps;
00336 
00337 /*     Compute approximate maximum, minimum singular values */
00338 
00339     smax = 0.f;
00340     i__1 = *n;
00341     for (i__ = 1; i__ <= i__1; ++i__) {
00342 /* Computing MAX */
00343         r__2 = smax, r__3 = (r__1 = d__[i__], dabs(r__1));
00344         smax = dmax(r__2,r__3);
00345 /* L20: */
00346     }
00347     i__1 = *n - 1;
00348     for (i__ = 1; i__ <= i__1; ++i__) {
00349 /* Computing MAX */
00350         r__2 = smax, r__3 = (r__1 = e[i__], dabs(r__1));
00351         smax = dmax(r__2,r__3);
00352 /* L30: */
00353     }
00354     sminl = 0.f;
00355     if (tol >= 0.f) {
00356 
00357 /*        Relative accuracy desired */
00358 
00359         sminoa = dabs(d__[1]);
00360         if (sminoa == 0.f) {
00361             goto L50;
00362         }
00363         mu = sminoa;
00364         i__1 = *n;
00365         for (i__ = 2; i__ <= i__1; ++i__) {
00366             mu = (r__2 = d__[i__], dabs(r__2)) * (mu / (mu + (r__1 = e[i__ - 
00367                     1], dabs(r__1))));
00368             sminoa = dmin(sminoa,mu);
00369             if (sminoa == 0.f) {
00370                 goto L50;
00371             }
00372 /* L40: */
00373         }
00374 L50:
00375         sminoa /= sqrt((real) (*n));
00376 /* Computing MAX */
00377         r__1 = tol * sminoa, r__2 = *n * 6 * *n * unfl;
00378         thresh = dmax(r__1,r__2);
00379     } else {
00380 
00381 /*        Absolute accuracy desired */
00382 
00383 /* Computing MAX */
00384         r__1 = dabs(tol) * smax, r__2 = *n * 6 * *n * unfl;
00385         thresh = dmax(r__1,r__2);
00386     }
00387 
00388 /*     Prepare for main iteration loop for the singular values */
00389 /*     (MAXIT is the maximum number of passes through the inner */
00390 /*     loop permitted before nonconvergence signalled.) */
00391 
00392     maxit = *n * 6 * *n;
00393     iter = 0;
00394     oldll = -1;
00395     oldm = -1;
00396 
00397 /*     M points to last element of unconverged part of matrix */
00398 
00399     m = *n;
00400 
00401 /*     Begin main iteration loop */
00402 
00403 L60:
00404 
00405 /*     Check for convergence or exceeding iteration count */
00406 
00407     if (m <= 1) {
00408         goto L160;
00409     }
00410     if (iter > maxit) {
00411         goto L200;
00412     }
00413 
00414 /*     Find diagonal block of matrix to work on */
00415 
00416     if (tol < 0.f && (r__1 = d__[m], dabs(r__1)) <= thresh) {
00417         d__[m] = 0.f;
00418     }
00419     smax = (r__1 = d__[m], dabs(r__1));
00420     smin = smax;
00421     i__1 = m - 1;
00422     for (lll = 1; lll <= i__1; ++lll) {
00423         ll = m - lll;
00424         abss = (r__1 = d__[ll], dabs(r__1));
00425         abse = (r__1 = e[ll], dabs(r__1));
00426         if (tol < 0.f && abss <= thresh) {
00427             d__[ll] = 0.f;
00428         }
00429         if (abse <= thresh) {
00430             goto L80;
00431         }
00432         smin = dmin(smin,abss);
00433 /* Computing MAX */
00434         r__1 = max(smax,abss);
00435         smax = dmax(r__1,abse);
00436 /* L70: */
00437     }
00438     ll = 0;
00439     goto L90;
00440 L80:
00441     e[ll] = 0.f;
00442 
00443 /*     Matrix splits since E(LL) = 0 */
00444 
00445     if (ll == m - 1) {
00446 
00447 /*        Convergence of bottom singular value, return to top of loop */
00448 
00449         --m;
00450         goto L60;
00451     }
00452 L90:
00453     ++ll;
00454 
00455 /*     E(LL) through E(M-1) are nonzero, E(LL-1) is zero */
00456 
00457     if (ll == m - 1) {
00458 
00459 /*        2 by 2 block, handle separately */
00460 
00461         slasv2_(&d__[m - 1], &e[m - 1], &d__[m], &sigmn, &sigmx, &sinr, &cosr, 
00462                  &sinl, &cosl);
00463         d__[m - 1] = sigmx;
00464         e[m - 1] = 0.f;
00465         d__[m] = sigmn;
00466 
00467 /*        Compute singular vectors, if desired */
00468 
00469         if (*ncvt > 0) {
00470             csrot_(ncvt, &vt[m - 1 + vt_dim1], ldvt, &vt[m + vt_dim1], ldvt, &
00471                     cosr, &sinr);
00472         }
00473         if (*nru > 0) {
00474             csrot_(nru, &u[(m - 1) * u_dim1 + 1], &c__1, &u[m * u_dim1 + 1], &
00475                     c__1, &cosl, &sinl);
00476         }
00477         if (*ncc > 0) {
00478             csrot_(ncc, &c__[m - 1 + c_dim1], ldc, &c__[m + c_dim1], ldc, &
00479                     cosl, &sinl);
00480         }
00481         m += -2;
00482         goto L60;
00483     }
00484 
00485 /*     If working on new submatrix, choose shift direction */
00486 /*     (from larger end diagonal element towards smaller) */
00487 
00488     if (ll > oldm || m < oldll) {
00489         if ((r__1 = d__[ll], dabs(r__1)) >= (r__2 = d__[m], dabs(r__2))) {
00490 
00491 /*           Chase bulge from top (big end) to bottom (small end) */
00492 
00493             idir = 1;
00494         } else {
00495 
00496 /*           Chase bulge from bottom (big end) to top (small end) */
00497 
00498             idir = 2;
00499         }
00500     }
00501 
00502 /*     Apply convergence tests */
00503 
00504     if (idir == 1) {
00505 
00506 /*        Run convergence test in forward direction */
00507 /*        First apply standard test to bottom of matrix */
00508 
00509         if ((r__2 = e[m - 1], dabs(r__2)) <= dabs(tol) * (r__1 = d__[m], dabs(
00510                 r__1)) || tol < 0.f && (r__3 = e[m - 1], dabs(r__3)) <= 
00511                 thresh) {
00512             e[m - 1] = 0.f;
00513             goto L60;
00514         }
00515 
00516         if (tol >= 0.f) {
00517 
00518 /*           If relative accuracy desired, */
00519 /*           apply convergence criterion forward */
00520 
00521             mu = (r__1 = d__[ll], dabs(r__1));
00522             sminl = mu;
00523             i__1 = m - 1;
00524             for (lll = ll; lll <= i__1; ++lll) {
00525                 if ((r__1 = e[lll], dabs(r__1)) <= tol * mu) {
00526                     e[lll] = 0.f;
00527                     goto L60;
00528                 }
00529                 mu = (r__2 = d__[lll + 1], dabs(r__2)) * (mu / (mu + (r__1 = 
00530                         e[lll], dabs(r__1))));
00531                 sminl = dmin(sminl,mu);
00532 /* L100: */
00533             }
00534         }
00535 
00536     } else {
00537 
00538 /*        Run convergence test in backward direction */
00539 /*        First apply standard test to top of matrix */
00540 
00541         if ((r__2 = e[ll], dabs(r__2)) <= dabs(tol) * (r__1 = d__[ll], dabs(
00542                 r__1)) || tol < 0.f && (r__3 = e[ll], dabs(r__3)) <= thresh) {
00543             e[ll] = 0.f;
00544             goto L60;
00545         }
00546 
00547         if (tol >= 0.f) {
00548 
00549 /*           If relative accuracy desired, */
00550 /*           apply convergence criterion backward */
00551 
00552             mu = (r__1 = d__[m], dabs(r__1));
00553             sminl = mu;
00554             i__1 = ll;
00555             for (lll = m - 1; lll >= i__1; --lll) {
00556                 if ((r__1 = e[lll], dabs(r__1)) <= tol * mu) {
00557                     e[lll] = 0.f;
00558                     goto L60;
00559                 }
00560                 mu = (r__2 = d__[lll], dabs(r__2)) * (mu / (mu + (r__1 = e[
00561                         lll], dabs(r__1))));
00562                 sminl = dmin(sminl,mu);
00563 /* L110: */
00564             }
00565         }
00566     }
00567     oldll = ll;
00568     oldm = m;
00569 
00570 /*     Compute shift.  First, test if shifting would ruin relative */
00571 /*     accuracy, and if so set the shift to zero. */
00572 
00573 /* Computing MAX */
00574     r__1 = eps, r__2 = tol * .01f;
00575     if (tol >= 0.f && *n * tol * (sminl / smax) <= dmax(r__1,r__2)) {
00576 
00577 /*        Use a zero shift to avoid loss of relative accuracy */
00578 
00579         shift = 0.f;
00580     } else {
00581 
00582 /*        Compute the shift from 2-by-2 block at end of matrix */
00583 
00584         if (idir == 1) {
00585             sll = (r__1 = d__[ll], dabs(r__1));
00586             slas2_(&d__[m - 1], &e[m - 1], &d__[m], &shift, &r__);
00587         } else {
00588             sll = (r__1 = d__[m], dabs(r__1));
00589             slas2_(&d__[ll], &e[ll], &d__[ll + 1], &shift, &r__);
00590         }
00591 
00592 /*        Test if shift negligible, and if so set to zero */
00593 
00594         if (sll > 0.f) {
00595 /* Computing 2nd power */
00596             r__1 = shift / sll;
00597             if (r__1 * r__1 < eps) {
00598                 shift = 0.f;
00599             }
00600         }
00601     }
00602 
00603 /*     Increment iteration count */
00604 
00605     iter = iter + m - ll;
00606 
00607 /*     If SHIFT = 0, do simplified QR iteration */
00608 
00609     if (shift == 0.f) {
00610         if (idir == 1) {
00611 
00612 /*           Chase bulge from top to bottom */
00613 /*           Save cosines and sines for later singular vector updates */
00614 
00615             cs = 1.f;
00616             oldcs = 1.f;
00617             i__1 = m - 1;
00618             for (i__ = ll; i__ <= i__1; ++i__) {
00619                 r__1 = d__[i__] * cs;
00620                 slartg_(&r__1, &e[i__], &cs, &sn, &r__);
00621                 if (i__ > ll) {
00622                     e[i__ - 1] = oldsn * r__;
00623                 }
00624                 r__1 = oldcs * r__;
00625                 r__2 = d__[i__ + 1] * sn;
00626                 slartg_(&r__1, &r__2, &oldcs, &oldsn, &d__[i__]);
00627                 rwork[i__ - ll + 1] = cs;
00628                 rwork[i__ - ll + 1 + nm1] = sn;
00629                 rwork[i__ - ll + 1 + nm12] = oldcs;
00630                 rwork[i__ - ll + 1 + nm13] = oldsn;
00631 /* L120: */
00632             }
00633             h__ = d__[m] * cs;
00634             d__[m] = h__ * oldcs;
00635             e[m - 1] = h__ * oldsn;
00636 
00637 /*           Update singular vectors */
00638 
00639             if (*ncvt > 0) {
00640                 i__1 = m - ll + 1;
00641                 clasr_("L", "V", "F", &i__1, ncvt, &rwork[1], &rwork[*n], &vt[
00642                         ll + vt_dim1], ldvt);
00643             }
00644             if (*nru > 0) {
00645                 i__1 = m - ll + 1;
00646                 clasr_("R", "V", "F", nru, &i__1, &rwork[nm12 + 1], &rwork[
00647                         nm13 + 1], &u[ll * u_dim1 + 1], ldu);
00648             }
00649             if (*ncc > 0) {
00650                 i__1 = m - ll + 1;
00651                 clasr_("L", "V", "F", &i__1, ncc, &rwork[nm12 + 1], &rwork[
00652                         nm13 + 1], &c__[ll + c_dim1], ldc);
00653             }
00654 
00655 /*           Test convergence */
00656 
00657             if ((r__1 = e[m - 1], dabs(r__1)) <= thresh) {
00658                 e[m - 1] = 0.f;
00659             }
00660 
00661         } else {
00662 
00663 /*           Chase bulge from bottom to top */
00664 /*           Save cosines and sines for later singular vector updates */
00665 
00666             cs = 1.f;
00667             oldcs = 1.f;
00668             i__1 = ll + 1;
00669             for (i__ = m; i__ >= i__1; --i__) {
00670                 r__1 = d__[i__] * cs;
00671                 slartg_(&r__1, &e[i__ - 1], &cs, &sn, &r__);
00672                 if (i__ < m) {
00673                     e[i__] = oldsn * r__;
00674                 }
00675                 r__1 = oldcs * r__;
00676                 r__2 = d__[i__ - 1] * sn;
00677                 slartg_(&r__1, &r__2, &oldcs, &oldsn, &d__[i__]);
00678                 rwork[i__ - ll] = cs;
00679                 rwork[i__ - ll + nm1] = -sn;
00680                 rwork[i__ - ll + nm12] = oldcs;
00681                 rwork[i__ - ll + nm13] = -oldsn;
00682 /* L130: */
00683             }
00684             h__ = d__[ll] * cs;
00685             d__[ll] = h__ * oldcs;
00686             e[ll] = h__ * oldsn;
00687 
00688 /*           Update singular vectors */
00689 
00690             if (*ncvt > 0) {
00691                 i__1 = m - ll + 1;
00692                 clasr_("L", "V", "B", &i__1, ncvt, &rwork[nm12 + 1], &rwork[
00693                         nm13 + 1], &vt[ll + vt_dim1], ldvt);
00694             }
00695             if (*nru > 0) {
00696                 i__1 = m - ll + 1;
00697                 clasr_("R", "V", "B", nru, &i__1, &rwork[1], &rwork[*n], &u[
00698                         ll * u_dim1 + 1], ldu);
00699             }
00700             if (*ncc > 0) {
00701                 i__1 = m - ll + 1;
00702                 clasr_("L", "V", "B", &i__1, ncc, &rwork[1], &rwork[*n], &c__[
00703                         ll + c_dim1], ldc);
00704             }
00705 
00706 /*           Test convergence */
00707 
00708             if ((r__1 = e[ll], dabs(r__1)) <= thresh) {
00709                 e[ll] = 0.f;
00710             }
00711         }
00712     } else {
00713 
00714 /*        Use nonzero shift */
00715 
00716         if (idir == 1) {
00717 
00718 /*           Chase bulge from top to bottom */
00719 /*           Save cosines and sines for later singular vector updates */
00720 
00721             f = ((r__1 = d__[ll], dabs(r__1)) - shift) * (r_sign(&c_b49, &d__[
00722                     ll]) + shift / d__[ll]);
00723             g = e[ll];
00724             i__1 = m - 1;
00725             for (i__ = ll; i__ <= i__1; ++i__) {
00726                 slartg_(&f, &g, &cosr, &sinr, &r__);
00727                 if (i__ > ll) {
00728                     e[i__ - 1] = r__;
00729                 }
00730                 f = cosr * d__[i__] + sinr * e[i__];
00731                 e[i__] = cosr * e[i__] - sinr * d__[i__];
00732                 g = sinr * d__[i__ + 1];
00733                 d__[i__ + 1] = cosr * d__[i__ + 1];
00734                 slartg_(&f, &g, &cosl, &sinl, &r__);
00735                 d__[i__] = r__;
00736                 f = cosl * e[i__] + sinl * d__[i__ + 1];
00737                 d__[i__ + 1] = cosl * d__[i__ + 1] - sinl * e[i__];
00738                 if (i__ < m - 1) {
00739                     g = sinl * e[i__ + 1];
00740                     e[i__ + 1] = cosl * e[i__ + 1];
00741                 }
00742                 rwork[i__ - ll + 1] = cosr;
00743                 rwork[i__ - ll + 1 + nm1] = sinr;
00744                 rwork[i__ - ll + 1 + nm12] = cosl;
00745                 rwork[i__ - ll + 1 + nm13] = sinl;
00746 /* L140: */
00747             }
00748             e[m - 1] = f;
00749 
00750 /*           Update singular vectors */
00751 
00752             if (*ncvt > 0) {
00753                 i__1 = m - ll + 1;
00754                 clasr_("L", "V", "F", &i__1, ncvt, &rwork[1], &rwork[*n], &vt[
00755                         ll + vt_dim1], ldvt);
00756             }
00757             if (*nru > 0) {
00758                 i__1 = m - ll + 1;
00759                 clasr_("R", "V", "F", nru, &i__1, &rwork[nm12 + 1], &rwork[
00760                         nm13 + 1], &u[ll * u_dim1 + 1], ldu);
00761             }
00762             if (*ncc > 0) {
00763                 i__1 = m - ll + 1;
00764                 clasr_("L", "V", "F", &i__1, ncc, &rwork[nm12 + 1], &rwork[
00765                         nm13 + 1], &c__[ll + c_dim1], ldc);
00766             }
00767 
00768 /*           Test convergence */
00769 
00770             if ((r__1 = e[m - 1], dabs(r__1)) <= thresh) {
00771                 e[m - 1] = 0.f;
00772             }
00773 
00774         } else {
00775 
00776 /*           Chase bulge from bottom to top */
00777 /*           Save cosines and sines for later singular vector updates */
00778 
00779             f = ((r__1 = d__[m], dabs(r__1)) - shift) * (r_sign(&c_b49, &d__[
00780                     m]) + shift / d__[m]);
00781             g = e[m - 1];
00782             i__1 = ll + 1;
00783             for (i__ = m; i__ >= i__1; --i__) {
00784                 slartg_(&f, &g, &cosr, &sinr, &r__);
00785                 if (i__ < m) {
00786                     e[i__] = r__;
00787                 }
00788                 f = cosr * d__[i__] + sinr * e[i__ - 1];
00789                 e[i__ - 1] = cosr * e[i__ - 1] - sinr * d__[i__];
00790                 g = sinr * d__[i__ - 1];
00791                 d__[i__ - 1] = cosr * d__[i__ - 1];
00792                 slartg_(&f, &g, &cosl, &sinl, &r__);
00793                 d__[i__] = r__;
00794                 f = cosl * e[i__ - 1] + sinl * d__[i__ - 1];
00795                 d__[i__ - 1] = cosl * d__[i__ - 1] - sinl * e[i__ - 1];
00796                 if (i__ > ll + 1) {
00797                     g = sinl * e[i__ - 2];
00798                     e[i__ - 2] = cosl * e[i__ - 2];
00799                 }
00800                 rwork[i__ - ll] = cosr;
00801                 rwork[i__ - ll + nm1] = -sinr;
00802                 rwork[i__ - ll + nm12] = cosl;
00803                 rwork[i__ - ll + nm13] = -sinl;
00804 /* L150: */
00805             }
00806             e[ll] = f;
00807 
00808 /*           Test convergence */
00809 
00810             if ((r__1 = e[ll], dabs(r__1)) <= thresh) {
00811                 e[ll] = 0.f;
00812             }
00813 
00814 /*           Update singular vectors if desired */
00815 
00816             if (*ncvt > 0) {
00817                 i__1 = m - ll + 1;
00818                 clasr_("L", "V", "B", &i__1, ncvt, &rwork[nm12 + 1], &rwork[
00819                         nm13 + 1], &vt[ll + vt_dim1], ldvt);
00820             }
00821             if (*nru > 0) {
00822                 i__1 = m - ll + 1;
00823                 clasr_("R", "V", "B", nru, &i__1, &rwork[1], &rwork[*n], &u[
00824                         ll * u_dim1 + 1], ldu);
00825             }
00826             if (*ncc > 0) {
00827                 i__1 = m - ll + 1;
00828                 clasr_("L", "V", "B", &i__1, ncc, &rwork[1], &rwork[*n], &c__[
00829                         ll + c_dim1], ldc);
00830             }
00831         }
00832     }
00833 
00834 /*     QR iteration finished, go back and check convergence */
00835 
00836     goto L60;
00837 
00838 /*     All singular values converged, so make them positive */
00839 
00840 L160:
00841     i__1 = *n;
00842     for (i__ = 1; i__ <= i__1; ++i__) {
00843         if (d__[i__] < 0.f) {
00844             d__[i__] = -d__[i__];
00845 
00846 /*           Change sign of singular vectors, if desired */
00847 
00848             if (*ncvt > 0) {
00849                 csscal_(ncvt, &c_b72, &vt[i__ + vt_dim1], ldvt);
00850             }
00851         }
00852 /* L170: */
00853     }
00854 
00855 /*     Sort the singular values into decreasing order (insertion sort on */
00856 /*     singular values, but only one transposition per singular vector) */
00857 
00858     i__1 = *n - 1;
00859     for (i__ = 1; i__ <= i__1; ++i__) {
00860 
00861 /*        Scan for smallest D(I) */
00862 
00863         isub = 1;
00864         smin = d__[1];
00865         i__2 = *n + 1 - i__;
00866         for (j = 2; j <= i__2; ++j) {
00867             if (d__[j] <= smin) {
00868                 isub = j;
00869                 smin = d__[j];
00870             }
00871 /* L180: */
00872         }
00873         if (isub != *n + 1 - i__) {
00874 
00875 /*           Swap singular values and vectors */
00876 
00877             d__[isub] = d__[*n + 1 - i__];
00878             d__[*n + 1 - i__] = smin;
00879             if (*ncvt > 0) {
00880                 cswap_(ncvt, &vt[isub + vt_dim1], ldvt, &vt[*n + 1 - i__ + 
00881                         vt_dim1], ldvt);
00882             }
00883             if (*nru > 0) {
00884                 cswap_(nru, &u[isub * u_dim1 + 1], &c__1, &u[(*n + 1 - i__) * 
00885                         u_dim1 + 1], &c__1);
00886             }
00887             if (*ncc > 0) {
00888                 cswap_(ncc, &c__[isub + c_dim1], ldc, &c__[*n + 1 - i__ + 
00889                         c_dim1], ldc);
00890             }
00891         }
00892 /* L190: */
00893     }
00894     goto L220;
00895 
00896 /*     Maximum number of iterations exceeded, failure to converge */
00897 
00898 L200:
00899     *info = 0;
00900     i__1 = *n - 1;
00901     for (i__ = 1; i__ <= i__1; ++i__) {
00902         if (e[i__] != 0.f) {
00903             ++(*info);
00904         }
00905 /* L210: */
00906     }
00907 L220:
00908     return 0;
00909 
00910 /*     End of CBDSQR */
00911 
00912 } /* cbdsqr_ */


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:55:15