00001 /* sdisna.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 /* Subroutine */ int sdisna_(char *job, integer *m, integer *n, real *d__, 00017 real *sep, integer *info) 00018 { 00019 /* System generated locals */ 00020 integer i__1; 00021 real r__1, r__2, r__3; 00022 00023 /* Local variables */ 00024 integer i__, k; 00025 real eps; 00026 logical decr, left, incr, sing, eigen; 00027 extern logical lsame_(char *, char *); 00028 real anorm; 00029 logical right; 00030 real oldgap; 00031 extern doublereal slamch_(char *); 00032 real safmin; 00033 extern /* Subroutine */ int xerbla_(char *, integer *); 00034 real newgap, thresh; 00035 00036 00037 /* -- LAPACK routine (version 3.2) -- */ 00038 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ 00039 /* November 2006 */ 00040 00041 /* .. Scalar Arguments .. */ 00042 /* .. */ 00043 /* .. Array Arguments .. */ 00044 /* .. */ 00045 00046 /* Purpose */ 00047 /* ======= */ 00048 00049 /* SDISNA computes the reciprocal condition numbers for the eigenvectors */ 00050 /* of a real symmetric or complex Hermitian matrix or for the left or */ 00051 /* right singular vectors of a general m-by-n matrix. The reciprocal */ 00052 /* condition number is the 'gap' between the corresponding eigenvalue or */ 00053 /* singular value and the nearest other one. */ 00054 00055 /* The bound on the error, measured by angle in radians, in the I-th */ 00056 /* computed vector is given by */ 00057 00058 /* SLAMCH( 'E' ) * ( ANORM / SEP( I ) ) */ 00059 00060 /* where ANORM = 2-norm(A) = max( abs( D(j) ) ). SEP(I) is not allowed */ 00061 /* to be smaller than SLAMCH( 'E' )*ANORM in order to limit the size of */ 00062 /* the error bound. */ 00063 00064 /* SDISNA may also be used to compute error bounds for eigenvectors of */ 00065 /* the generalized symmetric definite eigenproblem. */ 00066 00067 /* Arguments */ 00068 /* ========= */ 00069 00070 /* JOB (input) CHARACTER*1 */ 00071 /* Specifies for which problem the reciprocal condition numbers */ 00072 /* should be computed: */ 00073 /* = 'E': the eigenvectors of a symmetric/Hermitian matrix; */ 00074 /* = 'L': the left singular vectors of a general matrix; */ 00075 /* = 'R': the right singular vectors of a general matrix. */ 00076 00077 /* M (input) INTEGER */ 00078 /* The number of rows of the matrix. M >= 0. */ 00079 00080 /* N (input) INTEGER */ 00081 /* If JOB = 'L' or 'R', the number of columns of the matrix, */ 00082 /* in which case N >= 0. Ignored if JOB = 'E'. */ 00083 00084 /* D (input) REAL array, dimension (M) if JOB = 'E' */ 00085 /* dimension (min(M,N)) if JOB = 'L' or 'R' */ 00086 /* The eigenvalues (if JOB = 'E') or singular values (if JOB = */ 00087 /* 'L' or 'R') of the matrix, in either increasing or decreasing */ 00088 /* order. If singular values, they must be non-negative. */ 00089 00090 /* SEP (output) REAL array, dimension (M) if JOB = 'E' */ 00091 /* dimension (min(M,N)) if JOB = 'L' or 'R' */ 00092 /* The reciprocal condition numbers of the vectors. */ 00093 00094 /* INFO (output) INTEGER */ 00095 /* = 0: successful exit. */ 00096 /* < 0: if INFO = -i, the i-th argument had an illegal value. */ 00097 00098 /* ===================================================================== */ 00099 00100 /* .. Parameters .. */ 00101 /* .. */ 00102 /* .. Local Scalars .. */ 00103 /* .. */ 00104 /* .. External Functions .. */ 00105 /* .. */ 00106 /* .. Intrinsic Functions .. */ 00107 /* .. */ 00108 /* .. External Subroutines .. */ 00109 /* .. */ 00110 /* .. Executable Statements .. */ 00111 00112 /* Test the input arguments */ 00113 00114 /* Parameter adjustments */ 00115 --sep; 00116 --d__; 00117 00118 /* Function Body */ 00119 *info = 0; 00120 eigen = lsame_(job, "E"); 00121 left = lsame_(job, "L"); 00122 right = lsame_(job, "R"); 00123 sing = left || right; 00124 if (eigen) { 00125 k = *m; 00126 } else if (sing) { 00127 k = min(*m,*n); 00128 } 00129 if (! eigen && ! sing) { 00130 *info = -1; 00131 } else if (*m < 0) { 00132 *info = -2; 00133 } else if (k < 0) { 00134 *info = -3; 00135 } else { 00136 incr = TRUE_; 00137 decr = TRUE_; 00138 i__1 = k - 1; 00139 for (i__ = 1; i__ <= i__1; ++i__) { 00140 if (incr) { 00141 incr = incr && d__[i__] <= d__[i__ + 1]; 00142 } 00143 if (decr) { 00144 decr = decr && d__[i__] >= d__[i__ + 1]; 00145 } 00146 /* L10: */ 00147 } 00148 if (sing && k > 0) { 00149 if (incr) { 00150 incr = incr && 0.f <= d__[1]; 00151 } 00152 if (decr) { 00153 decr = decr && d__[k] >= 0.f; 00154 } 00155 } 00156 if (! (incr || decr)) { 00157 *info = -4; 00158 } 00159 } 00160 if (*info != 0) { 00161 i__1 = -(*info); 00162 xerbla_("SDISNA", &i__1); 00163 return 0; 00164 } 00165 00166 /* Quick return if possible */ 00167 00168 if (k == 0) { 00169 return 0; 00170 } 00171 00172 /* Compute reciprocal condition numbers */ 00173 00174 if (k == 1) { 00175 sep[1] = slamch_("O"); 00176 } else { 00177 oldgap = (r__1 = d__[2] - d__[1], dabs(r__1)); 00178 sep[1] = oldgap; 00179 i__1 = k - 1; 00180 for (i__ = 2; i__ <= i__1; ++i__) { 00181 newgap = (r__1 = d__[i__ + 1] - d__[i__], dabs(r__1)); 00182 sep[i__] = dmin(oldgap,newgap); 00183 oldgap = newgap; 00184 /* L20: */ 00185 } 00186 sep[k] = oldgap; 00187 } 00188 if (sing) { 00189 if (left && *m > *n || right && *m < *n) { 00190 if (incr) { 00191 sep[1] = dmin(sep[1],d__[1]); 00192 } 00193 if (decr) { 00194 /* Computing MIN */ 00195 r__1 = sep[k], r__2 = d__[k]; 00196 sep[k] = dmin(r__1,r__2); 00197 } 00198 } 00199 } 00200 00201 /* Ensure that reciprocal condition numbers are not less than */ 00202 /* threshold, in order to limit the size of the error bound */ 00203 00204 eps = slamch_("E"); 00205 safmin = slamch_("S"); 00206 /* Computing MAX */ 00207 r__2 = dabs(d__[1]), r__3 = (r__1 = d__[k], dabs(r__1)); 00208 anorm = dmax(r__2,r__3); 00209 if (anorm == 0.f) { 00210 thresh = eps; 00211 } else { 00212 /* Computing MAX */ 00213 r__1 = eps * anorm; 00214 thresh = dmax(r__1,safmin); 00215 } 00216 i__1 = k; 00217 for (i__ = 1; i__ <= i__1; ++i__) { 00218 /* Computing MAX */ 00219 r__1 = sep[i__]; 00220 sep[i__] = dmax(r__1,thresh); 00221 /* L30: */ 00222 } 00223 00224 return 0; 00225 00226 /* End of SDISNA */ 00227 00228 } /* sdisna_ */