dlasq1.c
Go to the documentation of this file.
00001 /* dlasq1.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__1 = 1;
00019 static integer c__2 = 2;
00020 static integer c__0 = 0;
00021 
00022 /* Subroutine */ int dlasq1_(integer *n, doublereal *d__, doublereal *e, 
00023         doublereal *work, integer *info)
00024 {
00025     /* System generated locals */
00026     integer i__1, i__2;
00027     doublereal d__1, d__2, d__3;
00028 
00029     /* Builtin functions */
00030     double sqrt(doublereal);
00031 
00032     /* Local variables */
00033     integer i__;
00034     doublereal eps;
00035     extern /* Subroutine */ int dlas2_(doublereal *, doublereal *, doublereal 
00036             *, doublereal *, doublereal *);
00037     doublereal scale;
00038     integer iinfo;
00039     doublereal sigmn;
00040     extern /* Subroutine */ int dcopy_(integer *, doublereal *, integer *, 
00041             doublereal *, integer *);
00042     doublereal sigmx;
00043     extern /* Subroutine */ int dlasq2_(integer *, doublereal *, integer *);
00044     extern doublereal dlamch_(char *);
00045     extern /* Subroutine */ int dlascl_(char *, integer *, integer *, 
00046             doublereal *, doublereal *, integer *, integer *, doublereal *, 
00047             integer *, integer *);
00048     doublereal safmin;
00049     extern /* Subroutine */ int xerbla_(char *, integer *), dlasrt_(
00050             char *, integer *, doublereal *, integer *);
00051 
00052 
00053 /*  -- LAPACK routine (version 3.2)                                    -- */
00054 
00055 /*  -- Contributed by Osni Marques of the Lawrence Berkeley National   -- */
00056 /*  -- Laboratory and Beresford Parlett of the Univ. of California at  -- */
00057 /*  -- Berkeley                                                        -- */
00058 /*  -- November 2008                                                   -- */
00059 
00060 /*  -- LAPACK is a software package provided by Univ. of Tennessee,    -- */
00061 /*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */
00062 
00063 /*     .. Scalar Arguments .. */
00064 /*     .. */
00065 /*     .. Array Arguments .. */
00066 /*     .. */
00067 
00068 /*  Purpose */
00069 /*  ======= */
00070 
00071 /*  DLASQ1 computes the singular values of a real N-by-N bidiagonal */
00072 /*  matrix with diagonal D and off-diagonal E. The singular values */
00073 /*  are computed to high relative accuracy, in the absence of */
00074 /*  denormalization, underflow and overflow. The algorithm was first */
00075 /*  presented in */
00076 
00077 /*  "Accurate singular values and differential qd algorithms" by K. V. */
00078 /*  Fernando and B. N. Parlett, Numer. Math., Vol-67, No. 2, pp. 191-230, */
00079 /*  1994, */
00080 
00081 /*  and the present implementation is described in "An implementation of */
00082 /*  the dqds Algorithm (Positive Case)", LAPACK Working Note. */
00083 
00084 /*  Arguments */
00085 /*  ========= */
00086 
00087 /*  N     (input) INTEGER */
00088 /*        The number of rows and columns in the matrix. N >= 0. */
00089 
00090 /*  D     (input/output) DOUBLE PRECISION array, dimension (N) */
00091 /*        On entry, D contains the diagonal elements of the */
00092 /*        bidiagonal matrix whose SVD is desired. On normal exit, */
00093 /*        D contains the singular values in decreasing order. */
00094 
00095 /*  E     (input/output) DOUBLE PRECISION array, dimension (N) */
00096 /*        On entry, elements E(1:N-1) contain the off-diagonal elements */
00097 /*        of the bidiagonal matrix whose SVD is desired. */
00098 /*        On exit, E is overwritten. */
00099 
00100 /*  WORK  (workspace) DOUBLE PRECISION array, dimension (4*N) */
00101 
00102 /*  INFO  (output) INTEGER */
00103 /*        = 0: successful exit */
00104 /*        < 0: if INFO = -i, the i-th argument had an illegal value */
00105 /*        > 0: the algorithm failed */
00106 /*             = 1, a split was marked by a positive value in E */
00107 /*             = 2, current block of Z not diagonalized after 30*N */
00108 /*                  iterations (in inner while loop) */
00109 /*             = 3, termination criterion of outer while loop not met */
00110 /*                  (program created more than N unreduced blocks) */
00111 
00112 /*  ===================================================================== */
00113 
00114 /*     .. Parameters .. */
00115 /*     .. */
00116 /*     .. Local Scalars .. */
00117 /*     .. */
00118 /*     .. External Subroutines .. */
00119 /*     .. */
00120 /*     .. External Functions .. */
00121 /*     .. */
00122 /*     .. Intrinsic Functions .. */
00123 /*     .. */
00124 /*     .. Executable Statements .. */
00125 
00126     /* Parameter adjustments */
00127     --work;
00128     --e;
00129     --d__;
00130 
00131     /* Function Body */
00132     *info = 0;
00133     if (*n < 0) {
00134         *info = -2;
00135         i__1 = -(*info);
00136         xerbla_("DLASQ1", &i__1);
00137         return 0;
00138     } else if (*n == 0) {
00139         return 0;
00140     } else if (*n == 1) {
00141         d__[1] = abs(d__[1]);
00142         return 0;
00143     } else if (*n == 2) {
00144         dlas2_(&d__[1], &e[1], &d__[2], &sigmn, &sigmx);
00145         d__[1] = sigmx;
00146         d__[2] = sigmn;
00147         return 0;
00148     }
00149 
00150 /*     Estimate the largest singular value. */
00151 
00152     sigmx = 0.;
00153     i__1 = *n - 1;
00154     for (i__ = 1; i__ <= i__1; ++i__) {
00155         d__[i__] = (d__1 = d__[i__], abs(d__1));
00156 /* Computing MAX */
00157         d__2 = sigmx, d__3 = (d__1 = e[i__], abs(d__1));
00158         sigmx = max(d__2,d__3);
00159 /* L10: */
00160     }
00161     d__[*n] = (d__1 = d__[*n], abs(d__1));
00162 
00163 /*     Early return if SIGMX is zero (matrix is already diagonal). */
00164 
00165     if (sigmx == 0.) {
00166         dlasrt_("D", n, &d__[1], &iinfo);
00167         return 0;
00168     }
00169 
00170     i__1 = *n;
00171     for (i__ = 1; i__ <= i__1; ++i__) {
00172 /* Computing MAX */
00173         d__1 = sigmx, d__2 = d__[i__];
00174         sigmx = max(d__1,d__2);
00175 /* L20: */
00176     }
00177 
00178 /*     Copy D and E into WORK (in the Z format) and scale (squaring the */
00179 /*     input data makes scaling by a power of the radix pointless). */
00180 
00181     eps = dlamch_("Precision");
00182     safmin = dlamch_("Safe minimum");
00183     scale = sqrt(eps / safmin);
00184     dcopy_(n, &d__[1], &c__1, &work[1], &c__2);
00185     i__1 = *n - 1;
00186     dcopy_(&i__1, &e[1], &c__1, &work[2], &c__2);
00187     i__1 = (*n << 1) - 1;
00188     i__2 = (*n << 1) - 1;
00189     dlascl_("G", &c__0, &c__0, &sigmx, &scale, &i__1, &c__1, &work[1], &i__2, 
00190             &iinfo);
00191 
00192 /*     Compute the q's and e's. */
00193 
00194     i__1 = (*n << 1) - 1;
00195     for (i__ = 1; i__ <= i__1; ++i__) {
00196 /* Computing 2nd power */
00197         d__1 = work[i__];
00198         work[i__] = d__1 * d__1;
00199 /* L30: */
00200     }
00201     work[*n * 2] = 0.;
00202 
00203     dlasq2_(n, &work[1], info);
00204 
00205     if (*info == 0) {
00206         i__1 = *n;
00207         for (i__ = 1; i__ <= i__1; ++i__) {
00208             d__[i__] = sqrt(work[i__]);
00209 /* L40: */
00210         }
00211         dlascl_("G", &c__0, &c__0, &scale, &sigmx, n, &c__1, &d__[1], n, &
00212                 iinfo);
00213     }
00214 
00215     return 0;
00216 
00217 /*     End of DLASQ1 */
00218 
00219 } /* dlasq1_ */


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