sget22.c
Go to the documentation of this file.
00001 /* sget22.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 real c_b20 = 0.f;
00019 static integer c__2 = 2;
00020 static real c_b25 = 1.f;
00021 static integer c__1 = 1;
00022 static real c_b30 = -1.f;
00023 
00024 /* Subroutine */ int sget22_(char *transa, char *transe, char *transw, 
00025         integer *n, real *a, integer *lda, real *e, integer *lde, real *wr, 
00026         real *wi, real *work, real *result)
00027 {
00028     /* System generated locals */
00029     integer a_dim1, a_offset, e_dim1, e_offset, i__1, i__2;
00030     real r__1, r__2, r__3, r__4;
00031 
00032     /* Local variables */
00033     integer j;
00034     real ulp;
00035     integer ince, jcol, jvec;
00036     real unfl, wmat[4]  /* was [2][2] */, temp1;
00037     integer iecol;
00038     extern logical lsame_(char *, char *);
00039     integer ipair;
00040     extern /* Subroutine */ int sgemm_(char *, char *, integer *, integer *, 
00041             integer *, real *, real *, integer *, real *, integer *, real *, 
00042             real *, integer *);
00043     char norma[1];
00044     real anorm;
00045     char norme[1];
00046     real enorm;
00047     integer ierow;
00048     extern /* Subroutine */ int saxpy_(integer *, real *, real *, integer *, 
00049             real *, integer *);
00050     extern doublereal slamch_(char *), slange_(char *, integer *, 
00051             integer *, real *, integer *, real *);
00052     real enrmin, enrmax;
00053     extern /* Subroutine */ int slaset_(char *, integer *, integer *, real *, 
00054             real *, real *, integer *);
00055     integer itrnse;
00056     real errnrm;
00057 
00058 
00059 /*  -- LAPACK test routine (version 3.1) -- */
00060 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00061 /*     November 2006 */
00062 
00063 /*     .. Scalar Arguments .. */
00064 /*     .. */
00065 /*     .. Array Arguments .. */
00066 /*     .. */
00067 
00068 /*  Purpose */
00069 /*  ======= */
00070 
00071 /*  SGET22 does an eigenvector check. */
00072 
00073 /*  The basic test is: */
00074 
00075 /*     RESULT(1) = | A E  -  E W | / ( |A| |E| ulp ) */
00076 
00077 /*  using the 1-norm.  It also tests the normalization of E: */
00078 
00079 /*     RESULT(2) = max | m-norm(E(j)) - 1 | / ( n ulp ) */
00080 /*                  j */
00081 
00082 /*  where E(j) is the j-th eigenvector, and m-norm is the max-norm of a */
00083 /*  vector.  If an eigenvector is complex, as determined from WI(j) */
00084 /*  nonzero, then the max-norm of the vector ( er + i*ei ) is the maximum */
00085 /*  of */
00086 /*     |er(1)| + |ei(1)|, ... , |er(n)| + |ei(n)| */
00087 
00088 /*  W is a block diagonal matrix, with a 1 by 1 block for each real */
00089 /*  eigenvalue and a 2 by 2 block for each complex conjugate pair. */
00090 /*  If eigenvalues j and j+1 are a complex conjugate pair, so that */
00091 /*  WR(j) = WR(j+1) = wr and WI(j) = - WI(j+1) = wi, then the 2 by 2 */
00092 /*  block corresponding to the pair will be: */
00093 
00094 /*     (  wr  wi  ) */
00095 /*     ( -wi  wr  ) */
00096 
00097 /*  Such a block multiplying an n by 2 matrix ( ur ui ) on the right */
00098 /*  will be the same as multiplying  ur + i*ui  by  wr + i*wi. */
00099 
00100 /*  To handle various schemes for storage of left eigenvectors, there are */
00101 /*  options to use A-transpose instead of A, E-transpose instead of E, */
00102 /*  and/or W-transpose instead of W. */
00103 
00104 /*  Arguments */
00105 /*  ========== */
00106 
00107 /*  TRANSA  (input) CHARACTER*1 */
00108 /*          Specifies whether or not A is transposed. */
00109 /*          = 'N':  No transpose */
00110 /*          = 'T':  Transpose */
00111 /*          = 'C':  Conjugate transpose (= Transpose) */
00112 
00113 /*  TRANSE  (input) CHARACTER*1 */
00114 /*          Specifies whether or not E is transposed. */
00115 /*          = 'N':  No transpose, eigenvectors are in columns of E */
00116 /*          = 'T':  Transpose, eigenvectors are in rows of E */
00117 /*          = 'C':  Conjugate transpose (= Transpose) */
00118 
00119 /*  TRANSW  (input) CHARACTER*1 */
00120 /*          Specifies whether or not W is transposed. */
00121 /*          = 'N':  No transpose */
00122 /*          = 'T':  Transpose, use -WI(j) instead of WI(j) */
00123 /*          = 'C':  Conjugate transpose, use -WI(j) instead of WI(j) */
00124 
00125 /*  N       (input) INTEGER */
00126 /*          The order of the matrix A.  N >= 0. */
00127 
00128 /*  A       (input) REAL array, dimension (LDA,N) */
00129 /*          The matrix whose eigenvectors are in E. */
00130 
00131 /*  LDA     (input) INTEGER */
00132 /*          The leading dimension of the array A.  LDA >= max(1,N). */
00133 
00134 /*  E       (input) REAL array, dimension (LDE,N) */
00135 /*          The matrix of eigenvectors. If TRANSE = 'N', the eigenvectors */
00136 /*          are stored in the columns of E, if TRANSE = 'T' or 'C', the */
00137 /*          eigenvectors are stored in the rows of E. */
00138 
00139 /*  LDE     (input) INTEGER */
00140 /*          The leading dimension of the array E.  LDE >= max(1,N). */
00141 
00142 /*  WR      (input) REAL array, dimension (N) */
00143 /*  WI      (input) REAL array, dimension (N) */
00144 /*          The real and imaginary parts of the eigenvalues of A. */
00145 /*          Purely real eigenvalues are indicated by WI(j) = 0. */
00146 /*          Complex conjugate pairs are indicated by WR(j)=WR(j+1) and */
00147 /*          WI(j) = - WI(j+1) non-zero; the real part is assumed to be */
00148 /*          stored in the j-th row/column and the imaginary part in */
00149 /*          the (j+1)-th row/column. */
00150 
00151 /*  WORK    (workspace) REAL array, dimension (N*(N+1)) */
00152 
00153 /*  RESULT  (output) REAL array, dimension (2) */
00154 /*          RESULT(1) = | A E  -  E W | / ( |A| |E| ulp ) */
00155 /*          RESULT(2) = max | m-norm(E(j)) - 1 | / ( n ulp ) */
00156 
00157 /*  ===================================================================== */
00158 
00159 /*     .. Parameters .. */
00160 /*     .. */
00161 /*     .. Local Scalars .. */
00162 /*     .. */
00163 /*     .. Local Arrays .. */
00164 /*     .. */
00165 /*     .. External Functions .. */
00166 /*     .. */
00167 /*     .. External Subroutines .. */
00168 /*     .. */
00169 /*     .. Intrinsic Functions .. */
00170 /*     .. */
00171 /*     .. Executable Statements .. */
00172 
00173 /*     Initialize RESULT (in case N=0) */
00174 
00175     /* Parameter adjustments */
00176     a_dim1 = *lda;
00177     a_offset = 1 + a_dim1;
00178     a -= a_offset;
00179     e_dim1 = *lde;
00180     e_offset = 1 + e_dim1;
00181     e -= e_offset;
00182     --wr;
00183     --wi;
00184     --work;
00185     --result;
00186 
00187     /* Function Body */
00188     result[1] = 0.f;
00189     result[2] = 0.f;
00190     if (*n <= 0) {
00191         return 0;
00192     }
00193 
00194     unfl = slamch_("Safe minimum");
00195     ulp = slamch_("Precision");
00196 
00197     itrnse = 0;
00198     ince = 1;
00199     *(unsigned char *)norma = 'O';
00200     *(unsigned char *)norme = 'O';
00201 
00202     if (lsame_(transa, "T") || lsame_(transa, "C")) {
00203         *(unsigned char *)norma = 'I';
00204     }
00205     if (lsame_(transe, "T") || lsame_(transe, "C")) {
00206         *(unsigned char *)norme = 'I';
00207         itrnse = 1;
00208         ince = *lde;
00209     }
00210 
00211 /*     Check normalization of E */
00212 
00213     enrmin = 1.f / ulp;
00214     enrmax = 0.f;
00215     if (itrnse == 0) {
00216 
00217 /*        Eigenvectors are column vectors. */
00218 
00219         ipair = 0;
00220         i__1 = *n;
00221         for (jvec = 1; jvec <= i__1; ++jvec) {
00222             temp1 = 0.f;
00223             if (ipair == 0 && jvec < *n && wi[jvec] != 0.f) {
00224                 ipair = 1;
00225             }
00226             if (ipair == 1) {
00227 
00228 /*              Complex eigenvector */
00229 
00230                 i__2 = *n;
00231                 for (j = 1; j <= i__2; ++j) {
00232 /* Computing MAX */
00233                     r__3 = temp1, r__4 = (r__1 = e[j + jvec * e_dim1], dabs(
00234                             r__1)) + (r__2 = e[j + (jvec + 1) * e_dim1], dabs(
00235                             r__2));
00236                     temp1 = dmax(r__3,r__4);
00237 /* L10: */
00238                 }
00239                 enrmin = dmin(enrmin,temp1);
00240                 enrmax = dmax(enrmax,temp1);
00241                 ipair = 2;
00242             } else if (ipair == 2) {
00243                 ipair = 0;
00244             } else {
00245 
00246 /*              Real eigenvector */
00247 
00248                 i__2 = *n;
00249                 for (j = 1; j <= i__2; ++j) {
00250 /* Computing MAX */
00251                     r__2 = temp1, r__3 = (r__1 = e[j + jvec * e_dim1], dabs(
00252                             r__1));
00253                     temp1 = dmax(r__2,r__3);
00254 /* L20: */
00255                 }
00256                 enrmin = dmin(enrmin,temp1);
00257                 enrmax = dmax(enrmax,temp1);
00258                 ipair = 0;
00259             }
00260 /* L30: */
00261         }
00262 
00263     } else {
00264 
00265 /*        Eigenvectors are row vectors. */
00266 
00267         i__1 = *n;
00268         for (jvec = 1; jvec <= i__1; ++jvec) {
00269             work[jvec] = 0.f;
00270 /* L40: */
00271         }
00272 
00273         i__1 = *n;
00274         for (j = 1; j <= i__1; ++j) {
00275             ipair = 0;
00276             i__2 = *n;
00277             for (jvec = 1; jvec <= i__2; ++jvec) {
00278                 if (ipair == 0 && jvec < *n && wi[jvec] != 0.f) {
00279                     ipair = 1;
00280                 }
00281                 if (ipair == 1) {
00282 /* Computing MAX */
00283                     r__3 = work[jvec], r__4 = (r__1 = e[j + jvec * e_dim1], 
00284                             dabs(r__1)) + (r__2 = e[j + (jvec + 1) * e_dim1], 
00285                             dabs(r__2));
00286                     work[jvec] = dmax(r__3,r__4);
00287                     work[jvec + 1] = work[jvec];
00288                 } else if (ipair == 2) {
00289                     ipair = 0;
00290                 } else {
00291 /* Computing MAX */
00292                     r__2 = work[jvec], r__3 = (r__1 = e[j + jvec * e_dim1], 
00293                             dabs(r__1));
00294                     work[jvec] = dmax(r__2,r__3);
00295                     ipair = 0;
00296                 }
00297 /* L50: */
00298             }
00299 /* L60: */
00300         }
00301 
00302         i__1 = *n;
00303         for (jvec = 1; jvec <= i__1; ++jvec) {
00304 /* Computing MIN */
00305             r__1 = enrmin, r__2 = work[jvec];
00306             enrmin = dmin(r__1,r__2);
00307 /* Computing MAX */
00308             r__1 = enrmax, r__2 = work[jvec];
00309             enrmax = dmax(r__1,r__2);
00310 /* L70: */
00311         }
00312     }
00313 
00314 /*     Norm of A: */
00315 
00316 /* Computing MAX */
00317     r__1 = slange_(norma, n, n, &a[a_offset], lda, &work[1]);
00318     anorm = dmax(r__1,unfl);
00319 
00320 /*     Norm of E: */
00321 
00322 /* Computing MAX */
00323     r__1 = slange_(norme, n, n, &e[e_offset], lde, &work[1]);
00324     enorm = dmax(r__1,ulp);
00325 
00326 /*     Norm of error: */
00327 
00328 /*     Error =  AE - EW */
00329 
00330     slaset_("Full", n, n, &c_b20, &c_b20, &work[1], n);
00331 
00332     ipair = 0;
00333     ierow = 1;
00334     iecol = 1;
00335 
00336     i__1 = *n;
00337     for (jcol = 1; jcol <= i__1; ++jcol) {
00338         if (itrnse == 1) {
00339             ierow = jcol;
00340         } else {
00341             iecol = jcol;
00342         }
00343 
00344         if (ipair == 0 && wi[jcol] != 0.f) {
00345             ipair = 1;
00346         }
00347 
00348         if (ipair == 1) {
00349             wmat[0] = wr[jcol];
00350             wmat[1] = -wi[jcol];
00351             wmat[2] = wi[jcol];
00352             wmat[3] = wr[jcol];
00353             sgemm_(transe, transw, n, &c__2, &c__2, &c_b25, &e[ierow + iecol *
00354                      e_dim1], lde, wmat, &c__2, &c_b20, &work[*n * (jcol - 1) 
00355                     + 1], n);
00356             ipair = 2;
00357         } else if (ipair == 2) {
00358             ipair = 0;
00359 
00360         } else {
00361 
00362             saxpy_(n, &wr[jcol], &e[ierow + iecol * e_dim1], &ince, &work[*n *
00363                      (jcol - 1) + 1], &c__1);
00364             ipair = 0;
00365         }
00366 
00367 /* L80: */
00368     }
00369 
00370     sgemm_(transa, transe, n, n, n, &c_b25, &a[a_offset], lda, &e[e_offset], 
00371             lde, &c_b30, &work[1], n);
00372 
00373     errnrm = slange_("One", n, n, &work[1], n, &work[*n * *n + 1]) 
00374             / enorm;
00375 
00376 /*     Compute RESULT(1) (avoiding under/overflow) */
00377 
00378     if (anorm > errnrm) {
00379         result[1] = errnrm / anorm / ulp;
00380     } else {
00381         if (anorm < 1.f) {
00382             result[1] = dmin(errnrm,anorm) / anorm / ulp;
00383         } else {
00384 /* Computing MIN */
00385             r__1 = errnrm / anorm;
00386             result[1] = dmin(r__1,1.f) / ulp;
00387         }
00388     }
00389 
00390 /*     Compute RESULT(2) : the normalization error in E. */
00391 
00392 /* Computing MAX */
00393     r__3 = (r__1 = enrmax - 1.f, dabs(r__1)), r__4 = (r__2 = enrmin - 1.f, 
00394             dabs(r__2));
00395     result[2] = dmax(r__3,r__4) / ((real) (*n) * ulp);
00396 
00397     return 0;
00398 
00399 /*     End of SGET22 */
00400 
00401 } /* sget22_ */


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