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


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