PLASMA  2.4.5
PLASMA - Parallel Linear Algebra for Scalable Multi-core Architectures
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
zlaror.f
Go to the documentation of this file.
1  SUBROUTINE zlaror( SIDE, INIT, M, N, A, LDA, ISEED, X, INFO )
2 *
3 * -- LAPACK auxiliary test routine (version 3.1) --
4 * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
5 * November 2006
6 *
7 * .. Scalar Arguments ..
8  CHARACTER init, side
9  INTEGER info, lda, m, n
10 * ..
11 * .. Array Arguments ..
12  INTEGER iseed( 4 )
13  COMPLEX*16 a( lda, * ), x( * )
14 * ..
15 *
16 * Purpose
17 * =======
18 *
19 * ZLAROR pre- or post-multiplies an M by N matrix A by a random
20 * unitary matrix U, overwriting A. A may optionally be
21 * initialized to the identity matrix before multiplying by U.
22 * U is generated using the method of G.W. Stewart
23 * ( SIAM J. Numer. Anal. 17, 1980, pp. 403-409 ).
24 * (BLAS-2 version)
25 *
26 * Arguments
27 * =========
28 *
29 * SIDE - CHARACTER*1
30 * SIDE specifies whether A is multiplied on the left or right
31 * by U.
32 * SIDE = 'L' Multiply A on the left (premultiply) by U
33 * SIDE = 'R' Multiply A on the right (postmultiply) by U*
34 * SIDE = 'C' Multiply A on the left by U and the right by U*
35 * SIDE = 'T' Multiply A on the left by U and the right by U'
36 * Not modified.
37 *
38 * INIT - CHARACTER*1
39 * INIT specifies whether or not A should be initialized to
40 * the identity matrix.
41 * INIT = 'I' Initialize A to (a section of) the
42 * identity matrix before applying U.
43 * INIT = 'N' No initialization. Apply U to the
44 * input matrix A.
45 *
46 * INIT = 'I' may be used to generate square (i.e., unitary)
47 * or rectangular orthogonal matrices (orthogonality being
48 * in the sense of ZDOTC):
49 *
50 * For square matrices, M=N, and SIDE many be either 'L' or
51 * 'R'; the rows will be orthogonal to each other, as will the
52 * columns.
53 * For rectangular matrices where M < N, SIDE = 'R' will
54 * produce a dense matrix whose rows will be orthogonal and
55 * whose columns will not, while SIDE = 'L' will produce a
56 * matrix whose rows will be orthogonal, and whose first M
57 * columns will be orthogonal, the remaining columns being
58 * zero.
59 * For matrices where M > N, just use the previous
60 * explaination, interchanging 'L' and 'R' and "rows" and
61 * "columns".
62 *
63 * Not modified.
64 *
65 * M - INTEGER
66 * Number of rows of A. Not modified.
67 *
68 * N - INTEGER
69 * Number of columns of A. Not modified.
70 *
71 * A - COMPLEX*16 array, dimension ( LDA, N )
72 * Input and output array. Overwritten by U A ( if SIDE = 'L' )
73 * or by A U ( if SIDE = 'R' )
74 * or by U A U* ( if SIDE = 'C')
75 * or by U A U' ( if SIDE = 'T') on exit.
76 *
77 * LDA - INTEGER
78 * Leading dimension of A. Must be at least MAX ( 1, M ).
79 * Not modified.
80 *
81 * ISEED - INTEGER array, dimension ( 4 )
82 * On entry ISEED specifies the seed of the random number
83 * generator. The array elements should be between 0 and 4095;
84 * if not they will be reduced mod 4096. Also, ISEED(4) must
85 * be odd. The random number generator uses a linear
86 * congruential sequence limited to small integers, and so
87 * should produce machine independent random numbers. The
88 * values of ISEED are changed on exit, and can be used in the
89 * next call to ZLAROR to continue the same random number
90 * sequence.
91 * Modified.
92 *
93 * X - COMPLEX*16 array, dimension ( 3*MAX( M, N ) )
94 * Workspace. Of length:
95 * 2*M + N if SIDE = 'L',
96 * 2*N + M if SIDE = 'R',
97 * 3*N if SIDE = 'C' or 'T'.
98 * Modified.
99 *
100 * INFO - INTEGER
101 * An error flag. It is set to:
102 * 0 if no error.
103 * 1 if ZLARND returned a bad random number (installation
104 * problem)
105 * -1 if SIDE is not L, R, C, or T.
106 * -3 if M is negative.
107 * -4 if N is negative or if SIDE is C or T and N is not equal
108 * to M.
109 * -6 if LDA is less than M.
110 *
111 * =====================================================================
112 *
113 * .. Parameters ..
114  DOUBLE PRECISION zero, one, toosml
115  parameter( zero = 0.0d+0, one = 1.0d+0,
116  $ toosml = 1.0d-20 )
117  COMPLEX*16 czero, cone
118  parameter( czero = ( 0.0d+0, 0.0d+0 ),
119  $ cone = ( 1.0d+0, 0.0d+0 ) )
120 * ..
121 * .. Local Scalars ..
122  INTEGER irow, itype, ixfrm, j, jcol, kbeg, nxfrm
123  DOUBLE PRECISION factor, xabs, xnorm
124  COMPLEX*16 csign, xnorms
125 * ..
126 * .. External Functions ..
127  LOGICAL lsame
128  DOUBLE PRECISION dznrm2
129  COMPLEX*16 zlarnd
130  EXTERNAL lsame, dznrm2, zlarnd
131 * ..
132 * .. External Subroutines ..
133  EXTERNAL xerbla, zgemv, zgerc, zlacgv, zlaset, zscal
134 * ..
135 * .. Intrinsic Functions ..
136  INTRINSIC abs, dcmplx, dconjg
137 * ..
138 * .. Executable Statements ..
139 *
140  IF( n.EQ.0 .OR. m.EQ.0 )
141  $ return
142 *
143  itype = 0
144  IF( lsame( side, 'L' ) ) THEN
145  itype = 1
146  ELSE IF( lsame( side, 'R' ) ) THEN
147  itype = 2
148  ELSE IF( lsame( side, 'C' ) ) THEN
149  itype = 3
150  ELSE IF( lsame( side, 'T' ) ) THEN
151  itype = 4
152  END IF
153 *
154 * Check for argument errors.
155 *
156  info = 0
157  IF( itype.EQ.0 ) THEN
158  info = -1
159  ELSE IF( m.LT.0 ) THEN
160  info = -3
161  ELSE IF( n.LT.0 .OR. ( itype.EQ.3 .AND. n.NE.m ) ) THEN
162  info = -4
163  ELSE IF( lda.LT.m ) THEN
164  info = -6
165  END IF
166  IF( info.NE.0 ) THEN
167  CALL xerbla( 'ZLAROR', -info )
168  return
169  END IF
170 *
171  IF( itype.EQ.1 ) THEN
172  nxfrm = m
173  ELSE
174  nxfrm = n
175  END IF
176 *
177 * Initialize A to the identity matrix if desired
178 *
179  IF( lsame( init, 'I' ) )
180  $ CALL zlaset( 'Full', m, n, czero, cone, a, lda )
181 *
182 * If no rotation possible, still multiply by
183 * a random complex number from the circle |x| = 1
184 *
185 * 2) Compute Rotation by computing Householder
186 * Transformations H(2), H(3), ..., H(n). Note that the
187 * order in which they are computed is irrelevant.
188 *
189  DO 10 j = 1, nxfrm
190  x( j ) = czero
191  10 continue
192 *
193  DO 30 ixfrm = 2, nxfrm
194  kbeg = nxfrm - ixfrm + 1
195 *
196 * Generate independent normal( 0, 1 ) random numbers
197 *
198  DO 20 j = kbeg, nxfrm
199  x( j ) = zlarnd( 3, iseed )
200  20 continue
201 *
202 * Generate a Householder transformation from the random vector X
203 *
204  xnorm = dznrm2( ixfrm, x( kbeg ), 1 )
205  xabs = abs( x( kbeg ) )
206  IF( xabs.NE.czero ) THEN
207  csign = x( kbeg ) / xabs
208  ELSE
209  csign = cone
210  END IF
211  xnorms = csign*xnorm
212  x( nxfrm+kbeg ) = -csign
213  factor = xnorm*( xnorm+xabs )
214  IF( abs( factor ).LT.toosml ) THEN
215  info = 1
216  CALL xerbla( 'ZLAROR', -info )
217  return
218  ELSE
219  factor = one / factor
220  END IF
221  x( kbeg ) = x( kbeg ) + xnorms
222 *
223 * Apply Householder transformation to A
224 *
225  IF( itype.EQ.1 .OR. itype.EQ.3 .OR. itype.EQ.4 ) THEN
226 *
227 * Apply H(k) on the left of A
228 *
229  CALL zgemv( 'C', ixfrm, n, cone, a( kbeg, 1 ), lda,
230  $ x( kbeg ), 1, czero, x( 2*nxfrm+1 ), 1 )
231  CALL zgerc( ixfrm, n, -dcmplx( factor ), x( kbeg ), 1,
232  $ x( 2*nxfrm+1 ), 1, a( kbeg, 1 ), lda )
233 *
234  END IF
235 *
236  IF( itype.GE.2 .AND. itype.LE.4 ) THEN
237 *
238 * Apply H(k)* (or H(k)') on the right of A
239 *
240  IF( itype.EQ.4 ) THEN
241  CALL zlacgv( ixfrm, x( kbeg ), 1 )
242  END IF
243 *
244  CALL zgemv( 'N', m, ixfrm, cone, a( 1, kbeg ), lda,
245  $ x( kbeg ), 1, czero, x( 2*nxfrm+1 ), 1 )
246  CALL zgerc( m, ixfrm, -dcmplx( factor ), x( 2*nxfrm+1 ), 1,
247  $ x( kbeg ), 1, a( 1, kbeg ), lda )
248 *
249  END IF
250  30 continue
251 *
252  x( 1 ) = zlarnd( 3, iseed )
253  xabs = abs( x( 1 ) )
254  IF( xabs.NE.zero ) THEN
255  csign = x( 1 ) / xabs
256  ELSE
257  csign = cone
258  END IF
259  x( 2*nxfrm ) = csign
260 *
261 * Scale the matrix A by D.
262 *
263  IF( itype.EQ.1 .OR. itype.EQ.3 .OR. itype.EQ.4 ) THEN
264  DO 40 irow = 1, m
265  CALL zscal( n, dconjg( x( nxfrm+irow ) ), a( irow, 1 ),
266  $ lda )
267  40 continue
268  END IF
269 *
270  IF( itype.EQ.2 .OR. itype.EQ.3 ) THEN
271  DO 50 jcol = 1, n
272  CALL zscal( m, x( nxfrm+jcol ), a( 1, jcol ), 1 )
273  50 continue
274  END IF
275 *
276  IF( itype.EQ.4 ) THEN
277  DO 60 jcol = 1, n
278  CALL zscal( m, dconjg( x( nxfrm+jcol ) ), a( 1, jcol ), 1 )
279  60 continue
280  END IF
281  return
282 *
283 * End of ZLAROR
284 *
285  END