KTH framework for Nek5000 toolboxes; testing version  0.0.1
dorgqr.f
Go to the documentation of this file.
1  SUBROUTINE dorgqr( M, N, K, A, LDA, TAU, WORK, LWORK, INFO )
2 *
3 * -- LAPACK routine (version 3.0) --
4 * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
5 * Courant Institute, Argonne National Lab, and Rice University
6 * June 30, 1999
7 *
8 * .. Scalar Arguments ..
9  INTEGER INFO, K, LDA, LWORK, M, N
10 * ..
11 * .. Array Arguments ..
12  DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )
13 * ..
14 *
15 * Purpose
16 * =======
17 *
18 * DORGQR generates an M-by-N real matrix Q with orthonormal columns,
19 * which is defined as the first N columns of a product of K elementary
20 * reflectors of order M
21 *
22 * Q = H(1) H(2) . . . H(k)
23 *
24 * as returned by DGEQRF.
25 *
26 * Arguments
27 * =========
28 *
29 * M (input) INTEGER
30 * The number of rows of the matrix Q. M >= 0.
31 *
32 * N (input) INTEGER
33 * The number of columns of the matrix Q. M >= N >= 0.
34 *
35 * K (input) INTEGER
36 * The number of elementary reflectors whose product defines the
37 * matrix Q. N >= K >= 0.
38 *
39 * A (input/output) DOUBLE PRECISION array, dimension (LDA,N)
40 * On entry, the i-th column must contain the vector which
41 * defines the elementary reflector H(i), for i = 1,2,...,k, as
42 * returned by DGEQRF in the first k columns of its array
43 * argument A.
44 * On exit, the M-by-N matrix Q.
45 *
46 * LDA (input) INTEGER
47 * The first dimension of the array A. LDA >= max(1,M).
48 *
49 * TAU (input) DOUBLE PRECISION array, dimension (K)
50 * TAU(i) must contain the scalar factor of the elementary
51 * reflector H(i), as returned by DGEQRF.
52 *
53 * WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK)
54 * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
55 *
56 * LWORK (input) INTEGER
57 * The dimension of the array WORK. LWORK >= max(1,N).
58 * For optimum performance LWORK >= N*NB, where NB is the
59 * optimal blocksize.
60 *
61 * If LWORK = -1, then a workspace query is assumed; the routine
62 * only calculates the optimal size of the WORK array, returns
63 * this value as the first entry of the WORK array, and no error
64 * message related to LWORK is issued by XERBLA.
65 *
66 * INFO (output) INTEGER
67 * = 0: successful exit
68 * < 0: if INFO = -i, the i-th argument has an illegal value
69 *
70 * =====================================================================
71 *
72 * .. Parameters ..
73  DOUBLE PRECISION ZERO
74  parameter( zero = 0.0d+0 )
75 * ..
76 * .. Local Scalars ..
77  LOGICAL LQUERY
78  INTEGER I, IB, IINFO, IWS, J, KI, KK, L, LDWORK,
79  $ LWKOPT, NB, NBMIN, NX
80 * ..
81 * .. External Subroutines ..
82  EXTERNAL dlarfb, dlarft, dorg2r, xerbla
83 * ..
84 * .. Intrinsic Functions ..
85  INTRINSIC max, min
86 * ..
87 * .. External Functions ..
88  INTEGER ILAENV
89  EXTERNAL ilaenv
90 * ..
91 * .. Executable Statements ..
92 *
93 * Test the input arguments
94 *
95  info = 0
96  nb = ilaenv( 1, 'DORGQR', ' ', m, n, k, -1 )
97  lwkopt = max( 1, n )*nb
98  work( 1 ) = lwkopt
99  lquery = ( lwork.EQ.-1 )
100  IF( m.LT.0 ) THEN
101  info = -1
102  ELSE IF( n.LT.0 .OR. n.GT.m ) THEN
103  info = -2
104  ELSE IF( k.LT.0 .OR. k.GT.n ) THEN
105  info = -3
106  ELSE IF( lda.LT.max( 1, m ) ) THEN
107  info = -5
108  ELSE IF( lwork.LT.max( 1, n ) .AND. .NOT.lquery ) THEN
109  info = -8
110  END IF
111  IF( info.NE.0 ) THEN
112  CALL xerbla( 'DORGQR', -info )
113  RETURN
114  ELSE IF( lquery ) THEN
115  RETURN
116  END IF
117 *
118 * Quick return if possible
119 *
120  IF( n.LE.0 ) THEN
121  work( 1 ) = 1
122  RETURN
123  END IF
124 *
125  nbmin = 2
126  nx = 0
127  iws = n
128  IF( nb.GT.1 .AND. nb.LT.k ) THEN
129 *
130 * Determine when to cross over from blocked to unblocked code.
131 *
132  nx = max( 0, ilaenv( 3, 'DORGQR', ' ', m, n, k, -1 ) )
133  IF( nx.LT.k ) THEN
134 *
135 * Determine if workspace is large enough for blocked code.
136 *
137  ldwork = n
138  iws = ldwork*nb
139  IF( lwork.LT.iws ) THEN
140 *
141 * Not enough workspace to use optimal NB: reduce NB and
142 * determine the minimum value of NB.
143 *
144  nb = lwork / ldwork
145  nbmin = max( 2, ilaenv( 2, 'DORGQR', ' ', m, n, k, -1 ) )
146  END IF
147  END IF
148  END IF
149 *
150  IF( nb.GE.nbmin .AND. nb.LT.k .AND. nx.LT.k ) THEN
151 *
152 * Use blocked code after the last block.
153 * The first kk columns are handled by the block method.
154 *
155  ki = ( ( k-nx-1 ) / nb )*nb
156  kk = min( k, ki+nb )
157 *
158 * Set A(1:kk,kk+1:n) to zero.
159 *
160  DO 20 j = kk + 1, n
161  DO 10 i = 1, kk
162  a( i, j ) = zero
163  10 CONTINUE
164  20 CONTINUE
165  ELSE
166  kk = 0
167  END IF
168 *
169 * Use unblocked code for the last or only block.
170 *
171  IF( kk.LT.n )
172  $ CALL dorg2r( m-kk, n-kk, k-kk, a( kk+1, kk+1 ), lda,
173  $ tau( kk+1 ), work, iinfo )
174 *
175  IF( kk.GT.0 ) THEN
176 *
177 * Use blocked code
178 *
179  DO 50 i = ki + 1, 1, -nb
180  ib = min( nb, k-i+1 )
181  IF( i+ib.LE.n ) THEN
182 *
183 * Form the triangular factor of the block reflector
184 * H = H(i) H(i+1) . . . H(i+ib-1)
185 *
186  CALL dlarft( 'Forward', 'Columnwise', m-i+1, ib,
187  $ a( i, i ), lda, tau( i ), work, ldwork )
188 *
189 * Apply H to A(i:m,i+ib:n) from the left
190 *
191  CALL dlarfb( 'Left', 'No transpose', 'Forward',
192  $ 'Columnwise', m-i+1, n-i-ib+1, ib,
193  $ a( i, i ), lda, work, ldwork, a( i, i+ib ),
194  $ lda, work( ib+1 ), ldwork )
195  END IF
196 *
197 * Apply H to rows i:m of current block
198 *
199  CALL dorg2r( m-i+1, ib, ib, a( i, i ), lda, tau( i ), work,
200  $ iinfo )
201 *
202 * Set rows 1:i-1 of current block to zero
203 *
204  DO 40 j = i, i + ib - 1
205  DO 30 l = 1, i - 1
206  a( l, j ) = zero
207  30 CONTINUE
208  40 CONTINUE
209  50 CONTINUE
210  END IF
211 *
212  work( 1 ) = iws
213  RETURN
214 *
215 * End of DORGQR
216 *
217  END
subroutine dlarfb(SIDE, TRANS, DIRECT, STOREV, M, N, K, V, LDV, T, LDT, C, LDC, WORK, LDWORK)
Definition: dlarfb.f:3
subroutine dlarft(DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT)
Definition: dlarft.f:2
subroutine dorg2r(M, N, K, A, LDA, TAU, WORK, INFO)
Definition: dorg2r.f:2
subroutine dorgqr(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
Definition: dorgqr.f:2
subroutine xerbla(SRNAME, INFO)
Definition: xerbla.f:2