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


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