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_ */