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


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