sdisna.c
Go to the documentation of this file.
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_ */


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