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

◆ zgghd3()

subroutine zgghd3 ( character compq,
character compz,
integer n,
integer ilo,
integer ihi,
complex*16, dimension( lda, * ) a,
integer lda,
complex*16, dimension( ldb, * ) b,
integer ldb,
complex*16, dimension( ldq, * ) q,
integer ldq,
complex*16, dimension( ldz, * ) z,
integer ldz,
complex*16, dimension( * ) work,
integer lwork,
integer info )

ZGGHD3

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

Purpose:
!>
!> ZGGHD3 reduces a pair of complex matrices (A,B) to generalized upper
!> Hessenberg form using unitary transformations, where A is a
!> general matrix and B is upper triangular.  The form of the
!> generalized eigenvalue problem is
!>    A*x = lambda*B*x,
!> and B is typically made upper triangular by computing its QR
!> factorization and moving the unitary matrix Q to the left side
!> of the equation.
!>
!> This subroutine simultaneously reduces A to a Hessenberg matrix H:
!>    Q**H*A*Z = H
!> and transforms B to another upper triangular matrix T:
!>    Q**H*B*Z = T
!> in order to reduce the problem to its standard form
!>    H*y = lambda*T*y
!> where y = Z**H*x.
!>
!> The unitary matrices Q and Z are determined as products of Givens
!> rotations.  They may either be formed explicitly, or they may be
!> postmultiplied into input matrices Q1 and Z1, so that
!>      Q1 * A * Z1**H = (Q1*Q) * H * (Z1*Z)**H
!>      Q1 * B * Z1**H = (Q1*Q) * T * (Z1*Z)**H
!> If Q1 is the unitary matrix from the QR factorization of B in the
!> original equation A*x = lambda*B*x, then ZGGHD3 reduces the original
!> problem to generalized Hessenberg form.
!>
!> This is a blocked variant of CGGHRD, using matrix-matrix
!> multiplications for parts of the computation to enhance performance.
!> 
Parameters
[in]COMPQ
!>          COMPQ is CHARACTER*1
!>          = 'N': do not compute Q;
!>          = 'I': Q is initialized to the unit matrix, and the
!>                 unitary matrix Q is returned;
!>          = 'V': Q must contain a unitary matrix Q1 on entry,
!>                 and the product Q1*Q is returned.
!> 
[in]COMPZ
!>          COMPZ is CHARACTER*1
!>          = 'N': do not compute Z;
!>          = 'I': Z is initialized to the unit matrix, and the
!>                 unitary matrix Z is returned;
!>          = 'V': Z must contain a unitary matrix Z1 on entry,
!>                 and the product Z1*Z is returned.
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrices A and B.  N >= 0.
!> 
[in]ILO
!>          ILO is INTEGER
!> 
[in]IHI
!>          IHI is INTEGER
!>
!>          ILO and IHI mark the rows and columns of A which are to be
!>          reduced.  It is assumed that A is already upper triangular
!>          in rows and columns 1:ILO-1 and IHI+1:N.  ILO and IHI are
!>          normally set by a previous call to ZGGBAL; otherwise they
!>          should be set to 1 and N respectively.
!>          1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
!> 
[in,out]A
!>          A is COMPLEX*16 array, dimension (LDA, N)
!>          On entry, the N-by-N general matrix to be reduced.
!>          On exit, the upper triangle and the first subdiagonal of A
!>          are overwritten with the upper Hessenberg matrix H, and the
!>          rest is set to zero.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,N).
!> 
[in,out]B
!>          B is COMPLEX*16 array, dimension (LDB, N)
!>          On entry, the N-by-N upper triangular matrix B.
!>          On exit, the upper triangular matrix T = Q**H B Z.  The
!>          elements below the diagonal are set to zero.
!> 
[in]LDB
!>          LDB is INTEGER
!>          The leading dimension of the array B.  LDB >= max(1,N).
!> 
[in,out]Q
!>          Q is COMPLEX*16 array, dimension (LDQ, N)
!>          On entry, if COMPQ = 'V', the unitary matrix Q1, typically
!>          from the QR factorization of B.
!>          On exit, if COMPQ='I', the unitary matrix Q, and if
!>          COMPQ = 'V', the product Q1*Q.
!>          Not referenced if COMPQ='N'.
!> 
[in]LDQ
!>          LDQ is INTEGER
!>          The leading dimension of the array Q.
!>          LDQ >= N if COMPQ='V' or 'I'; LDQ >= 1 otherwise.
!> 
[in,out]Z
!>          Z is COMPLEX*16 array, dimension (LDZ, N)
!>          On entry, if COMPZ = 'V', the unitary matrix Z1.
!>          On exit, if COMPZ='I', the unitary matrix Z, and if
!>          COMPZ = 'V', the product Z1*Z.
!>          Not referenced if COMPZ='N'.
!> 
[in]LDZ
!>          LDZ is INTEGER
!>          The leading dimension of the array Z.
!>          LDZ >= N if COMPZ='V' or 'I'; LDZ >= 1 otherwise.
!> 
[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 length of the array WORK. LWORK >= 1.
!>          For optimum performance LWORK >= 6*N*NB, where NB is the
!>          optimal blocksize.
!>
!>          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.
Further Details:
!>
!>  This routine reduces A to Hessenberg form and maintains B in triangular form
!>  using a blocked variant of Moler and Stewart's original algorithm,
!>  as described by Kagstrom, Kressner, Quintana-Orti, and Quintana-Orti
!>  (BIT 2008).
!> 

Definition at line 223 of file zgghd3.f.

226*
227* -- LAPACK computational routine --
228* -- LAPACK is a software package provided by Univ. of Tennessee, --
229* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
230*
231 IMPLICIT NONE
232*
233* .. Scalar Arguments ..
234 CHARACTER COMPQ, COMPZ
235 INTEGER IHI, ILO, INFO, LDA, LDB, LDQ, LDZ, N, LWORK
236* ..
237* .. Array Arguments ..
238 COMPLEX*16 A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
239 $ Z( LDZ, * ), WORK( * )
240* ..
241*
242* =====================================================================
243*
244* .. Parameters ..
245 COMPLEX*16 CONE, CZERO
246 parameter( cone = ( 1.0d+0, 0.0d+0 ),
247 $ czero = ( 0.0d+0, 0.0d+0 ) )
248* ..
249* .. Local Scalars ..
250 LOGICAL BLK22, INITQ, INITZ, LQUERY, WANTQ, WANTZ
251 CHARACTER*1 COMPQ2, COMPZ2
252 INTEGER COLA, I, IERR, J, J0, JCOL, JJ, JROW, K,
253 $ KACC22, LEN, LWKOPT, N2NB, NB, NBLST, NBMIN,
254 $ NH, NNB, NX, PPW, PPWO, PW, TOP, TOPQ
255 DOUBLE PRECISION C
256 COMPLEX*16 C1, C2, CTEMP, S, S1, S2, TEMP, TEMP1, TEMP2,
257 $ TEMP3
258* ..
259* .. External Functions ..
260 LOGICAL LSAME
261 INTEGER ILAENV
262 EXTERNAL ilaenv, lsame
263* ..
264* .. External Subroutines ..
265 EXTERNAL zgghrd, zlartg, zlaset, zunm22, zrot,
266 $ zgemm,
268* ..
269* .. Intrinsic Functions ..
270 INTRINSIC dble, dcmplx, dconjg, max
271* ..
272* .. Executable Statements ..
273*
274* Decode and test the input parameters.
275*
276 info = 0
277 nb = ilaenv( 1, 'ZGGHD3', ' ', n, ilo, ihi, -1 )
278 nh = ihi - ilo + 1
279 IF( nh.LE.1 ) THEN
280 lwkopt = 1
281 ELSE
282 lwkopt = 6*n*nb
283 END IF
284 work( 1 ) = dcmplx( lwkopt )
285 initq = lsame( compq, 'I' )
286 wantq = initq .OR. lsame( compq, 'V' )
287 initz = lsame( compz, 'I' )
288 wantz = initz .OR. lsame( compz, 'V' )
289 lquery = ( lwork.EQ.-1 )
290*
291 IF( .NOT.lsame( compq, 'N' ) .AND. .NOT.wantq ) THEN
292 info = -1
293 ELSE IF( .NOT.lsame( compz, 'N' ) .AND. .NOT.wantz ) THEN
294 info = -2
295 ELSE IF( n.LT.0 ) THEN
296 info = -3
297 ELSE IF( ilo.LT.1 ) THEN
298 info = -4
299 ELSE IF( ihi.GT.n .OR. ihi.LT.ilo-1 ) THEN
300 info = -5
301 ELSE IF( lda.LT.max( 1, n ) ) THEN
302 info = -7
303 ELSE IF( ldb.LT.max( 1, n ) ) THEN
304 info = -9
305 ELSE IF( ( wantq .AND. ldq.LT.n ) .OR. ldq.LT.1 ) THEN
306 info = -11
307 ELSE IF( ( wantz .AND. ldz.LT.n ) .OR. ldz.LT.1 ) THEN
308 info = -13
309 ELSE IF( lwork.LT.1 .AND. .NOT.lquery ) THEN
310 info = -15
311 END IF
312 IF( info.NE.0 ) THEN
313 CALL xerbla( 'ZGGHD3', -info )
314 RETURN
315 ELSE IF( lquery ) THEN
316 RETURN
317 END IF
318*
319* Initialize Q and Z if desired.
320*
321 IF( initq )
322 $ CALL zlaset( 'All', n, n, czero, cone, q, ldq )
323 IF( initz )
324 $ CALL zlaset( 'All', n, n, czero, cone, z, ldz )
325*
326* Zero out lower triangle of B.
327*
328 IF( n.GT.1 )
329 $ CALL zlaset( 'Lower', n-1, n-1, czero, czero, b(2, 1), ldb )
330*
331* Quick return if possible
332*
333 IF( nh.LE.1 ) THEN
334 work( 1 ) = cone
335 RETURN
336 END IF
337*
338* Determine the blocksize.
339*
340 nbmin = ilaenv( 2, 'ZGGHD3', ' ', n, ilo, ihi, -1 )
341 IF( nb.GT.1 .AND. nb.LT.nh ) THEN
342*
343* Determine when to use unblocked instead of blocked code.
344*
345 nx = max( nb, ilaenv( 3, 'ZGGHD3', ' ', n, ilo, ihi, -1 ) )
346 IF( nx.LT.nh ) THEN
347*
348* Determine if workspace is large enough for blocked code.
349*
350 IF( lwork.LT.lwkopt ) THEN
351*
352* Not enough workspace to use optimal NB: determine the
353* minimum value of NB, and reduce NB or force use of
354* unblocked code.
355*
356 nbmin = max( 2, ilaenv( 2, 'ZGGHD3', ' ', n, ilo, ihi,
357 $ -1 ) )
358 IF( lwork.GE.6*n*nbmin ) THEN
359 nb = lwork / ( 6*n )
360 ELSE
361 nb = 1
362 END IF
363 END IF
364 END IF
365 END IF
366*
367 IF( nb.LT.nbmin .OR. nb.GE.nh ) THEN
368*
369* Use unblocked code below
370*
371 jcol = ilo
372*
373 ELSE
374*
375* Use blocked code
376*
377 kacc22 = ilaenv( 16, 'ZGGHD3', ' ', n, ilo, ihi, -1 )
378 blk22 = kacc22.EQ.2
379 DO jcol = ilo, ihi-2, nb
380 nnb = min( nb, ihi-jcol-1 )
381*
382* Initialize small unitary factors that will hold the
383* accumulated Givens rotations in workspace.
384* N2NB denotes the number of 2*NNB-by-2*NNB factors
385* NBLST denotes the (possibly smaller) order of the last
386* factor.
387*
388 n2nb = ( ihi-jcol-1 ) / nnb - 1
389 nblst = ihi - jcol - n2nb*nnb
390 CALL zlaset( 'All', nblst, nblst, czero, cone, work,
391 $ nblst )
392 pw = nblst * nblst + 1
393 DO i = 1, n2nb
394 CALL zlaset( 'All', 2*nnb, 2*nnb, czero, cone,
395 $ work( pw ), 2*nnb )
396 pw = pw + 4*nnb*nnb
397 END DO
398*
399* Reduce columns JCOL:JCOL+NNB-1 of A to Hessenberg form.
400*
401 DO j = jcol, jcol+nnb-1
402*
403* Reduce Jth column of A. Store cosines and sines in Jth
404* column of A and B, respectively.
405*
406 DO i = ihi, j+2, -1
407 temp = a( i-1, j )
408 CALL zlartg( temp, a( i, j ), c, s, a( i-1, j ) )
409 a( i, j ) = dcmplx( c )
410 b( i, j ) = s
411 END DO
412*
413* Accumulate Givens rotations into workspace array.
414*
415 ppw = ( nblst + 1 )*( nblst - 2 ) - j + jcol + 1
416 len = 2 + j - jcol
417 jrow = j + n2nb*nnb + 2
418 DO i = ihi, jrow, -1
419 ctemp = a( i, j )
420 s = b( i, j )
421 DO jj = ppw, ppw+len-1
422 temp = work( jj + nblst )
423 work( jj + nblst ) = ctemp*temp - s*work( jj )
424 work( jj ) = dconjg( s )*temp + ctemp*work( jj )
425 END DO
426 len = len + 1
427 ppw = ppw - nblst - 1
428 END DO
429*
430 ppwo = nblst*nblst + ( nnb+j-jcol-1 )*2*nnb + nnb
431 j0 = jrow - nnb
432 DO jrow = j0, j+2, -nnb
433 ppw = ppwo
434 len = 2 + j - jcol
435 DO i = jrow+nnb-1, jrow, -1
436 ctemp = a( i, j )
437 s = b( i, j )
438 DO jj = ppw, ppw+len-1
439 temp = work( jj + 2*nnb )
440 work( jj + 2*nnb ) = ctemp*temp - s*work( jj )
441 work( jj ) = dconjg( s )*temp + ctemp*work( jj )
442 END DO
443 len = len + 1
444 ppw = ppw - 2*nnb - 1
445 END DO
446 ppwo = ppwo + 4*nnb*nnb
447 END DO
448*
449* TOP denotes the number of top rows in A and B that will
450* not be updated during the next steps.
451*
452 IF( jcol.LE.2 ) THEN
453 top = 0
454 ELSE
455 top = jcol
456 END IF
457*
458* Propagate transformations through B and replace stored
459* left sines/cosines by right sines/cosines.
460*
461 DO jj = n, j+1, -1
462*
463* Update JJth column of B.
464*
465 DO i = min( jj+1, ihi ), j+2, -1
466 ctemp = a( i, j )
467 s = b( i, j )
468 temp = b( i, jj )
469 b( i, jj ) = ctemp*temp - dconjg( s )*b( i-1, jj )
470 b( i-1, jj ) = s*temp + ctemp*b( i-1, jj )
471 END DO
472*
473* Annihilate B( JJ+1, JJ ).
474*
475 IF( jj.LT.ihi ) THEN
476 temp = b( jj+1, jj+1 )
477 CALL zlartg( temp, b( jj+1, jj ), c, s,
478 $ b( jj+1, jj+1 ) )
479 b( jj+1, jj ) = czero
480 CALL zrot( jj-top, b( top+1, jj+1 ), 1,
481 $ b( top+1, jj ), 1, c, s )
482 a( jj+1, j ) = dcmplx( c )
483 b( jj+1, j ) = -dconjg( s )
484 END IF
485 END DO
486*
487* Update A by transformations from right.
488*
489 jj = mod( ihi-j-1, 3 )
490 DO i = ihi-j-3, jj+1, -3
491 ctemp = a( j+1+i, j )
492 s = -b( j+1+i, j )
493 c1 = a( j+2+i, j )
494 s1 = -b( j+2+i, j )
495 c2 = a( j+3+i, j )
496 s2 = -b( j+3+i, j )
497*
498 DO k = top+1, ihi
499 temp = a( k, j+i )
500 temp1 = a( k, j+i+1 )
501 temp2 = a( k, j+i+2 )
502 temp3 = a( k, j+i+3 )
503 a( k, j+i+3 ) = c2*temp3 + dconjg( s2 )*temp2
504 temp2 = -s2*temp3 + c2*temp2
505 a( k, j+i+2 ) = c1*temp2 + dconjg( s1 )*temp1
506 temp1 = -s1*temp2 + c1*temp1
507 a( k, j+i+1 ) = ctemp*temp1 + dconjg( s )*temp
508 a( k, j+i ) = -s*temp1 + ctemp*temp
509 END DO
510 END DO
511*
512 IF( jj.GT.0 ) THEN
513 DO i = jj, 1, -1
514 c = dble( a( j+1+i, j ) )
515 CALL zrot( ihi-top, a( top+1, j+i+1 ), 1,
516 $ a( top+1, j+i ), 1, c,
517 $ -dconjg( b( j+1+i, j ) ) )
518 END DO
519 END IF
520*
521* Update (J+1)th column of A by transformations from left.
522*
523 IF ( j .LT. jcol + nnb - 1 ) THEN
524 len = 1 + j - jcol
525*
526* Multiply with the trailing accumulated unitary
527* matrix, which takes the form
528*
529* [ U11 U12 ]
530* U = [ ],
531* [ U21 U22 ]
532*
533* where U21 is a LEN-by-LEN matrix and U12 is lower
534* triangular.
535*
536 jrow = ihi - nblst + 1
537 CALL zgemv( 'Conjugate', nblst, len, cone, work,
538 $ nblst, a( jrow, j+1 ), 1, czero,
539 $ work( pw ), 1 )
540 ppw = pw + len
541 DO i = jrow, jrow+nblst-len-1
542 work( ppw ) = a( i, j+1 )
543 ppw = ppw + 1
544 END DO
545 CALL ztrmv( 'Lower', 'Conjugate', 'Non-unit',
546 $ nblst-len, work( len*nblst + 1 ), nblst,
547 $ work( pw+len ), 1 )
548 CALL zgemv( 'Conjugate', len, nblst-len, cone,
549 $ work( (len+1)*nblst - len + 1 ), nblst,
550 $ a( jrow+nblst-len, j+1 ), 1, cone,
551 $ work( pw+len ), 1 )
552 ppw = pw
553 DO i = jrow, jrow+nblst-1
554 a( i, j+1 ) = work( ppw )
555 ppw = ppw + 1
556 END DO
557*
558* Multiply with the other accumulated unitary
559* matrices, which take the form
560*
561* [ U11 U12 0 ]
562* [ ]
563* U = [ U21 U22 0 ],
564* [ ]
565* [ 0 0 I ]
566*
567* where I denotes the (NNB-LEN)-by-(NNB-LEN) identity
568* matrix, U21 is a LEN-by-LEN upper triangular matrix
569* and U12 is an NNB-by-NNB lower triangular matrix.
570*
571 ppwo = 1 + nblst*nblst
572 j0 = jrow - nnb
573 DO jrow = j0, jcol+1, -nnb
574 ppw = pw + len
575 DO i = jrow, jrow+nnb-1
576 work( ppw ) = a( i, j+1 )
577 ppw = ppw + 1
578 END DO
579 ppw = pw
580 DO i = jrow+nnb, jrow+nnb+len-1
581 work( ppw ) = a( i, j+1 )
582 ppw = ppw + 1
583 END DO
584 CALL ztrmv( 'Upper', 'Conjugate', 'Non-unit',
585 $ len,
586 $ work( ppwo + nnb ), 2*nnb, work( pw ),
587 $ 1 )
588 CALL ztrmv( 'Lower', 'Conjugate', 'Non-unit',
589 $ nnb,
590 $ work( ppwo + 2*len*nnb ),
591 $ 2*nnb, work( pw + len ), 1 )
592 CALL zgemv( 'Conjugate', nnb, len, cone,
593 $ work( ppwo ), 2*nnb, a( jrow, j+1 ), 1,
594 $ cone, work( pw ), 1 )
595 CALL zgemv( 'Conjugate', len, nnb, cone,
596 $ work( ppwo + 2*len*nnb + nnb ), 2*nnb,
597 $ a( jrow+nnb, j+1 ), 1, cone,
598 $ work( pw+len ), 1 )
599 ppw = pw
600 DO i = jrow, jrow+len+nnb-1
601 a( i, j+1 ) = work( ppw )
602 ppw = ppw + 1
603 END DO
604 ppwo = ppwo + 4*nnb*nnb
605 END DO
606 END IF
607 END DO
608*
609* Apply accumulated unitary matrices to A.
610*
611 cola = n - jcol - nnb + 1
612 j = ihi - nblst + 1
613 CALL zgemm( 'Conjugate', 'No Transpose', nblst,
614 $ cola, nblst, cone, work, nblst,
615 $ a( j, jcol+nnb ), lda, czero, work( pw ),
616 $ nblst )
617 CALL zlacpy( 'All', nblst, cola, work( pw ), nblst,
618 $ a( j, jcol+nnb ), lda )
619 ppwo = nblst*nblst + 1
620 j0 = j - nnb
621 DO j = j0, jcol+1, -nnb
622 IF ( blk22 ) THEN
623*
624* Exploit the structure of
625*
626* [ U11 U12 ]
627* U = [ ]
628* [ U21 U22 ],
629*
630* where all blocks are NNB-by-NNB, U21 is upper
631* triangular and U12 is lower triangular.
632*
633 CALL zunm22( 'Left', 'Conjugate', 2*nnb, cola, nnb,
634 $ nnb, work( ppwo ), 2*nnb,
635 $ a( j, jcol+nnb ), lda, work( pw ),
636 $ lwork-pw+1, ierr )
637 ELSE
638*
639* Ignore the structure of U.
640*
641 CALL zgemm( 'Conjugate', 'No Transpose', 2*nnb,
642 $ cola, 2*nnb, cone, work( ppwo ), 2*nnb,
643 $ a( j, jcol+nnb ), lda, czero, work( pw ),
644 $ 2*nnb )
645 CALL zlacpy( 'All', 2*nnb, cola, work( pw ), 2*nnb,
646 $ a( j, jcol+nnb ), lda )
647 END IF
648 ppwo = ppwo + 4*nnb*nnb
649 END DO
650*
651* Apply accumulated unitary matrices to Q.
652*
653 IF( wantq ) THEN
654 j = ihi - nblst + 1
655 IF ( initq ) THEN
656 topq = max( 2, j - jcol + 1 )
657 nh = ihi - topq + 1
658 ELSE
659 topq = 1
660 nh = n
661 END IF
662 CALL zgemm( 'No Transpose', 'No Transpose', nh,
663 $ nblst, nblst, cone, q( topq, j ), ldq,
664 $ work, nblst, czero, work( pw ), nh )
665 CALL zlacpy( 'All', nh, nblst, work( pw ), nh,
666 $ q( topq, j ), ldq )
667 ppwo = nblst*nblst + 1
668 j0 = j - nnb
669 DO j = j0, jcol+1, -nnb
670 IF ( initq ) THEN
671 topq = max( 2, j - jcol + 1 )
672 nh = ihi - topq + 1
673 END IF
674 IF ( blk22 ) THEN
675*
676* Exploit the structure of U.
677*
678 CALL zunm22( 'Right', 'No Transpose', nh, 2*nnb,
679 $ nnb, nnb, work( ppwo ), 2*nnb,
680 $ q( topq, j ), ldq, work( pw ),
681 $ lwork-pw+1, ierr )
682 ELSE
683*
684* Ignore the structure of U.
685*
686 CALL zgemm( 'No Transpose', 'No Transpose', nh,
687 $ 2*nnb, 2*nnb, cone, q( topq, j ), ldq,
688 $ work( ppwo ), 2*nnb, czero, work( pw ),
689 $ nh )
690 CALL zlacpy( 'All', nh, 2*nnb, work( pw ), nh,
691 $ q( topq, j ), ldq )
692 END IF
693 ppwo = ppwo + 4*nnb*nnb
694 END DO
695 END IF
696*
697* Accumulate right Givens rotations if required.
698*
699 IF ( wantz .OR. top.GT.0 ) THEN
700*
701* Initialize small unitary factors that will hold the
702* accumulated Givens rotations in workspace.
703*
704 CALL zlaset( 'All', nblst, nblst, czero, cone, work,
705 $ nblst )
706 pw = nblst * nblst + 1
707 DO i = 1, n2nb
708 CALL zlaset( 'All', 2*nnb, 2*nnb, czero, cone,
709 $ work( pw ), 2*nnb )
710 pw = pw + 4*nnb*nnb
711 END DO
712*
713* Accumulate Givens rotations into workspace array.
714*
715 DO j = jcol, jcol+nnb-1
716 ppw = ( nblst + 1 )*( nblst - 2 ) - j + jcol + 1
717 len = 2 + j - jcol
718 jrow = j + n2nb*nnb + 2
719 DO i = ihi, jrow, -1
720 ctemp = a( i, j )
721 a( i, j ) = czero
722 s = b( i, j )
723 b( i, j ) = czero
724 DO jj = ppw, ppw+len-1
725 temp = work( jj + nblst )
726 work( jj + nblst ) = ctemp*temp -
727 $ dconjg( s )*work( jj )
728 work( jj ) = s*temp + ctemp*work( jj )
729 END DO
730 len = len + 1
731 ppw = ppw - nblst - 1
732 END DO
733*
734 ppwo = nblst*nblst + ( nnb+j-jcol-1 )*2*nnb + nnb
735 j0 = jrow - nnb
736 DO jrow = j0, j+2, -nnb
737 ppw = ppwo
738 len = 2 + j - jcol
739 DO i = jrow+nnb-1, jrow, -1
740 ctemp = a( i, j )
741 a( i, j ) = czero
742 s = b( i, j )
743 b( i, j ) = czero
744 DO jj = ppw, ppw+len-1
745 temp = work( jj + 2*nnb )
746 work( jj + 2*nnb ) = ctemp*temp -
747 $ dconjg( s )*work( jj )
748 work( jj ) = s*temp + ctemp*work( jj )
749 END DO
750 len = len + 1
751 ppw = ppw - 2*nnb - 1
752 END DO
753 ppwo = ppwo + 4*nnb*nnb
754 END DO
755 END DO
756 ELSE
757*
758 CALL zlaset( 'Lower', ihi - jcol - 1, nnb, czero,
759 $ czero,
760 $ a( jcol + 2, jcol ), lda )
761 CALL zlaset( 'Lower', ihi - jcol - 1, nnb, czero,
762 $ czero,
763 $ b( jcol + 2, jcol ), ldb )
764 END IF
765*
766* Apply accumulated unitary matrices to A and B.
767*
768 IF ( top.GT.0 ) THEN
769 j = ihi - nblst + 1
770 CALL zgemm( 'No Transpose', 'No Transpose', top,
771 $ nblst, nblst, cone, a( 1, j ), lda,
772 $ work, nblst, czero, work( pw ), top )
773 CALL zlacpy( 'All', top, nblst, work( pw ), top,
774 $ a( 1, j ), lda )
775 ppwo = nblst*nblst + 1
776 j0 = j - nnb
777 DO j = j0, jcol+1, -nnb
778 IF ( blk22 ) THEN
779*
780* Exploit the structure of U.
781*
782 CALL zunm22( 'Right', 'No Transpose', top,
783 $ 2*nnb,
784 $ nnb, nnb, work( ppwo ), 2*nnb,
785 $ a( 1, j ), lda, work( pw ),
786 $ lwork-pw+1, ierr )
787 ELSE
788*
789* Ignore the structure of U.
790*
791 CALL zgemm( 'No Transpose', 'No Transpose', top,
792 $ 2*nnb, 2*nnb, cone, a( 1, j ), lda,
793 $ work( ppwo ), 2*nnb, czero,
794 $ work( pw ), top )
795 CALL zlacpy( 'All', top, 2*nnb, work( pw ), top,
796 $ a( 1, j ), lda )
797 END IF
798 ppwo = ppwo + 4*nnb*nnb
799 END DO
800*
801 j = ihi - nblst + 1
802 CALL zgemm( 'No Transpose', 'No Transpose', top,
803 $ nblst, nblst, cone, b( 1, j ), ldb,
804 $ work, nblst, czero, work( pw ), top )
805 CALL zlacpy( 'All', top, nblst, work( pw ), top,
806 $ b( 1, j ), ldb )
807 ppwo = nblst*nblst + 1
808 j0 = j - nnb
809 DO j = j0, jcol+1, -nnb
810 IF ( blk22 ) THEN
811*
812* Exploit the structure of U.
813*
814 CALL zunm22( 'Right', 'No Transpose', top,
815 $ 2*nnb,
816 $ nnb, nnb, work( ppwo ), 2*nnb,
817 $ b( 1, j ), ldb, work( pw ),
818 $ lwork-pw+1, ierr )
819 ELSE
820*
821* Ignore the structure of U.
822*
823 CALL zgemm( 'No Transpose', 'No Transpose', top,
824 $ 2*nnb, 2*nnb, cone, b( 1, j ), ldb,
825 $ work( ppwo ), 2*nnb, czero,
826 $ work( pw ), top )
827 CALL zlacpy( 'All', top, 2*nnb, work( pw ), top,
828 $ b( 1, j ), ldb )
829 END IF
830 ppwo = ppwo + 4*nnb*nnb
831 END DO
832 END IF
833*
834* Apply accumulated unitary matrices to Z.
835*
836 IF( wantz ) THEN
837 j = ihi - nblst + 1
838 IF ( initq ) THEN
839 topq = max( 2, j - jcol + 1 )
840 nh = ihi - topq + 1
841 ELSE
842 topq = 1
843 nh = n
844 END IF
845 CALL zgemm( 'No Transpose', 'No Transpose', nh,
846 $ nblst, nblst, cone, z( topq, j ), ldz,
847 $ work, nblst, czero, work( pw ), nh )
848 CALL zlacpy( 'All', nh, nblst, work( pw ), nh,
849 $ z( topq, j ), ldz )
850 ppwo = nblst*nblst + 1
851 j0 = j - nnb
852 DO j = j0, jcol+1, -nnb
853 IF ( initq ) THEN
854 topq = max( 2, j - jcol + 1 )
855 nh = ihi - topq + 1
856 END IF
857 IF ( blk22 ) THEN
858*
859* Exploit the structure of U.
860*
861 CALL zunm22( 'Right', 'No Transpose', nh, 2*nnb,
862 $ nnb, nnb, work( ppwo ), 2*nnb,
863 $ z( topq, j ), ldz, work( pw ),
864 $ lwork-pw+1, ierr )
865 ELSE
866*
867* Ignore the structure of U.
868*
869 CALL zgemm( 'No Transpose', 'No Transpose', nh,
870 $ 2*nnb, 2*nnb, cone, z( topq, j ), ldz,
871 $ work( ppwo ), 2*nnb, czero, work( pw ),
872 $ nh )
873 CALL zlacpy( 'All', nh, 2*nnb, work( pw ), nh,
874 $ z( topq, j ), ldz )
875 END IF
876 ppwo = ppwo + 4*nnb*nnb
877 END DO
878 END IF
879 END DO
880 END IF
881*
882* Use unblocked code to reduce the rest of the matrix
883* Avoid re-initialization of modified Q and Z.
884*
885 compq2 = compq
886 compz2 = compz
887 IF ( jcol.NE.ilo ) THEN
888 IF ( wantq )
889 $ compq2 = 'V'
890 IF ( wantz )
891 $ compz2 = 'V'
892 END IF
893*
894 IF ( jcol.LT.ihi )
895 $ CALL zgghrd( compq2, compz2, n, jcol, ihi, a, lda, b, ldb,
896 $ q,
897 $ ldq, z, ldz, ierr )
898*
899 work( 1 ) = dcmplx( lwkopt )
900*
901 RETURN
902*
903* End of ZGGHD3
904*
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine zgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
ZGEMM
Definition zgemm.f:188
subroutine zgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
ZGEMV
Definition zgemv.f:160
subroutine zgghrd(compq, compz, n, ilo, ihi, a, lda, b, ldb, q, ldq, z, ldz, info)
ZGGHRD
Definition zgghrd.f:203
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
Definition ilaenv.f:160
subroutine zlacpy(uplo, m, n, a, lda, b, ldb)
ZLACPY copies all or part of one two-dimensional array to another.
Definition zlacpy.f:101
subroutine zlartg(f, g, c, s, r)
ZLARTG generates a plane rotation with real cosine and complex sine.
Definition zlartg.f90:116
subroutine zlaset(uplo, m, n, alpha, beta, a, lda)
ZLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
Definition zlaset.f:104
logical function lsame(ca, cb)
LSAME
Definition lsame.f:48
subroutine zrot(n, cx, incx, cy, incy, c, s)
ZROT applies a plane rotation with real cosine and complex sine to a pair of complex vectors.
Definition zrot.f:101
subroutine ztrmv(uplo, trans, diag, n, a, lda, x, incx)
ZTRMV
Definition ztrmv.f:147
subroutine zunm22(side, trans, m, n, n1, n2, q, ldq, c, ldc, work, lwork, info)
ZUNM22 multiplies a general matrix by a banded unitary matrix.
Definition zunm22.f:160
Here is the call graph for this function:
Here is the caller graph for this function: