claror.c
Go to the documentation of this file.
00001 /* claror.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 complex c_b1 = {0.f,0.f};
00019 static complex c_b2 = {1.f,0.f};
00020 static integer c__3 = 3;
00021 static integer c__1 = 1;
00022 
00023 /* Subroutine */ int claror_(char *side, char *init, integer *m, integer *n, 
00024         complex *a, integer *lda, integer *iseed, complex *x, integer *info)
00025 {
00026     /* System generated locals */
00027     integer a_dim1, a_offset, i__1, i__2, i__3;
00028     complex q__1, q__2;
00029 
00030     /* Builtin functions */
00031     double c_abs(complex *);
00032     void r_cnjg(complex *, complex *);
00033 
00034     /* Local variables */
00035     integer j, kbeg, jcol;
00036     real xabs;
00037     integer irow;
00038     extern /* Subroutine */ int cgerc_(integer *, integer *, complex *, 
00039             complex *, integer *, complex *, integer *, complex *, integer *),
00040              cscal_(integer *, complex *, complex *, integer *);
00041     extern logical lsame_(char *, char *);
00042     extern /* Subroutine */ int cgemv_(char *, integer *, integer *, complex *
00043 , complex *, integer *, complex *, integer *, complex *, complex *
00044 , integer *);
00045     complex csign;
00046     integer ixfrm, itype, nxfrm;
00047     real xnorm;
00048     extern doublereal scnrm2_(integer *, complex *, integer *);
00049     extern /* Subroutine */ int clacgv_(integer *, complex *, integer *);
00050     extern /* Complex */ VOID clarnd_(complex *, integer *, integer *);
00051     extern /* Subroutine */ int claset_(char *, integer *, integer *, complex 
00052             *, complex *, complex *, integer *), xerbla_(char *, 
00053             integer *);
00054     real factor;
00055     complex xnorms;
00056 
00057 
00058 /*  -- LAPACK auxiliary test routine (version 3.1) -- */
00059 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00060 /*     November 2006 */
00061 
00062 /*     .. Scalar Arguments .. */
00063 /*     .. */
00064 /*     .. Array Arguments .. */
00065 /*     .. */
00066 
00067 /*  Purpose */
00068 /*  ======= */
00069 
00070 /*     CLAROR pre- or post-multiplies an M by N matrix A by a random */
00071 /*     unitary matrix U, overwriting A. A may optionally be */
00072 /*     initialized to the identity matrix before multiplying by U. */
00073 /*     U is generated using the method of G.W. Stewart */
00074 /*     ( SIAM J. Numer. Anal. 17, 1980, pp. 403-409 ). */
00075 /*     (BLAS-2 version) */
00076 
00077 /*  Arguments */
00078 /*  ========= */
00079 
00080 /*  SIDE   - CHARACTER*1 */
00081 /*           SIDE specifies whether A is multiplied on the left or right */
00082 /*           by U. */
00083 /*       SIDE = 'L'   Multiply A on the left (premultiply) by U */
00084 /*       SIDE = 'R'   Multiply A on the right (postmultiply) by U* */
00085 /*       SIDE = 'C'   Multiply A on the left by U and the right by U* */
00086 /*       SIDE = 'T'   Multiply A on the left by U and the right by U' */
00087 /*           Not modified. */
00088 
00089 /*  INIT   - CHARACTER*1 */
00090 /*           INIT specifies whether or not A should be initialized to */
00091 /*           the identity matrix. */
00092 /*              INIT = 'I'   Initialize A to (a section of) the */
00093 /*                           identity matrix before applying U. */
00094 /*              INIT = 'N'   No initialization.  Apply U to the */
00095 /*                           input matrix A. */
00096 
00097 /*           INIT = 'I' may be used to generate square (i.e., unitary) */
00098 /*           or rectangular orthogonal matrices (orthogonality being */
00099 /*           in the sense of CDOTC): */
00100 
00101 /*           For square matrices, M=N, and SIDE many be either 'L' or */
00102 /*           'R'; the rows will be orthogonal to each other, as will the */
00103 /*           columns. */
00104 /*           For rectangular matrices where M < N, SIDE = 'R' will */
00105 /*           produce a dense matrix whose rows will be orthogonal and */
00106 /*           whose columns will not, while SIDE = 'L' will produce a */
00107 /*           matrix whose rows will be orthogonal, and whose first M */
00108 /*           columns will be orthogonal, the remaining columns being */
00109 /*           zero. */
00110 /*           For matrices where M > N, just use the previous */
00111 /*           explaination, interchanging 'L' and 'R' and "rows" and */
00112 /*           "columns". */
00113 
00114 /*           Not modified. */
00115 
00116 /*  M      - INTEGER */
00117 /*           Number of rows of A. Not modified. */
00118 
00119 /*  N      - INTEGER */
00120 /*           Number of columns of A. Not modified. */
00121 
00122 /*  A      - COMPLEX array, dimension ( LDA, N ) */
00123 /*           Input and output array. Overwritten by U A ( if SIDE = 'L' ) */
00124 /*           or by A U ( if SIDE = 'R' ) */
00125 /*           or by U A U* ( if SIDE = 'C') */
00126 /*           or by U A U' ( if SIDE = 'T') on exit. */
00127 
00128 /*  LDA    - INTEGER */
00129 /*           Leading dimension of A. Must be at least MAX ( 1, M ). */
00130 /*           Not modified. */
00131 
00132 /*  ISEED  - INTEGER array, dimension ( 4 ) */
00133 /*           On entry ISEED specifies the seed of the random number */
00134 /*           generator. The array elements should be between 0 and 4095; */
00135 /*           if not they will be reduced mod 4096.  Also, ISEED(4) must */
00136 /*           be odd.  The random number generator uses a linear */
00137 /*           congruential sequence limited to small integers, and so */
00138 /*           should produce machine independent random numbers. The */
00139 /*           values of ISEED are changed on exit, and can be used in the */
00140 /*           next call to CLAROR to continue the same random number */
00141 /*           sequence. */
00142 /*           Modified. */
00143 
00144 /*  X      - COMPLEX array, dimension ( 3*MAX( M, N ) ) */
00145 /*           Workspace. Of length: */
00146 /*               2*M + N if SIDE = 'L', */
00147 /*               2*N + M if SIDE = 'R', */
00148 /*               3*N     if SIDE = 'C' or 'T'. */
00149 /*           Modified. */
00150 
00151 /*  INFO   - INTEGER */
00152 /*           An error flag.  It is set to: */
00153 /*            0  if no error. */
00154 /*            1  if CLARND returned a bad random number (installation */
00155 /*               problem) */
00156 /*           -1  if SIDE is not L, R, C, or T. */
00157 /*           -3  if M is negative. */
00158 /*           -4  if N is negative or if SIDE is C or T and N is not equal */
00159 /*               to M. */
00160 /*           -6  if LDA is less than M. */
00161 
00162 /*  ===================================================================== */
00163 
00164 /*     .. Parameters .. */
00165 /*     .. */
00166 /*     .. Local Scalars .. */
00167 /*     .. */
00168 /*     .. External Functions .. */
00169 /*     .. */
00170 /*     .. External Subroutines .. */
00171 /*     .. */
00172 /*     .. Intrinsic Functions .. */
00173 /*     .. */
00174 /*     .. Executable Statements .. */
00175 
00176     /* Parameter adjustments */
00177     a_dim1 = *lda;
00178     a_offset = 1 + a_dim1;
00179     a -= a_offset;
00180     --iseed;
00181     --x;
00182 
00183     /* Function Body */
00184     if (*n == 0 || *m == 0) {
00185         return 0;
00186     }
00187 
00188     itype = 0;
00189     if (lsame_(side, "L")) {
00190         itype = 1;
00191     } else if (lsame_(side, "R")) {
00192         itype = 2;
00193     } else if (lsame_(side, "C")) {
00194         itype = 3;
00195     } else if (lsame_(side, "T")) {
00196         itype = 4;
00197     }
00198 
00199 /*     Check for argument errors. */
00200 
00201     *info = 0;
00202     if (itype == 0) {
00203         *info = -1;
00204     } else if (*m < 0) {
00205         *info = -3;
00206     } else if (*n < 0 || itype == 3 && *n != *m) {
00207         *info = -4;
00208     } else if (*lda < *m) {
00209         *info = -6;
00210     }
00211     if (*info != 0) {
00212         i__1 = -(*info);
00213         xerbla_("CLAROR", &i__1);
00214         return 0;
00215     }
00216 
00217     if (itype == 1) {
00218         nxfrm = *m;
00219     } else {
00220         nxfrm = *n;
00221     }
00222 
00223 /*     Initialize A to the identity matrix if desired */
00224 
00225     if (lsame_(init, "I")) {
00226         claset_("Full", m, n, &c_b1, &c_b2, &a[a_offset], lda);
00227     }
00228 
00229 /*     If no rotation possible, still multiply by */
00230 /*     a random complex number from the circle |x| = 1 */
00231 
00232 /*      2)      Compute Rotation by computing Householder */
00233 /*              Transformations H(2), H(3), ..., H(n).  Note that the */
00234 /*              order in which they are computed is irrelevant. */
00235 
00236     i__1 = nxfrm;
00237     for (j = 1; j <= i__1; ++j) {
00238         i__2 = j;
00239         x[i__2].r = 0.f, x[i__2].i = 0.f;
00240 /* L40: */
00241     }
00242 
00243     i__1 = nxfrm;
00244     for (ixfrm = 2; ixfrm <= i__1; ++ixfrm) {
00245         kbeg = nxfrm - ixfrm + 1;
00246 
00247 /*        Generate independent normal( 0, 1 ) random numbers */
00248 
00249         i__2 = nxfrm;
00250         for (j = kbeg; j <= i__2; ++j) {
00251             i__3 = j;
00252             clarnd_(&q__1, &c__3, &iseed[1]);
00253             x[i__3].r = q__1.r, x[i__3].i = q__1.i;
00254 /* L50: */
00255         }
00256 
00257 /*        Generate a Householder transformation from the random vector X */
00258 
00259         xnorm = scnrm2_(&ixfrm, &x[kbeg], &c__1);
00260         xabs = c_abs(&x[kbeg]);
00261         if (xabs != 0.f) {
00262             i__2 = kbeg;
00263             q__1.r = x[i__2].r / xabs, q__1.i = x[i__2].i / xabs;
00264             csign.r = q__1.r, csign.i = q__1.i;
00265         } else {
00266             csign.r = 1.f, csign.i = 0.f;
00267         }
00268         q__1.r = xnorm * csign.r, q__1.i = xnorm * csign.i;
00269         xnorms.r = q__1.r, xnorms.i = q__1.i;
00270         i__2 = nxfrm + kbeg;
00271         q__1.r = -csign.r, q__1.i = -csign.i;
00272         x[i__2].r = q__1.r, x[i__2].i = q__1.i;
00273         factor = xnorm * (xnorm + xabs);
00274         if (dabs(factor) < 1e-20f) {
00275             *info = 1;
00276             i__2 = -(*info);
00277             xerbla_("CLAROR", &i__2);
00278             return 0;
00279         } else {
00280             factor = 1.f / factor;
00281         }
00282         i__2 = kbeg;
00283         i__3 = kbeg;
00284         q__1.r = x[i__3].r + xnorms.r, q__1.i = x[i__3].i + xnorms.i;
00285         x[i__2].r = q__1.r, x[i__2].i = q__1.i;
00286 
00287 /*        Apply Householder transformation to A */
00288 
00289         if (itype == 1 || itype == 3 || itype == 4) {
00290 
00291 /*           Apply H(k) on the left of A */
00292 
00293             cgemv_("C", &ixfrm, n, &c_b2, &a[kbeg + a_dim1], lda, &x[kbeg], &
00294                     c__1, &c_b1, &x[(nxfrm << 1) + 1], &c__1);
00295             q__2.r = factor, q__2.i = 0.f;
00296             q__1.r = -q__2.r, q__1.i = -q__2.i;
00297             cgerc_(&ixfrm, n, &q__1, &x[kbeg], &c__1, &x[(nxfrm << 1) + 1], &
00298                     c__1, &a[kbeg + a_dim1], lda);
00299 
00300         }
00301 
00302         if (itype >= 2 && itype <= 4) {
00303 
00304 /*           Apply H(k)* (or H(k)') on the right of A */
00305 
00306             if (itype == 4) {
00307                 clacgv_(&ixfrm, &x[kbeg], &c__1);
00308             }
00309 
00310             cgemv_("N", m, &ixfrm, &c_b2, &a[kbeg * a_dim1 + 1], lda, &x[kbeg]
00311 , &c__1, &c_b1, &x[(nxfrm << 1) + 1], &c__1);
00312             q__2.r = factor, q__2.i = 0.f;
00313             q__1.r = -q__2.r, q__1.i = -q__2.i;
00314             cgerc_(m, &ixfrm, &q__1, &x[(nxfrm << 1) + 1], &c__1, &x[kbeg], &
00315                     c__1, &a[kbeg * a_dim1 + 1], lda);
00316 
00317         }
00318 /* L60: */
00319     }
00320 
00321     clarnd_(&q__1, &c__3, &iseed[1]);
00322     x[1].r = q__1.r, x[1].i = q__1.i;
00323     xabs = c_abs(&x[1]);
00324     if (xabs != 0.f) {
00325         q__1.r = x[1].r / xabs, q__1.i = x[1].i / xabs;
00326         csign.r = q__1.r, csign.i = q__1.i;
00327     } else {
00328         csign.r = 1.f, csign.i = 0.f;
00329     }
00330     i__1 = nxfrm << 1;
00331     x[i__1].r = csign.r, x[i__1].i = csign.i;
00332 
00333 /*     Scale the matrix A by D. */
00334 
00335     if (itype == 1 || itype == 3 || itype == 4) {
00336         i__1 = *m;
00337         for (irow = 1; irow <= i__1; ++irow) {
00338             r_cnjg(&q__1, &x[nxfrm + irow]);
00339             cscal_(n, &q__1, &a[irow + a_dim1], lda);
00340 /* L70: */
00341         }
00342     }
00343 
00344     if (itype == 2 || itype == 3) {
00345         i__1 = *n;
00346         for (jcol = 1; jcol <= i__1; ++jcol) {
00347             cscal_(m, &x[nxfrm + jcol], &a[jcol * a_dim1 + 1], &c__1);
00348 /* L80: */
00349         }
00350     }
00351 
00352     if (itype == 4) {
00353         i__1 = *n;
00354         for (jcol = 1; jcol <= i__1; ++jcol) {
00355             r_cnjg(&q__1, &x[nxfrm + jcol]);
00356             cscal_(m, &q__1, &a[jcol * a_dim1 + 1], &c__1);
00357 /* L90: */
00358         }
00359     }
00360     return 0;
00361 
00362 /*     End of CLAROR */
00363 
00364 } /* claror_ */


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