LAPACK  3.9.1
LAPACK: Linear Algebra PACKage

◆ zunmbr()

subroutine zunmbr ( character  VECT,
character  SIDE,
character  TRANS,
integer  M,
integer  N,
integer  K,
complex*16, dimension( lda, * )  A,
integer  LDA,
complex*16, dimension( * )  TAU,
complex*16, dimension( ldc, * )  C,
integer  LDC,
complex*16, dimension( * )  WORK,
integer  LWORK,
integer  INFO 
)

ZUNMBR

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

Purpose:
 If VECT = 'Q', ZUNMBR 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', ZUNMBR 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 ZGEBRD 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 ZGEBRD.
          If VECT = 'P', the number of rows in the original
          matrix reduced by ZGEBRD.
          K >= 0.
[in]A
          A is COMPLEX*16 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 ZGEBRD.
[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*16 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 ZGEBRD in the array argument TAUQ or TAUP.
[in,out]C
          C is COMPLEX*16 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*16 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 194 of file zunmbr.f.

196 *
197 * -- LAPACK computational routine --
198 * -- LAPACK is a software package provided by Univ. of Tennessee, --
199 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
200 *
201 * .. Scalar Arguments ..
202  CHARACTER SIDE, TRANS, VECT
203  INTEGER INFO, K, LDA, LDC, LWORK, M, N
204 * ..
205 * .. Array Arguments ..
206  COMPLEX*16 A( LDA, * ), C( LDC, * ), TAU( * ), 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  EXTERNAL lsame, ilaenv
220 * ..
221 * .. External Subroutines ..
222  EXTERNAL xerbla, zunmlq, zunmqr
223 * ..
224 * .. Intrinsic Functions ..
225  INTRINSIC max, min
226 * ..
227 * .. Executable Statements ..
228 *
229 * Test the input arguments
230 *
231  info = 0
232  applyq = lsame( vect, 'Q' )
233  left = lsame( side, 'L' )
234  notran = lsame( trans, 'N' )
235  lquery = ( lwork.EQ.-1 )
236 *
237 * NQ is the order of Q or P and NW is the minimum dimension of WORK
238 *
239  IF( left ) THEN
240  nq = m
241  nw = n
242  ELSE
243  nq = n
244  nw = m
245  END IF
246  IF( m.EQ.0 .OR. n.EQ.0 ) THEN
247  nw = 0
248  END IF
249  IF( .NOT.applyq .AND. .NOT.lsame( vect, 'P' ) ) THEN
250  info = -1
251  ELSE IF( .NOT.left .AND. .NOT.lsame( side, 'R' ) ) THEN
252  info = -2
253  ELSE IF( .NOT.notran .AND. .NOT.lsame( trans, 'C' ) ) THEN
254  info = -3
255  ELSE IF( m.LT.0 ) THEN
256  info = -4
257  ELSE IF( n.LT.0 ) THEN
258  info = -5
259  ELSE IF( k.LT.0 ) THEN
260  info = -6
261  ELSE IF( ( applyq .AND. lda.LT.max( 1, nq ) ) .OR.
262  $ ( .NOT.applyq .AND. lda.LT.max( 1, min( nq, k ) ) ) )
263  $ THEN
264  info = -8
265  ELSE IF( ldc.LT.max( 1, m ) ) THEN
266  info = -11
267  ELSE IF( lwork.LT.max( 1, nw ) .AND. .NOT.lquery ) THEN
268  info = -13
269  END IF
270 *
271  IF( info.EQ.0 ) THEN
272  IF( nw.GT.0 ) THEN
273  IF( applyq ) THEN
274  IF( left ) THEN
275  nb = ilaenv( 1, 'ZUNMQR', side // trans, m-1, n, m-1,
276  $ -1 )
277  ELSE
278  nb = ilaenv( 1, 'ZUNMQR', side // trans, m, n-1, n-1,
279  $ -1 )
280  END IF
281  ELSE
282  IF( left ) THEN
283  nb = ilaenv( 1, 'ZUNMLQ', side // trans, m-1, n, m-1,
284  $ -1 )
285  ELSE
286  nb = ilaenv( 1, 'ZUNMLQ', side // trans, m, n-1, n-1,
287  $ -1 )
288  END IF
289  END IF
290  lwkopt = max( 1, nw*nb )
291  ELSE
292  lwkopt = 1
293  END IF
294  work( 1 ) = lwkopt
295  END IF
296 *
297  IF( info.NE.0 ) THEN
298  CALL xerbla( 'ZUNMBR', -info )
299  RETURN
300  ELSE IF( lquery ) THEN
301  RETURN
302  END IF
303 *
304 * Quick return if possible
305 *
306  IF( m.EQ.0 .OR. n.EQ.0 )
307  $ RETURN
308 *
309  IF( applyq ) THEN
310 *
311 * Apply Q
312 *
313  IF( nq.GE.k ) THEN
314 *
315 * Q was determined by a call to ZGEBRD with nq >= k
316 *
317  CALL zunmqr( side, trans, m, n, k, a, lda, tau, c, ldc,
318  $ work, lwork, iinfo )
319  ELSE IF( nq.GT.1 ) THEN
320 *
321 * Q was determined by a call to ZGEBRD with nq < k
322 *
323  IF( left ) THEN
324  mi = m - 1
325  ni = n
326  i1 = 2
327  i2 = 1
328  ELSE
329  mi = m
330  ni = n - 1
331  i1 = 1
332  i2 = 2
333  END IF
334  CALL zunmqr( side, trans, mi, ni, nq-1, a( 2, 1 ), lda, tau,
335  $ c( i1, i2 ), ldc, work, lwork, iinfo )
336  END IF
337  ELSE
338 *
339 * Apply P
340 *
341  IF( notran ) THEN
342  transt = 'C'
343  ELSE
344  transt = 'N'
345  END IF
346  IF( nq.GT.k ) THEN
347 *
348 * P was determined by a call to ZGEBRD with nq > k
349 *
350  CALL zunmlq( side, transt, m, n, k, a, lda, tau, c, ldc,
351  $ work, lwork, iinfo )
352  ELSE IF( nq.GT.1 ) THEN
353 *
354 * P was determined by a call to ZGEBRD with nq <= k
355 *
356  IF( left ) THEN
357  mi = m - 1
358  ni = n
359  i1 = 2
360  i2 = 1
361  ELSE
362  mi = m
363  ni = n - 1
364  i1 = 1
365  i2 = 2
366  END IF
367  CALL zunmlq( side, transt, mi, ni, nq-1, a( 1, 2 ), lda,
368  $ tau, c( i1, i2 ), ldc, work, lwork, iinfo )
369  END IF
370  END IF
371  work( 1 ) = lwkopt
372  RETURN
373 *
374 * End of ZUNMBR
375 *
integer function ilaenv(ISPEC, NAME, OPTS, N1, N2, N3, N4)
ILAENV
Definition: ilaenv.f:162
subroutine xerbla(SRNAME, INFO)
XERBLA
Definition: xerbla.f:60
logical function lsame(CA, CB)
LSAME
Definition: lsame.f:53
subroutine zunmlq(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
ZUNMLQ
Definition: zunmlq.f:167
subroutine zunmqr(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
ZUNMQR
Definition: zunmqr.f:167
Here is the call graph for this function:
Here is the caller graph for this function: