| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 | 
							- /* dlasq1.f -- translated by f2c (version 20061008).
 
-    You must link the resulting object file with libf2c:
 
- 	on Microsoft Windows system, link with libf2c.lib;
 
- 	on Linux or Unix systems, link with .../path/to/libf2c.a -lm
 
- 	or, if you install libf2c.a in a standard place, with -lf2c -lm
 
- 	-- in that order, at the end of the command line, as in
 
- 		cc *.o -lf2c -lm
 
- 	Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
 
- 		http://www.netlib.org/f2c/libf2c.zip
 
- */
 
- #include "f2c.h"
 
- #include "blaswrap.h"
 
- /* Table of constant values */
 
- static integer c__1 = 1;
 
- static integer c__2 = 2;
 
- static integer c__0 = 0;
 
- /* Subroutine */ int dlasq1_(integer *n, doublereal *d__, doublereal *e, 
 
- 	doublereal *work, integer *info)
 
- {
 
-     /* System generated locals */
 
-     integer i__1, i__2;
 
-     doublereal d__1, d__2, d__3;
 
-     /* Builtin functions */
 
-     double sqrt(doublereal);
 
-     /* Local variables */
 
-     integer i__;
 
-     doublereal eps;
 
-     extern /* Subroutine */ int dlas2_(doublereal *, doublereal *, doublereal 
 
- 	    *, doublereal *, doublereal *);
 
-     doublereal scale;
 
-     integer iinfo;
 
-     doublereal sigmn;
 
-     extern /* Subroutine */ int dcopy_(integer *, doublereal *, integer *, 
 
- 	    doublereal *, integer *);
 
-     doublereal sigmx;
 
-     extern /* Subroutine */ int dlasq2_(integer *, doublereal *, integer *);
 
-     extern doublereal dlamch_(char *);
 
-     extern /* Subroutine */ int dlascl_(char *, integer *, integer *, 
 
- 	    doublereal *, doublereal *, integer *, integer *, doublereal *, 
 
- 	    integer *, integer *);
 
-     doublereal safmin;
 
-     extern /* Subroutine */ int xerbla_(char *, integer *), dlasrt_(
 
- 	    char *, integer *, doublereal *, integer *);
 
- /*  -- LAPACK routine (version 3.2)                                    -- */
 
- /*  -- Contributed by Osni Marques of the Lawrence Berkeley National   -- */
 
- /*  -- Laboratory and Beresford Parlett of the Univ. of California at  -- */
 
- /*  -- Berkeley                                                        -- */
 
- /*  -- November 2008                                                   -- */
 
- /*  -- LAPACK is a software package provided by Univ. of Tennessee,    -- */
 
- /*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */
 
- /*     .. Scalar Arguments .. */
 
- /*     .. */
 
- /*     .. Array Arguments .. */
 
- /*     .. */
 
- /*  Purpose */
 
- /*  ======= */
 
- /*  DLASQ1 computes the singular values of a real N-by-N bidiagonal */
 
- /*  matrix with diagonal D and off-diagonal E. The singular values */
 
- /*  are computed to high relative accuracy, in the absence of */
 
- /*  denormalization, underflow and overflow. The algorithm was first */
 
- /*  presented in */
 
- /*  "Accurate singular values and differential qd algorithms" by K. V. */
 
- /*  Fernando and B. N. Parlett, Numer. Math., Vol-67, No. 2, pp. 191-230, */
 
- /*  1994, */
 
- /*  and the present implementation is described in "An implementation of */
 
- /*  the dqds Algorithm (Positive Case)", LAPACK Working Note. */
 
- /*  Arguments */
 
- /*  ========= */
 
- /*  N     (input) INTEGER */
 
- /*        The number of rows and columns in the matrix. N >= 0. */
 
- /*  D     (input/output) DOUBLE PRECISION array, dimension (N) */
 
- /*        On entry, D contains the diagonal elements of the */
 
- /*        bidiagonal matrix whose SVD is desired. On normal exit, */
 
- /*        D contains the singular values in decreasing order. */
 
- /*  E     (input/output) DOUBLE PRECISION array, dimension (N) */
 
- /*        On entry, elements E(1:N-1) contain the off-diagonal elements */
 
- /*        of the bidiagonal matrix whose SVD is desired. */
 
- /*        On exit, E is overwritten. */
 
- /*  WORK  (workspace) DOUBLE PRECISION array, dimension (4*N) */
 
- /*  INFO  (output) INTEGER */
 
- /*        = 0: successful exit */
 
- /*        < 0: if INFO = -i, the i-th argument had an illegal value */
 
- /*        > 0: the algorithm failed */
 
- /*             = 1, a split was marked by a positive value in E */
 
- /*             = 2, current block of Z not diagonalized after 30*N */
 
- /*                  iterations (in inner while loop) */
 
- /*             = 3, termination criterion of outer while loop not met */
 
- /*                  (program created more than N unreduced blocks) */
 
- /*  ===================================================================== */
 
- /*     .. Parameters .. */
 
- /*     .. */
 
- /*     .. Local Scalars .. */
 
- /*     .. */
 
- /*     .. External Subroutines .. */
 
- /*     .. */
 
- /*     .. External Functions .. */
 
- /*     .. */
 
- /*     .. Intrinsic Functions .. */
 
- /*     .. */
 
- /*     .. Executable Statements .. */
 
-     /* Parameter adjustments */
 
-     --work;
 
-     --e;
 
-     --d__;
 
-     /* Function Body */
 
-     *info = 0;
 
-     if (*n < 0) {
 
- 	*info = -2;
 
- 	i__1 = -(*info);
 
- 	xerbla_("DLASQ1", &i__1);
 
- 	return 0;
 
-     } else if (*n == 0) {
 
- 	return 0;
 
-     } else if (*n == 1) {
 
- 	d__[1] = abs(d__[1]);
 
- 	return 0;
 
-     } else if (*n == 2) {
 
- 	dlas2_(&d__[1], &e[1], &d__[2], &sigmn, &sigmx);
 
- 	d__[1] = sigmx;
 
- 	d__[2] = sigmn;
 
- 	return 0;
 
-     }
 
- /*     Estimate the largest singular value. */
 
-     sigmx = 0.;
 
-     i__1 = *n - 1;
 
-     for (i__ = 1; i__ <= i__1; ++i__) {
 
- 	d__[i__] = (d__1 = d__[i__], abs(d__1));
 
- /* Computing MAX */
 
- 	d__2 = sigmx, d__3 = (d__1 = e[i__], abs(d__1));
 
- 	sigmx = max(d__2,d__3);
 
- /* L10: */
 
-     }
 
-     d__[*n] = (d__1 = d__[*n], abs(d__1));
 
- /*     Early return if SIGMX is zero (matrix is already diagonal). */
 
-     if (sigmx == 0.) {
 
- 	dlasrt_("D", n, &d__[1], &iinfo);
 
- 	return 0;
 
-     }
 
-     i__1 = *n;
 
-     for (i__ = 1; i__ <= i__1; ++i__) {
 
- /* Computing MAX */
 
- 	d__1 = sigmx, d__2 = d__[i__];
 
- 	sigmx = max(d__1,d__2);
 
- /* L20: */
 
-     }
 
- /*     Copy D and E into WORK (in the Z format) and scale (squaring the */
 
- /*     input data makes scaling by a power of the radix pointless). */
 
-     eps = dlamch_("Precision");
 
-     safmin = dlamch_("Safe minimum");
 
-     scale = sqrt(eps / safmin);
 
-     dcopy_(n, &d__[1], &c__1, &work[1], &c__2);
 
-     i__1 = *n - 1;
 
-     dcopy_(&i__1, &e[1], &c__1, &work[2], &c__2);
 
-     i__1 = (*n << 1) - 1;
 
-     i__2 = (*n << 1) - 1;
 
-     dlascl_("G", &c__0, &c__0, &sigmx, &scale, &i__1, &c__1, &work[1], &i__2, 
 
- 	    &iinfo);
 
- /*     Compute the q's and e's. */
 
-     i__1 = (*n << 1) - 1;
 
-     for (i__ = 1; i__ <= i__1; ++i__) {
 
- /* Computing 2nd power */
 
- 	d__1 = work[i__];
 
- 	work[i__] = d__1 * d__1;
 
- /* L30: */
 
-     }
 
-     work[*n * 2] = 0.;
 
-     dlasq2_(n, &work[1], info);
 
-     if (*info == 0) {
 
- 	i__1 = *n;
 
- 	for (i__ = 1; i__ <= i__1; ++i__) {
 
- 	    d__[i__] = sqrt(work[i__]);
 
- /* L40: */
 
- 	}
 
- 	dlascl_("G", &c__0, &c__0, &scale, &sigmx, n, &c__1, &d__[1], n, &
 
- 		iinfo);
 
-     }
 
-     return 0;
 
- /*     End of DLASQ1 */
 
- } /* dlasq1_ */
 
 
  |