sqrt12.c
Go to the documentation of this file.
00001 /* sqrt12.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__7 = 7;
00019 static integer c__1 = 1;
00020 static real c_b6 = 0.f;
00021 static integer c__0 = 0;
00022 static real c_b33 = -1.f;
00023 
00024 doublereal sqrt12_(integer *m, integer *n, real *a, integer *lda, real *s, 
00025         real *work, integer *lwork)
00026 {
00027     /* System generated locals */
00028     integer a_dim1, a_offset, i__1, i__2;
00029     real ret_val;
00030 
00031     /* Local variables */
00032     integer i__, j, mn, iscl, info;
00033     real anrm;
00034     extern doublereal snrm2_(integer *, real *, integer *), sasum_(integer *, 
00035             real *, integer *);
00036     real dummy[1];
00037     extern /* Subroutine */ int saxpy_(integer *, real *, real *, integer *, 
00038             real *, integer *), sgebd2_(integer *, integer *, real *, integer 
00039             *, real *, real *, real *, real *, real *, integer *), slabad_(
00040             real *, real *);
00041     extern doublereal slamch_(char *), slange_(char *, integer *, 
00042             integer *, real *, integer *, real *);
00043     extern /* Subroutine */ int xerbla_(char *, integer *);
00044     real bignum;
00045     extern /* Subroutine */ int slascl_(char *, integer *, integer *, real *, 
00046             real *, integer *, integer *, real *, integer *, integer *), slaset_(char *, integer *, integer *, real *, real *, 
00047             real *, integer *), sbdsqr_(char *, integer *, integer *, 
00048             integer *, integer *, real *, real *, real *, integer *, real *, 
00049             integer *, real *, integer *, real *, integer *);
00050     real smlnum, nrmsvl;
00051 
00052 
00053 /*  -- LAPACK test routine (version 3.1.1) -- */
00054 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00055 /*     January 2007 */
00056 
00057 /*     .. Scalar Arguments .. */
00058 /*     .. */
00059 /*     .. Array Arguments .. */
00060 /*     .. */
00061 
00062 /*  Purpose */
00063 /*  ======= */
00064 
00065 /*  SQRT12 computes the singular values `svlues' of the upper trapezoid */
00066 /*  of A(1:M,1:N) and returns the ratio */
00067 
00068 /*       || s - svlues||/(||svlues||*eps*max(M,N)) */
00069 
00070 /*  Arguments */
00071 /*  ========= */
00072 
00073 /*  M       (input) INTEGER */
00074 /*          The number of rows of the matrix A. */
00075 
00076 /*  N       (input) INTEGER */
00077 /*          The number of columns of the matrix A. */
00078 
00079 /*  A       (input) REAL array, dimension (LDA,N) */
00080 /*          The M-by-N matrix A. Only the upper trapezoid is referenced. */
00081 
00082 /*  LDA     (input) INTEGER */
00083 /*          The leading dimension of the array A. */
00084 
00085 /*  S       (input) REAL array, dimension (min(M,N)) */
00086 /*          The singular values of the matrix A. */
00087 
00088 /*  WORK    (workspace) REAL array, dimension (LWORK) */
00089 
00090 /*  LWORK   (input) INTEGER */
00091 /*          The length of the array WORK. LWORK >= max(M*N + 4*min(M,N) + */
00092 /*          max(M,N), M*N+2*MIN( M, N )+4*N). */
00093 
00094 /*  ===================================================================== */
00095 
00096 /*     .. Parameters .. */
00097 /*     .. */
00098 /*     .. Local Scalars .. */
00099 /*     .. */
00100 /*     .. External Functions .. */
00101 /*     .. */
00102 /*     .. External Subroutines .. */
00103 /*     .. */
00104 /*     .. Intrinsic Functions .. */
00105 /*     .. */
00106 /*     .. Local Arrays .. */
00107 /*     .. */
00108 /*     .. Executable Statements .. */
00109 
00110     /* Parameter adjustments */
00111     a_dim1 = *lda;
00112     a_offset = 1 + a_dim1;
00113     a -= a_offset;
00114     --s;
00115     --work;
00116 
00117     /* Function Body */
00118     ret_val = 0.f;
00119 
00120 /*     Test that enough workspace is supplied */
00121 
00122 /* Computing MAX */
00123     i__1 = *m * *n + (min(*m,*n) << 2) + max(*m,*n), i__2 = *m * *n + (min(*m,
00124             *n) << 1) + (*n << 2);
00125     if (*lwork < max(i__1,i__2)) {
00126         xerbla_("SQRT12", &c__7);
00127         return ret_val;
00128     }
00129 
00130 /*     Quick return if possible */
00131 
00132     mn = min(*m,*n);
00133     if ((real) mn <= 0.f) {
00134         return ret_val;
00135     }
00136 
00137     nrmsvl = snrm2_(&mn, &s[1], &c__1);
00138 
00139 /*     Copy upper triangle of A into work */
00140 
00141     slaset_("Full", m, n, &c_b6, &c_b6, &work[1], m);
00142     i__1 = *n;
00143     for (j = 1; j <= i__1; ++j) {
00144         i__2 = min(j,*m);
00145         for (i__ = 1; i__ <= i__2; ++i__) {
00146             work[(j - 1) * *m + i__] = a[i__ + j * a_dim1];
00147 /* L10: */
00148         }
00149 /* L20: */
00150     }
00151 
00152 /*     Get machine parameters */
00153 
00154     smlnum = slamch_("S") / slamch_("P");
00155     bignum = 1.f / smlnum;
00156     slabad_(&smlnum, &bignum);
00157 
00158 /*     Scale work if max entry outside range [SMLNUM,BIGNUM] */
00159 
00160     anrm = slange_("M", m, n, &work[1], m, dummy);
00161     iscl = 0;
00162     if (anrm > 0.f && anrm < smlnum) {
00163 
00164 /*        Scale matrix norm up to SMLNUM */
00165 
00166         slascl_("G", &c__0, &c__0, &anrm, &smlnum, m, n, &work[1], m, &info);
00167         iscl = 1;
00168     } else if (anrm > bignum) {
00169 
00170 /*        Scale matrix norm down to BIGNUM */
00171 
00172         slascl_("G", &c__0, &c__0, &anrm, &bignum, m, n, &work[1], m, &info);
00173         iscl = 1;
00174     }
00175 
00176     if (anrm != 0.f) {
00177 
00178 /*        Compute SVD of work */
00179 
00180         sgebd2_(m, n, &work[1], m, &work[*m * *n + 1], &work[*m * *n + mn + 1]
00181 , &work[*m * *n + (mn << 1) + 1], &work[*m * *n + mn * 3 + 1], 
00182                  &work[*m * *n + (mn << 2) + 1], &info);
00183         sbdsqr_("Upper", &mn, &c__0, &c__0, &c__0, &work[*m * *n + 1], &work[*
00184                 m * *n + mn + 1], dummy, &mn, dummy, &c__1, dummy, &mn, &work[
00185                 *m * *n + (mn << 1) + 1], &info);
00186 
00187         if (iscl == 1) {
00188             if (anrm > bignum) {
00189                 slascl_("G", &c__0, &c__0, &bignum, &anrm, &mn, &c__1, &work[*
00190                         m * *n + 1], &mn, &info);
00191             }
00192             if (anrm < smlnum) {
00193                 slascl_("G", &c__0, &c__0, &smlnum, &anrm, &mn, &c__1, &work[*
00194                         m * *n + 1], &mn, &info);
00195             }
00196         }
00197 
00198     } else {
00199 
00200         i__1 = mn;
00201         for (i__ = 1; i__ <= i__1; ++i__) {
00202             work[*m * *n + i__] = 0.f;
00203 /* L30: */
00204         }
00205     }
00206 
00207 /*     Compare s and singular values of work */
00208 
00209     saxpy_(&mn, &c_b33, &s[1], &c__1, &work[*m * *n + 1], &c__1);
00210     ret_val = sasum_(&mn, &work[*m * *n + 1], &c__1) / (slamch_("Epsilon") * (real) max(*m,*n));
00211     if (nrmsvl != 0.f) {
00212         ret_val /= nrmsvl;
00213     }
00214 
00215     return ret_val;
00216 
00217 /*     End of SQRT12 */
00218 
00219 } /* sqrt12_ */


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