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


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