LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches

◆ cunmbr()

subroutine cunmbr ( character vect,
character side,
character trans,
integer m,
integer n,
integer k,
complex, dimension( lda, * ) a,
integer lda,
complex, dimension( * ) tau,
complex, dimension( ldc, * ) c,
integer ldc,
complex, dimension( * ) work,
integer lwork,
integer info )

CUNMBR

Download CUNMBR + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> If VECT = 'Q', CUNMBR overwrites the general complex M-by-N matrix C
!> with
!>                 SIDE = 'L'     SIDE = 'R'
!> TRANS = 'N':      Q * C          C * Q
!> TRANS = 'C':      Q**H * C       C * Q**H
!>
!> If VECT = 'P', CUNMBR overwrites the general complex M-by-N matrix C
!> with
!>                 SIDE = 'L'     SIDE = 'R'
!> TRANS = 'N':      P * C          C * P
!> TRANS = 'C':      P**H * C       C * P**H
!>
!> Here Q and P**H are the unitary matrices determined by CGEBRD when
!> reducing a complex matrix A to bidiagonal form: A = Q * B * P**H. Q
!> and P**H are defined as products of elementary reflectors H(i) and
!> G(i) respectively.
!>
!> Let nq = m if SIDE = 'L' and nq = n if SIDE = 'R'. Thus nq is the
!> order of the unitary matrix Q or P**H that is applied.
!>
!> If VECT = 'Q', A is assumed to have been an NQ-by-K matrix:
!> if nq >= k, Q = H(1) H(2) . . . H(k);
!> if nq < k, Q = H(1) H(2) . . . H(nq-1).
!>
!> If VECT = 'P', A is assumed to have been a K-by-NQ matrix:
!> if k < nq, P = G(1) G(2) . . . G(k);
!> if k >= nq, P = G(1) G(2) . . . G(nq-1).
!> 
Parameters
[in]VECT
!>          VECT is CHARACTER*1
!>          = 'Q': apply Q or Q**H;
!>          = 'P': apply P or P**H.
!> 
[in]SIDE
!>          SIDE is CHARACTER*1
!>          = 'L': apply Q, Q**H, P or P**H from the Left;
!>          = 'R': apply Q, Q**H, P or P**H from the Right.
!> 
[in]TRANS
!>          TRANS is CHARACTER*1
!>          = 'N':  No transpose, apply Q or P;
!>          = 'C':  Conjugate transpose, apply Q**H or P**H.
!> 
[in]M
!>          M is INTEGER
!>          The number of rows of the matrix C. M >= 0.
!> 
[in]N
!>          N is INTEGER
!>          The number of columns of the matrix C. N >= 0.
!> 
[in]K
!>          K is INTEGER
!>          If VECT = 'Q', the number of columns in the original
!>          matrix reduced by CGEBRD.
!>          If VECT = 'P', the number of rows in the original
!>          matrix reduced by CGEBRD.
!>          K >= 0.
!> 
[in]A
!>          A is COMPLEX array, dimension
!>                                (LDA,min(nq,K)) if VECT = 'Q'
!>                                (LDA,nq)        if VECT = 'P'
!>          The vectors which define the elementary reflectors H(i) and
!>          G(i), whose products determine the matrices Q and P, as
!>          returned by CGEBRD.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.
!>          If VECT = 'Q', LDA >= max(1,nq);
!>          if VECT = 'P', LDA >= max(1,min(nq,K)).
!> 
[in]TAU
!>          TAU is COMPLEX array, dimension (min(nq,K))
!>          TAU(i) must contain the scalar factor of the elementary
!>          reflector H(i) or G(i) which determines Q or P, as returned
!>          by CGEBRD in the array argument TAUQ or TAUP.
!> 
[in,out]C
!>          C is COMPLEX array, dimension (LDC,N)
!>          On entry, the M-by-N matrix C.
!>          On exit, C is overwritten by Q*C or Q**H*C or C*Q**H or C*Q
!>          or P*C or P**H*C or C*P or C*P**H.
!> 
[in]LDC
!>          LDC is INTEGER
!>          The leading dimension of the array C. LDC >= max(1,M).
!> 
[out]WORK
!>          WORK is COMPLEX array, dimension (MAX(1,LWORK))
!>          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
!> 
[in]LWORK
!>          LWORK is INTEGER
!>          The dimension of the array WORK.
!>          If SIDE = 'L', LWORK >= max(1,N);
!>          if SIDE = 'R', LWORK >= max(1,M);
!>          if N = 0 or M = 0, LWORK >= 1.
!>          For optimum performance LWORK >= max(1,N*NB) if SIDE = 'L',
!>          and LWORK >= max(1,M*NB) if SIDE = 'R', where NB is the
!>          optimal blocksize. (NB = 0 if M = 0 or N = 0.)
!>
!>          If LWORK = -1, then a workspace query is assumed; the routine
!>          only calculates the optimal size of the WORK array, returns
!>          this value as the first entry of the WORK array, and no error
!>          message related to LWORK is issued by XERBLA.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!>          < 0:  if INFO = -i, the i-th argument had an illegal value
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 193 of file cunmbr.f.

