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


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