|
kusano |
7d535a |
/* -- translated by f2c (version 19940927).
|
|
kusano |
7d535a |
You must link the resulting object file with the libraries:
|
|
kusano |
7d535a |
-lf2c -lm (in that order)
|
|
kusano |
7d535a |
*/
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
#include "f2c.h"
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Table of constant values */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
static complex c_b1 = {0.f,0.f};
|
|
kusano |
7d535a |
static complex c_b2 = {1.f,0.f};
|
|
kusano |
7d535a |
static integer c__3 = 3;
|
|
kusano |
7d535a |
static integer c__1 = 1;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Subroutine */ int claror_(char *side, char *init, integer *m, integer *n,
|
|
kusano |
7d535a |
complex *a, integer *lda, integer *iseed, complex *x, integer *info)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
/* System generated locals */
|
|
kusano |
7d535a |
integer a_dim1, a_offset, i__1, i__2, i__3;
|
|
kusano |
7d535a |
complex q__1, q__2;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Builtin functions */
|
|
kusano |
7d535a |
double c_abs(complex *);
|
|
kusano |
7d535a |
void r_cnjg(complex *, complex *);
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Local variables */
|
|
kusano |
7d535a |
static integer kbeg, jcol;
|
|
kusano |
7d535a |
static real xabs;
|
|
kusano |
7d535a |
static integer irow, j;
|
|
kusano |
7d535a |
extern /* Subroutine */ int cgerc_(integer *, integer *, complex *,
|
|
kusano |
7d535a |
complex *, integer *, complex *, integer *, complex *, integer *),
|
|
kusano |
7d535a |
cscal_(integer *, complex *, complex *, integer *);
|
|
kusano |
7d535a |
extern logical lsame_(char *, char *);
|
|
kusano |
7d535a |
extern /* Subroutine */ int cgemv_(char *, integer *, integer *, complex *
|
|
kusano |
7d535a |
, complex *, integer *, complex *, integer *, complex *, complex *
|
|
kusano |
7d535a |
, integer *);
|
|
kusano |
7d535a |
static complex csign;
|
|
kusano |
7d535a |
static integer ixfrm, itype, nxfrm;
|
|
kusano |
7d535a |
static real xnorm;
|
|
kusano |
7d535a |
extern real scnrm2_(integer *, complex *, integer *);
|
|
kusano |
7d535a |
extern /* Subroutine */ int clacgv_(integer *, complex *, integer *);
|
|
kusano |
7d535a |
extern /* Complex */ VOID clarnd_(complex *, integer *, integer *);
|
|
kusano |
7d535a |
extern /* Subroutine */ int claset_(char *, integer *, integer *, complex
|
|
kusano |
7d535a |
*, complex *, complex *, integer *), xerbla_(char *,
|
|
kusano |
7d535a |
integer *);
|
|
kusano |
7d535a |
static real factor;
|
|
kusano |
7d535a |
static complex xnorms;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* -- LAPACK auxiliary test routine (version 2.0) --
|
|
kusano |
7d535a |
Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
|
|
kusano |
7d535a |
Courant Institute, Argonne National Lab, and Rice University
|
|
kusano |
7d535a |
September 30, 1994
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
Purpose
|
|
kusano |
7d535a |
=======
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
CLAROR pre- or post-multiplies an M by N matrix A by a random
|
|
kusano |
7d535a |
unitary matrix U, overwriting A. A may optionally be
|
|
kusano |
7d535a |
initialized to the identity matrix before multiplying by U.
|
|
kusano |
7d535a |
U is generated using the method of G.W. Stewart
|
|
kusano |
7d535a |
( SIAM J. Numer. Anal. 17, 1980, pp. 403-409 ).
|
|
kusano |
7d535a |
(BLAS-2 version)
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
Arguments
|
|
kusano |
7d535a |
=========
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
SIDE - CHARACTER*1
|
|
kusano |
7d535a |
SIDE specifies whether A is multiplied on the left or right
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
by U.
|
|
kusano |
7d535a |
SIDE = 'L' Multiply A on the left (premultiply) by U
|
|
kusano |
7d535a |
SIDE = 'R' Multiply A on the right (postmultiply) by U*
|
|
kusano |
7d535a |
SIDE = 'C' Multiply A on the left by U and the right by U*
|
|
kusano |
7d535a |
SIDE = 'T' Multiply A on the left by U and the right by U'
|
|
kusano |
7d535a |
Not modified.
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
INIT - CHARACTER*1
|
|
kusano |
7d535a |
INIT specifies whether or not A should be initialized to
|
|
kusano |
7d535a |
the identity matrix.
|
|
kusano |
7d535a |
INIT = 'I' Initialize A to (a section of) the
|
|
kusano |
7d535a |
identity matrix before applying U.
|
|
kusano |
7d535a |
INIT = 'N' No initialization. Apply U to the
|
|
kusano |
7d535a |
input matrix A.
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
INIT = 'I' may be used to generate square (i.e., unitary)
|
|
kusano |
7d535a |
or rectangular orthogonal matrices (orthogonality being
|
|
kusano |
7d535a |
in the sense of CDOTC):
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
For square matrices, M=N, and SIDE many be either 'L' or
|
|
kusano |
7d535a |
'R'; the rows will be orthogonal to each other, as will the
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
columns.
|
|
kusano |
7d535a |
For rectangular matrices where M < N, SIDE = 'R' will
|
|
kusano |
7d535a |
produce a dense matrix whose rows will be orthogonal and
|
|
kusano |
7d535a |
whose columns will not, while SIDE = 'L' will produce a
|
|
kusano |
7d535a |
matrix whose rows will be orthogonal, and whose first M
|
|
kusano |
7d535a |
columns will be orthogonal, the remaining columns being
|
|
kusano |
7d535a |
zero.
|
|
kusano |
7d535a |
For matrices where M > N, just use the previous
|
|
kusano |
7d535a |
explaination, interchanging 'L' and 'R' and "rows" and
|
|
kusano |
7d535a |
"columns".
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
Not modified.
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
M - INTEGER
|
|
kusano |
7d535a |
Number of rows of A. Not modified.
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
N - INTEGER
|
|
kusano |
7d535a |
Number of columns of A. Not modified.
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
A - COMPLEX array, dimension ( LDA, N )
|
|
kusano |
7d535a |
Input and output array. Overwritten by U A ( if SIDE = 'L' )
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
or by A U ( if SIDE = 'R' )
|
|
kusano |
7d535a |
or by U A U* ( if SIDE = 'C')
|
|
kusano |
7d535a |
or by U A U' ( if SIDE = 'T') on exit.
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
LDA - INTEGER
|
|
kusano |
7d535a |
Leading dimension of A. Must be at least MAX ( 1, M ).
|
|
kusano |
7d535a |
Not modified.
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
ISEED - INTEGER array, dimension ( 4 )
|
|
kusano |
7d535a |
On entry ISEED specifies the seed of the random number
|
|
kusano |
7d535a |
generator. The array elements should be between 0 and 4095;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
if not they will be reduced mod 4096. Also, ISEED(4) must
|
|
kusano |
7d535a |
be odd. The random number generator uses a linear
|
|
kusano |
7d535a |
congruential sequence limited to small integers, and so
|
|
kusano |
7d535a |
should produce machine independent random numbers. The
|
|
kusano |
7d535a |
values of ISEED are changed on exit, and can be used in the
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
next call to CLAROR to continue the same random number
|
|
kusano |
7d535a |
sequence.
|
|
kusano |
7d535a |
Modified.
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
X - COMPLEX array, dimension ( 3*MAX( M, N ) )
|
|
kusano |
7d535a |
Workspace. Of length:
|
|
kusano |
7d535a |
2*M + N if SIDE = 'L',
|
|
kusano |
7d535a |
2*N + M if SIDE = 'R',
|
|
kusano |
7d535a |
3*N if SIDE = 'C' or 'T'.
|
|
kusano |
7d535a |
Modified.
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
INFO - INTEGER
|
|
kusano |
7d535a |
An error flag. It is set to:
|
|
kusano |
7d535a |
0 if no error.
|
|
kusano |
7d535a |
1 if CLARND returned a bad random number (installation
|
|
kusano |
7d535a |
problem)
|
|
kusano |
7d535a |
-1 if SIDE is not L, R, C, or T.
|
|
kusano |
7d535a |
-3 if M is negative.
|
|
kusano |
7d535a |
-4 if N is negative or if SIDE is C or T and N is not equal
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
to M.
|
|
kusano |
7d535a |
-6 if LDA is less than M.
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
=====================================================================
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
Parameter adjustments */
|
|
kusano |
7d535a |
a_dim1 = *lda;
|
|
kusano |
7d535a |
a_offset = a_dim1 + 1;
|
|
kusano |
7d535a |
a -= a_offset;
|
|
kusano |
7d535a |
--iseed;
|
|
kusano |
7d535a |
--x;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Function Body */
|
|
kusano |
7d535a |
if (*n == 0 || *m == 0) {
|
|
kusano |
7d535a |
return 0;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
itype = 0;
|
|
kusano |
7d535a |
if (lsame_(side, "L")) {
|
|
kusano |
7d535a |
itype = 1;
|
|
kusano |
7d535a |
} else if (lsame_(side, "R")) {
|
|
kusano |
7d535a |
itype = 2;
|
|
kusano |
7d535a |
} else if (lsame_(side, "C")) {
|
|
kusano |
7d535a |
itype = 3;
|
|
kusano |
7d535a |
} else if (lsame_(side, "T")) {
|
|
kusano |
7d535a |
itype = 4;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Check for argument errors. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
*info = 0;
|
|
kusano |
7d535a |
if (itype == 0) {
|
|
kusano |
7d535a |
*info = -1;
|
|
kusano |
7d535a |
} else if (*m < 0) {
|
|
kusano |
7d535a |
*info = -3;
|
|
kusano |
7d535a |
} else if (*n < 0 || itype == 3 && *n != *m) {
|
|
kusano |
7d535a |
*info = -4;
|
|
kusano |
7d535a |
} else if (*lda < *m) {
|
|
kusano |
7d535a |
*info = -6;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (*info != 0) {
|
|
kusano |
7d535a |
i__1 = -(*info);
|
|
kusano |
7d535a |
xerbla_("CLAROR", &i__1);
|
|
kusano |
7d535a |
return 0;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
if (itype == 1) {
|
|
kusano |
7d535a |
nxfrm = *m;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
nxfrm = *n;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Initialize A to the identity matrix if desired */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
if (lsame_(init, "I")) {
|
|
kusano |
7d535a |
claset_("Full", m, n, &c_b1, &c_b2, &a[a_offset], lda);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* If no rotation possible, still multiply by
|
|
kusano |
7d535a |
a random complex number from the circle |x| = 1
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
2) Compute Rotation by computing Householder
|
|
kusano |
7d535a |
Transformations H(2), H(3), ..., H(n). Note that the
|
|
kusano |
7d535a |
order in which they are computed is irrelevant. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
i__1 = nxfrm;
|
|
kusano |
7d535a |
for (j = 1; j <= i__1; ++j) {
|
|
kusano |
7d535a |
i__2 = j;
|
|
kusano |
7d535a |
x[i__2].r = 0.f, x[i__2].i = 0.f;
|
|
kusano |
7d535a |
/* L40: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
i__1 = nxfrm;
|
|
kusano |
7d535a |
for (ixfrm = 2; ixfrm <= i__1; ++ixfrm) {
|
|
kusano |
7d535a |
kbeg = nxfrm - ixfrm + 1;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Generate independent normal( 0, 1 ) random numbers */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
i__2 = nxfrm;
|
|
kusano |
7d535a |
for (j = kbeg; j <= i__2; ++j) {
|
|
kusano |
7d535a |
i__3 = j;
|
|
kusano |
7d535a |
clarnd_(&q__1, &c__3, &iseed[1]);
|
|
kusano |
7d535a |
x[i__3].r = q__1.r, x[i__3].i = q__1.i;
|
|
kusano |
7d535a |
/* L50: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Generate a Householder transformation from the random vector
|
|
kusano |
7d535a |
X */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
xnorm = scnrm2_(&ixfrm, &x[kbeg], &c__1);
|
|
kusano |
7d535a |
xabs = c_abs(&x[kbeg]);
|
|
kusano |
7d535a |
if (xabs != 0.f) {
|
|
kusano |
7d535a |
i__2 = kbeg;
|
|
kusano |
7d535a |
q__1.r = x[i__2].r / xabs, q__1.i = x[i__2].i / xabs;
|
|
kusano |
7d535a |
csign.r = q__1.r, csign.i = q__1.i;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
csign.r = 1.f, csign.i = 0.f;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
q__1.r = xnorm * csign.r, q__1.i = xnorm * csign.i;
|
|
kusano |
7d535a |
xnorms.r = q__1.r, xnorms.i = q__1.i;
|
|
kusano |
7d535a |
i__2 = nxfrm + kbeg;
|
|
kusano |
7d535a |
q__1.r = -(doublereal)csign.r, q__1.i = -(doublereal)csign.i;
|
|
kusano |
7d535a |
x[i__2].r = q__1.r, x[i__2].i = q__1.i;
|
|
kusano |
7d535a |
factor = xnorm * (xnorm + xabs);
|
|
kusano |
7d535a |
if (dabs(factor) < 1e-20f) {
|
|
kusano |
7d535a |
*info = 1;
|
|
kusano |
7d535a |
i__2 = -(*info);
|
|
kusano |
7d535a |
xerbla_("CLAROR", &i__2);
|
|
kusano |
7d535a |
return 0;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
factor = 1.f / factor;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
i__2 = kbeg;
|
|
kusano |
7d535a |
i__3 = kbeg;
|
|
kusano |
7d535a |
q__1.r = x[i__3].r + xnorms.r, q__1.i = x[i__3].i + xnorms.i;
|
|
kusano |
7d535a |
x[i__2].r = q__1.r, x[i__2].i = q__1.i;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Apply Householder transformation to A */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
if (itype == 1 || itype == 3 || itype == 4) {
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Apply H(k) on the left of A */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
cgemv_("C", &ixfrm, n, &c_b2, &a[kbeg + a_dim1], lda, &x[kbeg], &
|
|
kusano |
7d535a |
c__1, &c_b1, &x[(nxfrm << 1) + 1], &c__1);
|
|
kusano |
7d535a |
q__2.r = factor, q__2.i = 0.f;
|
|
kusano |
7d535a |
q__1.r = -(doublereal)q__2.r, q__1.i = -(doublereal)q__2.i;
|
|
kusano |
7d535a |
cgerc_(&ixfrm, n, &q__1, &x[kbeg], &c__1, &x[(nxfrm << 1) + 1], &
|
|
kusano |
7d535a |
c__1, &a[kbeg + a_dim1], lda);
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
if (itype >= 2 && itype <= 4) {
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Apply H(k)* (or H(k)') on the right of A */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
if (itype == 4) {
|
|
kusano |
7d535a |
clacgv_(&ixfrm, &x[kbeg], &c__1);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
cgemv_("N", m, &ixfrm, &c_b2, &a[kbeg * a_dim1 + 1], lda, &x[kbeg]
|
|
kusano |
7d535a |
, &c__1, &c_b1, &x[(nxfrm << 1) + 1], &c__1);
|
|
kusano |
7d535a |
q__2.r = factor, q__2.i = 0.f;
|
|
kusano |
7d535a |
q__1.r = -(doublereal)q__2.r, q__1.i = -(doublereal)q__2.i;
|
|
kusano |
7d535a |
cgerc_(m, &ixfrm, &q__1, &x[(nxfrm << 1) + 1], &c__1, &x[kbeg], &
|
|
kusano |
7d535a |
c__1, &a[kbeg * a_dim1 + 1], lda);
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L60: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
clarnd_(&q__1, &c__3, &iseed[1]);
|
|
kusano |
7d535a |
x[1].r = q__1.r, x[1].i = q__1.i;
|
|
kusano |
7d535a |
xabs = c_abs(&x[1]);
|
|
kusano |
7d535a |
if (xabs != 0.f) {
|
|
kusano |
7d535a |
q__1.r = x[1].r / xabs, q__1.i = x[1].i / xabs;
|
|
kusano |
7d535a |
csign.r = q__1.r, csign.i = q__1.i;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
csign.r = 1.f, csign.i = 0.f;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
i__1 = nxfrm << 1;
|
|
kusano |
7d535a |
x[i__1].r = csign.r, x[i__1].i = csign.i;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Scale the matrix A by D. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
if (itype == 1 || itype == 3 || itype == 4) {
|
|
kusano |
7d535a |
i__1 = *m;
|
|
kusano |
7d535a |
for (irow = 1; irow <= i__1; ++irow) {
|
|
kusano |
7d535a |
r_cnjg(&q__1, &x[nxfrm + irow]);
|
|
kusano |
7d535a |
cscal_(n, &q__1, &a[irow + a_dim1], lda);
|
|
kusano |
7d535a |
/* L70: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
if (itype == 2 || itype == 3) {
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (jcol = 1; jcol <= i__1; ++jcol) {
|
|
kusano |
7d535a |
cscal_(m, &x[nxfrm + jcol], &a[jcol * a_dim1 + 1], &c__1);
|
|
kusano |
7d535a |
/* L80: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
if (itype == 4) {
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (jcol = 1; jcol <= i__1; ++jcol) {
|
|
kusano |
7d535a |
r_cnjg(&q__1, &x[nxfrm + jcol]);
|
|
kusano |
7d535a |
cscal_(m, &q__1, &a[jcol * a_dim1 + 1], &c__1);
|
|
kusano |
7d535a |
/* L90: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
return 0;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* End of CLAROR */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
} /* claror_ */
|
|
kusano |
7d535a |
|