slatm4.c
Go to the documentation of this file.
00001 /* slatm4.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_b3 = 0.f;
00019 
00020 /* Subroutine */ int slatm4_(integer *itype, integer *n, integer *nz1, 
00021         integer *nz2, integer *isign, real *amagn, real *rcond, real *triang, 
00022         integer *idist, integer *iseed, real *a, integer *lda)
00023 {
00024     /* System generated locals */
00025     integer a_dim1, a_offset, i__1, i__2, i__3, i__4;
00026     real r__1, r__2, r__3, r__4;
00027     doublereal d__1, d__2;
00028 
00029     /* Builtin functions */
00030     double pow_dd(doublereal *, doublereal *), log(doublereal), exp(
00031             doublereal), sqrt(doublereal);
00032 
00033     /* Local variables */
00034     integer i__, k, jc, jd;
00035     real cl, cr;
00036     integer jr;
00037     real sl, sr, sv1, sv2;
00038     integer kbeg, isdb, kend, ioff, isde, klen;
00039     real temp, alpha;
00040     extern doublereal slamch_(char *);
00041     real safmin;
00042     extern doublereal slaran_(integer *), slarnd_(integer *, integer *);
00043     extern /* Subroutine */ int slaset_(char *, integer *, integer *, real *, 
00044             real *, real *, integer *);
00045 
00046 
00047 /*  -- LAPACK auxiliary test routine (version 3.1) -- */
00048 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00049 /*     November 2006 */
00050 
00051 /*     .. Scalar Arguments .. */
00052 /*     .. */
00053 /*     .. Array Arguments .. */
00054 /*     .. */
00055 
00056 /*  Purpose */
00057 /*  ======= */
00058 
00059 /*  SLATM4 generates basic square matrices, which may later be */
00060 /*  multiplied by others in order to produce test matrices.  It is */
00061 /*  intended mainly to be used to test the generalized eigenvalue */
00062 /*  routines. */
00063 
00064 /*  It first generates the diagonal and (possibly) subdiagonal, */
00065 /*  according to the value of ITYPE, NZ1, NZ2, ISIGN, AMAGN, and RCOND. */
00066 /*  It then fills in the upper triangle with random numbers, if TRIANG is */
00067 /*  non-zero. */
00068 
00069 /*  Arguments */
00070 /*  ========= */
00071 
00072 /*  ITYPE   (input) INTEGER */
00073 /*          The "type" of matrix on the diagonal and sub-diagonal. */
00074 /*          If ITYPE < 0, then type abs(ITYPE) is generated and then */
00075 /*             swapped end for end (A(I,J) := A'(N-J,N-I).)  See also */
00076 /*             the description of AMAGN and ISIGN. */
00077 
00078 /*          Special types: */
00079 /*          = 0:  the zero matrix. */
00080 /*          = 1:  the identity. */
00081 /*          = 2:  a transposed Jordan block. */
00082 /*          = 3:  If N is odd, then a k+1 x k+1 transposed Jordan block */
00083 /*                followed by a k x k identity block, where k=(N-1)/2. */
00084 /*                If N is even, then k=(N-2)/2, and a zero diagonal entry */
00085 /*                is tacked onto the end. */
00086 
00087 /*          Diagonal types.  The diagonal consists of NZ1 zeros, then */
00088 /*             k=N-NZ1-NZ2 nonzeros.  The subdiagonal is zero.  ITYPE */
00089 /*             specifies the nonzero diagonal entries as follows: */
00090 /*          = 4:  1, ..., k */
00091 /*          = 5:  1, RCOND, ..., RCOND */
00092 /*          = 6:  1, ..., 1, RCOND */
00093 /*          = 7:  1, a, a^2, ..., a^(k-1)=RCOND */
00094 /*          = 8:  1, 1-d, 1-2*d, ..., 1-(k-1)*d=RCOND */
00095 /*          = 9:  random numbers chosen from (RCOND,1) */
00096 /*          = 10: random numbers with distribution IDIST (see SLARND.) */
00097 
00098 /*  N       (input) INTEGER */
00099 /*          The order of the matrix. */
00100 
00101 /*  NZ1     (input) INTEGER */
00102 /*          If abs(ITYPE) > 3, then the first NZ1 diagonal entries will */
00103 /*          be zero. */
00104 
00105 /*  NZ2     (input) INTEGER */
00106 /*          If abs(ITYPE) > 3, then the last NZ2 diagonal entries will */
00107 /*          be zero. */
00108 
00109 /*  ISIGN   (input) INTEGER */
00110 /*          = 0: The sign of the diagonal and subdiagonal entries will */
00111 /*               be left unchanged. */
00112 /*          = 1: The diagonal and subdiagonal entries will have their */
00113 /*               sign changed at random. */
00114 /*          = 2: If ITYPE is 2 or 3, then the same as ISIGN=1. */
00115 /*               Otherwise, with probability 0.5, odd-even pairs of */
00116 /*               diagonal entries A(2*j-1,2*j-1), A(2*j,2*j) will be */
00117 /*               converted to a 2x2 block by pre- and post-multiplying */
00118 /*               by distinct random orthogonal rotations.  The remaining */
00119 /*               diagonal entries will have their sign changed at random. */
00120 
00121 /*  AMAGN   (input) REAL */
00122 /*          The diagonal and subdiagonal entries will be multiplied by */
00123 /*          AMAGN. */
00124 
00125 /*  RCOND   (input) REAL */
00126 /*          If abs(ITYPE) > 4, then the smallest diagonal entry will be */
00127 /*          entry will be RCOND.  RCOND must be between 0 and 1. */
00128 
00129 /*  TRIANG  (input) REAL */
00130 /*          The entries above the diagonal will be random numbers with */
00131 /*          magnitude bounded by TRIANG (i.e., random numbers multiplied */
00132 /*          by TRIANG.) */
00133 
00134 /*  IDIST   (input) INTEGER */
00135 /*          Specifies the type of distribution to be used to generate a */
00136 /*          random matrix. */
00137 /*          = 1:  UNIFORM( 0, 1 ) */
00138 /*          = 2:  UNIFORM( -1, 1 ) */
00139 /*          = 3:  NORMAL ( 0, 1 ) */
00140 
00141 /*  ISEED   (input/output) INTEGER array, dimension (4) */
00142 /*          On entry ISEED specifies the seed of the random number */
00143 /*          generator.  The values of ISEED are changed on exit, and can */
00144 /*          be used in the next call to SLATM4 to continue the same */
00145 /*          random number sequence. */
00146 /*          Note: ISEED(4) should be odd, for the random number generator */
00147 /*          used at present. */
00148 
00149 /*  A       (output) REAL array, dimension (LDA, N) */
00150 /*          Array to be computed. */
00151 
00152 /*  LDA     (input) INTEGER */
00153 /*          Leading dimension of A.  Must be at least 1 and at least N. */
00154 
00155 /*  ===================================================================== */
00156 
00157 /*     .. Parameters .. */
00158 /*     .. */
00159 /*     .. Local Scalars .. */
00160 /*     .. */
00161 /*     .. External Functions .. */
00162 /*     .. */
00163 /*     .. External Subroutines .. */
00164 /*     .. */
00165 /*     .. Intrinsic Functions .. */
00166 /*     .. */
00167 /*     .. Executable Statements .. */
00168 
00169     /* Parameter adjustments */
00170     --iseed;
00171     a_dim1 = *lda;
00172     a_offset = 1 + a_dim1;
00173     a -= a_offset;
00174 
00175     /* Function Body */
00176     if (*n <= 0) {
00177         return 0;
00178     }
00179     slaset_("Full", n, n, &c_b3, &c_b3, &a[a_offset], lda);
00180 
00181 /*     Insure a correct ISEED */
00182 
00183     if (iseed[4] % 2 != 1) {
00184         ++iseed[4];
00185     }
00186 
00187 /*     Compute diagonal and subdiagonal according to ITYPE, NZ1, NZ2, */
00188 /*     and RCOND */
00189 
00190     if (*itype != 0) {
00191         if (abs(*itype) >= 4) {
00192 /* Computing MAX */
00193 /* Computing MIN */
00194             i__3 = *n, i__4 = *nz1 + 1;
00195             i__1 = 1, i__2 = min(i__3,i__4);
00196             kbeg = max(i__1,i__2);
00197 /* Computing MAX */
00198 /* Computing MIN */
00199             i__3 = *n, i__4 = *n - *nz2;
00200             i__1 = kbeg, i__2 = min(i__3,i__4);
00201             kend = max(i__1,i__2);
00202             klen = kend + 1 - kbeg;
00203         } else {
00204             kbeg = 1;
00205             kend = *n;
00206             klen = *n;
00207         }
00208         isdb = 1;
00209         isde = 0;
00210         switch (abs(*itype)) {
00211             case 1:  goto L10;
00212             case 2:  goto L30;
00213             case 3:  goto L50;
00214             case 4:  goto L80;
00215             case 5:  goto L100;
00216             case 6:  goto L120;
00217             case 7:  goto L140;
00218             case 8:  goto L160;
00219             case 9:  goto L180;
00220             case 10:  goto L200;
00221         }
00222 
00223 /*        abs(ITYPE) = 1: Identity */
00224 
00225 L10:
00226         i__1 = *n;
00227         for (jd = 1; jd <= i__1; ++jd) {
00228             a[jd + jd * a_dim1] = 1.f;
00229 /* L20: */
00230         }
00231         goto L220;
00232 
00233 /*        abs(ITYPE) = 2: Transposed Jordan block */
00234 
00235 L30:
00236         i__1 = *n - 1;
00237         for (jd = 1; jd <= i__1; ++jd) {
00238             a[jd + 1 + jd * a_dim1] = 1.f;
00239 /* L40: */
00240         }
00241         isdb = 1;
00242         isde = *n - 1;
00243         goto L220;
00244 
00245 /*        abs(ITYPE) = 3: Transposed Jordan block, followed by the */
00246 /*                        identity. */
00247 
00248 L50:
00249         k = (*n - 1) / 2;
00250         i__1 = k;
00251         for (jd = 1; jd <= i__1; ++jd) {
00252             a[jd + 1 + jd * a_dim1] = 1.f;
00253 /* L60: */
00254         }
00255         isdb = 1;
00256         isde = k;
00257         i__1 = (k << 1) + 1;
00258         for (jd = k + 2; jd <= i__1; ++jd) {
00259             a[jd + jd * a_dim1] = 1.f;
00260 /* L70: */
00261         }
00262         goto L220;
00263 
00264 /*        abs(ITYPE) = 4: 1,...,k */
00265 
00266 L80:
00267         i__1 = kend;
00268         for (jd = kbeg; jd <= i__1; ++jd) {
00269             a[jd + jd * a_dim1] = (real) (jd - *nz1);
00270 /* L90: */
00271         }
00272         goto L220;
00273 
00274 /*        abs(ITYPE) = 5: One large D value: */
00275 
00276 L100:
00277         i__1 = kend;
00278         for (jd = kbeg + 1; jd <= i__1; ++jd) {
00279             a[jd + jd * a_dim1] = *rcond;
00280 /* L110: */
00281         }
00282         a[kbeg + kbeg * a_dim1] = 1.f;
00283         goto L220;
00284 
00285 /*        abs(ITYPE) = 6: One small D value: */
00286 
00287 L120:
00288         i__1 = kend - 1;
00289         for (jd = kbeg; jd <= i__1; ++jd) {
00290             a[jd + jd * a_dim1] = 1.f;
00291 /* L130: */
00292         }
00293         a[kend + kend * a_dim1] = *rcond;
00294         goto L220;
00295 
00296 /*        abs(ITYPE) = 7: Exponentially distributed D values: */
00297 
00298 L140:
00299         a[kbeg + kbeg * a_dim1] = 1.f;
00300         if (klen > 1) {
00301             d__1 = (doublereal) (*rcond);
00302             d__2 = (doublereal) (1.f / (real) (klen - 1));
00303             alpha = pow_dd(&d__1, &d__2);
00304             i__1 = klen;
00305             for (i__ = 2; i__ <= i__1; ++i__) {
00306                 d__1 = (doublereal) alpha;
00307                 d__2 = (doublereal) ((real) (i__ - 1));
00308                 a[*nz1 + i__ + (*nz1 + i__) * a_dim1] = pow_dd(&d__1, &d__2);
00309 /* L150: */
00310             }
00311         }
00312         goto L220;
00313 
00314 /*        abs(ITYPE) = 8: Arithmetically distributed D values: */
00315 
00316 L160:
00317         a[kbeg + kbeg * a_dim1] = 1.f;
00318         if (klen > 1) {
00319             alpha = (1.f - *rcond) / (real) (klen - 1);
00320             i__1 = klen;
00321             for (i__ = 2; i__ <= i__1; ++i__) {
00322                 a[*nz1 + i__ + (*nz1 + i__) * a_dim1] = (real) (klen - i__) * 
00323                         alpha + *rcond;
00324 /* L170: */
00325             }
00326         }
00327         goto L220;
00328 
00329 /*        abs(ITYPE) = 9: Randomly distributed D values on ( RCOND, 1): */
00330 
00331 L180:
00332         alpha = log(*rcond);
00333         i__1 = kend;
00334         for (jd = kbeg; jd <= i__1; ++jd) {
00335             a[jd + jd * a_dim1] = exp(alpha * slaran_(&iseed[1]));
00336 /* L190: */
00337         }
00338         goto L220;
00339 
00340 /*        abs(ITYPE) = 10: Randomly distributed D values from DIST */
00341 
00342 L200:
00343         i__1 = kend;
00344         for (jd = kbeg; jd <= i__1; ++jd) {
00345             a[jd + jd * a_dim1] = slarnd_(idist, &iseed[1]);
00346 /* L210: */
00347         }
00348 
00349 L220:
00350 
00351 /*        Scale by AMAGN */
00352 
00353         i__1 = kend;
00354         for (jd = kbeg; jd <= i__1; ++jd) {
00355             a[jd + jd * a_dim1] = *amagn * a[jd + jd * a_dim1];
00356 /* L230: */
00357         }
00358         i__1 = isde;
00359         for (jd = isdb; jd <= i__1; ++jd) {
00360             a[jd + 1 + jd * a_dim1] = *amagn * a[jd + 1 + jd * a_dim1];
00361 /* L240: */
00362         }
00363 
00364 /*        If ISIGN = 1 or 2, assign random signs to diagonal and */
00365 /*        subdiagonal */
00366 
00367         if (*isign > 0) {
00368             i__1 = kend;
00369             for (jd = kbeg; jd <= i__1; ++jd) {
00370                 if (a[jd + jd * a_dim1] != 0.f) {
00371                     if (slaran_(&iseed[1]) > .5f) {
00372                         a[jd + jd * a_dim1] = -a[jd + jd * a_dim1];
00373                     }
00374                 }
00375 /* L250: */
00376             }
00377             i__1 = isde;
00378             for (jd = isdb; jd <= i__1; ++jd) {
00379                 if (a[jd + 1 + jd * a_dim1] != 0.f) {
00380                     if (slaran_(&iseed[1]) > .5f) {
00381                         a[jd + 1 + jd * a_dim1] = -a[jd + 1 + jd * a_dim1];
00382                     }
00383                 }
00384 /* L260: */
00385             }
00386         }
00387 
00388 /*        Reverse if ITYPE < 0 */
00389 
00390         if (*itype < 0) {
00391             i__1 = (kbeg + kend - 1) / 2;
00392             for (jd = kbeg; jd <= i__1; ++jd) {
00393                 temp = a[jd + jd * a_dim1];
00394                 a[jd + jd * a_dim1] = a[kbeg + kend - jd + (kbeg + kend - jd) 
00395                         * a_dim1];
00396                 a[kbeg + kend - jd + (kbeg + kend - jd) * a_dim1] = temp;
00397 /* L270: */
00398             }
00399             i__1 = (*n - 1) / 2;
00400             for (jd = 1; jd <= i__1; ++jd) {
00401                 temp = a[jd + 1 + jd * a_dim1];
00402                 a[jd + 1 + jd * a_dim1] = a[*n + 1 - jd + (*n - jd) * a_dim1];
00403                 a[*n + 1 - jd + (*n - jd) * a_dim1] = temp;
00404 /* L280: */
00405             }
00406         }
00407 
00408 /*        If ISIGN = 2, and no subdiagonals already, then apply */
00409 /*        random rotations to make 2x2 blocks. */
00410 
00411         if (*isign == 2 && *itype != 2 && *itype != 3) {
00412             safmin = slamch_("S");
00413             i__1 = kend - 1;
00414             for (jd = kbeg; jd <= i__1; jd += 2) {
00415                 if (slaran_(&iseed[1]) > .5f) {
00416 
00417 /*                 Rotation on left. */
00418 
00419                     cl = slaran_(&iseed[1]) * 2.f - 1.f;
00420                     sl = slaran_(&iseed[1]) * 2.f - 1.f;
00421 /* Computing MAX */
00422 /* Computing 2nd power */
00423                     r__3 = cl;
00424 /* Computing 2nd power */
00425                     r__4 = sl;
00426                     r__1 = safmin, r__2 = sqrt(r__3 * r__3 + r__4 * r__4);
00427                     temp = 1.f / dmax(r__1,r__2);
00428                     cl *= temp;
00429                     sl *= temp;
00430 
00431 /*                 Rotation on right. */
00432 
00433                     cr = slaran_(&iseed[1]) * 2.f - 1.f;
00434                     sr = slaran_(&iseed[1]) * 2.f - 1.f;
00435 /* Computing MAX */
00436 /* Computing 2nd power */
00437                     r__3 = cr;
00438 /* Computing 2nd power */
00439                     r__4 = sr;
00440                     r__1 = safmin, r__2 = sqrt(r__3 * r__3 + r__4 * r__4);
00441                     temp = 1.f / dmax(r__1,r__2);
00442                     cr *= temp;
00443                     sr *= temp;
00444 
00445 /*                 Apply */
00446 
00447                     sv1 = a[jd + jd * a_dim1];
00448                     sv2 = a[jd + 1 + (jd + 1) * a_dim1];
00449                     a[jd + jd * a_dim1] = cl * cr * sv1 + sl * sr * sv2;
00450                     a[jd + 1 + jd * a_dim1] = -sl * cr * sv1 + cl * sr * sv2;
00451                     a[jd + (jd + 1) * a_dim1] = -cl * sr * sv1 + sl * cr * 
00452                             sv2;
00453                     a[jd + 1 + (jd + 1) * a_dim1] = sl * sr * sv1 + cl * cr * 
00454                             sv2;
00455                 }
00456 /* L290: */
00457             }
00458         }
00459 
00460     }
00461 
00462 /*     Fill in upper triangle (except for 2x2 blocks) */
00463 
00464     if (*triang != 0.f) {
00465         if (*isign != 2 || *itype == 2 || *itype == 3) {
00466             ioff = 1;
00467         } else {
00468             ioff = 2;
00469             i__1 = *n - 1;
00470             for (jr = 1; jr <= i__1; ++jr) {
00471                 if (a[jr + 1 + jr * a_dim1] == 0.f) {
00472                     a[jr + (jr + 1) * a_dim1] = *triang * slarnd_(idist, &
00473                             iseed[1]);
00474                 }
00475 /* L300: */
00476             }
00477         }
00478 
00479         i__1 = *n;
00480         for (jc = 2; jc <= i__1; ++jc) {
00481             i__2 = jc - ioff;
00482             for (jr = 1; jr <= i__2; ++jr) {
00483                 a[jr + jc * a_dim1] = *triang * slarnd_(idist, &iseed[1]);
00484 /* L310: */
00485             }
00486 /* L320: */
00487         }
00488     }
00489 
00490     return 0;
00491 
00492 /*     End of SLATM4 */
00493 
00494 } /* slatm4_ */


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