1*> \brief <b> ZGGESX computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE matrices</b>
2*
3*  =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6*            http://www.netlib.org/lapack/explore-html/
7*
8*> \htmlonly
9*> Download ZGGESX + dependencies
10*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zggesx.f">
11*> [TGZ]</a>
12*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zggesx.f">
13*> [ZIP]</a>
14*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zggesx.f">
15*> [TXT]</a>
16*> \endhtmlonly
17*
18*  Definition:
19*  ===========
20*
21*       SUBROUTINE ZGGESX( JOBVSL, JOBVSR, SORT, SELCTG, SENSE, N, A, LDA,
22*                          B, LDB, SDIM, ALPHA, BETA, VSL, LDVSL, VSR,
23*                          LDVSR, RCONDE, RCONDV, WORK, LWORK, RWORK,
24*                          IWORK, LIWORK, BWORK, INFO )
25*
26*       .. Scalar Arguments ..
27*       CHARACTER          JOBVSL, JOBVSR, SENSE, SORT
28*       INTEGER            INFO, LDA, LDB, LDVSL, LDVSR, LIWORK, LWORK, N,
29*      $                   SDIM
30*       ..
31*       .. Array Arguments ..
32*       LOGICAL            BWORK( * )
33*       INTEGER            IWORK( * )
34*       DOUBLE PRECISION   RCONDE( 2 ), RCONDV( 2 ), RWORK( * )
35*       COMPLEX*16         A( LDA, * ), ALPHA( * ), B( LDB, * ),
36*      $                   BETA( * ), VSL( LDVSL, * ), VSR( LDVSR, * ),
37*      $                   WORK( * )
38*       ..
39*       .. Function Arguments ..
40*       LOGICAL            SELCTG
41*       EXTERNAL           SELCTG
42*       ..
43*
44*
45*> \par Purpose:
46*  =============
47*>
48*> \verbatim
49*>
50*> ZGGESX computes for a pair of N-by-N complex nonsymmetric matrices
51*> (A,B), the generalized eigenvalues, the complex Schur form (S,T),
52*> and, optionally, the left and/or right matrices of Schur vectors (VSL
53*> and VSR).  This gives the generalized Schur factorization
54*>
55*>      (A,B) = ( (VSL) S (VSR)**H, (VSL) T (VSR)**H )
56*>
57*> where (VSR)**H is the conjugate-transpose of VSR.
58*>
59*> Optionally, it also orders the eigenvalues so that a selected cluster
60*> of eigenvalues appears in the leading diagonal blocks of the upper
61*> triangular matrix S and the upper triangular matrix T; computes
62*> a reciprocal condition number for the average of the selected
63*> eigenvalues (RCONDE); and computes a reciprocal condition number for
64*> the right and left deflating subspaces corresponding to the selected
65*> eigenvalues (RCONDV). The leading columns of VSL and VSR then form
66*> an orthonormal basis for the corresponding left and right eigenspaces
67*> (deflating subspaces).
68*>
69*> A generalized eigenvalue for a pair of matrices (A,B) is a scalar w
70*> or a ratio alpha/beta = w, such that  A - w*B is singular.  It is
71*> usually represented as the pair (alpha,beta), as there is a
72*> reasonable interpretation for beta=0 or for both being zero.
73*>
74*> A pair of matrices (S,T) is in generalized complex Schur form if T is
75*> upper triangular with non-negative diagonal and S is upper
76*> triangular.
77*> \endverbatim
78*
79*  Arguments:
80*  ==========
81*
82*> \param[in] JOBVSL
83*> \verbatim
84*>          JOBVSL is CHARACTER*1
85*>          = 'N':  do not compute the left Schur vectors;
86*>          = 'V':  compute the left Schur vectors.
87*> \endverbatim
88*>
89*> \param[in] JOBVSR
90*> \verbatim
91*>          JOBVSR is CHARACTER*1
92*>          = 'N':  do not compute the right Schur vectors;
93*>          = 'V':  compute the right Schur vectors.
94*> \endverbatim
95*>
96*> \param[in] SORT
97*> \verbatim
98*>          SORT is CHARACTER*1
99*>          Specifies whether or not to order the eigenvalues on the
100*>          diagonal of the generalized Schur form.
101*>          = 'N':  Eigenvalues are not ordered;
102*>          = 'S':  Eigenvalues are ordered (see SELCTG).
103*> \endverbatim
104*>
105*> \param[in] SELCTG
106*> \verbatim
107*>          SELCTG is a LOGICAL FUNCTION of two COMPLEX*16 arguments
108*>          SELCTG must be declared EXTERNAL in the calling subroutine.
109*>          If SORT = 'N', SELCTG is not referenced.
110*>          If SORT = 'S', SELCTG is used to select eigenvalues to sort
111*>          to the top left of the Schur form.
112*>          Note that a selected complex eigenvalue may no longer satisfy
113*>          SELCTG(ALPHA(j),BETA(j)) = .TRUE. after ordering, since
114*>          ordering may change the value of complex eigenvalues
115*>          (especially if the eigenvalue is ill-conditioned), in this
116*>          case INFO is set to N+3 see INFO below).
117*> \endverbatim
118*>
119*> \param[in] SENSE
120*> \verbatim
121*>          SENSE is CHARACTER*1
122*>          Determines which reciprocal condition numbers are computed.
123*>          = 'N': None are computed;
124*>          = 'E': Computed for average of selected eigenvalues only;
125*>          = 'V': Computed for selected deflating subspaces only;
126*>          = 'B': Computed for both.
127*>          If SENSE = 'E', 'V', or 'B', SORT must equal 'S'.
128*> \endverbatim
129*>
130*> \param[in] N
131*> \verbatim
132*>          N is INTEGER
133*>          The order of the matrices A, B, VSL, and VSR.  N >= 0.
134*> \endverbatim
135*>
136*> \param[in,out] A
137*> \verbatim
138*>          A is COMPLEX*16 array, dimension (LDA, N)
139*>          On entry, the first of the pair of matrices.
140*>          On exit, A has been overwritten by its generalized Schur
141*>          form S.
142*> \endverbatim
143*>
144*> \param[in] LDA
145*> \verbatim
146*>          LDA is INTEGER
147*>          The leading dimension of A.  LDA >= max(1,N).
148*> \endverbatim
149*>
150*> \param[in,out] B
151*> \verbatim
152*>          B is COMPLEX*16 array, dimension (LDB, N)
153*>          On entry, the second of the pair of matrices.
154*>          On exit, B has been overwritten by its generalized Schur
155*>          form T.
156*> \endverbatim
157*>
158*> \param[in] LDB
159*> \verbatim
160*>          LDB is INTEGER
161*>          The leading dimension of B.  LDB >= max(1,N).
162*> \endverbatim
163*>
164*> \param[out] SDIM
165*> \verbatim
166*>          SDIM is INTEGER
167*>          If SORT = 'N', SDIM = 0.
168*>          If SORT = 'S', SDIM = number of eigenvalues (after sorting)
169*>          for which SELCTG is true.
170*> \endverbatim
171*>
172*> \param[out] ALPHA
173*> \verbatim
174*>          ALPHA is COMPLEX*16 array, dimension (N)
175*> \endverbatim
176*>
177*> \param[out] BETA
178*> \verbatim
179*>          BETA is COMPLEX*16 array, dimension (N)
180*>          On exit, ALPHA(j)/BETA(j), j=1,...,N, will be the
181*>          generalized eigenvalues.  ALPHA(j) and BETA(j),j=1,...,N  are
182*>          the diagonals of the complex Schur form (S,T).  BETA(j) will
183*>          be non-negative real.
184*>
185*>          Note: the quotients ALPHA(j)/BETA(j) may easily over- or
186*>          underflow, and BETA(j) may even be zero.  Thus, the user
187*>          should avoid naively computing the ratio alpha/beta.
188*>          However, ALPHA will be always less than and usually
189*>          comparable with norm(A) in magnitude, and BETA always less
190*>          than and usually comparable with norm(B).
191*> \endverbatim
192*>
193*> \param[out] VSL
194*> \verbatim
195*>          VSL is COMPLEX*16 array, dimension (LDVSL,N)
196*>          If JOBVSL = 'V', VSL will contain the left Schur vectors.
197*>          Not referenced if JOBVSL = 'N'.
198*> \endverbatim
199*>
200*> \param[in] LDVSL
201*> \verbatim
202*>          LDVSL is INTEGER
203*>          The leading dimension of the matrix VSL. LDVSL >=1, and
204*>          if JOBVSL = 'V', LDVSL >= N.
205*> \endverbatim
206*>
207*> \param[out] VSR
208*> \verbatim
209*>          VSR is COMPLEX*16 array, dimension (LDVSR,N)
210*>          If JOBVSR = 'V', VSR will contain the right Schur vectors.
211*>          Not referenced if JOBVSR = 'N'.
212*> \endverbatim
213*>
214*> \param[in] LDVSR
215*> \verbatim
216*>          LDVSR is INTEGER
217*>          The leading dimension of the matrix VSR. LDVSR >= 1, and
218*>          if JOBVSR = 'V', LDVSR >= N.
219*> \endverbatim
220*>
221*> \param[out] RCONDE
222*> \verbatim
223*>          RCONDE is DOUBLE PRECISION array, dimension ( 2 )
224*>          If SENSE = 'E' or 'B', RCONDE(1) and RCONDE(2) contain the
225*>          reciprocal condition numbers for the average of the selected
226*>          eigenvalues.
227*>          Not referenced if SENSE = 'N' or 'V'.
228*> \endverbatim
229*>
230*> \param[out] RCONDV
231*> \verbatim
232*>          RCONDV is DOUBLE PRECISION array, dimension ( 2 )
233*>          If SENSE = 'V' or 'B', RCONDV(1) and RCONDV(2) contain the
234*>          reciprocal condition number for the selected deflating
235*>          subspaces.
236*>          Not referenced if SENSE = 'N' or 'E'.
237*> \endverbatim
238*>
239*> \param[out] WORK
240*> \verbatim
241*>          WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
242*>          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
243*> \endverbatim
244*>
245*> \param[in] LWORK
246*> \verbatim
247*>          LWORK is INTEGER
248*>          The dimension of the array WORK.
249*>          If N = 0, LWORK >= 1, else if SENSE = 'E', 'V', or 'B',
250*>          LWORK >= MAX(1,2*N,2*SDIM*(N-SDIM)), else
251*>          LWORK >= MAX(1,2*N).  Note that 2*SDIM*(N-SDIM) <= N*N/2.
252*>          Note also that an error is only returned if
253*>          LWORK < MAX(1,2*N), but if SENSE = 'E' or 'V' or 'B' this may
254*>          not be large enough.
255*>
256*>          If LWORK = -1, then a workspace query is assumed; the routine
257*>          only calculates the bound on the optimal size of the WORK
258*>          array and the minimum size of the IWORK array, returns these
259*>          values as the first entries of the WORK and IWORK arrays, and
260*>          no error message related to LWORK or LIWORK is issued by
261*>          XERBLA.
262*> \endverbatim
263*>
264*> \param[out] RWORK
265*> \verbatim
266*>          RWORK is DOUBLE PRECISION array, dimension ( 8*N )
267*>          Real workspace.
268*> \endverbatim
269*>
270*> \param[out] IWORK
271*> \verbatim
272*>          IWORK is INTEGER array, dimension (MAX(1,LIWORK))
273*>          On exit, if INFO = 0, IWORK(1) returns the minimum LIWORK.
274*> \endverbatim
275*>
276*> \param[in] LIWORK
277*> \verbatim
278*>          LIWORK is INTEGER
279*>          The dimension of the array IWORK.
280*>          If SENSE = 'N' or N = 0, LIWORK >= 1, otherwise
281*>          LIWORK >= N+2.
282*>
283*>          If LIWORK = -1, then a workspace query is assumed; the
284*>          routine only calculates the bound on the optimal size of the
285*>          WORK array and the minimum size of the IWORK array, returns
286*>          these values as the first entries of the WORK and IWORK
287*>          arrays, and no error message related to LWORK or LIWORK is
288*>          issued by XERBLA.
289*> \endverbatim
290*>
291*> \param[out] BWORK
292*> \verbatim
293*>          BWORK is LOGICAL array, dimension (N)
294*>          Not referenced if SORT = 'N'.
295*> \endverbatim
296*>
297*> \param[out] INFO
298*> \verbatim
299*>          INFO is INTEGER
300*>          = 0:  successful exit
301*>          < 0:  if INFO = -i, the i-th argument had an illegal value.
302*>          = 1,...,N:
303*>                The QZ iteration failed.  (A,B) are not in Schur
304*>                form, but ALPHA(j) and BETA(j) should be correct for
305*>                j=INFO+1,...,N.
306*>          > N:  =N+1: other than QZ iteration failed in ZHGEQZ
307*>                =N+2: after reordering, roundoff changed values of
308*>                      some complex eigenvalues so that leading
309*>                      eigenvalues in the Generalized Schur form no
310*>                      longer satisfy SELCTG=.TRUE.  This could also
311*>                      be caused due to scaling.
312*>                =N+3: reordering failed in ZTGSEN.
313*> \endverbatim
314*
315*  Authors:
316*  ========
317*
318*> \author Univ. of Tennessee
319*> \author Univ. of California Berkeley
320*> \author Univ. of Colorado Denver
321*> \author NAG Ltd.
322*
323*> \ingroup complex16GEeigen
324*
325*  =====================================================================
326      SUBROUTINE ZGGESX( JOBVSL, JOBVSR, SORT, SELCTG, SENSE, N, A, LDA,
327     $                   B, LDB, SDIM, ALPHA, BETA, VSL, LDVSL, VSR,
328     $                   LDVSR, RCONDE, RCONDV, WORK, LWORK, RWORK,
329     $                   IWORK, LIWORK, BWORK, INFO )
330*
331*  -- LAPACK driver routine --
332*  -- LAPACK is a software package provided by Univ. of Tennessee,    --
333*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
334*
335*     .. Scalar Arguments ..
336      CHARACTER          JOBVSL, JOBVSR, SENSE, SORT
337      INTEGER            INFO, LDA, LDB, LDVSL, LDVSR, LIWORK, LWORK, N,
338     $                   SDIM
339*     ..
340*     .. Array Arguments ..
341      LOGICAL            BWORK( * )
342      INTEGER            IWORK( * )
343      DOUBLE PRECISION   RCONDE( 2 ), RCONDV( 2 ), RWORK( * )
344      COMPLEX*16         A( LDA, * ), ALPHA( * ), B( LDB, * ),
345     $                   BETA( * ), VSL( LDVSL, * ), VSR( LDVSR, * ),
346     $                   WORK( * )
347*     ..
348*     .. Function Arguments ..
349      LOGICAL            SELCTG
350      EXTERNAL           SELCTG
351*     ..
352*
353*  =====================================================================
354*
355*     .. Parameters ..
356      DOUBLE PRECISION   ZERO, ONE
357      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
358      COMPLEX*16         CZERO, CONE
359      PARAMETER          ( CZERO = ( 0.0D+0, 0.0D+0 ),
360     $                   CONE = ( 1.0D+0, 0.0D+0 ) )
361*     ..
362*     .. Local Scalars ..
363      LOGICAL            CURSL, ILASCL, ILBSCL, ILVSL, ILVSR, LASTSL,
364     $                   LQUERY, WANTSB, WANTSE, WANTSN, WANTST, WANTSV
365      INTEGER            I, ICOLS, IERR, IHI, IJOB, IJOBVL, IJOBVR,
366     $                   ILEFT, ILO, IRIGHT, IROWS, IRWRK, ITAU, IWRK,
367     $                   LIWMIN, LWRK, MAXWRK, MINWRK
368      DOUBLE PRECISION   ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PL,
369     $                   PR, SMLNUM
370*     ..
371*     .. Local Arrays ..
372      DOUBLE PRECISION   DIF( 2 )
373*     ..
374*     .. External Subroutines ..
375      EXTERNAL           DLABAD, XERBLA, ZGEQRF, ZGGBAK, ZGGBAL, ZGGHRD,
376     $                   ZHGEQZ, ZLACPY, ZLASCL, ZLASET, ZTGSEN, ZUNGQR,
377     $                   ZUNMQR
378*     ..
379*     .. External Functions ..
380      LOGICAL            LSAME
381      INTEGER            ILAENV
382      DOUBLE PRECISION   DLAMCH, ZLANGE
383      EXTERNAL           LSAME, ILAENV, DLAMCH, ZLANGE
384*     ..
385*     .. Intrinsic Functions ..
386      INTRINSIC          MAX, SQRT
387*     ..
388*     .. Executable Statements ..
389*
390*     Decode the input arguments
391*
392      IF( LSAME( JOBVSL, 'N' ) ) THEN
393         IJOBVL = 1
394         ILVSL = .FALSE.
395      ELSE IF( LSAME( JOBVSL, 'V' ) ) THEN
396         IJOBVL = 2
397         ILVSL = .TRUE.
398      ELSE
399         IJOBVL = -1
400         ILVSL = .FALSE.
401      END IF
402*
403      IF( LSAME( JOBVSR, 'N' ) ) THEN
404         IJOBVR = 1
405         ILVSR = .FALSE.
406      ELSE IF( LSAME( JOBVSR, 'V' ) ) THEN
407         IJOBVR = 2
408         ILVSR = .TRUE.
409      ELSE
410         IJOBVR = -1
411         ILVSR = .FALSE.
412      END IF
413*
414      WANTST = LSAME( SORT, 'S' )
415      WANTSN = LSAME( SENSE, 'N' )
416      WANTSE = LSAME( SENSE, 'E' )
417      WANTSV = LSAME( SENSE, 'V' )
418      WANTSB = LSAME( SENSE, 'B' )
419      LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )
420      IF( WANTSN ) THEN
421         IJOB = 0
422      ELSE IF( WANTSE ) THEN
423         IJOB = 1
424      ELSE IF( WANTSV ) THEN
425         IJOB = 2
426      ELSE IF( WANTSB ) THEN
427         IJOB = 4
428      END IF
429*
430*     Test the input arguments
431*
432      INFO = 0
433      IF( IJOBVL.LE.0 ) THEN
434         INFO = -1
435      ELSE IF( IJOBVR.LE.0 ) THEN
436         INFO = -2
437      ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THEN
438         INFO = -3
439      ELSE IF( .NOT.( WANTSN .OR. WANTSE .OR. WANTSV .OR. WANTSB ) .OR.
440     $         ( .NOT.WANTST .AND. .NOT.WANTSN ) ) THEN
441         INFO = -5
442      ELSE IF( N.LT.0 ) THEN
443         INFO = -6
444      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
445         INFO = -8
446      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
447         INFO = -10
448      ELSE IF( LDVSL.LT.1 .OR. ( ILVSL .AND. LDVSL.LT.N ) ) THEN
449         INFO = -15
450      ELSE IF( LDVSR.LT.1 .OR. ( ILVSR .AND. LDVSR.LT.N ) ) THEN
451         INFO = -17
452      END IF
453*
454*     Compute workspace
455*      (Note: Comments in the code beginning "Workspace:" describe the
456*       minimal amount of workspace needed at that point in the code,
457*       as well as the preferred amount for good performance.
458*       NB refers to the optimal block size for the immediately
459*       following subroutine, as returned by ILAENV.)
460*
461      IF( INFO.EQ.0 ) THEN
462         IF( N.GT.0) THEN
463            MINWRK = 2*N
464            MAXWRK = N*(1 + ILAENV( 1, 'ZGEQRF', ' ', N, 1, N, 0 ) )
465            MAXWRK = MAX( MAXWRK, N*( 1 +
466     $                    ILAENV( 1, 'ZUNMQR', ' ', N, 1, N, -1 ) ) )
467            IF( ILVSL ) THEN
468               MAXWRK = MAX( MAXWRK, N*( 1 +
469     $                       ILAENV( 1, 'ZUNGQR', ' ', N, 1, N, -1 ) ) )
470            END IF
471            LWRK = MAXWRK
472            IF( IJOB.GE.1 )
473     $         LWRK = MAX( LWRK, N*N/2 )
474         ELSE
475            MINWRK = 1
476            MAXWRK = 1
477            LWRK   = 1
478         END IF
479         WORK( 1 ) = LWRK
480         IF( WANTSN .OR. N.EQ.0 ) THEN
481            LIWMIN = 1
482         ELSE
483            LIWMIN = N + 2
484         END IF
485         IWORK( 1 ) = LIWMIN
486*
487         IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
488            INFO = -21
489         ELSE IF( LIWORK.LT.LIWMIN  .AND. .NOT.LQUERY) THEN
490            INFO = -24
491         END IF
492      END IF
493*
494      IF( INFO.NE.0 ) THEN
495         CALL XERBLA( 'ZGGESX', -INFO )
496         RETURN
497      ELSE IF (LQUERY) THEN
498         RETURN
499      END IF
500*
501*     Quick return if possible
502*
503      IF( N.EQ.0 ) THEN
504         SDIM = 0
505         RETURN
506      END IF
507*
508*     Get machine constants
509*
510      EPS = DLAMCH( 'P' )
511      SMLNUM = DLAMCH( 'S' )
512      BIGNUM = ONE / SMLNUM
513      CALL DLABAD( SMLNUM, BIGNUM )
514      SMLNUM = SQRT( SMLNUM ) / EPS
515      BIGNUM = ONE / SMLNUM
516*
517*     Scale A if max element outside range [SMLNUM,BIGNUM]
518*
519      ANRM = ZLANGE( 'M', N, N, A, LDA, RWORK )
520      ILASCL = .FALSE.
521      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
522         ANRMTO = SMLNUM
523         ILASCL = .TRUE.
524      ELSE IF( ANRM.GT.BIGNUM ) THEN
525         ANRMTO = BIGNUM
526         ILASCL = .TRUE.
527      END IF
528      IF( ILASCL )
529     $   CALL ZLASCL( 'G', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR )
530*
531*     Scale B if max element outside range [SMLNUM,BIGNUM]
532*
533      BNRM = ZLANGE( 'M', N, N, B, LDB, RWORK )
534      ILBSCL = .FALSE.
535      IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
536         BNRMTO = SMLNUM
537         ILBSCL = .TRUE.
538      ELSE IF( BNRM.GT.BIGNUM ) THEN
539         BNRMTO = BIGNUM
540         ILBSCL = .TRUE.
541      END IF
542      IF( ILBSCL )
543     $   CALL ZLASCL( 'G', 0, 0, BNRM, BNRMTO, N, N, B, LDB, IERR )
544*
545*     Permute the matrix to make it more nearly triangular
546*     (Real Workspace: need 6*N)
547*
548      ILEFT = 1
549      IRIGHT = N + 1
550      IRWRK = IRIGHT + N
551      CALL ZGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, RWORK( ILEFT ),
552     $             RWORK( IRIGHT ), RWORK( IRWRK ), IERR )
553*
554*     Reduce B to triangular form (QR decomposition of B)
555*     (Complex Workspace: need N, prefer N*NB)
556*
557      IROWS = IHI + 1 - ILO
558      ICOLS = N + 1 - ILO
559      ITAU = 1
560      IWRK = ITAU + IROWS
561      CALL ZGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
562     $             WORK( IWRK ), LWORK+1-IWRK, IERR )
563*
564*     Apply the unitary transformation to matrix A
565*     (Complex Workspace: need N, prefer N*NB)
566*
567      CALL ZUNMQR( 'L', 'C', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
568     $             WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ),
569     $             LWORK+1-IWRK, IERR )
570*
571*     Initialize VSL
572*     (Complex Workspace: need N, prefer N*NB)
573*
574      IF( ILVSL ) THEN
575         CALL ZLASET( 'Full', N, N, CZERO, CONE, VSL, LDVSL )
576         IF( IROWS.GT.1 ) THEN
577            CALL ZLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
578     $                   VSL( ILO+1, ILO ), LDVSL )
579         END IF
580         CALL ZUNGQR( IROWS, IROWS, IROWS, VSL( ILO, ILO ), LDVSL,
581     $                WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR )
582      END IF
583*
584*     Initialize VSR
585*
586      IF( ILVSR )
587     $   CALL ZLASET( 'Full', N, N, CZERO, CONE, VSR, LDVSR )
588*
589*     Reduce to generalized Hessenberg form
590*     (Workspace: none needed)
591*
592      CALL ZGGHRD( JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB, VSL,
593     $             LDVSL, VSR, LDVSR, IERR )
594*
595      SDIM = 0
596*
597*     Perform QZ algorithm, computing Schur vectors if desired
598*     (Complex Workspace: need N)
599*     (Real Workspace:    need N)
600*
601      IWRK = ITAU
602      CALL ZHGEQZ( 'S', JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB,
603     $             ALPHA, BETA, VSL, LDVSL, VSR, LDVSR, WORK( IWRK ),
604     $             LWORK+1-IWRK, RWORK( IRWRK ), IERR )
605      IF( IERR.NE.0 ) THEN
606         IF( IERR.GT.0 .AND. IERR.LE.N ) THEN
607            INFO = IERR
608         ELSE IF( IERR.GT.N .AND. IERR.LE.2*N ) THEN
609            INFO = IERR - N
610         ELSE
611            INFO = N + 1
612         END IF
613         GO TO 40
614      END IF
615*
616*     Sort eigenvalues ALPHA/BETA and compute the reciprocal of
617*     condition number(s)
618*
619      IF( WANTST ) THEN
620*
621*        Undo scaling on eigenvalues before SELCTGing
622*
623         IF( ILASCL )
624     $      CALL ZLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHA, N, IERR )
625         IF( ILBSCL )
626     $      CALL ZLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
627*
628*        Select eigenvalues
629*
630         DO 10 I = 1, N
631            BWORK( I ) = SELCTG( ALPHA( I ), BETA( I ) )
632   10    CONTINUE
633*
634*        Reorder eigenvalues, transform Generalized Schur vectors, and
635*        compute reciprocal condition numbers
636*        (Complex Workspace: If IJOB >= 1, need MAX(1, 2*SDIM*(N-SDIM))
637*                            otherwise, need 1 )
638*
639         CALL ZTGSEN( IJOB, ILVSL, ILVSR, BWORK, N, A, LDA, B, LDB,
640     $                ALPHA, BETA, VSL, LDVSL, VSR, LDVSR, SDIM, PL, PR,
641     $                DIF, WORK( IWRK ), LWORK-IWRK+1, IWORK, LIWORK,
642     $                IERR )
643*
644         IF( IJOB.GE.1 )
645     $      MAXWRK = MAX( MAXWRK, 2*SDIM*( N-SDIM ) )
646         IF( IERR.EQ.-21 ) THEN
647*
648*            not enough complex workspace
649*
650            INFO = -21
651         ELSE
652            IF( IJOB.EQ.1 .OR. IJOB.EQ.4 ) THEN
653               RCONDE( 1 ) = PL
654               RCONDE( 2 ) = PR
655            END IF
656            IF( IJOB.EQ.2 .OR. IJOB.EQ.4 ) THEN
657               RCONDV( 1 ) = DIF( 1 )
658               RCONDV( 2 ) = DIF( 2 )
659            END IF
660            IF( IERR.EQ.1 )
661     $         INFO = N + 3
662         END IF
663*
664      END IF
665*
666*     Apply permutation to VSL and VSR
667*     (Workspace: none needed)
668*
669      IF( ILVSL )
670     $   CALL ZGGBAK( 'P', 'L', N, ILO, IHI, RWORK( ILEFT ),
671     $                RWORK( IRIGHT ), N, VSL, LDVSL, IERR )
672*
673      IF( ILVSR )
674     $   CALL ZGGBAK( 'P', 'R', N, ILO, IHI, RWORK( ILEFT ),
675     $                RWORK( IRIGHT ), N, VSR, LDVSR, IERR )
676*
677*     Undo scaling
678*
679      IF( ILASCL ) THEN
680         CALL ZLASCL( 'U', 0, 0, ANRMTO, ANRM, N, N, A, LDA, IERR )
681         CALL ZLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHA, N, IERR )
682      END IF
683*
684      IF( ILBSCL ) THEN
685         CALL ZLASCL( 'U', 0, 0, BNRMTO, BNRM, N, N, B, LDB, IERR )
686         CALL ZLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
687      END IF
688*
689      IF( WANTST ) THEN
690*
691*        Check if reordering is correct
692*
693         LASTSL = .TRUE.
694         SDIM = 0
695         DO 30 I = 1, N
696            CURSL = SELCTG( ALPHA( I ), BETA( I ) )
697            IF( CURSL )
698     $         SDIM = SDIM + 1
699            IF( CURSL .AND. .NOT.LASTSL )
700     $         INFO = N + 2
701            LASTSL = CURSL
702   30    CONTINUE
703*
704      END IF
705*
706   40 CONTINUE
707*
708      WORK( 1 ) = MAXWRK
709      IWORK( 1 ) = LIWMIN
710*
711      RETURN
712*
713*     End of ZGGESX
714*
715      END
716