dlatm4.c
Go to the documentation of this file.
00001 /* dlatm4.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_b3 = 0.;
00019 
00020 /* Subroutine */ int dlatm4_(integer *itype, integer *n, integer *nz1, 
00021         integer *nz2, integer *isign, doublereal *amagn, doublereal *rcond, 
00022         doublereal *triang, integer *idist, integer *iseed, doublereal *a, 
00023         integer *lda)
00024 {
00025     /* System generated locals */
00026     integer a_dim1, a_offset, i__1, i__2, i__3, i__4;
00027     doublereal d__1, d__2, d__3, d__4;
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     doublereal cl, cr;
00036     integer jr;
00037     doublereal sl, sr, sv1, sv2;
00038     integer kbeg, isdb, kend, ioff, isde, klen;
00039     doublereal temp, alpha;
00040     extern doublereal dlamch_(char *), dlaran_(integer *), dlarnd_(
00041             integer *, integer *);
00042     extern /* Subroutine */ int dlaset_(char *, integer *, integer *, 
00043             doublereal *, doublereal *, doublereal *, integer *);
00044     doublereal safmin;
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 /*  DLATM4 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 DLARND.) */
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) DOUBLE PRECISION */
00122 /*          The diagonal and subdiagonal entries will be multiplied by */
00123 /*          AMAGN. */
00124 
00125 /*  RCOND   (input) DOUBLE PRECISION */
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) DOUBLE PRECISION */
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 DLATM4 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) DOUBLE PRECISION 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     dlaset_("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.;
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.;
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.;
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.;
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] = (doublereal) (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.;
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.;
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.;
00300         if (klen > 1) {
00301             d__1 = 1. / (doublereal) (klen - 1);
00302             alpha = pow_dd(rcond, &d__1);
00303             i__1 = klen;
00304             for (i__ = 2; i__ <= i__1; ++i__) {
00305                 d__1 = (doublereal) (i__ - 1);
00306                 a[*nz1 + i__ + (*nz1 + i__) * a_dim1] = pow_dd(&alpha, &d__1);
00307 /* L150: */
00308             }
00309         }
00310         goto L220;
00311 
00312 /*        abs(ITYPE) = 8: Arithmetically distributed D values: */
00313 
00314 L160:
00315         a[kbeg + kbeg * a_dim1] = 1.;
00316         if (klen > 1) {
00317             alpha = (1. - *rcond) / (doublereal) (klen - 1);
00318             i__1 = klen;
00319             for (i__ = 2; i__ <= i__1; ++i__) {
00320                 a[*nz1 + i__ + (*nz1 + i__) * a_dim1] = (doublereal) (klen - 
00321                         i__) * alpha + *rcond;
00322 /* L170: */
00323             }
00324         }
00325         goto L220;
00326 
00327 /*        abs(ITYPE) = 9: Randomly distributed D values on ( RCOND, 1): */
00328 
00329 L180:
00330         alpha = log(*rcond);
00331         i__1 = kend;
00332         for (jd = kbeg; jd <= i__1; ++jd) {
00333             a[jd + jd * a_dim1] = exp(alpha * dlaran_(&iseed[1]));
00334 /* L190: */
00335         }
00336         goto L220;
00337 
00338 /*        abs(ITYPE) = 10: Randomly distributed D values from DIST */
00339 
00340 L200:
00341         i__1 = kend;
00342         for (jd = kbeg; jd <= i__1; ++jd) {
00343             a[jd + jd * a_dim1] = dlarnd_(idist, &iseed[1]);
00344 /* L210: */
00345         }
00346 
00347 L220:
00348 
00349 /*        Scale by AMAGN */
00350 
00351         i__1 = kend;
00352         for (jd = kbeg; jd <= i__1; ++jd) {
00353             a[jd + jd * a_dim1] = *amagn * a[jd + jd * a_dim1];
00354 /* L230: */
00355         }
00356         i__1 = isde;
00357         for (jd = isdb; jd <= i__1; ++jd) {
00358             a[jd + 1 + jd * a_dim1] = *amagn * a[jd + 1 + jd * a_dim1];
00359 /* L240: */
00360         }
00361 
00362 /*        If ISIGN = 1 or 2, assign random signs to diagonal and */
00363 /*        subdiagonal */
00364 
00365         if (*isign > 0) {
00366             i__1 = kend;
00367             for (jd = kbeg; jd <= i__1; ++jd) {
00368                 if (a[jd + jd * a_dim1] != 0.) {
00369                     if (dlaran_(&iseed[1]) > .5) {
00370                         a[jd + jd * a_dim1] = -a[jd + jd * a_dim1];
00371                     }
00372                 }
00373 /* L250: */
00374             }
00375             i__1 = isde;
00376             for (jd = isdb; jd <= i__1; ++jd) {
00377                 if (a[jd + 1 + jd * a_dim1] != 0.) {
00378                     if (dlaran_(&iseed[1]) > .5) {
00379                         a[jd + 1 + jd * a_dim1] = -a[jd + 1 + jd * a_dim1];
00380                     }
00381                 }
00382 /* L260: */
00383             }
00384         }
00385 
00386 /*        Reverse if ITYPE < 0 */
00387 
00388         if (*itype < 0) {
00389             i__1 = (kbeg + kend - 1) / 2;
00390             for (jd = kbeg; jd <= i__1; ++jd) {
00391                 temp = a[jd + jd * a_dim1];
00392                 a[jd + jd * a_dim1] = a[kbeg + kend - jd + (kbeg + kend - jd) 
00393                         * a_dim1];
00394                 a[kbeg + kend - jd + (kbeg + kend - jd) * a_dim1] = temp;
00395 /* L270: */
00396             }
00397             i__1 = (*n - 1) / 2;
00398             for (jd = 1; jd <= i__1; ++jd) {
00399                 temp = a[jd + 1 + jd * a_dim1];
00400                 a[jd + 1 + jd * a_dim1] = a[*n + 1 - jd + (*n - jd) * a_dim1];
00401                 a[*n + 1 - jd + (*n - jd) * a_dim1] = temp;
00402 /* L280: */
00403             }
00404         }
00405 
00406 /*        If ISIGN = 2, and no subdiagonals already, then apply */
00407 /*        random rotations to make 2x2 blocks. */
00408 
00409         if (*isign == 2 && *itype != 2 && *itype != 3) {
00410             safmin = dlamch_("S");
00411             i__1 = kend - 1;
00412             for (jd = kbeg; jd <= i__1; jd += 2) {
00413                 if (dlaran_(&iseed[1]) > .5) {
00414 
00415 /*                 Rotation on left. */
00416 
00417                     cl = dlaran_(&iseed[1]) * 2. - 1.;
00418                     sl = dlaran_(&iseed[1]) * 2. - 1.;
00419 /* Computing MAX */
00420 /* Computing 2nd power */
00421                     d__3 = cl;
00422 /* Computing 2nd power */
00423                     d__4 = sl;
00424                     d__1 = safmin, d__2 = sqrt(d__3 * d__3 + d__4 * d__4);
00425                     temp = 1. / max(d__1,d__2);
00426                     cl *= temp;
00427                     sl *= temp;
00428 
00429 /*                 Rotation on right. */
00430 
00431                     cr = dlaran_(&iseed[1]) * 2. - 1.;
00432                     sr = dlaran_(&iseed[1]) * 2. - 1.;
00433 /* Computing MAX */
00434 /* Computing 2nd power */
00435                     d__3 = cr;
00436 /* Computing 2nd power */
00437                     d__4 = sr;
00438                     d__1 = safmin, d__2 = sqrt(d__3 * d__3 + d__4 * d__4);
00439                     temp = 1. / max(d__1,d__2);
00440                     cr *= temp;
00441                     sr *= temp;
00442 
00443 /*                 Apply */
00444 
00445                     sv1 = a[jd + jd * a_dim1];
00446                     sv2 = a[jd + 1 + (jd + 1) * a_dim1];
00447                     a[jd + jd * a_dim1] = cl * cr * sv1 + sl * sr * sv2;
00448                     a[jd + 1 + jd * a_dim1] = -sl * cr * sv1 + cl * sr * sv2;
00449                     a[jd + (jd + 1) * a_dim1] = -cl * sr * sv1 + sl * cr * 
00450                             sv2;
00451                     a[jd + 1 + (jd + 1) * a_dim1] = sl * sr * sv1 + cl * cr * 
00452                             sv2;
00453                 }
00454 /* L290: */
00455             }
00456         }
00457 
00458     }
00459 
00460 /*     Fill in upper triangle (except for 2x2 blocks) */
00461 
00462     if (*triang != 0.) {
00463         if (*isign != 2 || *itype == 2 || *itype == 3) {
00464             ioff = 1;
00465         } else {
00466             ioff = 2;
00467             i__1 = *n - 1;
00468             for (jr = 1; jr <= i__1; ++jr) {
00469                 if (a[jr + 1 + jr * a_dim1] == 0.) {
00470                     a[jr + (jr + 1) * a_dim1] = *triang * dlarnd_(idist, &
00471                             iseed[1]);
00472                 }
00473 /* L300: */
00474             }
00475         }
00476 
00477         i__1 = *n;
00478         for (jc = 2; jc <= i__1; ++jc) {
00479             i__2 = jc - ioff;
00480             for (jr = 1; jr <= i__2; ++jr) {
00481                 a[jr + jc * a_dim1] = *triang * dlarnd_(idist, &iseed[1]);
00482 /* L310: */
00483             }
00484 /* L320: */
00485         }
00486     }
00487 
00488     return 0;
00489 
00490 /*     End of DLATM4 */
00491 
00492 } /* dlatm4_ */


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