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


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