OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
cgghd3.f
Go to the documentation of this file.
1*> \brief \b CGGHD3
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> \htmlonly
9*> Download CGGHD3 + dependencies
10*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cgghd3.f">
11*> [TGZ]</a>
12*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/cgghd3.f">
13*> [ZIP]</a>
14*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cgghd3.f">
15*> [TXT]</a>
16*> \endhtmlonly
17*
18* Definition:
19* ===========
20*
21* SUBROUTINE CGGHD3( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q,
22* $ LDQ, Z, LDZ, WORK, LWORK, INFO )
23*
24* .. Scalar Arguments ..
25* CHARACTER COMPQ, COMPZ
26* INTEGER IHI, ILO, INFO, LDA, LDB, LDQ, LDZ, N, LWORK
27* ..
28* .. Array Arguments ..
29* COMPLEX A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
30* $ Z( LDZ, * ), WORK( * )
31* ..
32*
33*
34*> \par Purpose:
35* =============
36*>
37*> \verbatim
38*>
39*>
40*> CGGHD3 reduces a pair of complex matrices (A,B) to generalized upper
41*> Hessenberg form using unitary transformations, where A is a
42*> general matrix and B is upper triangular. The form of the
43*> generalized eigenvalue problem is
44*> A*x = lambda*B*x,
45*> and B is typically made upper triangular by computing its QR
46*> factorization and moving the unitary matrix Q to the left side
47*> of the equation.
48*>
49*> This subroutine simultaneously reduces A to a Hessenberg matrix H:
50*> Q**H*A*Z = H
51*> and transforms B to another upper triangular matrix T:
52*> Q**H*B*Z = T
53*> in order to reduce the problem to its standard form
54*> H*y = lambda*T*y
55*> where y = Z**H*x.
56*>
57*> The unitary matrices Q and Z are determined as products of Givens
58*> rotations. They may either be formed explicitly, or they may be
59*> postmultiplied into input matrices Q1 and Z1, so that
60*>
61*> Q1 * A * Z1**H = (Q1*Q) * H * (Z1*Z)**H
62*>
63*> Q1 * B * Z1**H = (Q1*Q) * T * (Z1*Z)**H
64*>
65*> If Q1 is the unitary matrix from the QR factorization of B in the
66*> original equation A*x = lambda*B*x, then CGGHD3 reduces the original
67*> problem to generalized Hessenberg form.
68*>
69*> This is a blocked variant of CGGHRD, using matrix-matrix
70*> multiplications for parts of the computation to enhance performance.
71*> \endverbatim
72*
73* Arguments:
74* ==========
75*
76*> \param[in] COMPQ
77*> \verbatim
78*> COMPQ is CHARACTER*1
79*> = 'N': do not compute Q;
80*> = 'I': Q is initialized to the unit matrix, and the
81*> unitary matrix Q is returned;
82*> = 'V': Q must contain a unitary matrix Q1 on entry,
83*> and the product Q1*Q is returned.
84*> \endverbatim
85*>
86*> \param[in] COMPZ
87*> \verbatim
88*> COMPZ is CHARACTER*1
89*> = 'N': do not compute Z;
90*> = 'I': Z is initialized to the unit matrix, and the
91*> unitary matrix Z is returned;
92*> = 'V': Z must contain a unitary matrix Z1 on entry,
93*> and the product Z1*Z is returned.
94*> \endverbatim
95*>
96*> \param[in] N
97*> \verbatim
98*> N is INTEGER
99*> The order of the matrices A and B. N >= 0.
100*> \endverbatim
101*>
102*> \param[in] ILO
103*> \verbatim
104*> ILO is INTEGER
105*> \endverbatim
106*>
107*> \param[in] IHI
108*> \verbatim
109*> IHI is INTEGER
110*>
111*> ILO and IHI mark the rows and columns of A which are to be
112*> reduced. It is assumed that A is already upper triangular
113*> in rows and columns 1:ILO-1 and IHI+1:N. ILO and IHI are
114*> normally set by a previous call to CGGBAL; otherwise they
115*> should be set to 1 and N respectively.
116*> 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
117*> \endverbatim
118*>
119*> \param[in,out] A
120*> \verbatim
121*> A is COMPLEX array, dimension (LDA, N)
122*> On entry, the N-by-N general matrix to be reduced.
123*> On exit, the upper triangle and the first subdiagonal of A
124*> are overwritten with the upper Hessenberg matrix H, and the
125*> rest is set to zero.
126*> \endverbatim
127*>
128*> \param[in] LDA
129*> \verbatim
130*> LDA is INTEGER
131*> The leading dimension of the array A. LDA >= max(1,N).
132*> \endverbatim
133*>
134*> \param[in,out] B
135*> \verbatim
136*> B is COMPLEX array, dimension (LDB, N)
137*> On entry, the N-by-N upper triangular matrix B.
138*> On exit, the upper triangular matrix T = Q**H B Z. The
139*> elements below the diagonal are set to zero.
140*> \endverbatim
141*>
142*> \param[in] LDB
143*> \verbatim
144*> LDB is INTEGER
145*> The leading dimension of the array B. LDB >= max(1,N).
146*> \endverbatim
147*>
148*> \param[in,out] Q
149*> \verbatim
150*> Q is COMPLEX array, dimension (LDQ, N)
151*> On entry, if COMPQ = 'V', the unitary matrix Q1, typically
152*> from the QR factorization of B.
153*> On exit, if COMPQ='I', the unitary matrix Q, and if
154*> COMPQ = 'V', the product Q1*Q.
155*> Not referenced if COMPQ='N'.
156*> \endverbatim
157*>
158*> \param[in] LDQ
159*> \verbatim
160*> LDQ is INTEGER
161*> The leading dimension of the array Q.
162*> LDQ >= N if COMPQ='V' or 'I'; LDQ >= 1 otherwise.
163*> \endverbatim
164*>
165*> \param[in,out] Z
166*> \verbatim
167*> Z is COMPLEX array, dimension (LDZ, N)
168*> On entry, if COMPZ = 'V', the unitary matrix Z1.
169*> On exit, if COMPZ='I', the unitary matrix Z, and if
170*> COMPZ = 'V', the product Z1*Z.
171*> Not referenced if COMPZ='N'.
172*> \endverbatim
173*>
174*> \param[in] LDZ
175*> \verbatim
176*> LDZ is INTEGER
177*> The leading dimension of the array Z.
178*> LDZ >= N if COMPZ='V' or 'I'; LDZ >= 1 otherwise.
179*> \endverbatim
180*>
181*> \param[out] WORK
182*> \verbatim
183*> WORK is COMPLEX array, dimension (LWORK)
184*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
185*> \endverbatim
186*>
187*> \param[in] LWORK
188*> \verbatim
189*> LWORK is INTEGER
190*> The length of the array WORK. LWORK >= 1.
191*> For optimum performance LWORK >= 6*N*NB, where NB is the
192*> optimal blocksize.
193*>
194*> If LWORK = -1, then a workspace query is assumed; the routine
195*> only calculates the optimal size of the WORK array, returns
196*> this value as the first entry of the WORK array, and no error
197*> message related to LWORK is issued by XERBLA.
198*> \endverbatim
199*>
200*> \param[out] INFO
201*> \verbatim
202*> INFO is INTEGER
203*> = 0: successful exit.
204*> < 0: if INFO = -i, the i-th argument had an illegal value.
205*> \endverbatim
206*
207* Authors:
208* ========
209*
210*> \author Univ. of Tennessee
211*> \author Univ. of California Berkeley
212*> \author Univ. of Colorado Denver
213*> \author NAG Ltd.
214*
215*> \ingroup complexOTHERcomputational
216*
217*> \par Further Details:
218* =====================
219*>
220*> \verbatim
221*>
222*> This routine reduces A to Hessenberg form and maintains B in triangular form
223*> using a blocked variant of Moler and Stewart's original algorithm,
224*> as described by Kagstrom, Kressner, Quintana-Orti, and Quintana-Orti
225*> (BIT 2008).
226*> \endverbatim
227*>
228* =====================================================================
229 SUBROUTINE cgghd3( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q,
230 $ LDQ, Z, LDZ, WORK, LWORK, INFO )
231*
232* -- LAPACK computational routine --
233* -- LAPACK is a software package provided by Univ. of Tennessee, --
234* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
235*
236*
237 IMPLICIT NONE
238*
239* .. Scalar Arguments ..
240 CHARACTER COMPQ, COMPZ
241 INTEGER IHI, ILO, INFO, LDA, LDB, LDQ, LDZ, N, LWORK
242* ..
243* .. Array Arguments ..
244 COMPLEX A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
245 $ z( ldz, * ), work( * )
246* ..
247*
248* =====================================================================
249*
250* .. Parameters ..
251 COMPLEX CONE, CZERO
252 parameter( cone = ( 1.0e+0, 0.0e+0 ),
253 $ czero = ( 0.0e+0, 0.0e+0 ) )
254* ..
255* .. Local Scalars ..
256 LOGICAL BLK22, INITQ, INITZ, LQUERY, WANTQ, WANTZ
257 CHARACTER*1 COMPQ2, COMPZ2
258 INTEGER COLA, I, IERR, J, J0, JCOL, JJ, JROW, K,
259 $ kacc22, len, lwkopt, n2nb, nb, nblst, nbmin,
260 $ nh, nnb, nx, ppw, ppwo, pw, top, topq
261 REAL C
262 COMPLEX C1, C2, CTEMP, S, S1, S2, TEMP, TEMP1, TEMP2,
263 $ temp3
264* ..
265* .. External Functions ..
266 LOGICAL LSAME
267 INTEGER ILAENV
268 EXTERNAL ilaenv, lsame
269* ..
270* .. External Subroutines ..
271 EXTERNAL cgghrd, clartg, claset, cunm22, crot, cgemm,
273* ..
274* .. Intrinsic Functions ..
275 INTRINSIC real, cmplx, conjg, max
276* ..
277* .. Executable Statements ..
278*
279* Decode and test the input parameters.
280*
281 info = 0
282 nb = ilaenv( 1, 'CGGHD3', ' ', n, ilo, ihi, -1 )
283 lwkopt = max( 6*n*nb, 1 )
284 work( 1 ) = cmplx( 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( 'CGGHD3', -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 claset( 'All', n, n, czero, cone, q, ldq )
323 IF( initz )
324 $ CALL claset( 'All', n, n, czero, cone, z, ldz )
325*
326* Zero out lower triangle of B.
327*
328 IF( n.GT.1 )
329 $ CALL claset( 'Lower', n-1, n-1, czero, czero, b(2, 1), ldb )
330*
331* Quick return if possible
332*
333 nh = ihi - ilo + 1
334 IF( nh.LE.1 ) THEN
335 work( 1 ) = cone
336 RETURN
337 END IF
338*
339* Determine the blocksize.
340*
341 nbmin = ilaenv( 2, 'CGGHD3', ' ', n, ilo, ihi, -1 )
342 IF( nb.GT.1 .AND. nb.LT.nh ) THEN
343*
344* Determine when to use unblocked instead of blocked code.
345*
346 nx = max( nb, ilaenv( 3, 'CGGHD3', ' ', n, ilo, ihi, -1 ) )
347 IF( nx.LT.nh ) THEN
348*
349* Determine if workspace is large enough for blocked code.
350*
351 IF( lwork.LT.lwkopt ) THEN
352*
353* Not enough workspace to use optimal NB: determine the
354* minimum value of NB, and reduce NB or force use of
355* unblocked code.
356*
357 nbmin = max( 2, ilaenv( 2, 'CGGHD3', ' ', n, ilo, ihi,
358 $ -1 ) )
359 IF( lwork.GE.6*n*nbmin ) THEN
360 nb = lwork / ( 6*n )
361 ELSE
362 nb = 1
363 END IF
364 END IF
365 END IF
366 END IF
367*
368 IF( nb.LT.nbmin .OR. nb.GE.nh ) THEN
369*
370* Use unblocked code below
371*
372 jcol = ilo
373*
374 ELSE
375*
376* Use blocked code
377*
378 kacc22 = ilaenv( 16, 'CGGHD3', ' ', n, ilo, ihi, -1 )
379 blk22 = kacc22.EQ.2
380 DO jcol = ilo, ihi-2, nb
381 nnb = min( nb, ihi-jcol-1 )
382*
383* Initialize small unitary factors that will hold the
384* accumulated Givens rotations in workspace.
385* N2NB denotes the number of 2*NNB-by-2*NNB factors
386* NBLST denotes the (possibly smaller) order of the last
387* factor.
388*
389 n2nb = ( ihi-jcol-1 ) / nnb - 1
390 nblst = ihi - jcol - n2nb*nnb
391 CALL claset( 'All', nblst, nblst, czero, cone, work, nblst )
392 pw = nblst * nblst + 1
393 DO i = 1, n2nb
394 CALL claset( '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 clartg( temp, a( i, j ), c, s, a( i-1, j ) )
409 a( i, j ) = cmplx( 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 ) = conjg( 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 ) = conjg( 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 - conjg( 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 clartg( temp, b( jj+1, jj ), c, s,
478 $ b( jj+1, jj+1 ) )
479 b( jj+1, jj ) = czero
480 CALL crot( jj-top, b( top+1, jj+1 ), 1,
481 $ b( top+1, jj ), 1, c, s )
482 a( jj+1, j ) = cmplx( c )
483 b( jj+1, j ) = -conjg( 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 + conjg( s2 )*temp2
504 temp2 = -s2*temp3 + c2*temp2
505 a( k, j+i+2 ) = c1*temp2 + conjg( s1 )*temp1
506 temp1 = -s1*temp2 + c1*temp1
507 a( k, j+i+1 ) = ctemp*temp1 + conjg( 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 crot( ihi-top, a( top+1, j+i+1 ), 1,
516 $ a( top+1, j+i ), 1, c,
517 $ -conjg( 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 cgemv( '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 ctrmv( 'lower', 'conjugate', 'non-unit',
546 $ NBLST-LEN, WORK( LEN*NBLST + 1 ), NBLST,
547 $ WORK( PW+LEN ), 1 )
548 CALL CGEMV( '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 CTRMV( 'upper', 'conjugate', 'non-unit', LEN,
585 $ WORK( PPWO + NNB ), 2*NNB, WORK( PW ),
586 $ 1 )
587 CALL CTRMV( 'lower', 'conjugate', 'non-unit', NNB,
588 $ WORK( PPWO + 2*LEN*NNB ),
589 $ 2*NNB, WORK( PW + LEN ), 1 )
590 CALL CGEMV( 'conjugate', NNB, LEN, CONE,
591 $ WORK( PPWO ), 2*NNB, A( JROW, J+1 ), 1,
592 $ CONE, WORK( PW ), 1 )
593 CALL CGEMV( 'conjugate', LEN, NNB, CONE,
594 $ WORK( PPWO + 2*LEN*NNB + NNB ), 2*NNB,
595 $ A( JROW+NNB, J+1 ), 1, CONE,
596 $ WORK( PW+LEN ), 1 )
597 PPW = PW
598 DO I = JROW, JROW+LEN+NNB-1
599 A( I, J+1 ) = WORK( PPW )
600 PPW = PPW + 1
601 END DO
602 PPWO = PPWO + 4*NNB*NNB
603 END DO
604 END IF
605 END DO
606*
607* Apply accumulated unitary matrices to A.
608*
609 COLA = N - JCOL - NNB + 1
610 J = IHI - NBLST + 1
611 CALL CGEMM( 'conjugate', 'no transpose', NBLST,
612 $ COLA, NBLST, CONE, WORK, NBLST,
613 $ A( J, JCOL+NNB ), LDA, CZERO, WORK( PW ),
614 $ NBLST )
615 CALL CLACPY( 'all', NBLST, COLA, WORK( PW ), NBLST,
616 $ A( J, JCOL+NNB ), LDA )
617 PPWO = NBLST*NBLST + 1
618 J0 = J - NNB
619 DO J = J0, JCOL+1, -NNB
620 IF ( BLK22 ) THEN
621*
622* Exploit the structure of
623*
624* [ U11 U12 ]
625* U = [ ]
626* [ U21 U22 ],
627*
628* where all blocks are NNB-by-NNB, U21 is upper
629* triangular and U12 is lower triangular.
630*
631 CALL CUNM22( 'left', 'conjugate', 2*NNB, COLA, NNB,
632 $ NNB, WORK( PPWO ), 2*NNB,
633 $ A( J, JCOL+NNB ), LDA, WORK( PW ),
634 $ LWORK-PW+1, IERR )
635 ELSE
636*
637* Ignore the structure of U.
638*
639 CALL CGEMM( 'conjugate', 'no transpose', 2*NNB,
640 $ COLA, 2*NNB, CONE, WORK( PPWO ), 2*NNB,
641 $ A( J, JCOL+NNB ), LDA, CZERO, WORK( PW ),
642 $ 2*NNB )
643 CALL CLACPY( 'all', 2*NNB, COLA, WORK( PW ), 2*NNB,
644 $ A( J, JCOL+NNB ), LDA )
645 END IF
646 PPWO = PPWO + 4*NNB*NNB
647 END DO
648*
649* Apply accumulated unitary matrices to Q.
650*
651 IF( WANTQ ) THEN
652 J = IHI - NBLST + 1
653 IF ( INITQ ) THEN
654 TOPQ = MAX( 2, J - JCOL + 1 )
655 NH = IHI - TOPQ + 1
656 ELSE
657 TOPQ = 1
658 NH = N
659 END IF
660 CALL CGEMM( 'no transpose', 'no transpose', NH,
661 $ NBLST, NBLST, CONE, Q( TOPQ, J ), LDQ,
662 $ WORK, NBLST, CZERO, WORK( PW ), NH )
663 CALL CLACPY( 'all', NH, NBLST, WORK( PW ), NH,
664 $ Q( TOPQ, J ), LDQ )
665 PPWO = NBLST*NBLST + 1
666 J0 = J - NNB
667 DO J = J0, JCOL+1, -NNB
668 IF ( INITQ ) THEN
669 TOPQ = MAX( 2, J - JCOL + 1 )
670 NH = IHI - TOPQ + 1
671 END IF
672 IF ( BLK22 ) THEN
673*
674* Exploit the structure of U.
675*
676 CALL CUNM22( 'right', 'no transpose', NH, 2*NNB,
677 $ NNB, NNB, WORK( PPWO ), 2*NNB,
678 $ Q( TOPQ, J ), LDQ, WORK( PW ),
679 $ LWORK-PW+1, IERR )
680 ELSE
681*
682* Ignore the structure of U.
683*
684 CALL CGEMM( 'no transpose', 'no transpose', NH,
685 $ 2*NNB, 2*NNB, CONE, Q( TOPQ, J ), LDQ,
686 $ WORK( PPWO ), 2*NNB, CZERO, WORK( PW ),
687 $ NH )
688 CALL CLACPY( 'all', NH, 2*NNB, WORK( PW ), NH,
689 $ Q( TOPQ, J ), LDQ )
690 END IF
691 PPWO = PPWO + 4*NNB*NNB
692 END DO
693 END IF
694*
695* Accumulate right Givens rotations if required.
696*
697.OR..GT. IF ( WANTZ TOP0 ) THEN
698*
699* Initialize small unitary factors that will hold the
700* accumulated Givens rotations in workspace.
701*
702 CALL CLASET( 'all', NBLST, NBLST, CZERO, CONE, WORK,
703 $ NBLST )
704 PW = NBLST * NBLST + 1
705 DO I = 1, N2NB
706 CALL CLASET( 'all', 2*NNB, 2*NNB, CZERO, CONE,
707 $ WORK( PW ), 2*NNB )
708 PW = PW + 4*NNB*NNB
709 END DO
710*
711* Accumulate Givens rotations into workspace array.
712*
713 DO J = JCOL, JCOL+NNB-1
714 PPW = ( NBLST + 1 )*( NBLST - 2 ) - J + JCOL + 1
715 LEN = 2 + J - JCOL
716 JROW = J + N2NB*NNB + 2
717 DO I = IHI, JROW, -1
718 CTEMP = A( I, J )
719 A( I, J ) = CZERO
720 S = B( I, J )
721 B( I, J ) = CZERO
722 DO JJ = PPW, PPW+LEN-1
723 TEMP = WORK( JJ + NBLST )
724 WORK( JJ + NBLST ) = CTEMP*TEMP -
725 $ CONJG( S )*WORK( JJ )
726 WORK( JJ ) = S*TEMP + CTEMP*WORK( JJ )
727 END DO
728 LEN = LEN + 1
729 PPW = PPW - NBLST - 1
730 END DO
731*
732 PPWO = NBLST*NBLST + ( NNB+J-JCOL-1 )*2*NNB + NNB
733 J0 = JROW - NNB
734 DO JROW = J0, J+2, -NNB
735 PPW = PPWO
736 LEN = 2 + J - JCOL
737 DO I = JROW+NNB-1, JROW, -1
738 CTEMP = A( I, J )
739 A( I, J ) = CZERO
740 S = B( I, J )
741 B( I, J ) = CZERO
742 DO JJ = PPW, PPW+LEN-1
743 TEMP = WORK( JJ + 2*NNB )
744 WORK( JJ + 2*NNB ) = CTEMP*TEMP -
745 $ CONJG( S )*WORK( JJ )
746 WORK( JJ ) = S*TEMP + CTEMP*WORK( JJ )
747 END DO
748 LEN = LEN + 1
749 PPW = PPW - 2*NNB - 1
750 END DO
751 PPWO = PPWO + 4*NNB*NNB
752 END DO
753 END DO
754 ELSE
755*
756 CALL CLASET( 'lower', IHI - JCOL - 1, NNB, CZERO, CZERO,
757 $ A( JCOL + 2, JCOL ), LDA )
758 CALL CLASET( 'lower', IHI - JCOL - 1, NNB, CZERO, CZERO,
759 $ B( JCOL + 2, JCOL ), LDB )
760 END IF
761*
762* Apply accumulated unitary matrices to A and B.
763*
764.GT. IF ( TOP0 ) THEN
765 J = IHI - NBLST + 1
766 CALL CGEMM( 'no transpose', 'no transpose', TOP,
767 $ NBLST, NBLST, CONE, A( 1, J ), LDA,
768 $ WORK, NBLST, CZERO, WORK( PW ), TOP )
769 CALL CLACPY( 'all', TOP, NBLST, WORK( PW ), TOP,
770 $ A( 1, J ), LDA )
771 PPWO = NBLST*NBLST + 1
772 J0 = J - NNB
773 DO J = J0, JCOL+1, -NNB
774 IF ( BLK22 ) THEN
775*
776* Exploit the structure of U.
777*
778 CALL CUNM22( 'right', 'no transpose', TOP, 2*NNB,
779 $ NNB, NNB, WORK( PPWO ), 2*NNB,
780 $ A( 1, J ), LDA, WORK( PW ),
781 $ LWORK-PW+1, IERR )
782 ELSE
783*
784* Ignore the structure of U.
785*
786 CALL CGEMM( 'no transpose', 'no transpose', TOP,
787 $ 2*NNB, 2*NNB, CONE, A( 1, J ), LDA,
788 $ WORK( PPWO ), 2*NNB, CZERO,
789 $ WORK( PW ), TOP )
790 CALL CLACPY( 'all', TOP, 2*NNB, WORK( PW ), TOP,
791 $ A( 1, J ), LDA )
792 END IF
793 PPWO = PPWO + 4*NNB*NNB
794 END DO
795*
796 J = IHI - NBLST + 1
797 CALL CGEMM( 'no transpose', 'no transpose', TOP,
798 $ NBLST, NBLST, CONE, B( 1, J ), LDB,
799 $ WORK, NBLST, CZERO, WORK( PW ), TOP )
800 CALL CLACPY( 'all', TOP, NBLST, WORK( PW ), TOP,
801 $ B( 1, J ), LDB )
802 PPWO = NBLST*NBLST + 1
803 J0 = J - NNB
804 DO J = J0, JCOL+1, -NNB
805 IF ( BLK22 ) THEN
806*
807* Exploit the structure of U.
808*
809 CALL CUNM22( 'right', 'no transpose', TOP, 2*NNB,
810 $ NNB, NNB, WORK( PPWO ), 2*NNB,
811 $ B( 1, J ), LDB, WORK( PW ),
812 $ LWORK-PW+1, IERR )
813 ELSE
814*
815* Ignore the structure of U.
816*
817 CALL CGEMM( 'no transpose', 'no transpose', TOP,
818 $ 2*NNB, 2*NNB, CONE, B( 1, J ), LDB,
819 $ WORK( PPWO ), 2*NNB, CZERO,
820 $ WORK( PW ), TOP )
821 CALL CLACPY( 'all', TOP, 2*NNB, WORK( PW ), TOP,
822 $ B( 1, J ), LDB )
823 END IF
824 PPWO = PPWO + 4*NNB*NNB
825 END DO
826 END IF
827*
828* Apply accumulated unitary matrices to Z.
829*
830 IF( WANTZ ) THEN
831 J = IHI - NBLST + 1
832 IF ( INITQ ) THEN
833 TOPQ = MAX( 2, J - JCOL + 1 )
834 NH = IHI - TOPQ + 1
835 ELSE
836 TOPQ = 1
837 NH = N
838 END IF
839 CALL CGEMM( 'no transpose', 'no transpose', NH,
840 $ NBLST, NBLST, CONE, Z( TOPQ, J ), LDZ,
841 $ WORK, NBLST, CZERO, WORK( PW ), NH )
842 CALL CLACPY( 'all', NH, NBLST, WORK( PW ), NH,
843 $ Z( TOPQ, J ), LDZ )
844 PPWO = NBLST*NBLST + 1
845 J0 = J - NNB
846 DO J = J0, JCOL+1, -NNB
847 IF ( INITQ ) THEN
848 TOPQ = MAX( 2, J - JCOL + 1 )
849 NH = IHI - TOPQ + 1
850 END IF
851 IF ( BLK22 ) THEN
852*
853* Exploit the structure of U.
854*
855 CALL CUNM22( 'right', 'no transpose', NH, 2*NNB,
856 $ NNB, NNB, WORK( PPWO ), 2*NNB,
857 $ Z( TOPQ, J ), LDZ, WORK( PW ),
858 $ LWORK-PW+1, IERR )
859 ELSE
860*
861* Ignore the structure of U.
862*
863 CALL CGEMM( 'no transpose', 'no transpose', NH,
864 $ 2*NNB, 2*NNB, CONE, Z( TOPQ, J ), LDZ,
865 $ WORK( PPWO ), 2*NNB, CZERO, WORK( PW ),
866 $ NH )
867 CALL CLACPY( 'all', NH, 2*NNB, WORK( PW ), NH,
868 $ Z( TOPQ, J ), LDZ )
869 END IF
870 PPWO = PPWO + 4*NNB*NNB
871 END DO
872 END IF
873 END DO
874 END IF
875*
876* Use unblocked code to reduce the rest of the matrix
877* Avoid re-initialization of modified Q and Z.
878*
879 COMPQ2 = COMPQ
880 COMPZ2 = COMPZ
881.NE. IF ( JCOLILO ) THEN
882 IF ( WANTQ )
883 $ COMPQ2 = 'v'
884 IF ( WANTZ )
885 $ COMPZ2 = 'v'
886 END IF
887*
888.LT. IF ( JCOLIHI )
889 $ CALL CGGHRD( COMPQ2, COMPZ2, N, JCOL, IHI, A, LDA, B, LDB, Q,
890 $ LDQ, Z, LDZ, IERR )
891 WORK( 1 ) = CMPLX( LWKOPT )
892*
893 RETURN
894*
895* End of CGGHD3
896*
897 END
float cmplx[2]
Definition pblas.h:136
subroutine clartg(f, g, c, s, r)
CLARTG generates a plane rotation with real cosine and complex sine.
Definition clartg.f90:118
subroutine xerbla(srname, info)
XERBLA
Definition xerbla.f:60
subroutine crot(n, cx, incx, cy, incy, c, s)
CROT applies a plane rotation with real cosine and complex sine to a pair of complex vectors.
Definition crot.f:103
subroutine clacpy(uplo, m, n, a, lda, b, ldb)
CLACPY copies all or part of one two-dimensional array to another.
Definition clacpy.f:103
subroutine claset(uplo, m, n, alpha, beta, a, lda)
CLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
Definition claset.f:106
subroutine cunm22(side, trans, m, n, n1, n2, q, ldq, c, ldc, work, lwork, info)
CUNM22 multiplies a general matrix by a banded unitary matrix.
Definition cunm22.f:162
subroutine cgghrd(compq, compz, n, ilo, ihi, a, lda, b, ldb, q, ldq, z, ldz, info)
CGGHRD
Definition cgghrd.f:204
subroutine cgghd3(compq, compz, n, ilo, ihi, a, lda, b, ldb, q, ldq, z, ldz, work, lwork, info)
CGGHD3
Definition cgghd3.f:231
subroutine ctrmv(uplo, trans, diag, n, a, lda, x, incx)
CTRMV
Definition ctrmv.f:147
subroutine cgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
CGEMV
Definition cgemv.f:158
subroutine cgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
CGEMM
Definition cgemm.f:187
#define min(a, b)
Definition macros.h:20
#define max(a, b)
Definition macros.h:21