195*
196* -- LAPACK computational routine --
197* -- LAPACK is a software package provided by Univ. of Tennessee, --
198* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
199*
200* .. Scalar Arguments ..
201 CHARACTER SIDE, TRANS, VECT
202 INTEGER INFO, K, LDA, LDC, LWORK, M, N
203* ..
204* .. Array Arguments ..
205 COMPLEX A( LDA, * ), C( LDC, * ), TAU( * ),
206 $ WORK( * )
207* ..
208*
209* =====================================================================
210*
211* .. Local Scalars ..
212 LOGICAL APPLYQ, LEFT, LQUERY, NOTRAN
213 CHARACTER TRANST
214 INTEGER I1, I2, IINFO, LWKOPT, MI, NB, NI, NQ, NW
215* ..
216* .. External Functions ..
217 LOGICAL LSAME
218 INTEGER ILAENV
219 REAL SROUNDUP_LWORK
220 EXTERNAL ilaenv, lsame, sroundup_lwork
221* ..
222* .. External Subroutines ..
223 EXTERNAL cunmlq, cunmqr, xerbla
224* ..
225* .. Intrinsic Functions ..
226 INTRINSIC max, min
227* ..
228* .. Executable Statements ..
229*
230* Test the input arguments
231*
232 info = 0
233 applyq = lsame( vect, 'Q' )
234 left = lsame( side, 'L' )
235 notran = lsame( trans, 'N' )
236 lquery = ( lwork.EQ.-1 )
237*
238* NQ is the order of Q or P and NW is the minimum dimension of WORK
239*
240 IF( left ) THEN
241 nq = m
242 nw = max( 1, n )
243 ELSE
244 nq = n
245 nw = max( 1, m )
246 END IF
247 IF( .NOT.applyq .AND. .NOT.lsame( vect, 'P' ) ) THEN
248 info = -1
249 ELSE IF( .NOT.left .AND. .NOT.lsame( side, 'R' ) ) THEN
250 info = -2
251 ELSE IF( .NOT.notran .AND. .NOT.lsame( trans, 'C' ) ) THEN
252 info = -3
253 ELSE IF( m.LT.0 ) THEN
254 info = -4
255 ELSE IF( n.LT.0 ) THEN
256 info = -5
257 ELSE IF( k.LT.0 ) THEN
258 info = -6
259 ELSE IF( ( applyq .AND. lda.LT.max( 1, nq ) ) .OR.
260 $ ( .NOT.applyq .AND. lda.LT.max( 1, min( nq, k ) ) ) )
261 $ THEN
262 info = -8
263 ELSE IF( ldc.LT.max( 1, m ) ) THEN
264 info = -11
265 ELSE IF( lwork.LT.nw .AND. .NOT.lquery ) THEN
266 info = -13
267 END IF
268*
269 IF( info.EQ.0 ) THEN
270 IF( m.GT.0 .AND. n.GT.0 ) THEN
271 IF( applyq ) THEN
272 IF( left ) THEN
273 nb = ilaenv( 1, 'CUNMQR', side // trans, m-1, n,
274 $ m-1,
275 $ -1 )
276 ELSE
277 nb = ilaenv( 1, 'CUNMQR', side // trans, m, n-1,
278 $ n-1,
279 $ -1 )
280 END IF
281 ELSE
282 IF( left ) THEN
283 nb = ilaenv( 1, 'CUNMLQ', side // trans, m-1, n,
284 $ m-1,
285 $ -1 )
286 ELSE
287 nb = ilaenv( 1, 'CUNMLQ', side // trans, m, n-1,
288 $ n-1,
289 $ -1 )
290 END IF
291 END IF
292 lwkopt = nw*nb
293 ELSE
294 lwkopt = 1
295 END IF
296 work( 1 ) = sroundup_lwork(lwkopt)
297 END IF
298*
299 IF( info.NE.0 ) THEN
300 CALL xerbla( 'CUNMBR', -info )
301 RETURN
302 ELSE IF( lquery ) THEN
303 RETURN
304 END IF
305*
306* Quick return if possible
307*
308 IF( m.EQ.0 .OR. n.EQ.0 )
309 $ RETURN
310*
311 IF( applyq ) THEN
312*
313* Apply Q
314*
315 IF( nq.GE.k ) THEN
316*
317* Q was determined by a call to CGEBRD with nq >= k
318*
319 CALL cunmqr( side, trans, m, n, k, a, lda, tau, c, ldc,
320 $ work, lwork, iinfo )
321 ELSE IF( nq.GT.1 ) THEN
322*
323* Q was determined by a call to CGEBRD with nq < k
324*
325 IF( left ) THEN
326 mi = m - 1
327 ni = n
328 i1 = 2
329 i2 = 1
330 ELSE
331 mi = m
332 ni = n - 1
333 i1 = 1
334 i2 = 2
335 END IF
336 CALL cunmqr( side, trans, mi, ni, nq-1, a( 2, 1 ), lda,
337 $ tau,
338 $ c( i1, i2 ), ldc, work, lwork, iinfo )
339 END IF
340 ELSE
341*
342* Apply P
343*
344 IF( notran ) THEN
345 transt = 'C'
346 ELSE
347 transt = 'N'
348 END IF
349 IF( nq.GT.k ) THEN
350*
351* P was determined by a call to CGEBRD with nq > k
352*
353 CALL cunmlq( side, transt, m, n, k, a, lda, tau, c, ldc,
354 $ work, lwork, iinfo )
355 ELSE IF( nq.GT.1 ) THEN
356*
357* P was determined by a call to CGEBRD with nq <= k
358*
359 IF( left ) THEN
360 mi = m - 1
361 ni = n
362 i1 = 2
363 i2 = 1
364 ELSE
365 mi = m
366 ni = n - 1
367 i1 = 1
368 i2 = 2
369 END IF
370 CALL cunmlq( side, transt, mi, ni, nq-1, a( 1, 2 ), lda,
371 $ tau, c( i1, i2 ), ldc, work, lwork, iinfo )
372 END IF
373 END IF
374 work( 1 ) = sroundup_lwork(lwkopt)
375 RETURN
376*
377* End of CUNMBR
378*
subroutine xerbla(srname, info)
Definition cblat2.f:3285
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
Definition ilaenv.f:160
logical function lsame(ca, cb)
LSAME
Definition lsame.f:48
real function sroundup_lwork(lwork)
SROUNDUP_LWORK
subroutine cunmlq(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
CUNMLQ
Definition cunmlq.f:166
subroutine cunmqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
CUNMQR
Definition cunmqr.f:166
Here is the call graph for this function:
Here is the caller graph for this function: