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


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:56:16