chet21.c
Go to the documentation of this file.
00001 /* chet21.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 complex c_b1 = {0.f,0.f};
00019 static complex c_b2 = {1.f,0.f};
00020 static integer c__1 = 1;
00021 
00022 /* Subroutine */ int chet21_(integer *itype, char *uplo, integer *n, integer *
00023         kband, complex *a, integer *lda, real *d__, real *e, complex *u, 
00024         integer *ldu, complex *v, integer *ldv, complex *tau, complex *work, 
00025         real *rwork, real *result)
00026 {
00027     /* System generated locals */
00028     integer a_dim1, a_offset, u_dim1, u_offset, v_dim1, v_offset, i__1, i__2, 
00029             i__3, i__4, i__5, i__6;
00030     real r__1, r__2;
00031     complex q__1, q__2, q__3;
00032 
00033     /* Local variables */
00034     integer j, jr;
00035     real ulp;
00036     extern /* Subroutine */ int cher_(char *, integer *, real *, complex *, 
00037             integer *, complex *, integer *);
00038     integer jcol;
00039     real unfl;
00040     integer jrow;
00041     extern /* Subroutine */ int cher2_(char *, integer *, complex *, complex *
00042 , integer *, complex *, integer *, complex *, integer *), 
00043             cgemm_(char *, char *, integer *, integer *, integer *, complex *, 
00044              complex *, integer *, complex *, integer *, complex *, complex *, 
00045              integer *);
00046     extern logical lsame_(char *, char *);
00047     integer iinfo;
00048     real anorm;
00049     char cuplo[1];
00050     complex vsave;
00051     logical lower;
00052     real wnorm;
00053     extern /* Subroutine */ int cunm2l_(char *, char *, integer *, integer *, 
00054             integer *, complex *, integer *, complex *, complex *, integer *, 
00055             complex *, integer *), cunm2r_(char *, char *, 
00056             integer *, integer *, integer *, complex *, integer *, complex *, 
00057             complex *, integer *, complex *, integer *);
00058     extern doublereal clange_(char *, integer *, integer *, complex *, 
00059             integer *, real *), clanhe_(char *, char *, integer *, 
00060             complex *, integer *, real *), slamch_(char *);
00061     extern /* Subroutine */ int clacpy_(char *, integer *, integer *, complex 
00062             *, integer *, complex *, integer *), claset_(char *, 
00063             integer *, integer *, complex *, complex *, complex *, integer *), clarfy_(char *, integer *, complex *, integer *, complex 
00064             *, complex *, integer *, complex *);
00065 
00066 
00067 /*  -- LAPACK test routine (version 3.1) -- */
00068 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00069 /*     November 2006 */
00070 
00071 /*     .. Scalar Arguments .. */
00072 /*     .. */
00073 /*     .. Array Arguments .. */
00074 /*     .. */
00075 
00076 /*  Purpose */
00077 /*  ======= */
00078 
00079 /*  CHET21 generally checks a decomposition of the form */
00080 
00081 /*     A = U S U* */
00082 
00083 /*  where * means conjugate transpose, A is hermitian, U is unitary, and */
00084 /*  S is diagonal (if KBAND=0) or (real) symmetric tridiagonal (if */
00085 /*  KBAND=1). */
00086 
00087 /*  If ITYPE=1, then U is represented as a dense matrix; otherwise U is */
00088 /*  expressed as a product of Householder transformations, whose vectors */
00089 /*  are stored in the array "V" and whose scaling constants are in "TAU". */
00090 /*  We shall use the letter "V" to refer to the product of Householder */
00091 /*  transformations (which should be equal to U). */
00092 
00093 /*  Specifically, if ITYPE=1, then: */
00094 
00095 /*     RESULT(1) = | A - U S U* | / ( |A| n ulp ) *and* */
00096 /*     RESULT(2) = | I - UU* | / ( n ulp ) */
00097 
00098 /*  If ITYPE=2, then: */
00099 
00100 /*     RESULT(1) = | A - V S V* | / ( |A| n ulp ) */
00101 
00102 /*  If ITYPE=3, then: */
00103 
00104 /*     RESULT(1) = | I - UV* | / ( n ulp ) */
00105 
00106 /*  For ITYPE > 1, the transformation U is expressed as a product */
00107 /*  V = H(1)...H(n-2),  where H(j) = I  -  tau(j) v(j) v(j)*  and each */
00108 /*  vector v(j) has its first j elements 0 and the remaining n-j elements */
00109 /*  stored in V(j+1:n,j). */
00110 
00111 /*  Arguments */
00112 /*  ========= */
00113 
00114 /*  ITYPE   (input) INTEGER */
00115 /*          Specifies the type of tests to be performed. */
00116 /*          1: U expressed as a dense unitary matrix: */
00117 /*             RESULT(1) = | A - U S U* | / ( |A| n ulp )   *and* */
00118 /*             RESULT(2) = | I - UU* | / ( n ulp ) */
00119 
00120 /*          2: U expressed as a product V of Housholder transformations: */
00121 /*             RESULT(1) = | A - V S V* | / ( |A| n ulp ) */
00122 
00123 /*          3: U expressed both as a dense unitary matrix and */
00124 /*             as a product of Housholder transformations: */
00125 /*             RESULT(1) = | I - UV* | / ( n ulp ) */
00126 
00127 /*  UPLO    (input) CHARACTER */
00128 /*          If UPLO='U', the upper triangle of A and V will be used and */
00129 /*          the (strictly) lower triangle will not be referenced. */
00130 /*          If UPLO='L', the lower triangle of A and V will be used and */
00131 /*          the (strictly) upper triangle will not be referenced. */
00132 
00133 /*  N       (input) INTEGER */
00134 /*          The size of the matrix.  If it is zero, CHET21 does nothing. */
00135 /*          It must be at least zero. */
00136 
00137 /*  KBAND   (input) INTEGER */
00138 /*          The bandwidth of the matrix.  It may only be zero or one. */
00139 /*          If zero, then S is diagonal, and E is not referenced.  If */
00140 /*          one, then S is symmetric tri-diagonal. */
00141 
00142 /*  A       (input) COMPLEX array, dimension (LDA, N) */
00143 /*          The original (unfactored) matrix.  It is assumed to be */
00144 /*          hermitian, and only the upper (UPLO='U') or only the lower */
00145 /*          (UPLO='L') will be referenced. */
00146 
00147 /*  LDA     (input) INTEGER */
00148 /*          The leading dimension of A.  It must be at least 1 */
00149 /*          and at least N. */
00150 
00151 /*  D       (input) REAL array, dimension (N) */
00152 /*          The diagonal of the (symmetric tri-) diagonal matrix. */
00153 
00154 /*  E       (input) REAL array, dimension (N-1) */
00155 /*          The off-diagonal of the (symmetric tri-) diagonal matrix. */
00156 /*          E(1) is the (1,2) and (2,1) element, E(2) is the (2,3) and */
00157 /*          (3,2) element, etc. */
00158 /*          Not referenced if KBAND=0. */
00159 
00160 /*  U       (input) COMPLEX array, dimension (LDU, N) */
00161 /*          If ITYPE=1 or 3, this contains the unitary matrix in */
00162 /*          the decomposition, expressed as a dense matrix.  If ITYPE=2, */
00163 /*          then it is not referenced. */
00164 
00165 /*  LDU     (input) INTEGER */
00166 /*          The leading dimension of U.  LDU must be at least N and */
00167 /*          at least 1. */
00168 
00169 /*  V       (input) COMPLEX array, dimension (LDV, N) */
00170 /*          If ITYPE=2 or 3, the columns of this array contain the */
00171 /*          Householder vectors used to describe the unitary matrix */
00172 /*          in the decomposition.  If UPLO='L', then the vectors are in */
00173 /*          the lower triangle, if UPLO='U', then in the upper */
00174 /*          triangle. */
00175 /*          *NOTE* If ITYPE=2 or 3, V is modified and restored.  The */
00176 /*          subdiagonal (if UPLO='L') or the superdiagonal (if UPLO='U') */
00177 /*          is set to one, and later reset to its original value, during */
00178 /*          the course of the calculation. */
00179 /*          If ITYPE=1, then it is neither referenced nor modified. */
00180 
00181 /*  LDV     (input) INTEGER */
00182 /*          The leading dimension of V.  LDV must be at least N and */
00183 /*          at least 1. */
00184 
00185 /*  TAU     (input) COMPLEX array, dimension (N) */
00186 /*          If ITYPE >= 2, then TAU(j) is the scalar factor of */
00187 /*          v(j) v(j)* in the Householder transformation H(j) of */
00188 /*          the product  U = H(1)...H(n-2) */
00189 /*          If ITYPE < 2, then TAU is not referenced. */
00190 
00191 /*  WORK    (workspace) COMPLEX array, dimension (2*N**2) */
00192 
00193 /*  RWORK   (workspace) REAL array, dimension (N) */
00194 
00195 /*  RESULT  (output) REAL array, dimension (2) */
00196 /*          The values computed by the two tests described above.  The */
00197 /*          values are currently limited to 1/ulp, to avoid overflow. */
00198 /*          RESULT(1) is always modified.  RESULT(2) is modified only */
00199 /*          if ITYPE=1. */
00200 
00201 /*  ===================================================================== */
00202 
00203 /*     .. Parameters .. */
00204 /*     .. */
00205 /*     .. Local Scalars .. */
00206 /*     .. */
00207 /*     .. External Functions .. */
00208 /*     .. */
00209 /*     .. External Subroutines .. */
00210 /*     .. */
00211 /*     .. Intrinsic Functions .. */
00212 /*     .. */
00213 /*     .. Executable Statements .. */
00214 
00215     /* Parameter adjustments */
00216     a_dim1 = *lda;
00217     a_offset = 1 + a_dim1;
00218     a -= a_offset;
00219     --d__;
00220     --e;
00221     u_dim1 = *ldu;
00222     u_offset = 1 + u_dim1;
00223     u -= u_offset;
00224     v_dim1 = *ldv;
00225     v_offset = 1 + v_dim1;
00226     v -= v_offset;
00227     --tau;
00228     --work;
00229     --rwork;
00230     --result;
00231 
00232     /* Function Body */
00233     result[1] = 0.f;
00234     if (*itype == 1) {
00235         result[2] = 0.f;
00236     }
00237     if (*n <= 0) {
00238         return 0;
00239     }
00240 
00241     if (lsame_(uplo, "U")) {
00242         lower = FALSE_;
00243         *(unsigned char *)cuplo = 'U';
00244     } else {
00245         lower = TRUE_;
00246         *(unsigned char *)cuplo = 'L';
00247     }
00248 
00249     unfl = slamch_("Safe minimum");
00250     ulp = slamch_("Epsilon") * slamch_("Base");
00251 
00252 /*     Some Error Checks */
00253 
00254     if (*itype < 1 || *itype > 3) {
00255         result[1] = 10.f / ulp;
00256         return 0;
00257     }
00258 
00259 /*     Do Test 1 */
00260 
00261 /*     Norm of A: */
00262 
00263     if (*itype == 3) {
00264         anorm = 1.f;
00265     } else {
00266 /* Computing MAX */
00267         r__1 = clanhe_("1", cuplo, n, &a[a_offset], lda, &rwork[1]);
00268         anorm = dmax(r__1,unfl);
00269     }
00270 
00271 /*     Compute error matrix: */
00272 
00273     if (*itype == 1) {
00274 
00275 /*        ITYPE=1: error = A - U S U* */
00276 
00277         claset_("Full", n, n, &c_b1, &c_b1, &work[1], n);
00278         clacpy_(cuplo, n, n, &a[a_offset], lda, &work[1], n);
00279 
00280         i__1 = *n;
00281         for (j = 1; j <= i__1; ++j) {
00282             r__1 = -d__[j];
00283             cher_(cuplo, n, &r__1, &u[j * u_dim1 + 1], &c__1, &work[1], n);
00284 /* L10: */
00285         }
00286 
00287         if (*n > 1 && *kband == 1) {
00288             i__1 = *n - 1;
00289             for (j = 1; j <= i__1; ++j) {
00290                 i__2 = j;
00291                 q__2.r = e[i__2], q__2.i = 0.f;
00292                 q__1.r = -q__2.r, q__1.i = -q__2.i;
00293                 cher2_(cuplo, n, &q__1, &u[j * u_dim1 + 1], &c__1, &u[(j - 1) 
00294                         * u_dim1 + 1], &c__1, &work[1], n);
00295 /* L20: */
00296             }
00297         }
00298         wnorm = clanhe_("1", cuplo, n, &work[1], n, &rwork[1]);
00299 
00300     } else if (*itype == 2) {
00301 
00302 /*        ITYPE=2: error = V S V* - A */
00303 
00304         claset_("Full", n, n, &c_b1, &c_b1, &work[1], n);
00305 
00306         if (lower) {
00307 /* Computing 2nd power */
00308             i__2 = *n;
00309             i__1 = i__2 * i__2;
00310             i__3 = *n;
00311             work[i__1].r = d__[i__3], work[i__1].i = 0.f;
00312             for (j = *n - 1; j >= 1; --j) {
00313                 if (*kband == 1) {
00314                     i__1 = (*n + 1) * (j - 1) + 2;
00315                     i__2 = j;
00316                     q__2.r = 1.f - tau[i__2].r, q__2.i = 0.f - tau[i__2].i;
00317                     i__3 = j;
00318                     q__1.r = e[i__3] * q__2.r, q__1.i = e[i__3] * q__2.i;
00319                     work[i__1].r = q__1.r, work[i__1].i = q__1.i;
00320                     i__1 = *n;
00321                     for (jr = j + 2; jr <= i__1; ++jr) {
00322                         i__2 = (j - 1) * *n + jr;
00323                         i__3 = j;
00324                         q__3.r = -tau[i__3].r, q__3.i = -tau[i__3].i;
00325                         i__4 = j;
00326                         q__2.r = e[i__4] * q__3.r, q__2.i = e[i__4] * q__3.i;
00327                         i__5 = jr + j * v_dim1;
00328                         q__1.r = q__2.r * v[i__5].r - q__2.i * v[i__5].i, 
00329                                 q__1.i = q__2.r * v[i__5].i + q__2.i * v[i__5]
00330                                 .r;
00331                         work[i__2].r = q__1.r, work[i__2].i = q__1.i;
00332 /* L30: */
00333                     }
00334                 }
00335 
00336                 i__1 = j + 1 + j * v_dim1;
00337                 vsave.r = v[i__1].r, vsave.i = v[i__1].i;
00338                 i__1 = j + 1 + j * v_dim1;
00339                 v[i__1].r = 1.f, v[i__1].i = 0.f;
00340                 i__1 = *n - j;
00341 /* Computing 2nd power */
00342                 i__2 = *n;
00343                 clarfy_("L", &i__1, &v[j + 1 + j * v_dim1], &c__1, &tau[j], &
00344                         work[(*n + 1) * j + 1], n, &work[i__2 * i__2 + 1]);
00345                 i__1 = j + 1 + j * v_dim1;
00346                 v[i__1].r = vsave.r, v[i__1].i = vsave.i;
00347                 i__1 = (*n + 1) * (j - 1) + 1;
00348                 i__2 = j;
00349                 work[i__1].r = d__[i__2], work[i__1].i = 0.f;
00350 /* L40: */
00351             }
00352         } else {
00353             work[1].r = d__[1], work[1].i = 0.f;
00354             i__1 = *n - 1;
00355             for (j = 1; j <= i__1; ++j) {
00356                 if (*kband == 1) {
00357                     i__2 = (*n + 1) * j;
00358                     i__3 = j;
00359                     q__2.r = 1.f - tau[i__3].r, q__2.i = 0.f - tau[i__3].i;
00360                     i__4 = j;
00361                     q__1.r = e[i__4] * q__2.r, q__1.i = e[i__4] * q__2.i;
00362                     work[i__2].r = q__1.r, work[i__2].i = q__1.i;
00363                     i__2 = j - 1;
00364                     for (jr = 1; jr <= i__2; ++jr) {
00365                         i__3 = j * *n + jr;
00366                         i__4 = j;
00367                         q__3.r = -tau[i__4].r, q__3.i = -tau[i__4].i;
00368                         i__5 = j;
00369                         q__2.r = e[i__5] * q__3.r, q__2.i = e[i__5] * q__3.i;
00370                         i__6 = jr + (j + 1) * v_dim1;
00371                         q__1.r = q__2.r * v[i__6].r - q__2.i * v[i__6].i, 
00372                                 q__1.i = q__2.r * v[i__6].i + q__2.i * v[i__6]
00373                                 .r;
00374                         work[i__3].r = q__1.r, work[i__3].i = q__1.i;
00375 /* L50: */
00376                     }
00377                 }
00378 
00379                 i__2 = j + (j + 1) * v_dim1;
00380                 vsave.r = v[i__2].r, vsave.i = v[i__2].i;
00381                 i__2 = j + (j + 1) * v_dim1;
00382                 v[i__2].r = 1.f, v[i__2].i = 0.f;
00383 /* Computing 2nd power */
00384                 i__2 = *n;
00385                 clarfy_("U", &j, &v[(j + 1) * v_dim1 + 1], &c__1, &tau[j], &
00386                         work[1], n, &work[i__2 * i__2 + 1]);
00387                 i__2 = j + (j + 1) * v_dim1;
00388                 v[i__2].r = vsave.r, v[i__2].i = vsave.i;
00389                 i__2 = (*n + 1) * j + 1;
00390                 i__3 = j + 1;
00391                 work[i__2].r = d__[i__3], work[i__2].i = 0.f;
00392 /* L60: */
00393             }
00394         }
00395 
00396         i__1 = *n;
00397         for (jcol = 1; jcol <= i__1; ++jcol) {
00398             if (lower) {
00399                 i__2 = *n;
00400                 for (jrow = jcol; jrow <= i__2; ++jrow) {
00401                     i__3 = jrow + *n * (jcol - 1);
00402                     i__4 = jrow + *n * (jcol - 1);
00403                     i__5 = jrow + jcol * a_dim1;
00404                     q__1.r = work[i__4].r - a[i__5].r, q__1.i = work[i__4].i 
00405                             - a[i__5].i;
00406                     work[i__3].r = q__1.r, work[i__3].i = q__1.i;
00407 /* L70: */
00408                 }
00409             } else {
00410                 i__2 = jcol;
00411                 for (jrow = 1; jrow <= i__2; ++jrow) {
00412                     i__3 = jrow + *n * (jcol - 1);
00413                     i__4 = jrow + *n * (jcol - 1);
00414                     i__5 = jrow + jcol * a_dim1;
00415                     q__1.r = work[i__4].r - a[i__5].r, q__1.i = work[i__4].i 
00416                             - a[i__5].i;
00417                     work[i__3].r = q__1.r, work[i__3].i = q__1.i;
00418 /* L80: */
00419                 }
00420             }
00421 /* L90: */
00422         }
00423         wnorm = clanhe_("1", cuplo, n, &work[1], n, &rwork[1]);
00424 
00425     } else if (*itype == 3) {
00426 
00427 /*        ITYPE=3: error = U V* - I */
00428 
00429         if (*n < 2) {
00430             return 0;
00431         }
00432         clacpy_(" ", n, n, &u[u_offset], ldu, &work[1], n);
00433         if (lower) {
00434             i__1 = *n - 1;
00435             i__2 = *n - 1;
00436 /* Computing 2nd power */
00437             i__3 = *n;
00438             cunm2r_("R", "C", n, &i__1, &i__2, &v[v_dim1 + 2], ldv, &tau[1], &
00439                     work[*n + 1], n, &work[i__3 * i__3 + 1], &iinfo);
00440         } else {
00441             i__1 = *n - 1;
00442             i__2 = *n - 1;
00443 /* Computing 2nd power */
00444             i__3 = *n;
00445             cunm2l_("R", "C", n, &i__1, &i__2, &v[(v_dim1 << 1) + 1], ldv, &
00446                     tau[1], &work[1], n, &work[i__3 * i__3 + 1], &iinfo);
00447         }
00448         if (iinfo != 0) {
00449             result[1] = 10.f / ulp;
00450             return 0;
00451         }
00452 
00453         i__1 = *n;
00454         for (j = 1; j <= i__1; ++j) {
00455             i__2 = (*n + 1) * (j - 1) + 1;
00456             i__3 = (*n + 1) * (j - 1) + 1;
00457             q__1.r = work[i__3].r - 1.f, q__1.i = work[i__3].i - 0.f;
00458             work[i__2].r = q__1.r, work[i__2].i = q__1.i;
00459 /* L100: */
00460         }
00461 
00462         wnorm = clange_("1", n, n, &work[1], n, &rwork[1]);
00463     }
00464 
00465     if (anorm > wnorm) {
00466         result[1] = wnorm / anorm / (*n * ulp);
00467     } else {
00468         if (anorm < 1.f) {
00469 /* Computing MIN */
00470             r__1 = wnorm, r__2 = *n * anorm;
00471             result[1] = dmin(r__1,r__2) / anorm / (*n * ulp);
00472         } else {
00473 /* Computing MIN */
00474             r__1 = wnorm / anorm, r__2 = (real) (*n);
00475             result[1] = dmin(r__1,r__2) / (*n * ulp);
00476         }
00477     }
00478 
00479 /*     Do Test 2 */
00480 
00481 /*     Compute  UU* - I */
00482 
00483     if (*itype == 1) {
00484         cgemm_("N", "C", n, n, n, &c_b2, &u[u_offset], ldu, &u[u_offset], ldu, 
00485                  &c_b1, &work[1], n);
00486 
00487         i__1 = *n;
00488         for (j = 1; j <= i__1; ++j) {
00489             i__2 = (*n + 1) * (j - 1) + 1;
00490             i__3 = (*n + 1) * (j - 1) + 1;
00491             q__1.r = work[i__3].r - 1.f, q__1.i = work[i__3].i - 0.f;
00492             work[i__2].r = q__1.r, work[i__2].i = q__1.i;
00493 /* L110: */
00494         }
00495 
00496 /* Computing MIN */
00497         r__1 = clange_("1", n, n, &work[1], n, &rwork[1]), r__2 = (
00498                 real) (*n);
00499         result[2] = dmin(r__1,r__2) / (*n * ulp);
00500     }
00501 
00502     return 0;
00503 
00504 /*     End of CHET21 */
00505 
00506 } /* chet21_ */


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