LAPACK  3.10.0
LAPACK: Linear Algebra PACKage
zlaror.f
Go to the documentation of this file.
1 *> \brief \b ZLAROR
2 *
3 * =========== DOCUMENTATION ===========
4 *
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
7 *
8 * Definition:
9 * ===========
10 *
11 * SUBROUTINE ZLAROR( SIDE, INIT, M, N, A, LDA, ISEED, X, INFO )
12 *
13 * .. Scalar Arguments ..
14 * CHARACTER INIT, SIDE
15 * INTEGER INFO, LDA, M, N
16 * ..
17 * .. Array Arguments ..
18 * INTEGER ISEED( 4 )
19 * COMPLEX*16 A( LDA, * ), X( * )
20 * ..
21 *
22 *
23 *> \par Purpose:
24 * =============
25 *>
26 *> \verbatim
27 *>
28 *> ZLAROR pre- or post-multiplies an M by N matrix A by a random
29 *> unitary matrix U, overwriting A. A may optionally be
30 *> initialized to the identity matrix before multiplying by U.
31 *> U is generated using the method of G.W. Stewart
32 *> ( SIAM J. Numer. Anal. 17, 1980, pp. 403-409 ).
33 *> (BLAS-2 version)
34 *> \endverbatim
35 *
36 * Arguments:
37 * ==========
38 *
39 *> \param[in] SIDE
40 *> \verbatim
41 *> SIDE is CHARACTER*1
42 *> SIDE specifies whether A is multiplied on the left or right
43 *> by U.
44 *> SIDE = 'L' Multiply A on the left (premultiply) by U
45 *> SIDE = 'R' Multiply A on the right (postmultiply) by UC> SIDE = 'C' Multiply A on the left by U and the right by UC> SIDE = 'T' Multiply A on the left by U and the right by U'
46 *> Not modified.
47 *> \endverbatim
48 *>
49 *> \param[in] INIT
50 *> \verbatim
51 *> INIT is CHARACTER*1
52 *> INIT specifies whether or not A should be initialized to
53 *> the identity matrix.
54 *> INIT = 'I' Initialize A to (a section of) the
55 *> identity matrix before applying U.
56 *> INIT = 'N' No initialization. Apply U to the
57 *> input matrix A.
58 *>
59 *> INIT = 'I' may be used to generate square (i.e., unitary)
60 *> or rectangular orthogonal matrices (orthogonality being
61 *> in the sense of ZDOTC):
62 *>
63 *> For square matrices, M=N, and SIDE many be either 'L' or
64 *> 'R'; the rows will be orthogonal to each other, as will the
65 *> columns.
66 *> For rectangular matrices where M < N, SIDE = 'R' will
67 *> produce a dense matrix whose rows will be orthogonal and
68 *> whose columns will not, while SIDE = 'L' will produce a
69 *> matrix whose rows will be orthogonal, and whose first M
70 *> columns will be orthogonal, the remaining columns being
71 *> zero.
72 *> For matrices where M > N, just use the previous
73 *> explanation, interchanging 'L' and 'R' and "rows" and
74 *> "columns".
75 *>
76 *> Not modified.
77 *> \endverbatim
78 *>
79 *> \param[in] M
80 *> \verbatim
81 *> M is INTEGER
82 *> Number of rows of A. Not modified.
83 *> \endverbatim
84 *>
85 *> \param[in] N
86 *> \verbatim
87 *> N is INTEGER
88 *> Number of columns of A. Not modified.
89 *> \endverbatim
90 *>
91 *> \param[in,out] A
92 *> \verbatim
93 *> A is COMPLEX*16 array, dimension ( LDA, N )
94 *> Input and output array. Overwritten by U A ( if SIDE = 'L' )
95 *> or by A U ( if SIDE = 'R' )
96 *> or by U A U* ( if SIDE = 'C')
97 *> or by U A U' ( if SIDE = 'T') on exit.
98 *> \endverbatim
99 *>
100 *> \param[in] LDA
101 *> \verbatim
102 *> LDA is INTEGER
103 *> Leading dimension of A. Must be at least MAX ( 1, M ).
104 *> Not modified.
105 *> \endverbatim
106 *>
107 *> \param[in,out] ISEED
108 *> \verbatim
109 *> ISEED is INTEGER array, dimension ( 4 )
110 *> On entry ISEED specifies the seed of the random number
111 *> generator. The array elements should be between 0 and 4095;
112 *> if not they will be reduced mod 4096. Also, ISEED(4) must
113 *> be odd. The random number generator uses a linear
114 *> congruential sequence limited to small integers, and so
115 *> should produce machine independent random numbers. The
116 *> values of ISEED are changed on exit, and can be used in the
117 *> next call to ZLAROR to continue the same random number
118 *> sequence.
119 *> Modified.
120 *> \endverbatim
121 *>
122 *> \param[out] X
123 *> \verbatim
124 *> X is COMPLEX*16 array, dimension ( 3*MAX( M, N ) )
125 *> Workspace. Of length:
126 *> 2*M + N if SIDE = 'L',
127 *> 2*N + M if SIDE = 'R',
128 *> 3*N if SIDE = 'C' or 'T'.
129 *> Modified.
130 *> \endverbatim
131 *>
132 *> \param[out] INFO
133 *> \verbatim
134 *> INFO is INTEGER
135 *> An error flag. It is set to:
136 *> 0 if no error.
137 *> 1 if ZLARND returned a bad random number (installation
138 *> problem)
139 *> -1 if SIDE is not L, R, C, or T.
140 *> -3 if M is negative.
141 *> -4 if N is negative or if SIDE is C or T and N is not equal
142 *> to M.
143 *> -6 if LDA is less than M.
144 *> \endverbatim
145 *
146 * Authors:
147 * ========
148 *
149 *> \author Univ. of Tennessee
150 *> \author Univ. of California Berkeley
151 *> \author Univ. of Colorado Denver
152 *> \author NAG Ltd.
153 *
154 *> \ingroup complex16_matgen
155 *
156 * =====================================================================
157  SUBROUTINE zlaror( SIDE, INIT, M, N, A, LDA, ISEED, X, INFO )
158 *
159 * -- LAPACK auxiliary routine --
160 * -- LAPACK is a software package provided by Univ. of Tennessee, --
161 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
162 *
163 * .. Scalar Arguments ..
164  CHARACTER INIT, SIDE
165  INTEGER INFO, LDA, M, N
166 * ..
167 * .. Array Arguments ..
168  INTEGER ISEED( 4 )
169  COMPLEX*16 A( LDA, * ), X( * )
170 * ..
171 *
172 * =====================================================================
173 *
174 * .. Parameters ..
175  DOUBLE PRECISION ZERO, ONE, TOOSML
176  parameter( zero = 0.0d+0, one = 1.0d+0,
177  $ toosml = 1.0d-20 )
178  COMPLEX*16 CZERO, CONE
179  parameter( czero = ( 0.0d+0, 0.0d+0 ),
180  $ cone = ( 1.0d+0, 0.0d+0 ) )
181 * ..
182 * .. Local Scalars ..
183  INTEGER IROW, ITYPE, IXFRM, J, JCOL, KBEG, NXFRM
184  DOUBLE PRECISION FACTOR, XABS, XNORM
185  COMPLEX*16 CSIGN, XNORMS
186 * ..
187 * .. External Functions ..
188  LOGICAL LSAME
189  DOUBLE PRECISION DZNRM2
190  COMPLEX*16 ZLARND
191  EXTERNAL lsame, dznrm2, zlarnd
192 * ..
193 * .. External Subroutines ..
194  EXTERNAL xerbla, zgemv, zgerc, zlacgv, zlaset, zscal
195 * ..
196 * .. Intrinsic Functions ..
197  INTRINSIC abs, dcmplx, dconjg
198 * ..
199 * .. Executable Statements ..
200 *
201  info = 0
202  IF( n.EQ.0 .OR. m.EQ.0 )
203  $ RETURN
204 *
205  itype = 0
206  IF( lsame( side, 'L' ) ) THEN
207  itype = 1
208  ELSE IF( lsame( side, 'R' ) ) THEN
209  itype = 2
210  ELSE IF( lsame( side, 'C' ) ) THEN
211  itype = 3
212  ELSE IF( lsame( side, 'T' ) ) THEN
213  itype = 4
214  END IF
215 *
216 * Check for argument errors.
217 *
218  IF( itype.EQ.0 ) THEN
219  info = -1
220  ELSE IF( m.LT.0 ) THEN
221  info = -3
222  ELSE IF( n.LT.0 .OR. ( itype.EQ.3 .AND. n.NE.m ) ) THEN
223  info = -4
224  ELSE IF( lda.LT.m ) THEN
225  info = -6
226  END IF
227  IF( info.NE.0 ) THEN
228  CALL xerbla( 'ZLAROR', -info )
229  RETURN
230  END IF
231 *
232  IF( itype.EQ.1 ) THEN
233  nxfrm = m
234  ELSE
235  nxfrm = n
236  END IF
237 *
238 * Initialize A to the identity matrix if desired
239 *
240  IF( lsame( init, 'I' ) )
241  $ CALL zlaset( 'Full', m, n, czero, cone, a, lda )
242 *
243 * If no rotation possible, still multiply by
244 * a random complex number from the circle |x| = 1
245 *
246 * 2) Compute Rotation by computing Householder
247 * Transformations H(2), H(3), ..., H(n). Note that the
248 * order in which they are computed is irrelevant.
249 *
250  DO 10 j = 1, nxfrm
251  x( j ) = czero
252  10 CONTINUE
253 *
254  DO 30 ixfrm = 2, nxfrm
255  kbeg = nxfrm - ixfrm + 1
256 *
257 * Generate independent normal( 0, 1 ) random numbers
258 *
259  DO 20 j = kbeg, nxfrm
260  x( j ) = zlarnd( 3, iseed )
261  20 CONTINUE
262 *
263 * Generate a Householder transformation from the random vector X
264 *
265  xnorm = dznrm2( ixfrm, x( kbeg ), 1 )
266  xabs = abs( x( kbeg ) )
267  IF( xabs.NE.czero ) THEN
268  csign = x( kbeg ) / xabs
269  ELSE
270  csign = cone
271  END IF
272  xnorms = csign*xnorm
273  x( nxfrm+kbeg ) = -csign
274  factor = xnorm*( xnorm+xabs )
275  IF( abs( factor ).LT.toosml ) THEN
276  info = 1
277  CALL xerbla( 'ZLAROR', -info )
278  RETURN
279  ELSE
280  factor = one / factor
281  END IF
282  x( kbeg ) = x( kbeg ) + xnorms
283 *
284 * Apply Householder transformation to A
285 *
286  IF( itype.EQ.1 .OR. itype.EQ.3 .OR. itype.EQ.4 ) THEN
287 *
288 * Apply H(k) on the left of A
289 *
290  CALL zgemv( 'C', ixfrm, n, cone, a( kbeg, 1 ), lda,
291  $ x( kbeg ), 1, czero, x( 2*nxfrm+1 ), 1 )
292  CALL zgerc( ixfrm, n, -dcmplx( factor ), x( kbeg ), 1,
293  $ x( 2*nxfrm+1 ), 1, a( kbeg, 1 ), lda )
294 *
295  END IF
296 *
297  IF( itype.GE.2 .AND. itype.LE.4 ) THEN
298 *
299 * Apply H(k)* (or H(k)') on the right of A
300 *
301  IF( itype.EQ.4 ) THEN
302  CALL zlacgv( ixfrm, x( kbeg ), 1 )
303  END IF
304 *
305  CALL zgemv( 'N', m, ixfrm, cone, a( 1, kbeg ), lda,
306  $ x( kbeg ), 1, czero, x( 2*nxfrm+1 ), 1 )
307  CALL zgerc( m, ixfrm, -dcmplx( factor ), x( 2*nxfrm+1 ), 1,
308  $ x( kbeg ), 1, a( 1, kbeg ), lda )
309 *
310  END IF
311  30 CONTINUE
312 *
313  x( 1 ) = zlarnd( 3, iseed )
314  xabs = abs( x( 1 ) )
315  IF( xabs.NE.zero ) THEN
316  csign = x( 1 ) / xabs
317  ELSE
318  csign = cone
319  END IF
320  x( 2*nxfrm ) = csign
321 *
322 * Scale the matrix A by D.
323 *
324  IF( itype.EQ.1 .OR. itype.EQ.3 .OR. itype.EQ.4 ) THEN
325  DO 40 irow = 1, m
326  CALL zscal( n, dconjg( x( nxfrm+irow ) ), a( irow, 1 ),
327  $ lda )
328  40 CONTINUE
329  END IF
330 *
331  IF( itype.EQ.2 .OR. itype.EQ.3 ) THEN
332  DO 50 jcol = 1, n
333  CALL zscal( m, x( nxfrm+jcol ), a( 1, jcol ), 1 )
334  50 CONTINUE
335  END IF
336 *
337  IF( itype.EQ.4 ) THEN
338  DO 60 jcol = 1, n
339  CALL zscal( m, dconjg( x( nxfrm+jcol ) ), a( 1, jcol ), 1 )
340  60 CONTINUE
341  END IF
342  RETURN
343 *
344 * End of ZLAROR
345 *
346  END
subroutine xerbla(SRNAME, INFO)
XERBLA
Definition: xerbla.f:60
subroutine zscal(N, ZA, ZX, INCX)
ZSCAL
Definition: zscal.f:78
subroutine zgerc(M, N, ALPHA, X, INCX, Y, INCY, A, LDA)
ZGERC
Definition: zgerc.f:130
subroutine zgemv(TRANS, M, N, ALPHA, A, LDA, X, INCX, BETA, Y, INCY)
ZGEMV
Definition: zgemv.f:158
subroutine zlaror(SIDE, INIT, M, N, A, LDA, ISEED, X, INFO)
ZLAROR
Definition: zlaror.f:158
subroutine zlaset(UPLO, M, N, ALPHA, BETA, A, LDA)
ZLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
Definition: zlaset.f:106
subroutine zlacgv(N, X, INCX)
ZLACGV conjugates a complex vector.
Definition: zlacgv.f:74