LAPACK  3.5.0
LAPACK: Linear Algebra PACKage
 All Classes Files Functions Variables Typedefs Macros
clagge.f
Go to the documentation of this file.
1 *> \brief \b CLAGGE
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 CLAGGE( M, N, KL, KU, D, A, LDA, ISEED, WORK, INFO )
12 *
13 * .. Scalar Arguments ..
14 * INTEGER INFO, KL, KU, LDA, M, N
15 * ..
16 * .. Array Arguments ..
17 * INTEGER ISEED( 4 )
18 * REAL D( * )
19 * COMPLEX A( LDA, * ), WORK( * )
20 * ..
21 *
22 *
23 *> \par Purpose:
24 * =============
25 *>
26 *> \verbatim
27 *>
28 *> CLAGGE generates a complex general m by n matrix A, by pre- and post-
29 *> multiplying a real diagonal matrix D with random unitary matrices:
30 *> A = U*D*V. The lower and upper bandwidths may then be reduced to
31 *> kl and ku by additional unitary transformations.
32 *> \endverbatim
33 *
34 * Arguments:
35 * ==========
36 *
37 *> \param[in] M
38 *> \verbatim
39 *> M is INTEGER
40 *> The number of rows of the matrix A. M >= 0.
41 *> \endverbatim
42 *>
43 *> \param[in] N
44 *> \verbatim
45 *> N is INTEGER
46 *> The number of columns of the matrix A. N >= 0.
47 *> \endverbatim
48 *>
49 *> \param[in] KL
50 *> \verbatim
51 *> KL is INTEGER
52 *> The number of nonzero subdiagonals within the band of A.
53 *> 0 <= KL <= M-1.
54 *> \endverbatim
55 *>
56 *> \param[in] KU
57 *> \verbatim
58 *> KU is INTEGER
59 *> The number of nonzero superdiagonals within the band of A.
60 *> 0 <= KU <= N-1.
61 *> \endverbatim
62 *>
63 *> \param[in] D
64 *> \verbatim
65 *> D is REAL array, dimension (min(M,N))
66 *> The diagonal elements of the diagonal matrix D.
67 *> \endverbatim
68 *>
69 *> \param[out] A
70 *> \verbatim
71 *> A is COMPLEX array, dimension (LDA,N)
72 *> The generated m by n matrix A.
73 *> \endverbatim
74 *>
75 *> \param[in] LDA
76 *> \verbatim
77 *> LDA is INTEGER
78 *> The leading dimension of the array A. LDA >= M.
79 *> \endverbatim
80 *>
81 *> \param[in,out] ISEED
82 *> \verbatim
83 *> ISEED is INTEGER array, dimension (4)
84 *> On entry, the seed of the random number generator; the array
85 *> elements must be between 0 and 4095, and ISEED(4) must be
86 *> odd.
87 *> On exit, the seed is updated.
88 *> \endverbatim
89 *>
90 *> \param[out] WORK
91 *> \verbatim
92 *> WORK is COMPLEX array, dimension (M+N)
93 *> \endverbatim
94 *>
95 *> \param[out] INFO
96 *> \verbatim
97 *> INFO is INTEGER
98 *> = 0: successful exit
99 *> < 0: if INFO = -i, the i-th argument had an illegal value
100 *> \endverbatim
101 *
102 * Authors:
103 * ========
104 *
105 *> \author Univ. of Tennessee
106 *> \author Univ. of California Berkeley
107 *> \author Univ. of Colorado Denver
108 *> \author NAG Ltd.
109 *
110 *> \date November 2011
111 *
112 *> \ingroup complex_matgen
113 *
114 * =====================================================================
115  SUBROUTINE clagge( M, N, KL, KU, D, A, LDA, ISEED, WORK, INFO )
116 *
117 * -- LAPACK auxiliary routine (version 3.4.0) --
118 * -- LAPACK is a software package provided by Univ. of Tennessee, --
119 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
120 * November 2011
121 *
122 * .. Scalar Arguments ..
123  INTEGER info, kl, ku, lda, m, n
124 * ..
125 * .. Array Arguments ..
126  INTEGER iseed( 4 )
127  REAL d( * )
128  COMPLEX a( lda, * ), work( * )
129 * ..
130 *
131 * =====================================================================
132 *
133 * .. Parameters ..
134  COMPLEX zero, one
135  parameter( zero = ( 0.0e+0, 0.0e+0 ),
136  $ one = ( 1.0e+0, 0.0e+0 ) )
137 * ..
138 * .. Local Scalars ..
139  INTEGER i, j
140  REAL wn
141  COMPLEX tau, wa, wb
142 * ..
143 * .. External Subroutines ..
144  EXTERNAL cgemv, cgerc, clacgv, clarnv, cscal, xerbla
145 * ..
146 * .. Intrinsic Functions ..
147  INTRINSIC abs, max, min, real
148 * ..
149 * .. External Functions ..
150  REAL scnrm2
151  EXTERNAL scnrm2
152 * ..
153 * .. Executable Statements ..
154 *
155 * Test the input arguments
156 *
157  info = 0
158  IF( m.LT.0 ) THEN
159  info = -1
160  ELSE IF( n.LT.0 ) THEN
161  info = -2
162  ELSE IF( kl.LT.0 .OR. kl.GT.m-1 ) THEN
163  info = -3
164  ELSE IF( ku.LT.0 .OR. ku.GT.n-1 ) THEN
165  info = -4
166  ELSE IF( lda.LT.max( 1, m ) ) THEN
167  info = -7
168  END IF
169  IF( info.LT.0 ) THEN
170  CALL xerbla( 'CLAGGE', -info )
171  RETURN
172  END IF
173 *
174 * initialize A to diagonal matrix
175 *
176  DO 20 j = 1, n
177  DO 10 i = 1, m
178  a( i, j ) = zero
179  10 CONTINUE
180  20 CONTINUE
181  DO 30 i = 1, min( m, n )
182  a( i, i ) = d( i )
183  30 CONTINUE
184 *
185 * pre- and post-multiply A by random unitary matrices
186 *
187  DO 40 i = min( m, n ), 1, -1
188  IF( i.LT.m ) THEN
189 *
190 * generate random reflection
191 *
192  CALL clarnv( 3, iseed, m-i+1, work )
193  wn = scnrm2( m-i+1, work, 1 )
194  wa = ( wn / abs( work( 1 ) ) )*work( 1 )
195  IF( wn.EQ.zero ) THEN
196  tau = zero
197  ELSE
198  wb = work( 1 ) + wa
199  CALL cscal( m-i, one / wb, work( 2 ), 1 )
200  work( 1 ) = one
201  tau = REAL( wb / wa )
202  END IF
203 *
204 * multiply A(i:m,i:n) by random reflection from the left
205 *
206  CALL cgemv( 'Conjugate transpose', m-i+1, n-i+1, one,
207  $ a( i, i ), lda, work, 1, zero, work( m+1 ), 1 )
208  CALL cgerc( m-i+1, n-i+1, -tau, work, 1, work( m+1 ), 1,
209  $ a( i, i ), lda )
210  END IF
211  IF( i.LT.n ) THEN
212 *
213 * generate random reflection
214 *
215  CALL clarnv( 3, iseed, n-i+1, work )
216  wn = scnrm2( n-i+1, work, 1 )
217  wa = ( wn / abs( work( 1 ) ) )*work( 1 )
218  IF( wn.EQ.zero ) THEN
219  tau = zero
220  ELSE
221  wb = work( 1 ) + wa
222  CALL cscal( n-i, one / wb, work( 2 ), 1 )
223  work( 1 ) = one
224  tau = REAL( wb / wa )
225  END IF
226 *
227 * multiply A(i:m,i:n) by random reflection from the right
228 *
229  CALL cgemv( 'No transpose', m-i+1, n-i+1, one, a( i, i ),
230  $ lda, work, 1, zero, work( n+1 ), 1 )
231  CALL cgerc( m-i+1, n-i+1, -tau, work( n+1 ), 1, work, 1,
232  $ a( i, i ), lda )
233  END IF
234  40 CONTINUE
235 *
236 * Reduce number of subdiagonals to KL and number of superdiagonals
237 * to KU
238 *
239  DO 70 i = 1, max( m-1-kl, n-1-ku )
240  IF( kl.LE.ku ) THEN
241 *
242 * annihilate subdiagonal elements first (necessary if KL = 0)
243 *
244  IF( i.LE.min( m-1-kl, n ) ) THEN
245 *
246 * generate reflection to annihilate A(kl+i+1:m,i)
247 *
248  wn = scnrm2( m-kl-i+1, a( kl+i, i ), 1 )
249  wa = ( wn / abs( a( kl+i, i ) ) )*a( kl+i, i )
250  IF( wn.EQ.zero ) THEN
251  tau = zero
252  ELSE
253  wb = a( kl+i, i ) + wa
254  CALL cscal( m-kl-i, one / wb, a( kl+i+1, i ), 1 )
255  a( kl+i, i ) = one
256  tau = REAL( wb / wa )
257  END IF
258 *
259 * apply reflection to A(kl+i:m,i+1:n) from the left
260 *
261  CALL cgemv( 'Conjugate transpose', m-kl-i+1, n-i, one,
262  $ a( kl+i, i+1 ), lda, a( kl+i, i ), 1, zero,
263  $ work, 1 )
264  CALL cgerc( m-kl-i+1, n-i, -tau, a( kl+i, i ), 1, work,
265  $ 1, a( kl+i, i+1 ), lda )
266  a( kl+i, i ) = -wa
267  END IF
268 *
269  IF( i.LE.min( n-1-ku, m ) ) THEN
270 *
271 * generate reflection to annihilate A(i,ku+i+1:n)
272 *
273  wn = scnrm2( n-ku-i+1, a( i, ku+i ), lda )
274  wa = ( wn / abs( a( i, ku+i ) ) )*a( i, ku+i )
275  IF( wn.EQ.zero ) THEN
276  tau = zero
277  ELSE
278  wb = a( i, ku+i ) + wa
279  CALL cscal( n-ku-i, one / wb, a( i, ku+i+1 ), lda )
280  a( i, ku+i ) = one
281  tau = REAL( wb / wa )
282  END IF
283 *
284 * apply reflection to A(i+1:m,ku+i:n) from the right
285 *
286  CALL clacgv( n-ku-i+1, a( i, ku+i ), lda )
287  CALL cgemv( 'No transpose', m-i, n-ku-i+1, one,
288  $ a( i+1, ku+i ), lda, a( i, ku+i ), lda, zero,
289  $ work, 1 )
290  CALL cgerc( m-i, n-ku-i+1, -tau, work, 1, a( i, ku+i ),
291  $ lda, a( i+1, ku+i ), lda )
292  a( i, ku+i ) = -wa
293  END IF
294  ELSE
295 *
296 * annihilate superdiagonal elements first (necessary if
297 * KU = 0)
298 *
299  IF( i.LE.min( n-1-ku, m ) ) THEN
300 *
301 * generate reflection to annihilate A(i,ku+i+1:n)
302 *
303  wn = scnrm2( n-ku-i+1, a( i, ku+i ), lda )
304  wa = ( wn / abs( a( i, ku+i ) ) )*a( i, ku+i )
305  IF( wn.EQ.zero ) THEN
306  tau = zero
307  ELSE
308  wb = a( i, ku+i ) + wa
309  CALL cscal( n-ku-i, one / wb, a( i, ku+i+1 ), lda )
310  a( i, ku+i ) = one
311  tau = REAL( wb / wa )
312  END IF
313 *
314 * apply reflection to A(i+1:m,ku+i:n) from the right
315 *
316  CALL clacgv( n-ku-i+1, a( i, ku+i ), lda )
317  CALL cgemv( 'No transpose', m-i, n-ku-i+1, one,
318  $ a( i+1, ku+i ), lda, a( i, ku+i ), lda, zero,
319  $ work, 1 )
320  CALL cgerc( m-i, n-ku-i+1, -tau, work, 1, a( i, ku+i ),
321  $ lda, a( i+1, ku+i ), lda )
322  a( i, ku+i ) = -wa
323  END IF
324 *
325  IF( i.LE.min( m-1-kl, n ) ) THEN
326 *
327 * generate reflection to annihilate A(kl+i+1:m,i)
328 *
329  wn = scnrm2( m-kl-i+1, a( kl+i, i ), 1 )
330  wa = ( wn / abs( a( kl+i, i ) ) )*a( kl+i, i )
331  IF( wn.EQ.zero ) THEN
332  tau = zero
333  ELSE
334  wb = a( kl+i, i ) + wa
335  CALL cscal( m-kl-i, one / wb, a( kl+i+1, i ), 1 )
336  a( kl+i, i ) = one
337  tau = REAL( wb / wa )
338  END IF
339 *
340 * apply reflection to A(kl+i:m,i+1:n) from the left
341 *
342  CALL cgemv( 'Conjugate transpose', m-kl-i+1, n-i, one,
343  $ a( kl+i, i+1 ), lda, a( kl+i, i ), 1, zero,
344  $ work, 1 )
345  CALL cgerc( m-kl-i+1, n-i, -tau, a( kl+i, i ), 1, work,
346  $ 1, a( kl+i, i+1 ), lda )
347  a( kl+i, i ) = -wa
348  END IF
349  END IF
350 *
351  DO 50 j = kl + i + 1, m
352  a( j, i ) = zero
353  50 CONTINUE
354 *
355  DO 60 j = ku + i + 1, n
356  a( i, j ) = zero
357  60 CONTINUE
358  70 CONTINUE
359  RETURN
360 *
361 * End of CLAGGE
362 *
363  END