zqrt14.c
Go to the documentation of this file.
00001 /* zqrt14.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__10 = 10;
00019 static integer c__1 = 1;
00020 static integer c__0 = 0;
00021 static doublereal c_b15 = 1.;
00022 
00023 doublereal zqrt14_(char *trans, integer *m, integer *n, integer *nrhs, 
00024         doublecomplex *a, integer *lda, doublecomplex *x, integer *ldx, 
00025         doublecomplex *work, integer *lwork)
00026 {
00027     /* System generated locals */
00028     integer a_dim1, a_offset, x_dim1, x_offset, i__1, i__2, i__3;
00029     doublereal ret_val, d__1, d__2;
00030     doublecomplex z__1;
00031 
00032     /* Builtin functions */
00033     double z_abs(doublecomplex *);
00034     void d_cnjg(doublecomplex *, doublecomplex *);
00035 
00036     /* Local variables */
00037     integer i__, j;
00038     doublereal err;
00039     integer info;
00040     doublereal anrm;
00041     logical tpsd;
00042     doublereal xnrm;
00043     extern logical lsame_(char *, char *);
00044     doublereal rwork[1];
00045     extern /* Subroutine */ int zgelq2_(integer *, integer *, doublecomplex *, 
00046              integer *, doublecomplex *, doublecomplex *, integer *), zgeqr2_(
00047             integer *, integer *, doublecomplex *, integer *, doublecomplex *, 
00048              doublecomplex *, integer *);
00049     extern doublereal dlamch_(char *);
00050     extern /* Subroutine */ int xerbla_(char *, integer *);
00051     extern doublereal zlange_(char *, integer *, integer *, doublecomplex *, 
00052             integer *, doublereal *);
00053     extern /* Subroutine */ int zlascl_(char *, integer *, integer *, 
00054             doublereal *, doublereal *, integer *, integer *, doublecomplex *, 
00055              integer *, integer *);
00056     integer ldwork;
00057     extern /* Subroutine */ int zlacpy_(char *, integer *, integer *, 
00058             doublecomplex *, integer *, doublecomplex *, integer *);
00059 
00060 
00061 /*  -- LAPACK test routine (version 3.1) -- */
00062 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00063 /*     November 2006 */
00064 
00065 /*     .. Scalar Arguments .. */
00066 /*     .. */
00067 /*     .. Array Arguments .. */
00068 /*     .. */
00069 
00070 /*  Purpose */
00071 /*  ======= */
00072 
00073 /*  ZQRT14 checks whether X is in the row space of A or A'.  It does so */
00074 /*  by scaling both X and A such that their norms are in the range */
00075 /*  [sqrt(eps), 1/sqrt(eps)], then computing a QR factorization of [A,X] */
00076 /*  (if TRANS = 'C') or an LQ factorization of [A',X]' (if TRANS = 'N'), */
00077 /*  and returning the norm of the trailing triangle, scaled by */
00078 /*  MAX(M,N,NRHS)*eps. */
00079 
00080 /*  Arguments */
00081 /*  ========= */
00082 
00083 /*  TRANS   (input) CHARACTER*1 */
00084 /*          = 'N':  No transpose, check for X in the row space of A */
00085 /*          = 'C':  Conjugate transpose, check for X in row space of A'. */
00086 
00087 /*  M       (input) INTEGER */
00088 /*          The number of rows of the matrix A. */
00089 
00090 /*  N       (input) INTEGER */
00091 /*          The number of columns of the matrix A. */
00092 
00093 /*  NRHS    (input) INTEGER */
00094 /*          The number of right hand sides, i.e., the number of columns */
00095 /*          of X. */
00096 
00097 /*  A       (input) COMPLEX*16 array, dimension (LDA,N) */
00098 /*          The M-by-N matrix A. */
00099 
00100 /*  LDA     (input) INTEGER */
00101 /*          The leading dimension of the array A. */
00102 
00103 /*  X       (input) COMPLEX*16 array, dimension (LDX,NRHS) */
00104 /*          If TRANS = 'N', the N-by-NRHS matrix X. */
00105 /*          IF TRANS = 'C', the M-by-NRHS matrix X. */
00106 
00107 /*  LDX     (input) INTEGER */
00108 /*          The leading dimension of the array X. */
00109 
00110 /*  WORK    (workspace) COMPLEX*16 array dimension (LWORK) */
00111 
00112 /*  LWORK   (input) INTEGER */
00113 /*          length of workspace array required */
00114 /*          If TRANS = 'N', LWORK >= (M+NRHS)*(N+2); */
00115 /*          if TRANS = 'C', LWORK >= (N+NRHS)*(M+2). */
00116 
00117 /*  ===================================================================== */
00118 
00119 /*     .. Parameters .. */
00120 /*     .. */
00121 /*     .. Local Scalars .. */
00122 /*     .. */
00123 /*     .. Local Arrays .. */
00124 /*     .. */
00125 /*     .. External Functions .. */
00126 /*     .. */
00127 /*     .. External Subroutines .. */
00128 /*     .. */
00129 /*     .. Intrinsic Functions .. */
00130 /*     .. */
00131 /*     .. Executable Statements .. */
00132 
00133     /* Parameter adjustments */
00134     a_dim1 = *lda;
00135     a_offset = 1 + a_dim1;
00136     a -= a_offset;
00137     x_dim1 = *ldx;
00138     x_offset = 1 + x_dim1;
00139     x -= x_offset;
00140     --work;
00141 
00142     /* Function Body */
00143     ret_val = 0.;
00144     if (lsame_(trans, "N")) {
00145         ldwork = *m + *nrhs;
00146         tpsd = FALSE_;
00147         if (*lwork < (*m + *nrhs) * (*n + 2)) {
00148             xerbla_("ZQRT14", &c__10);
00149             return ret_val;
00150         } else if (*n <= 0 || *nrhs <= 0) {
00151             return ret_val;
00152         }
00153     } else if (lsame_(trans, "C")) {
00154         ldwork = *m;
00155         tpsd = TRUE_;
00156         if (*lwork < (*n + *nrhs) * (*m + 2)) {
00157             xerbla_("ZQRT14", &c__10);
00158             return ret_val;
00159         } else if (*m <= 0 || *nrhs <= 0) {
00160             return ret_val;
00161         }
00162     } else {
00163         xerbla_("ZQRT14", &c__1);
00164         return ret_val;
00165     }
00166 
00167 /*     Copy and scale A */
00168 
00169     zlacpy_("All", m, n, &a[a_offset], lda, &work[1], &ldwork);
00170     anrm = zlange_("M", m, n, &work[1], &ldwork, rwork);
00171     if (anrm != 0.) {
00172         zlascl_("G", &c__0, &c__0, &anrm, &c_b15, m, n, &work[1], &ldwork, &
00173                 info);
00174     }
00175 
00176 /*     Copy X or X' into the right place and scale it */
00177 
00178     if (tpsd) {
00179 
00180 /*        Copy X into columns n+1:n+nrhs of work */
00181 
00182         zlacpy_("All", m, nrhs, &x[x_offset], ldx, &work[*n * ldwork + 1], &
00183                 ldwork);
00184         xnrm = zlange_("M", m, nrhs, &work[*n * ldwork + 1], &ldwork, rwork);
00185         if (xnrm != 0.) {
00186             zlascl_("G", &c__0, &c__0, &xnrm, &c_b15, m, nrhs, &work[*n * 
00187                     ldwork + 1], &ldwork, &info);
00188         }
00189         i__1 = *n + *nrhs;
00190         anrm = zlange_("One-norm", m, &i__1, &work[1], &ldwork, rwork);
00191 
00192 /*        Compute QR factorization of X */
00193 
00194         i__1 = *n + *nrhs;
00195 /* Computing MIN */
00196         i__2 = *m, i__3 = *n + *nrhs;
00197         zgeqr2_(m, &i__1, &work[1], &ldwork, &work[ldwork * (*n + *nrhs) + 1], 
00198                  &work[ldwork * (*n + *nrhs) + min(i__2, i__3)+ 1], &info);
00199 
00200 /*        Compute largest entry in upper triangle of */
00201 /*        work(n+1:m,n+1:n+nrhs) */
00202 
00203         err = 0.;
00204         i__1 = *n + *nrhs;
00205         for (j = *n + 1; j <= i__1; ++j) {
00206             i__2 = min(*m,j);
00207             for (i__ = *n + 1; i__ <= i__2; ++i__) {
00208 /* Computing MAX */
00209                 d__1 = err, d__2 = z_abs(&work[i__ + (j - 1) * *m]);
00210                 err = max(d__1,d__2);
00211 /* L10: */
00212             }
00213 /* L20: */
00214         }
00215 
00216     } else {
00217 
00218 /*        Copy X' into rows m+1:m+nrhs of work */
00219 
00220         i__1 = *n;
00221         for (i__ = 1; i__ <= i__1; ++i__) {
00222             i__2 = *nrhs;
00223             for (j = 1; j <= i__2; ++j) {
00224                 i__3 = *m + j + (i__ - 1) * ldwork;
00225                 d_cnjg(&z__1, &x[i__ + j * x_dim1]);
00226                 work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00227 /* L30: */
00228             }
00229 /* L40: */
00230         }
00231 
00232         xnrm = zlange_("M", nrhs, n, &work[*m + 1], &ldwork, rwork)
00233                 ;
00234         if (xnrm != 0.) {
00235             zlascl_("G", &c__0, &c__0, &xnrm, &c_b15, nrhs, n, &work[*m + 1], 
00236                     &ldwork, &info);
00237         }
00238 
00239 /*        Compute LQ factorization of work */
00240 
00241         zgelq2_(&ldwork, n, &work[1], &ldwork, &work[ldwork * *n + 1], &work[
00242                 ldwork * (*n + 1) + 1], &info);
00243 
00244 /*        Compute largest entry in lower triangle in */
00245 /*        work(m+1:m+nrhs,m+1:n) */
00246 
00247         err = 0.;
00248         i__1 = *n;
00249         for (j = *m + 1; j <= i__1; ++j) {
00250             i__2 = ldwork;
00251             for (i__ = j; i__ <= i__2; ++i__) {
00252 /* Computing MAX */
00253                 d__1 = err, d__2 = z_abs(&work[i__ + (j - 1) * ldwork]);
00254                 err = max(d__1,d__2);
00255 /* L50: */
00256             }
00257 /* L60: */
00258         }
00259 
00260     }
00261 
00262 /* Computing MAX */
00263     i__1 = max(*m,*n);
00264     ret_val = err / ((doublereal) max(i__1,*nrhs) * dlamch_("Epsilon"));
00265 
00266     return ret_val;
00267 
00268 /*     End of ZQRT14 */
00269 
00270 } /* zqrt14_ */


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