5 * SUBROUTINE SGEMLQ( SIDE, TRANS, M, N, K, A, LDA, WORK1,
6 * $ LWORK1, C, LDC, WORK2, LWORK2, INFO )
9 * .. Scalar Arguments ..
10 * CHARACTER SIDE, TRANS
11 * INTEGER INFO, LDA, M, N, K, MB, NB, LWORK1, LWORK2, LDC
13 * .. Array Arguments ..
14 * REAL A( LDA, * ), WORK1( * ), C(LDC, * ),
21 *> DGEMLQ overwrites the general real M-by-N matrix C with
24 *> SIDE = 'L' SIDE = 'R'
25 *> TRANS = 'N': Q * C C * Q
26 *> TRANS = 'T': Q**T * C C * Q**T
27 *> where Q is a real orthogonal matrix defined as the product
28 *> of blocked elementary reflectors computed by short wide LQ
29 *> factorization (DGELQ)
36 *> SIDE is CHARACTER*1
37 *> = 'L': apply Q or Q**T from the Left;
38 *> = 'R': apply Q or Q**T from the Right.
41 *> TRANS is CHARACTER*1
42 *> = 'N': No transpose, apply Q;
43 *> = 'T': Transpose, apply Q**T.
47 *> The number of rows of the matrix A. M >=0.
53 *> The number of columns of the matrix C. N >= M.
59 *> The number of elementary reflectors whose product defines
67 *> A is REAL array, dimension (LDA,K)
68 *> The i-th row must contain the vector which defines the blocked
69 *> elementary reflector H(i), for i = 1,2,...,k, as returned by
70 *> DLASWLQ in the first k rows of its array argument A.
76 *> The leading dimension of the array A.
77 *> If SIDE = 'L', LDA >= max(1,M);
78 *> if SIDE = 'R', LDA >= max(1,N).
83 *> WORK1 is REAL array, dimension (MAX(1,LWORK1)) is
90 *> The dimension of the array WORK1.
94 *> C is REAL array, dimension (LDC,N)
95 *> On entry, the M-by-N matrix C.
96 *> On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q.
99 *> The leading dimension of the array C. LDC >= max(1,M).
103 *> (workspace) REAL array, dimension (MAX(1,LWORK2))
109 *> The dimension of the array WORK2.
110 *> If LWORK2 = -1, then a workspace query is assumed; the routine
111 *> only calculates the optimal size of the WORK2 array, returns
112 *> this value as the third entry of the WORK2 array (WORK2(1)),
113 *> and no error message related to LWORK2 is issued by XERBLA.
119 *> = 0: successful exit
120 *> < 0: if INFO = -i, the i-th argument had an illegal value
126 *> \author Univ. of Tennessee
127 *> \author Univ. of California Berkeley
128 *> \author Univ. of Colorado Denver
131 *> \par Further Details:
132 * =====================
135 *> Depending on the matrix dimensions M and N, and row and column
136 *> block sizes MB and NB returned by ILAENV, GELQ will use either
137 *> LASWLQ(if the matrix is short-and-wide) or GELQT to compute
138 *> the LQ decomposition.
139 *> The output of LASWLQ or GELQT representing Q is stored in A and in
140 *> array WORK1(6:LWORK1) for later use.
141 *> WORK1(2:5) contains the matrix dimensions M,N and block sizes MB, NB
142 *> which are needed to interpret A and WORK1(6:LWORK1) for later use.
143 *> WORK1(1)=1 indicates that the code needed to take WORK1(2:5) and
144 *> decide whether LASWLQ or GELQT was used is the same as used below in
145 *> GELQ. For a detailed description of A and WORK1(6:LWORK1), see
146 *> Further Details in LASWLQ or GELQT.
149 * =====================================================================
150 SUBROUTINE SGEMLQ( SIDE, TRANS, M, N, K, A, LDA, WORK1, LWORK1,
151 $ C, LDC, WORK2, LWORK2, INFO )
153 * -- LAPACK computational routine (version 3.5.0) --
154 * -- LAPACK is a software package provided by Univ. of Tennessee, --
155 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
158 * .. Scalar Arguments ..
159 CHARACTER SIDE, TRANS
160 INTEGER INFO, LDA, M, N, K, LWORK1, LWORK2, LDC
162 * .. Array Arguments ..
163 REAL A( LDA, * ), C( LDC, * ), WORK1( * ), WORK2( * )
166 * =====================================================================
169 * .. Local Scalars ..
170 LOGICAL LEFT, RIGHT, TRAN, NOTRAN, LQUERY
171 INTEGER I, II, KK, MB, NB, LW, NBLCKS, MN
173 * .. External Functions ..
176 * .. External Subroutines ..
177 EXTERNAL STPMLQT, SGEMLQT, XERBLA
178 * .. Intrinsic Functions ..
179 INTRINSIC INT, MAX, MIN, MOD
181 * .. Executable Statements ..
183 * Test the input arguments
186 NOTRAN = LSAME( TRANS, 'N' )
187 TRAN = LSAME( TRANS, 'T' )
188 LEFT = LSAME( SIDE, 'L' )
189 RIGHT = LSAME( SIDE, 'R' )
200 IF ((NB.GT.K).AND.(MN.GT.K)) THEN
201 IF(MOD(MN-K, NB-K).EQ.0) THEN
202 NBLCKS = (MN-K)/(NB-K)
204 NBLCKS = (MN-K)/(NB-K) + 1
211 IF( .NOT.LEFT .AND. .NOT.RIGHT ) THEN
213 ELSE IF( .NOT.TRAN .AND. .NOT.NOTRAN ) THEN
215 ELSE IF( M.LT.0 ) THEN
217 ELSE IF( N.LT.0) THEN
219 ELSE IF( K.LT.0 ) THEN
221 ELSE IF( LDA.LT.MAX( 1, K ) ) THEN
223 ELSE IF( LWORK1.LT.MAX( 1, MB*K*NBLCKS+5 )) THEN
225 ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
227 ELSE IF(( LWORK2.LT.MAX(1,LW)).AND.(.NOT.LQUERY)) THEN
235 CALL XERBLA( 'SGEMLQ', -INFO )
237 ELSE IF (LQUERY) THEN
241 * Quick return if possible
243 IF( MIN(M,N,K).EQ.0 ) THEN
247 IF((LEFT.AND.M.LE.K).OR.(RIGHT.AND.N.LE.K).OR.(NB.LE.K).OR.
248 $ (NB.GE.MAX(M,N,K))) THEN
249 CALL SGEMLQT( SIDE, TRANS, M, N, K, MB, A, LDA,
250 $ WORK1(6), MB, C, LDC, WORK2, INFO)
252 CALL SLAMSWLQ( SIDE, TRANS, M, N, K, MB, NB, A, LDA, WORK1(6),
253 $ MB, C, LDC, WORK2, LWORK2, INFO )