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
dlaror.f
Go to the documentation of this file.
1  SUBROUTINE dlaror( 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  DOUBLE PRECISION a( lda, * ), x( * )
14 * ..
15 *
16 * Purpose
17 * =======
18 *
19 * DLAROR pre- or post-multiplies an M by N matrix A by a random
20 * orthogonal matrix U, overwriting A. A may optionally be initialized
21 * to the identity matrix before multiplying by U. U is generated using
22 * the method of G.W. Stewart (SIAM J. Numer. Anal. 17, 1980, 403-409).
23 *
24 * Arguments
25 * =========
26 *
27 * SIDE (input) CHARACTER*1
28 * Specifies whether A is multiplied on the left or right by U.
29 * = 'L': Multiply A on the left (premultiply) by U
30 * = 'R': Multiply A on the right (postmultiply) by U'
31 * = 'C' or 'T': Multiply A on the left by U and the right
32 * by U' (Here, U' means U-transpose.)
33 *
34 * INIT (input) CHARACTER*1
35 * Specifies whether or not A should be initialized to the
36 * identity matrix.
37 * = 'I': Initialize A to (a section of) the identity matrix
38 * before applying U.
39 * = 'N': No initialization. Apply U to the input matrix A.
40 *
41 * INIT = 'I' may be used to generate square or rectangular
42 * orthogonal matrices:
43 *
44 * For M = N and SIDE = 'L' or 'R', the rows will be orthogonal
45 * to each other, as will the columns.
46 *
47 * If M < N, SIDE = 'R' produces a dense matrix whose rows are
48 * orthogonal and whose columns are not, while SIDE = 'L'
49 * produces a matrix whose rows are orthogonal, and whose first
50 * M columns are orthogonal, and whose remaining columns are
51 * zero.
52 *
53 * If M > N, SIDE = 'L' produces a dense matrix whose columns
54 * are orthogonal and whose rows are not, while SIDE = 'R'
55 * produces a matrix whose columns are orthogonal, and whose
56 * first M rows are orthogonal, and whose remaining rows are
57 * zero.
58 *
59 * M (input) INTEGER
60 * The number of rows of A.
61 *
62 * N (input) INTEGER
63 * The number of columns of A.
64 *
65 * A (input/output) DOUBLE PRECISION array, dimension (LDA, N)
66 * On entry, the array A.
67 * On exit, overwritten by U A ( if SIDE = 'L' ),
68 * or by A U ( if SIDE = 'R' ),
69 * or by U A U' ( if SIDE = 'C' or 'T').
70 *
71 * LDA (input) INTEGER
72 * The leading dimension of the array A. LDA >= max(1,M).
73 *
74 * ISEED (input/output) INTEGER array, dimension (4)
75 * On entry ISEED specifies the seed of the random number
76 * generator. The array elements should be between 0 and 4095;
77 * if not they will be reduced mod 4096. Also, ISEED(4) must
78 * be odd. The random number generator uses a linear
79 * congruential sequence limited to small integers, and so
80 * should produce machine independent random numbers. The
81 * values of ISEED are changed on exit, and can be used in the
82 * next call to DLAROR to continue the same random number
83 * sequence.
84 *
85 * X (workspace) DOUBLE PRECISION array, dimension (3*MAX( M, N ))
86 * Workspace of length
87 * 2*M + N if SIDE = 'L',
88 * 2*N + M if SIDE = 'R',
89 * 3*N if SIDE = 'C' or 'T'.
90 *
91 * INFO (output) INTEGER
92 * An error flag. It is set to:
93 * = 0: normal return
94 * < 0: if INFO = -k, the k-th argument had an illegal value
95 * = 1: if the random numbers generated by DLARND are bad.
96 *
97 * =====================================================================
98 *
99 * .. Parameters ..
100  DOUBLE PRECISION zero, one, toosml
101  parameter( zero = 0.0d+0, one = 1.0d+0,
102  $ toosml = 1.0d-20 )
103 * ..
104 * .. Local Scalars ..
105  INTEGER irow, itype, ixfrm, j, jcol, kbeg, nxfrm
106  DOUBLE PRECISION factor, xnorm, xnorms
107 * ..
108 * .. External Functions ..
109  LOGICAL lsame
110  DOUBLE PRECISION dlarnd, dnrm2
111  EXTERNAL lsame, dlarnd, dnrm2
112 * ..
113 * .. External Subroutines ..
114  EXTERNAL dgemv, dger, dlaset, dscal, xerbla
115 * ..
116 * .. Intrinsic Functions ..
117  INTRINSIC abs, sign
118 * ..
119 * .. Executable Statements ..
120 *
121  IF( n.EQ.0 .OR. m.EQ.0 )
122  $ return
123 *
124  itype = 0
125  IF( lsame( side, 'L' ) ) THEN
126  itype = 1
127  ELSE IF( lsame( side, 'R' ) ) THEN
128  itype = 2
129  ELSE IF( lsame( side, 'C' ) .OR. lsame( side, 'T' ) ) THEN
130  itype = 3
131  END IF
132 *
133 * Check for argument errors.
134 *
135  info = 0
136  IF( itype.EQ.0 ) THEN
137  info = -1
138  ELSE IF( m.LT.0 ) THEN
139  info = -3
140  ELSE IF( n.LT.0 .OR. ( itype.EQ.3 .AND. n.NE.m ) ) THEN
141  info = -4
142  ELSE IF( lda.LT.m ) THEN
143  info = -6
144  END IF
145  IF( info.NE.0 ) THEN
146  CALL xerbla( 'DLAROR', -info )
147  return
148  END IF
149 *
150  IF( itype.EQ.1 ) THEN
151  nxfrm = m
152  ELSE
153  nxfrm = n
154  END IF
155 *
156 * Initialize A to the identity matrix if desired
157 *
158  IF( lsame( init, 'I' ) )
159  $ CALL dlaset( 'Full', m, n, zero, one, a, lda )
160 *
161 * If no rotation possible, multiply by random +/-1
162 *
163 * Compute rotation by computing Householder transformations
164 * H(2), H(3), ..., H(nhouse)
165 *
166  DO 10 j = 1, nxfrm
167  x( j ) = zero
168  10 continue
169 *
170  DO 30 ixfrm = 2, nxfrm
171  kbeg = nxfrm - ixfrm + 1
172 *
173 * Generate independent normal( 0, 1 ) random numbers
174 *
175  DO 20 j = kbeg, nxfrm
176  x( j ) = dlarnd( 3, iseed )
177  20 continue
178 *
179 * Generate a Householder transformation from the random vector X
180 *
181  xnorm = dnrm2( ixfrm, x( kbeg ), 1 )
182  xnorms = sign( xnorm, x( kbeg ) )
183  x( kbeg+nxfrm ) = sign( one, -x( kbeg ) )
184  factor = xnorms*( xnorms+x( kbeg ) )
185  IF( abs( factor ).LT.toosml ) THEN
186  info = 1
187  CALL xerbla( 'DLAROR', info )
188  return
189  ELSE
190  factor = one / factor
191  END IF
192  x( kbeg ) = x( kbeg ) + xnorms
193 *
194 * Apply Householder transformation to A
195 *
196  IF( itype.EQ.1 .OR. itype.EQ.3 ) THEN
197 *
198 * Apply H(k) from the left.
199 *
200  CALL dgemv( 'T', ixfrm, n, one, a( kbeg, 1 ), lda,
201  $ x( kbeg ), 1, zero, x( 2*nxfrm+1 ), 1 )
202  CALL dger( ixfrm, n, -factor, x( kbeg ), 1, x( 2*nxfrm+1 ),
203  $ 1, a( kbeg, 1 ), lda )
204 *
205  END IF
206 *
207  IF( itype.EQ.2 .OR. itype.EQ.3 ) THEN
208 *
209 * Apply H(k) from the right.
210 *
211  CALL dgemv( 'N', m, ixfrm, one, a( 1, kbeg ), lda,
212  $ x( kbeg ), 1, zero, x( 2*nxfrm+1 ), 1 )
213  CALL dger( m, ixfrm, -factor, x( 2*nxfrm+1 ), 1, x( kbeg ),
214  $ 1, a( 1, kbeg ), lda )
215 *
216  END IF
217  30 continue
218 *
219  x( 2*nxfrm ) = sign( one, dlarnd( 3, iseed ) )
220 *
221 * Scale the matrix A by D.
222 *
223  IF( itype.EQ.1 .OR. itype.EQ.3 ) THEN
224  DO 40 irow = 1, m
225  CALL dscal( n, x( nxfrm+irow ), a( irow, 1 ), lda )
226  40 continue
227  END IF
228 *
229  IF( itype.EQ.2 .OR. itype.EQ.3 ) THEN
230  DO 50 jcol = 1, n
231  CALL dscal( m, x( nxfrm+jcol ), a( 1, jcol ), 1 )
232  50 continue
233  END IF
234  return
235 *
236 * End of DLAROR
237 *
238  END