dhgeqz.c
Go to the documentation of this file.
00001 /* dhgeqz.f -- translated by f2c (version 20061008).
00002    You must link the resulting object file with libf2c:
00003         on Microsoft Windows system, link with libf2c.lib;
00004         on Linux or Unix systems, link with .../path/to/libf2c.a -lm
00005         or, if you install libf2c.a in a standard place, with -lf2c -lm
00006         -- in that order, at the end of the command line, as in
00007                 cc *.o -lf2c -lm
00008         Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
00009 
00010                 http://www.netlib.org/f2c/libf2c.zip
00011 */
00012 
00013 #include "f2c.h"
00014 #include "blaswrap.h"
00015 
00016 /* Table of constant values */
00017 
00018 static doublereal c_b12 = 0.;
00019 static doublereal c_b13 = 1.;
00020 static integer c__1 = 1;
00021 static integer c__3 = 3;
00022 
00023 /* Subroutine */ int dhgeqz_(char *job, char *compq, char *compz, integer *n, 
00024         integer *ilo, integer *ihi, doublereal *h__, integer *ldh, doublereal 
00025         *t, integer *ldt, doublereal *alphar, doublereal *alphai, doublereal *
00026         beta, doublereal *q, integer *ldq, doublereal *z__, integer *ldz, 
00027         doublereal *work, integer *lwork, integer *info)
00028 {
00029     /* System generated locals */
00030     integer h_dim1, h_offset, q_dim1, q_offset, t_dim1, t_offset, z_dim1, 
00031             z_offset, i__1, i__2, i__3, i__4;
00032     doublereal d__1, d__2, d__3, d__4;
00033 
00034     /* Builtin functions */
00035     double sqrt(doublereal);
00036 
00037     /* Local variables */
00038     doublereal c__;
00039     integer j;
00040     doublereal s, v[3], s1, s2, t1, u1, u2, a11, a12, a21, a22, b11, b22, c12,
00041              c21;
00042     integer jc;
00043     doublereal an, bn, cl, cq, cr;
00044     integer in;
00045     doublereal u12, w11, w12, w21;
00046     integer jr;
00047     doublereal cz, w22, sl, wi, sr, vs, wr, b1a, b2a, a1i, a2i, b1i, b2i, a1r,
00048              a2r, b1r, b2r, wr2, ad11, ad12, ad21, ad22, c11i, c22i;
00049     integer jch;
00050     doublereal c11r, c22r;
00051     logical ilq;
00052     doublereal u12l, tau, sqi;
00053     logical ilz;
00054     doublereal ulp, sqr, szi, szr, ad11l, ad12l, ad21l, ad22l, ad32l, wabs, 
00055             atol, btol, temp;
00056     extern /* Subroutine */ int drot_(integer *, doublereal *, integer *, 
00057             doublereal *, integer *, doublereal *, doublereal *), dlag2_(
00058             doublereal *, integer *, doublereal *, integer *, doublereal *, 
00059             doublereal *, doublereal *, doublereal *, doublereal *, 
00060             doublereal *);
00061     doublereal temp2, s1inv, scale;
00062     extern logical lsame_(char *, char *);
00063     integer iiter, ilast, jiter;
00064     doublereal anorm, bnorm;
00065     integer maxit;
00066     doublereal tempi, tempr;
00067     extern doublereal dlapy2_(doublereal *, doublereal *), dlapy3_(doublereal 
00068             *, doublereal *, doublereal *);
00069     extern /* Subroutine */ int dlasv2_(doublereal *, doublereal *, 
00070             doublereal *, doublereal *, doublereal *, doublereal *, 
00071             doublereal *, doublereal *, doublereal *);
00072     logical ilazr2;
00073     doublereal ascale, bscale;
00074     extern doublereal dlamch_(char *);
00075     extern /* Subroutine */ int dlarfg_(integer *, doublereal *, doublereal *, 
00076              integer *, doublereal *);
00077     extern doublereal dlanhs_(char *, integer *, doublereal *, integer *, 
00078             doublereal *);
00079     extern /* Subroutine */ int dlaset_(char *, integer *, integer *, 
00080             doublereal *, doublereal *, doublereal *, integer *);
00081     doublereal safmin;
00082     extern /* Subroutine */ int dlartg_(doublereal *, doublereal *, 
00083             doublereal *, doublereal *, doublereal *);
00084     doublereal safmax;
00085     extern /* Subroutine */ int xerbla_(char *, integer *);
00086     doublereal eshift;
00087     logical ilschr;
00088     integer icompq, ilastm, ischur;
00089     logical ilazro;
00090     integer icompz, ifirst, ifrstm, istart;
00091     logical ilpivt, lquery;
00092 
00093 
00094 /*  -- LAPACK routine (version 3.2.1)                                  -- */
00095 /*  -- LAPACK is a software package provided by Univ. of Tennessee,    -- */
00096 /*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */
00097 /*  -- April 2009                                                      -- */
00098 
00099 /*     .. Scalar Arguments .. */
00100 /*     .. */
00101 /*     .. Array Arguments .. */
00102 /*     .. */
00103 
00104 /*  Purpose */
00105 /*  ======= */
00106 
00107 /*  DHGEQZ computes the eigenvalues of a real matrix pair (H,T), */
00108 /*  where H is an upper Hessenberg matrix and T is upper triangular, */
00109 /*  using the double-shift QZ method. */
00110 /*  Matrix pairs of this type are produced by the reduction to */
00111 /*  generalized upper Hessenberg form of a real matrix pair (A,B): */
00112 
00113 /*     A = Q1*H*Z1**T,  B = Q1*T*Z1**T, */
00114 
00115 /*  as computed by DGGHRD. */
00116 
00117 /*  If JOB='S', then the Hessenberg-triangular pair (H,T) is */
00118 /*  also reduced to generalized Schur form, */
00119 
00120 /*     H = Q*S*Z**T,  T = Q*P*Z**T, */
00121 
00122 /*  where Q and Z are orthogonal matrices, P is an upper triangular */
00123 /*  matrix, and S is a quasi-triangular matrix with 1-by-1 and 2-by-2 */
00124 /*  diagonal blocks. */
00125 
00126 /*  The 1-by-1 blocks correspond to real eigenvalues of the matrix pair */
00127 /*  (H,T) and the 2-by-2 blocks correspond to complex conjugate pairs of */
00128 /*  eigenvalues. */
00129 
00130 /*  Additionally, the 2-by-2 upper triangular diagonal blocks of P */
00131 /*  corresponding to 2-by-2 blocks of S are reduced to positive diagonal */
00132 /*  form, i.e., if S(j+1,j) is non-zero, then P(j+1,j) = P(j,j+1) = 0, */
00133 /*  P(j,j) > 0, and P(j+1,j+1) > 0. */
00134 
00135 /*  Optionally, the orthogonal matrix Q from the generalized Schur */
00136 /*  factorization may be postmultiplied into an input matrix Q1, and the */
00137 /*  orthogonal matrix Z may be postmultiplied into an input matrix Z1. */
00138 /*  If Q1 and Z1 are the orthogonal matrices from DGGHRD that reduced */
00139 /*  the matrix pair (A,B) to generalized upper Hessenberg form, then the */
00140 /*  output matrices Q1*Q and Z1*Z are the orthogonal factors from the */
00141 /*  generalized Schur factorization of (A,B): */
00142 
00143 /*     A = (Q1*Q)*S*(Z1*Z)**T,  B = (Q1*Q)*P*(Z1*Z)**T. */
00144 
00145 /*  To avoid overflow, eigenvalues of the matrix pair (H,T) (equivalently, */
00146 /*  of (A,B)) are computed as a pair of values (alpha,beta), where alpha is */
00147 /*  complex and beta real. */
00148 /*  If beta is nonzero, lambda = alpha / beta is an eigenvalue of the */
00149 /*  generalized nonsymmetric eigenvalue problem (GNEP) */
00150 /*     A*x = lambda*B*x */
00151 /*  and if alpha is nonzero, mu = beta / alpha is an eigenvalue of the */
00152 /*  alternate form of the GNEP */
00153 /*     mu*A*y = B*y. */
00154 /*  Real eigenvalues can be read directly from the generalized Schur */
00155 /*  form: */
00156 /*    alpha = S(i,i), beta = P(i,i). */
00157 
00158 /*  Ref: C.B. Moler & G.W. Stewart, "An Algorithm for Generalized Matrix */
00159 /*       Eigenvalue Problems", SIAM J. Numer. Anal., 10(1973), */
00160 /*       pp. 241--256. */
00161 
00162 /*  Arguments */
00163 /*  ========= */
00164 
00165 /*  JOB     (input) CHARACTER*1 */
00166 /*          = 'E': Compute eigenvalues only; */
00167 /*          = 'S': Compute eigenvalues and the Schur form. */
00168 
00169 /*  COMPQ   (input) CHARACTER*1 */
00170 /*          = 'N': Left Schur vectors (Q) are not computed; */
00171 /*          = 'I': Q is initialized to the unit matrix and the matrix Q */
00172 /*                 of left Schur vectors of (H,T) is returned; */
00173 /*          = 'V': Q must contain an orthogonal matrix Q1 on entry and */
00174 /*                 the product Q1*Q is returned. */
00175 
00176 /*  COMPZ   (input) CHARACTER*1 */
00177 /*          = 'N': Right Schur vectors (Z) are not computed; */
00178 /*          = 'I': Z is initialized to the unit matrix and the matrix Z */
00179 /*                 of right Schur vectors of (H,T) is returned; */
00180 /*          = 'V': Z must contain an orthogonal matrix Z1 on entry and */
00181 /*                 the product Z1*Z is returned. */
00182 
00183 /*  N       (input) INTEGER */
00184 /*          The order of the matrices H, T, Q, and Z.  N >= 0. */
00185 
00186 /*  ILO     (input) INTEGER */
00187 /*  IHI     (input) INTEGER */
00188 /*          ILO and IHI mark the rows and columns of H which are in */
00189 /*          Hessenberg form.  It is assumed that A is already upper */
00190 /*          triangular in rows and columns 1:ILO-1 and IHI+1:N. */
00191 /*          If N > 0, 1 <= ILO <= IHI <= N; if N = 0, ILO=1 and IHI=0. */
00192 
00193 /*  H       (input/output) DOUBLE PRECISION array, dimension (LDH, N) */
00194 /*          On entry, the N-by-N upper Hessenberg matrix H. */
00195 /*          On exit, if JOB = 'S', H contains the upper quasi-triangular */
00196 /*          matrix S from the generalized Schur factorization; */
00197 /*          2-by-2 diagonal blocks (corresponding to complex conjugate */
00198 /*          pairs of eigenvalues) are returned in standard form, with */
00199 /*          H(i,i) = H(i+1,i+1) and H(i+1,i)*H(i,i+1) < 0. */
00200 /*          If JOB = 'E', the diagonal blocks of H match those of S, but */
00201 /*          the rest of H is unspecified. */
00202 
00203 /*  LDH     (input) INTEGER */
00204 /*          The leading dimension of the array H.  LDH >= max( 1, N ). */
00205 
00206 /*  T       (input/output) DOUBLE PRECISION array, dimension (LDT, N) */
00207 /*          On entry, the N-by-N upper triangular matrix T. */
00208 /*          On exit, if JOB = 'S', T contains the upper triangular */
00209 /*          matrix P from the generalized Schur factorization; */
00210 /*          2-by-2 diagonal blocks of P corresponding to 2-by-2 blocks of S */
00211 /*          are reduced to positive diagonal form, i.e., if H(j+1,j) is */
00212 /*          non-zero, then T(j+1,j) = T(j,j+1) = 0, T(j,j) > 0, and */
00213 /*          T(j+1,j+1) > 0. */
00214 /*          If JOB = 'E', the diagonal blocks of T match those of P, but */
00215 /*          the rest of T is unspecified. */
00216 
00217 /*  LDT     (input) INTEGER */
00218 /*          The leading dimension of the array T.  LDT >= max( 1, N ). */
00219 
00220 /*  ALPHAR  (output) DOUBLE PRECISION array, dimension (N) */
00221 /*          The real parts of each scalar alpha defining an eigenvalue */
00222 /*          of GNEP. */
00223 
00224 /*  ALPHAI  (output) DOUBLE PRECISION array, dimension (N) */
00225 /*          The imaginary parts of each scalar alpha defining an */
00226 /*          eigenvalue of GNEP. */
00227 /*          If ALPHAI(j) is zero, then the j-th eigenvalue is real; if */
00228 /*          positive, then the j-th and (j+1)-st eigenvalues are a */
00229 /*          complex conjugate pair, with ALPHAI(j+1) = -ALPHAI(j). */
00230 
00231 /*  BETA    (output) DOUBLE PRECISION array, dimension (N) */
00232 /*          The scalars beta that define the eigenvalues of GNEP. */
00233 /*          Together, the quantities alpha = (ALPHAR(j),ALPHAI(j)) and */
00234 /*          beta = BETA(j) represent the j-th eigenvalue of the matrix */
00235 /*          pair (A,B), in one of the forms lambda = alpha/beta or */
00236 /*          mu = beta/alpha.  Since either lambda or mu may overflow, */
00237 /*          they should not, in general, be computed. */
00238 
00239 /*  Q       (input/output) DOUBLE PRECISION array, dimension (LDQ, N) */
00240 /*          On entry, if COMPZ = 'V', the orthogonal matrix Q1 used in */
00241 /*          the reduction of (A,B) to generalized Hessenberg form. */
00242 /*          On exit, if COMPZ = 'I', the orthogonal matrix of left Schur */
00243 /*          vectors of (H,T), and if COMPZ = 'V', the orthogonal matrix */
00244 /*          of left Schur vectors of (A,B). */
00245 /*          Not referenced if COMPZ = 'N'. */
00246 
00247 /*  LDQ     (input) INTEGER */
00248 /*          The leading dimension of the array Q.  LDQ >= 1. */
00249 /*          If COMPQ='V' or 'I', then LDQ >= N. */
00250 
00251 /*  Z       (input/output) DOUBLE PRECISION array, dimension (LDZ, N) */
00252 /*          On entry, if COMPZ = 'V', the orthogonal matrix Z1 used in */
00253 /*          the reduction of (A,B) to generalized Hessenberg form. */
00254 /*          On exit, if COMPZ = 'I', the orthogonal matrix of */
00255 /*          right Schur vectors of (H,T), and if COMPZ = 'V', the */
00256 /*          orthogonal matrix of right Schur vectors of (A,B). */
00257 /*          Not referenced if COMPZ = 'N'. */
00258 
00259 /*  LDZ     (input) INTEGER */
00260 /*          The leading dimension of the array Z.  LDZ >= 1. */
00261 /*          If COMPZ='V' or 'I', then LDZ >= N. */
00262 
00263 /*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK)) */
00264 /*          On exit, if INFO >= 0, WORK(1) returns the optimal LWORK. */
00265 
00266 /*  LWORK   (input) INTEGER */
00267 /*          The dimension of the array WORK.  LWORK >= max(1,N). */
00268 
00269 /*          If LWORK = -1, then a workspace query is assumed; the routine */
00270 /*          only calculates the optimal size of the WORK array, returns */
00271 /*          this value as the first entry of the WORK array, and no error */
00272 /*          message related to LWORK is issued by XERBLA. */
00273 
00274 /*  INFO    (output) INTEGER */
00275 /*          = 0: successful exit */
00276 /*          < 0: if INFO = -i, the i-th argument had an illegal value */
00277 /*          = 1,...,N: the QZ iteration did not converge.  (H,T) is not */
00278 /*                     in Schur form, but ALPHAR(i), ALPHAI(i), and */
00279 /*                     BETA(i), i=INFO+1,...,N should be correct. */
00280 /*          = N+1,...,2*N: the shift calculation failed.  (H,T) is not */
00281 /*                     in Schur form, but ALPHAR(i), ALPHAI(i), and */
00282 /*                     BETA(i), i=INFO-N+1,...,N should be correct. */
00283 
00284 /*  Further Details */
00285 /*  =============== */
00286 
00287 /*  Iteration counters: */
00288 
00289 /*  JITER  -- counts iterations. */
00290 /*  IITER  -- counts iterations run since ILAST was last */
00291 /*            changed.  This is therefore reset only when a 1-by-1 or */
00292 /*            2-by-2 block deflates off the bottom. */
00293 
00294 /*  ===================================================================== */
00295 
00296 /*     .. Parameters .. */
00297 /*    $                     SAFETY = 1.0E+0 ) */
00298 /*     .. */
00299 /*     .. Local Scalars .. */
00300 /*     .. */
00301 /*     .. Local Arrays .. */
00302 /*     .. */
00303 /*     .. External Functions .. */
00304 /*     .. */
00305 /*     .. External Subroutines .. */
00306 /*     .. */
00307 /*     .. Intrinsic Functions .. */
00308 /*     .. */
00309 /*     .. Executable Statements .. */
00310 
00311 /*     Decode JOB, COMPQ, COMPZ */
00312 
00313     /* Parameter adjustments */
00314     h_dim1 = *ldh;
00315     h_offset = 1 + h_dim1;
00316     h__ -= h_offset;
00317     t_dim1 = *ldt;
00318     t_offset = 1 + t_dim1;
00319     t -= t_offset;
00320     --alphar;
00321     --alphai;
00322     --beta;
00323     q_dim1 = *ldq;
00324     q_offset = 1 + q_dim1;
00325     q -= q_offset;
00326     z_dim1 = *ldz;
00327     z_offset = 1 + z_dim1;
00328     z__ -= z_offset;
00329     --work;
00330 
00331     /* Function Body */
00332     if (lsame_(job, "E")) {
00333         ilschr = FALSE_;
00334         ischur = 1;
00335     } else if (lsame_(job, "S")) {
00336         ilschr = TRUE_;
00337         ischur = 2;
00338     } else {
00339         ischur = 0;
00340     }
00341 
00342     if (lsame_(compq, "N")) {
00343         ilq = FALSE_;
00344         icompq = 1;
00345     } else if (lsame_(compq, "V")) {
00346         ilq = TRUE_;
00347         icompq = 2;
00348     } else if (lsame_(compq, "I")) {
00349         ilq = TRUE_;
00350         icompq = 3;
00351     } else {
00352         icompq = 0;
00353     }
00354 
00355     if (lsame_(compz, "N")) {
00356         ilz = FALSE_;
00357         icompz = 1;
00358     } else if (lsame_(compz, "V")) {
00359         ilz = TRUE_;
00360         icompz = 2;
00361     } else if (lsame_(compz, "I")) {
00362         ilz = TRUE_;
00363         icompz = 3;
00364     } else {
00365         icompz = 0;
00366     }
00367 
00368 /*     Check Argument Values */
00369 
00370     *info = 0;
00371     work[1] = (doublereal) max(1,*n);
00372     lquery = *lwork == -1;
00373     if (ischur == 0) {
00374         *info = -1;
00375     } else if (icompq == 0) {
00376         *info = -2;
00377     } else if (icompz == 0) {
00378         *info = -3;
00379     } else if (*n < 0) {
00380         *info = -4;
00381     } else if (*ilo < 1) {
00382         *info = -5;
00383     } else if (*ihi > *n || *ihi < *ilo - 1) {
00384         *info = -6;
00385     } else if (*ldh < *n) {
00386         *info = -8;
00387     } else if (*ldt < *n) {
00388         *info = -10;
00389     } else if (*ldq < 1 || ilq && *ldq < *n) {
00390         *info = -15;
00391     } else if (*ldz < 1 || ilz && *ldz < *n) {
00392         *info = -17;
00393     } else if (*lwork < max(1,*n) && ! lquery) {
00394         *info = -19;
00395     }
00396     if (*info != 0) {
00397         i__1 = -(*info);
00398         xerbla_("DHGEQZ", &i__1);
00399         return 0;
00400     } else if (lquery) {
00401         return 0;
00402     }
00403 
00404 /*     Quick return if possible */
00405 
00406     if (*n <= 0) {
00407         work[1] = 1.;
00408         return 0;
00409     }
00410 
00411 /*     Initialize Q and Z */
00412 
00413     if (icompq == 3) {
00414         dlaset_("Full", n, n, &c_b12, &c_b13, &q[q_offset], ldq);
00415     }
00416     if (icompz == 3) {
00417         dlaset_("Full", n, n, &c_b12, &c_b13, &z__[z_offset], ldz);
00418     }
00419 
00420 /*     Machine Constants */
00421 
00422     in = *ihi + 1 - *ilo;
00423     safmin = dlamch_("S");
00424     safmax = 1. / safmin;
00425     ulp = dlamch_("E") * dlamch_("B");
00426     anorm = dlanhs_("F", &in, &h__[*ilo + *ilo * h_dim1], ldh, &work[1]);
00427     bnorm = dlanhs_("F", &in, &t[*ilo + *ilo * t_dim1], ldt, &work[1]);
00428 /* Computing MAX */
00429     d__1 = safmin, d__2 = ulp * anorm;
00430     atol = max(d__1,d__2);
00431 /* Computing MAX */
00432     d__1 = safmin, d__2 = ulp * bnorm;
00433     btol = max(d__1,d__2);
00434     ascale = 1. / max(safmin,anorm);
00435     bscale = 1. / max(safmin,bnorm);
00436 
00437 /*     Set Eigenvalues IHI+1:N */
00438 
00439     i__1 = *n;
00440     for (j = *ihi + 1; j <= i__1; ++j) {
00441         if (t[j + j * t_dim1] < 0.) {
00442             if (ilschr) {
00443                 i__2 = j;
00444                 for (jr = 1; jr <= i__2; ++jr) {
00445                     h__[jr + j * h_dim1] = -h__[jr + j * h_dim1];
00446                     t[jr + j * t_dim1] = -t[jr + j * t_dim1];
00447 /* L10: */
00448                 }
00449             } else {
00450                 h__[j + j * h_dim1] = -h__[j + j * h_dim1];
00451                 t[j + j * t_dim1] = -t[j + j * t_dim1];
00452             }
00453             if (ilz) {
00454                 i__2 = *n;
00455                 for (jr = 1; jr <= i__2; ++jr) {
00456                     z__[jr + j * z_dim1] = -z__[jr + j * z_dim1];
00457 /* L20: */
00458                 }
00459             }
00460         }
00461         alphar[j] = h__[j + j * h_dim1];
00462         alphai[j] = 0.;
00463         beta[j] = t[j + j * t_dim1];
00464 /* L30: */
00465     }
00466 
00467 /*     If IHI < ILO, skip QZ steps */
00468 
00469     if (*ihi < *ilo) {
00470         goto L380;
00471     }
00472 
00473 /*     MAIN QZ ITERATION LOOP */
00474 
00475 /*     Initialize dynamic indices */
00476 
00477 /*     Eigenvalues ILAST+1:N have been found. */
00478 /*        Column operations modify rows IFRSTM:whatever. */
00479 /*        Row operations modify columns whatever:ILASTM. */
00480 
00481 /*     If only eigenvalues are being computed, then */
00482 /*        IFRSTM is the row of the last splitting row above row ILAST; */
00483 /*        this is always at least ILO. */
00484 /*     IITER counts iterations since the last eigenvalue was found, */
00485 /*        to tell when to use an extraordinary shift. */
00486 /*     MAXIT is the maximum number of QZ sweeps allowed. */
00487 
00488     ilast = *ihi;
00489     if (ilschr) {
00490         ifrstm = 1;
00491         ilastm = *n;
00492     } else {
00493         ifrstm = *ilo;
00494         ilastm = *ihi;
00495     }
00496     iiter = 0;
00497     eshift = 0.;
00498     maxit = (*ihi - *ilo + 1) * 30;
00499 
00500     i__1 = maxit;
00501     for (jiter = 1; jiter <= i__1; ++jiter) {
00502 
00503 /*        Split the matrix if possible. */
00504 
00505 /*        Two tests: */
00506 /*           1: H(j,j-1)=0  or  j=ILO */
00507 /*           2: T(j,j)=0 */
00508 
00509         if (ilast == *ilo) {
00510 
00511 /*           Special case: j=ILAST */
00512 
00513             goto L80;
00514         } else {
00515             if ((d__1 = h__[ilast + (ilast - 1) * h_dim1], abs(d__1)) <= atol)
00516                      {
00517                 h__[ilast + (ilast - 1) * h_dim1] = 0.;
00518                 goto L80;
00519             }
00520         }
00521 
00522         if ((d__1 = t[ilast + ilast * t_dim1], abs(d__1)) <= btol) {
00523             t[ilast + ilast * t_dim1] = 0.;
00524             goto L70;
00525         }
00526 
00527 /*        General case: j<ILAST */
00528 
00529         i__2 = *ilo;
00530         for (j = ilast - 1; j >= i__2; --j) {
00531 
00532 /*           Test 1: for H(j,j-1)=0 or j=ILO */
00533 
00534             if (j == *ilo) {
00535                 ilazro = TRUE_;
00536             } else {
00537                 if ((d__1 = h__[j + (j - 1) * h_dim1], abs(d__1)) <= atol) {
00538                     h__[j + (j - 1) * h_dim1] = 0.;
00539                     ilazro = TRUE_;
00540                 } else {
00541                     ilazro = FALSE_;
00542                 }
00543             }
00544 
00545 /*           Test 2: for T(j,j)=0 */
00546 
00547             if ((d__1 = t[j + j * t_dim1], abs(d__1)) < btol) {
00548                 t[j + j * t_dim1] = 0.;
00549 
00550 /*              Test 1a: Check for 2 consecutive small subdiagonals in A */
00551 
00552                 ilazr2 = FALSE_;
00553                 if (! ilazro) {
00554                     temp = (d__1 = h__[j + (j - 1) * h_dim1], abs(d__1));
00555                     temp2 = (d__1 = h__[j + j * h_dim1], abs(d__1));
00556                     tempr = max(temp,temp2);
00557                     if (tempr < 1. && tempr != 0.) {
00558                         temp /= tempr;
00559                         temp2 /= tempr;
00560                     }
00561                     if (temp * (ascale * (d__1 = h__[j + 1 + j * h_dim1], abs(
00562                             d__1))) <= temp2 * (ascale * atol)) {
00563                         ilazr2 = TRUE_;
00564                     }
00565                 }
00566 
00567 /*              If both tests pass (1 & 2), i.e., the leading diagonal */
00568 /*              element of B in the block is zero, split a 1x1 block off */
00569 /*              at the top. (I.e., at the J-th row/column) The leading */
00570 /*              diagonal element of the remainder can also be zero, so */
00571 /*              this may have to be done repeatedly. */
00572 
00573                 if (ilazro || ilazr2) {
00574                     i__3 = ilast - 1;
00575                     for (jch = j; jch <= i__3; ++jch) {
00576                         temp = h__[jch + jch * h_dim1];
00577                         dlartg_(&temp, &h__[jch + 1 + jch * h_dim1], &c__, &s, 
00578                                  &h__[jch + jch * h_dim1]);
00579                         h__[jch + 1 + jch * h_dim1] = 0.;
00580                         i__4 = ilastm - jch;
00581                         drot_(&i__4, &h__[jch + (jch + 1) * h_dim1], ldh, &
00582                                 h__[jch + 1 + (jch + 1) * h_dim1], ldh, &c__, 
00583                                 &s);
00584                         i__4 = ilastm - jch;
00585                         drot_(&i__4, &t[jch + (jch + 1) * t_dim1], ldt, &t[
00586                                 jch + 1 + (jch + 1) * t_dim1], ldt, &c__, &s);
00587                         if (ilq) {
00588                             drot_(n, &q[jch * q_dim1 + 1], &c__1, &q[(jch + 1)
00589                                      * q_dim1 + 1], &c__1, &c__, &s);
00590                         }
00591                         if (ilazr2) {
00592                             h__[jch + (jch - 1) * h_dim1] *= c__;
00593                         }
00594                         ilazr2 = FALSE_;
00595                         if ((d__1 = t[jch + 1 + (jch + 1) * t_dim1], abs(d__1)
00596                                 ) >= btol) {
00597                             if (jch + 1 >= ilast) {
00598                                 goto L80;
00599                             } else {
00600                                 ifirst = jch + 1;
00601                                 goto L110;
00602                             }
00603                         }
00604                         t[jch + 1 + (jch + 1) * t_dim1] = 0.;
00605 /* L40: */
00606                     }
00607                     goto L70;
00608                 } else {
00609 
00610 /*                 Only test 2 passed -- chase the zero to T(ILAST,ILAST) */
00611 /*                 Then process as in the case T(ILAST,ILAST)=0 */
00612 
00613                     i__3 = ilast - 1;
00614                     for (jch = j; jch <= i__3; ++jch) {
00615                         temp = t[jch + (jch + 1) * t_dim1];
00616                         dlartg_(&temp, &t[jch + 1 + (jch + 1) * t_dim1], &c__, 
00617                                  &s, &t[jch + (jch + 1) * t_dim1]);
00618                         t[jch + 1 + (jch + 1) * t_dim1] = 0.;
00619                         if (jch < ilastm - 1) {
00620                             i__4 = ilastm - jch - 1;
00621                             drot_(&i__4, &t[jch + (jch + 2) * t_dim1], ldt, &
00622                                     t[jch + 1 + (jch + 2) * t_dim1], ldt, &
00623                                     c__, &s);
00624                         }
00625                         i__4 = ilastm - jch + 2;
00626                         drot_(&i__4, &h__[jch + (jch - 1) * h_dim1], ldh, &
00627                                 h__[jch + 1 + (jch - 1) * h_dim1], ldh, &c__, 
00628                                 &s);
00629                         if (ilq) {
00630                             drot_(n, &q[jch * q_dim1 + 1], &c__1, &q[(jch + 1)
00631                                      * q_dim1 + 1], &c__1, &c__, &s);
00632                         }
00633                         temp = h__[jch + 1 + jch * h_dim1];
00634                         dlartg_(&temp, &h__[jch + 1 + (jch - 1) * h_dim1], &
00635                                 c__, &s, &h__[jch + 1 + jch * h_dim1]);
00636                         h__[jch + 1 + (jch - 1) * h_dim1] = 0.;
00637                         i__4 = jch + 1 - ifrstm;
00638                         drot_(&i__4, &h__[ifrstm + jch * h_dim1], &c__1, &h__[
00639                                 ifrstm + (jch - 1) * h_dim1], &c__1, &c__, &s)
00640                                 ;
00641                         i__4 = jch - ifrstm;
00642                         drot_(&i__4, &t[ifrstm + jch * t_dim1], &c__1, &t[
00643                                 ifrstm + (jch - 1) * t_dim1], &c__1, &c__, &s)
00644                                 ;
00645                         if (ilz) {
00646                             drot_(n, &z__[jch * z_dim1 + 1], &c__1, &z__[(jch 
00647                                     - 1) * z_dim1 + 1], &c__1, &c__, &s);
00648                         }
00649 /* L50: */
00650                     }
00651                     goto L70;
00652                 }
00653             } else if (ilazro) {
00654 
00655 /*              Only test 1 passed -- work on J:ILAST */
00656 
00657                 ifirst = j;
00658                 goto L110;
00659             }
00660 
00661 /*           Neither test passed -- try next J */
00662 
00663 /* L60: */
00664         }
00665 
00666 /*        (Drop-through is "impossible") */
00667 
00668         *info = *n + 1;
00669         goto L420;
00670 
00671 /*        T(ILAST,ILAST)=0 -- clear H(ILAST,ILAST-1) to split off a */
00672 /*        1x1 block. */
00673 
00674 L70:
00675         temp = h__[ilast + ilast * h_dim1];
00676         dlartg_(&temp, &h__[ilast + (ilast - 1) * h_dim1], &c__, &s, &h__[
00677                 ilast + ilast * h_dim1]);
00678         h__[ilast + (ilast - 1) * h_dim1] = 0.;
00679         i__2 = ilast - ifrstm;
00680         drot_(&i__2, &h__[ifrstm + ilast * h_dim1], &c__1, &h__[ifrstm + (
00681                 ilast - 1) * h_dim1], &c__1, &c__, &s);
00682         i__2 = ilast - ifrstm;
00683         drot_(&i__2, &t[ifrstm + ilast * t_dim1], &c__1, &t[ifrstm + (ilast - 
00684                 1) * t_dim1], &c__1, &c__, &s);
00685         if (ilz) {
00686             drot_(n, &z__[ilast * z_dim1 + 1], &c__1, &z__[(ilast - 1) * 
00687                     z_dim1 + 1], &c__1, &c__, &s);
00688         }
00689 
00690 /*        H(ILAST,ILAST-1)=0 -- Standardize B, set ALPHAR, ALPHAI, */
00691 /*                              and BETA */
00692 
00693 L80:
00694         if (t[ilast + ilast * t_dim1] < 0.) {
00695             if (ilschr) {
00696                 i__2 = ilast;
00697                 for (j = ifrstm; j <= i__2; ++j) {
00698                     h__[j + ilast * h_dim1] = -h__[j + ilast * h_dim1];
00699                     t[j + ilast * t_dim1] = -t[j + ilast * t_dim1];
00700 /* L90: */
00701                 }
00702             } else {
00703                 h__[ilast + ilast * h_dim1] = -h__[ilast + ilast * h_dim1];
00704                 t[ilast + ilast * t_dim1] = -t[ilast + ilast * t_dim1];
00705             }
00706             if (ilz) {
00707                 i__2 = *n;
00708                 for (j = 1; j <= i__2; ++j) {
00709                     z__[j + ilast * z_dim1] = -z__[j + ilast * z_dim1];
00710 /* L100: */
00711                 }
00712             }
00713         }
00714         alphar[ilast] = h__[ilast + ilast * h_dim1];
00715         alphai[ilast] = 0.;
00716         beta[ilast] = t[ilast + ilast * t_dim1];
00717 
00718 /*        Go to next block -- exit if finished. */
00719 
00720         --ilast;
00721         if (ilast < *ilo) {
00722             goto L380;
00723         }
00724 
00725 /*        Reset counters */
00726 
00727         iiter = 0;
00728         eshift = 0.;
00729         if (! ilschr) {
00730             ilastm = ilast;
00731             if (ifrstm > ilast) {
00732                 ifrstm = *ilo;
00733             }
00734         }
00735         goto L350;
00736 
00737 /*        QZ step */
00738 
00739 /*        This iteration only involves rows/columns IFIRST:ILAST. We */
00740 /*        assume IFIRST < ILAST, and that the diagonal of B is non-zero. */
00741 
00742 L110:
00743         ++iiter;
00744         if (! ilschr) {
00745             ifrstm = ifirst;
00746         }
00747 
00748 /*        Compute single shifts. */
00749 
00750 /*        At this point, IFIRST < ILAST, and the diagonal elements of */
00751 /*        T(IFIRST:ILAST,IFIRST,ILAST) are larger than BTOL (in */
00752 /*        magnitude) */
00753 
00754         if (iiter / 10 * 10 == iiter) {
00755 
00756 /*           Exceptional shift.  Chosen for no particularly good reason. */
00757 /*           (Single shift only.) */
00758 
00759             if ((doublereal) maxit * safmin * (d__1 = h__[ilast - 1 + ilast * 
00760                     h_dim1], abs(d__1)) < (d__2 = t[ilast - 1 + (ilast - 1) * 
00761                     t_dim1], abs(d__2))) {
00762                 eshift += h__[ilast - 1 + ilast * h_dim1] / t[ilast - 1 + (
00763                         ilast - 1) * t_dim1];
00764             } else {
00765                 eshift += 1. / (safmin * (doublereal) maxit);
00766             }
00767             s1 = 1.;
00768             wr = eshift;
00769 
00770         } else {
00771 
00772 /*           Shifts based on the generalized eigenvalues of the */
00773 /*           bottom-right 2x2 block of A and B. The first eigenvalue */
00774 /*           returned by DLAG2 is the Wilkinson shift (AEP p.512), */
00775 
00776             d__1 = safmin * 100.;
00777             dlag2_(&h__[ilast - 1 + (ilast - 1) * h_dim1], ldh, &t[ilast - 1 
00778                     + (ilast - 1) * t_dim1], ldt, &d__1, &s1, &s2, &wr, &wr2, 
00779                     &wi);
00780 
00781 /* Computing MAX */
00782 /* Computing MAX */
00783             d__3 = 1., d__4 = abs(wr), d__3 = max(d__3,d__4), d__4 = abs(wi);
00784             d__1 = s1, d__2 = safmin * max(d__3,d__4);
00785             temp = max(d__1,d__2);
00786             if (wi != 0.) {
00787                 goto L200;
00788             }
00789         }
00790 
00791 /*        Fiddle with shift to avoid overflow */
00792 
00793         temp = min(ascale,1.) * (safmax * .5);
00794         if (s1 > temp) {
00795             scale = temp / s1;
00796         } else {
00797             scale = 1.;
00798         }
00799 
00800         temp = min(bscale,1.) * (safmax * .5);
00801         if (abs(wr) > temp) {
00802 /* Computing MIN */
00803             d__1 = scale, d__2 = temp / abs(wr);
00804             scale = min(d__1,d__2);
00805         }
00806         s1 = scale * s1;
00807         wr = scale * wr;
00808 
00809 /*        Now check for two consecutive small subdiagonals. */
00810 
00811         i__2 = ifirst + 1;
00812         for (j = ilast - 1; j >= i__2; --j) {
00813             istart = j;
00814             temp = (d__1 = s1 * h__[j + (j - 1) * h_dim1], abs(d__1));
00815             temp2 = (d__1 = s1 * h__[j + j * h_dim1] - wr * t[j + j * t_dim1],
00816                      abs(d__1));
00817             tempr = max(temp,temp2);
00818             if (tempr < 1. && tempr != 0.) {
00819                 temp /= tempr;
00820                 temp2 /= tempr;
00821             }
00822             if ((d__1 = ascale * h__[j + 1 + j * h_dim1] * temp, abs(d__1)) <=
00823                      ascale * atol * temp2) {
00824                 goto L130;
00825             }
00826 /* L120: */
00827         }
00828 
00829         istart = ifirst;
00830 L130:
00831 
00832 /*        Do an implicit single-shift QZ sweep. */
00833 
00834 /*        Initial Q */
00835 
00836         temp = s1 * h__[istart + istart * h_dim1] - wr * t[istart + istart * 
00837                 t_dim1];
00838         temp2 = s1 * h__[istart + 1 + istart * h_dim1];
00839         dlartg_(&temp, &temp2, &c__, &s, &tempr);
00840 
00841 /*        Sweep */
00842 
00843         i__2 = ilast - 1;
00844         for (j = istart; j <= i__2; ++j) {
00845             if (j > istart) {
00846                 temp = h__[j + (j - 1) * h_dim1];
00847                 dlartg_(&temp, &h__[j + 1 + (j - 1) * h_dim1], &c__, &s, &h__[
00848                         j + (j - 1) * h_dim1]);
00849                 h__[j + 1 + (j - 1) * h_dim1] = 0.;
00850             }
00851 
00852             i__3 = ilastm;
00853             for (jc = j; jc <= i__3; ++jc) {
00854                 temp = c__ * h__[j + jc * h_dim1] + s * h__[j + 1 + jc * 
00855                         h_dim1];
00856                 h__[j + 1 + jc * h_dim1] = -s * h__[j + jc * h_dim1] + c__ * 
00857                         h__[j + 1 + jc * h_dim1];
00858                 h__[j + jc * h_dim1] = temp;
00859                 temp2 = c__ * t[j + jc * t_dim1] + s * t[j + 1 + jc * t_dim1];
00860                 t[j + 1 + jc * t_dim1] = -s * t[j + jc * t_dim1] + c__ * t[j 
00861                         + 1 + jc * t_dim1];
00862                 t[j + jc * t_dim1] = temp2;
00863 /* L140: */
00864             }
00865             if (ilq) {
00866                 i__3 = *n;
00867                 for (jr = 1; jr <= i__3; ++jr) {
00868                     temp = c__ * q[jr + j * q_dim1] + s * q[jr + (j + 1) * 
00869                             q_dim1];
00870                     q[jr + (j + 1) * q_dim1] = -s * q[jr + j * q_dim1] + c__ *
00871                              q[jr + (j + 1) * q_dim1];
00872                     q[jr + j * q_dim1] = temp;
00873 /* L150: */
00874                 }
00875             }
00876 
00877             temp = t[j + 1 + (j + 1) * t_dim1];
00878             dlartg_(&temp, &t[j + 1 + j * t_dim1], &c__, &s, &t[j + 1 + (j + 
00879                     1) * t_dim1]);
00880             t[j + 1 + j * t_dim1] = 0.;
00881 
00882 /* Computing MIN */
00883             i__4 = j + 2;
00884             i__3 = min(i__4,ilast);
00885             for (jr = ifrstm; jr <= i__3; ++jr) {
00886                 temp = c__ * h__[jr + (j + 1) * h_dim1] + s * h__[jr + j * 
00887                         h_dim1];
00888                 h__[jr + j * h_dim1] = -s * h__[jr + (j + 1) * h_dim1] + c__ *
00889                          h__[jr + j * h_dim1];
00890                 h__[jr + (j + 1) * h_dim1] = temp;
00891 /* L160: */
00892             }
00893             i__3 = j;
00894             for (jr = ifrstm; jr <= i__3; ++jr) {
00895                 temp = c__ * t[jr + (j + 1) * t_dim1] + s * t[jr + j * t_dim1]
00896                         ;
00897                 t[jr + j * t_dim1] = -s * t[jr + (j + 1) * t_dim1] + c__ * t[
00898                         jr + j * t_dim1];
00899                 t[jr + (j + 1) * t_dim1] = temp;
00900 /* L170: */
00901             }
00902             if (ilz) {
00903                 i__3 = *n;
00904                 for (jr = 1; jr <= i__3; ++jr) {
00905                     temp = c__ * z__[jr + (j + 1) * z_dim1] + s * z__[jr + j *
00906                              z_dim1];
00907                     z__[jr + j * z_dim1] = -s * z__[jr + (j + 1) * z_dim1] + 
00908                             c__ * z__[jr + j * z_dim1];
00909                     z__[jr + (j + 1) * z_dim1] = temp;
00910 /* L180: */
00911                 }
00912             }
00913 /* L190: */
00914         }
00915 
00916         goto L350;
00917 
00918 /*        Use Francis double-shift */
00919 
00920 /*        Note: the Francis double-shift should work with real shifts, */
00921 /*              but only if the block is at least 3x3. */
00922 /*              This code may break if this point is reached with */
00923 /*              a 2x2 block with real eigenvalues. */
00924 
00925 L200:
00926         if (ifirst + 1 == ilast) {
00927 
00928 /*           Special case -- 2x2 block with complex eigenvectors */
00929 
00930 /*           Step 1: Standardize, that is, rotate so that */
00931 
00932 /*                       ( B11  0  ) */
00933 /*                   B = (         )  with B11 non-negative. */
00934 /*                       (  0  B22 ) */
00935 
00936             dlasv2_(&t[ilast - 1 + (ilast - 1) * t_dim1], &t[ilast - 1 + 
00937                     ilast * t_dim1], &t[ilast + ilast * t_dim1], &b22, &b11, &
00938                     sr, &cr, &sl, &cl);
00939 
00940             if (b11 < 0.) {
00941                 cr = -cr;
00942                 sr = -sr;
00943                 b11 = -b11;
00944                 b22 = -b22;
00945             }
00946 
00947             i__2 = ilastm + 1 - ifirst;
00948             drot_(&i__2, &h__[ilast - 1 + (ilast - 1) * h_dim1], ldh, &h__[
00949                     ilast + (ilast - 1) * h_dim1], ldh, &cl, &sl);
00950             i__2 = ilast + 1 - ifrstm;
00951             drot_(&i__2, &h__[ifrstm + (ilast - 1) * h_dim1], &c__1, &h__[
00952                     ifrstm + ilast * h_dim1], &c__1, &cr, &sr);
00953 
00954             if (ilast < ilastm) {
00955                 i__2 = ilastm - ilast;
00956                 drot_(&i__2, &t[ilast - 1 + (ilast + 1) * t_dim1], ldt, &t[
00957                         ilast + (ilast + 1) * t_dim1], ldt, &cl, &sl);
00958             }
00959             if (ifrstm < ilast - 1) {
00960                 i__2 = ifirst - ifrstm;
00961                 drot_(&i__2, &t[ifrstm + (ilast - 1) * t_dim1], &c__1, &t[
00962                         ifrstm + ilast * t_dim1], &c__1, &cr, &sr);
00963             }
00964 
00965             if (ilq) {
00966                 drot_(n, &q[(ilast - 1) * q_dim1 + 1], &c__1, &q[ilast * 
00967                         q_dim1 + 1], &c__1, &cl, &sl);
00968             }
00969             if (ilz) {
00970                 drot_(n, &z__[(ilast - 1) * z_dim1 + 1], &c__1, &z__[ilast * 
00971                         z_dim1 + 1], &c__1, &cr, &sr);
00972             }
00973 
00974             t[ilast - 1 + (ilast - 1) * t_dim1] = b11;
00975             t[ilast - 1 + ilast * t_dim1] = 0.;
00976             t[ilast + (ilast - 1) * t_dim1] = 0.;
00977             t[ilast + ilast * t_dim1] = b22;
00978 
00979 /*           If B22 is negative, negate column ILAST */
00980 
00981             if (b22 < 0.) {
00982                 i__2 = ilast;
00983                 for (j = ifrstm; j <= i__2; ++j) {
00984                     h__[j + ilast * h_dim1] = -h__[j + ilast * h_dim1];
00985                     t[j + ilast * t_dim1] = -t[j + ilast * t_dim1];
00986 /* L210: */
00987                 }
00988 
00989                 if (ilz) {
00990                     i__2 = *n;
00991                     for (j = 1; j <= i__2; ++j) {
00992                         z__[j + ilast * z_dim1] = -z__[j + ilast * z_dim1];
00993 /* L220: */
00994                     }
00995                 }
00996             }
00997 
00998 /*           Step 2: Compute ALPHAR, ALPHAI, and BETA (see refs.) */
00999 
01000 /*           Recompute shift */
01001 
01002             d__1 = safmin * 100.;
01003             dlag2_(&h__[ilast - 1 + (ilast - 1) * h_dim1], ldh, &t[ilast - 1 
01004                     + (ilast - 1) * t_dim1], ldt, &d__1, &s1, &temp, &wr, &
01005                     temp2, &wi);
01006 
01007 /*           If standardization has perturbed the shift onto real line, */
01008 /*           do another (real single-shift) QR step. */
01009 
01010             if (wi == 0.) {
01011                 goto L350;
01012             }
01013             s1inv = 1. / s1;
01014 
01015 /*           Do EISPACK (QZVAL) computation of alpha and beta */
01016 
01017             a11 = h__[ilast - 1 + (ilast - 1) * h_dim1];
01018             a21 = h__[ilast + (ilast - 1) * h_dim1];
01019             a12 = h__[ilast - 1 + ilast * h_dim1];
01020             a22 = h__[ilast + ilast * h_dim1];
01021 
01022 /*           Compute complex Givens rotation on right */
01023 /*           (Assume some element of C = (sA - wB) > unfl ) */
01024 /*                            __ */
01025 /*           (sA - wB) ( CZ   -SZ ) */
01026 /*                     ( SZ    CZ ) */
01027 
01028             c11r = s1 * a11 - wr * b11;
01029             c11i = -wi * b11;
01030             c12 = s1 * a12;
01031             c21 = s1 * a21;
01032             c22r = s1 * a22 - wr * b22;
01033             c22i = -wi * b22;
01034 
01035             if (abs(c11r) + abs(c11i) + abs(c12) > abs(c21) + abs(c22r) + abs(
01036                     c22i)) {
01037                 t1 = dlapy3_(&c12, &c11r, &c11i);
01038                 cz = c12 / t1;
01039                 szr = -c11r / t1;
01040                 szi = -c11i / t1;
01041             } else {
01042                 cz = dlapy2_(&c22r, &c22i);
01043                 if (cz <= safmin) {
01044                     cz = 0.;
01045                     szr = 1.;
01046                     szi = 0.;
01047                 } else {
01048                     tempr = c22r / cz;
01049                     tempi = c22i / cz;
01050                     t1 = dlapy2_(&cz, &c21);
01051                     cz /= t1;
01052                     szr = -c21 * tempr / t1;
01053                     szi = c21 * tempi / t1;
01054                 }
01055             }
01056 
01057 /*           Compute Givens rotation on left */
01058 
01059 /*           (  CQ   SQ ) */
01060 /*           (  __      )  A or B */
01061 /*           ( -SQ   CQ ) */
01062 
01063             an = abs(a11) + abs(a12) + abs(a21) + abs(a22);
01064             bn = abs(b11) + abs(b22);
01065             wabs = abs(wr) + abs(wi);
01066             if (s1 * an > wabs * bn) {
01067                 cq = cz * b11;
01068                 sqr = szr * b22;
01069                 sqi = -szi * b22;
01070             } else {
01071                 a1r = cz * a11 + szr * a12;
01072                 a1i = szi * a12;
01073                 a2r = cz * a21 + szr * a22;
01074                 a2i = szi * a22;
01075                 cq = dlapy2_(&a1r, &a1i);
01076                 if (cq <= safmin) {
01077                     cq = 0.;
01078                     sqr = 1.;
01079                     sqi = 0.;
01080                 } else {
01081                     tempr = a1r / cq;
01082                     tempi = a1i / cq;
01083                     sqr = tempr * a2r + tempi * a2i;
01084                     sqi = tempi * a2r - tempr * a2i;
01085                 }
01086             }
01087             t1 = dlapy3_(&cq, &sqr, &sqi);
01088             cq /= t1;
01089             sqr /= t1;
01090             sqi /= t1;
01091 
01092 /*           Compute diagonal elements of QBZ */
01093 
01094             tempr = sqr * szr - sqi * szi;
01095             tempi = sqr * szi + sqi * szr;
01096             b1r = cq * cz * b11 + tempr * b22;
01097             b1i = tempi * b22;
01098             b1a = dlapy2_(&b1r, &b1i);
01099             b2r = cq * cz * b22 + tempr * b11;
01100             b2i = -tempi * b11;
01101             b2a = dlapy2_(&b2r, &b2i);
01102 
01103 /*           Normalize so beta > 0, and Im( alpha1 ) > 0 */
01104 
01105             beta[ilast - 1] = b1a;
01106             beta[ilast] = b2a;
01107             alphar[ilast - 1] = wr * b1a * s1inv;
01108             alphai[ilast - 1] = wi * b1a * s1inv;
01109             alphar[ilast] = wr * b2a * s1inv;
01110             alphai[ilast] = -(wi * b2a) * s1inv;
01111 
01112 /*           Step 3: Go to next block -- exit if finished. */
01113 
01114             ilast = ifirst - 1;
01115             if (ilast < *ilo) {
01116                 goto L380;
01117             }
01118 
01119 /*           Reset counters */
01120 
01121             iiter = 0;
01122             eshift = 0.;
01123             if (! ilschr) {
01124                 ilastm = ilast;
01125                 if (ifrstm > ilast) {
01126                     ifrstm = *ilo;
01127                 }
01128             }
01129             goto L350;
01130         } else {
01131 
01132 /*           Usual case: 3x3 or larger block, using Francis implicit */
01133 /*                       double-shift */
01134 
01135 /*                                    2 */
01136 /*           Eigenvalue equation is  w  - c w + d = 0, */
01137 
01138 /*                                         -1 2        -1 */
01139 /*           so compute 1st column of  (A B  )  - c A B   + d */
01140 /*           using the formula in QZIT (from EISPACK) */
01141 
01142 /*           We assume that the block is at least 3x3 */
01143 
01144             ad11 = ascale * h__[ilast - 1 + (ilast - 1) * h_dim1] / (bscale * 
01145                     t[ilast - 1 + (ilast - 1) * t_dim1]);
01146             ad21 = ascale * h__[ilast + (ilast - 1) * h_dim1] / (bscale * t[
01147                     ilast - 1 + (ilast - 1) * t_dim1]);
01148             ad12 = ascale * h__[ilast - 1 + ilast * h_dim1] / (bscale * t[
01149                     ilast + ilast * t_dim1]);
01150             ad22 = ascale * h__[ilast + ilast * h_dim1] / (bscale * t[ilast + 
01151                     ilast * t_dim1]);
01152             u12 = t[ilast - 1 + ilast * t_dim1] / t[ilast + ilast * t_dim1];
01153             ad11l = ascale * h__[ifirst + ifirst * h_dim1] / (bscale * t[
01154                     ifirst + ifirst * t_dim1]);
01155             ad21l = ascale * h__[ifirst + 1 + ifirst * h_dim1] / (bscale * t[
01156                     ifirst + ifirst * t_dim1]);
01157             ad12l = ascale * h__[ifirst + (ifirst + 1) * h_dim1] / (bscale * 
01158                     t[ifirst + 1 + (ifirst + 1) * t_dim1]);
01159             ad22l = ascale * h__[ifirst + 1 + (ifirst + 1) * h_dim1] / (
01160                     bscale * t[ifirst + 1 + (ifirst + 1) * t_dim1]);
01161             ad32l = ascale * h__[ifirst + 2 + (ifirst + 1) * h_dim1] / (
01162                     bscale * t[ifirst + 1 + (ifirst + 1) * t_dim1]);
01163             u12l = t[ifirst + (ifirst + 1) * t_dim1] / t[ifirst + 1 + (ifirst 
01164                     + 1) * t_dim1];
01165 
01166             v[0] = (ad11 - ad11l) * (ad22 - ad11l) - ad12 * ad21 + ad21 * u12 
01167                     * ad11l + (ad12l - ad11l * u12l) * ad21l;
01168             v[1] = (ad22l - ad11l - ad21l * u12l - (ad11 - ad11l) - (ad22 - 
01169                     ad11l) + ad21 * u12) * ad21l;
01170             v[2] = ad32l * ad21l;
01171 
01172             istart = ifirst;
01173 
01174             dlarfg_(&c__3, v, &v[1], &c__1, &tau);
01175             v[0] = 1.;
01176 
01177 /*           Sweep */
01178 
01179             i__2 = ilast - 2;
01180             for (j = istart; j <= i__2; ++j) {
01181 
01182 /*              All but last elements: use 3x3 Householder transforms. */
01183 
01184 /*              Zero (j-1)st column of A */
01185 
01186                 if (j > istart) {
01187                     v[0] = h__[j + (j - 1) * h_dim1];
01188                     v[1] = h__[j + 1 + (j - 1) * h_dim1];
01189                     v[2] = h__[j + 2 + (j - 1) * h_dim1];
01190 
01191                     dlarfg_(&c__3, &h__[j + (j - 1) * h_dim1], &v[1], &c__1, &
01192                             tau);
01193                     v[0] = 1.;
01194                     h__[j + 1 + (j - 1) * h_dim1] = 0.;
01195                     h__[j + 2 + (j - 1) * h_dim1] = 0.;
01196                 }
01197 
01198                 i__3 = ilastm;
01199                 for (jc = j; jc <= i__3; ++jc) {
01200                     temp = tau * (h__[j + jc * h_dim1] + v[1] * h__[j + 1 + 
01201                             jc * h_dim1] + v[2] * h__[j + 2 + jc * h_dim1]);
01202                     h__[j + jc * h_dim1] -= temp;
01203                     h__[j + 1 + jc * h_dim1] -= temp * v[1];
01204                     h__[j + 2 + jc * h_dim1] -= temp * v[2];
01205                     temp2 = tau * (t[j + jc * t_dim1] + v[1] * t[j + 1 + jc * 
01206                             t_dim1] + v[2] * t[j + 2 + jc * t_dim1]);
01207                     t[j + jc * t_dim1] -= temp2;
01208                     t[j + 1 + jc * t_dim1] -= temp2 * v[1];
01209                     t[j + 2 + jc * t_dim1] -= temp2 * v[2];
01210 /* L230: */
01211                 }
01212                 if (ilq) {
01213                     i__3 = *n;
01214                     for (jr = 1; jr <= i__3; ++jr) {
01215                         temp = tau * (q[jr + j * q_dim1] + v[1] * q[jr + (j + 
01216                                 1) * q_dim1] + v[2] * q[jr + (j + 2) * q_dim1]
01217                                 );
01218                         q[jr + j * q_dim1] -= temp;
01219                         q[jr + (j + 1) * q_dim1] -= temp * v[1];
01220                         q[jr + (j + 2) * q_dim1] -= temp * v[2];
01221 /* L240: */
01222                     }
01223                 }
01224 
01225 /*              Zero j-th column of B (see DLAGBC for details) */
01226 
01227 /*              Swap rows to pivot */
01228 
01229                 ilpivt = FALSE_;
01230 /* Computing MAX */
01231                 d__3 = (d__1 = t[j + 1 + (j + 1) * t_dim1], abs(d__1)), d__4 =
01232                          (d__2 = t[j + 1 + (j + 2) * t_dim1], abs(d__2));
01233                 temp = max(d__3,d__4);
01234 /* Computing MAX */
01235                 d__3 = (d__1 = t[j + 2 + (j + 1) * t_dim1], abs(d__1)), d__4 =
01236                          (d__2 = t[j + 2 + (j + 2) * t_dim1], abs(d__2));
01237                 temp2 = max(d__3,d__4);
01238                 if (max(temp,temp2) < safmin) {
01239                     scale = 0.;
01240                     u1 = 1.;
01241                     u2 = 0.;
01242                     goto L250;
01243                 } else if (temp >= temp2) {
01244                     w11 = t[j + 1 + (j + 1) * t_dim1];
01245                     w21 = t[j + 2 + (j + 1) * t_dim1];
01246                     w12 = t[j + 1 + (j + 2) * t_dim1];
01247                     w22 = t[j + 2 + (j + 2) * t_dim1];
01248                     u1 = t[j + 1 + j * t_dim1];
01249                     u2 = t[j + 2 + j * t_dim1];
01250                 } else {
01251                     w21 = t[j + 1 + (j + 1) * t_dim1];
01252                     w11 = t[j + 2 + (j + 1) * t_dim1];
01253                     w22 = t[j + 1 + (j + 2) * t_dim1];
01254                     w12 = t[j + 2 + (j + 2) * t_dim1];
01255                     u2 = t[j + 1 + j * t_dim1];
01256                     u1 = t[j + 2 + j * t_dim1];
01257                 }
01258 
01259 /*              Swap columns if nec. */
01260 
01261                 if (abs(w12) > abs(w11)) {
01262                     ilpivt = TRUE_;
01263                     temp = w12;
01264                     temp2 = w22;
01265                     w12 = w11;
01266                     w22 = w21;
01267                     w11 = temp;
01268                     w21 = temp2;
01269                 }
01270 
01271 /*              LU-factor */
01272 
01273                 temp = w21 / w11;
01274                 u2 -= temp * u1;
01275                 w22 -= temp * w12;
01276                 w21 = 0.;
01277 
01278 /*              Compute SCALE */
01279 
01280                 scale = 1.;
01281                 if (abs(w22) < safmin) {
01282                     scale = 0.;
01283                     u2 = 1.;
01284                     u1 = -w12 / w11;
01285                     goto L250;
01286                 }
01287                 if (abs(w22) < abs(u2)) {
01288                     scale = (d__1 = w22 / u2, abs(d__1));
01289                 }
01290                 if (abs(w11) < abs(u1)) {
01291 /* Computing MIN */
01292                     d__2 = scale, d__3 = (d__1 = w11 / u1, abs(d__1));
01293                     scale = min(d__2,d__3);
01294                 }
01295 
01296 /*              Solve */
01297 
01298                 u2 = scale * u2 / w22;
01299                 u1 = (scale * u1 - w12 * u2) / w11;
01300 
01301 L250:
01302                 if (ilpivt) {
01303                     temp = u2;
01304                     u2 = u1;
01305                     u1 = temp;
01306                 }
01307 
01308 /*              Compute Householder Vector */
01309 
01310 /* Computing 2nd power */
01311                 d__1 = scale;
01312 /* Computing 2nd power */
01313                 d__2 = u1;
01314 /* Computing 2nd power */
01315                 d__3 = u2;
01316                 t1 = sqrt(d__1 * d__1 + d__2 * d__2 + d__3 * d__3);
01317                 tau = scale / t1 + 1.;
01318                 vs = -1. / (scale + t1);
01319                 v[0] = 1.;
01320                 v[1] = vs * u1;
01321                 v[2] = vs * u2;
01322 
01323 /*              Apply transformations from the right. */
01324 
01325 /* Computing MIN */
01326                 i__4 = j + 3;
01327                 i__3 = min(i__4,ilast);
01328                 for (jr = ifrstm; jr <= i__3; ++jr) {
01329                     temp = tau * (h__[jr + j * h_dim1] + v[1] * h__[jr + (j + 
01330                             1) * h_dim1] + v[2] * h__[jr + (j + 2) * h_dim1]);
01331                     h__[jr + j * h_dim1] -= temp;
01332                     h__[jr + (j + 1) * h_dim1] -= temp * v[1];
01333                     h__[jr + (j + 2) * h_dim1] -= temp * v[2];
01334 /* L260: */
01335                 }
01336                 i__3 = j + 2;
01337                 for (jr = ifrstm; jr <= i__3; ++jr) {
01338                     temp = tau * (t[jr + j * t_dim1] + v[1] * t[jr + (j + 1) *
01339                              t_dim1] + v[2] * t[jr + (j + 2) * t_dim1]);
01340                     t[jr + j * t_dim1] -= temp;
01341                     t[jr + (j + 1) * t_dim1] -= temp * v[1];
01342                     t[jr + (j + 2) * t_dim1] -= temp * v[2];
01343 /* L270: */
01344                 }
01345                 if (ilz) {
01346                     i__3 = *n;
01347                     for (jr = 1; jr <= i__3; ++jr) {
01348                         temp = tau * (z__[jr + j * z_dim1] + v[1] * z__[jr + (
01349                                 j + 1) * z_dim1] + v[2] * z__[jr + (j + 2) * 
01350                                 z_dim1]);
01351                         z__[jr + j * z_dim1] -= temp;
01352                         z__[jr + (j + 1) * z_dim1] -= temp * v[1];
01353                         z__[jr + (j + 2) * z_dim1] -= temp * v[2];
01354 /* L280: */
01355                     }
01356                 }
01357                 t[j + 1 + j * t_dim1] = 0.;
01358                 t[j + 2 + j * t_dim1] = 0.;
01359 /* L290: */
01360             }
01361 
01362 /*           Last elements: Use Givens rotations */
01363 
01364 /*           Rotations from the left */
01365 
01366             j = ilast - 1;
01367             temp = h__[j + (j - 1) * h_dim1];
01368             dlartg_(&temp, &h__[j + 1 + (j - 1) * h_dim1], &c__, &s, &h__[j + 
01369                     (j - 1) * h_dim1]);
01370             h__[j + 1 + (j - 1) * h_dim1] = 0.;
01371 
01372             i__2 = ilastm;
01373             for (jc = j; jc <= i__2; ++jc) {
01374                 temp = c__ * h__[j + jc * h_dim1] + s * h__[j + 1 + jc * 
01375                         h_dim1];
01376                 h__[j + 1 + jc * h_dim1] = -s * h__[j + jc * h_dim1] + c__ * 
01377                         h__[j + 1 + jc * h_dim1];
01378                 h__[j + jc * h_dim1] = temp;
01379                 temp2 = c__ * t[j + jc * t_dim1] + s * t[j + 1 + jc * t_dim1];
01380                 t[j + 1 + jc * t_dim1] = -s * t[j + jc * t_dim1] + c__ * t[j 
01381                         + 1 + jc * t_dim1];
01382                 t[j + jc * t_dim1] = temp2;
01383 /* L300: */
01384             }
01385             if (ilq) {
01386                 i__2 = *n;
01387                 for (jr = 1; jr <= i__2; ++jr) {
01388                     temp = c__ * q[jr + j * q_dim1] + s * q[jr + (j + 1) * 
01389                             q_dim1];
01390                     q[jr + (j + 1) * q_dim1] = -s * q[jr + j * q_dim1] + c__ *
01391                              q[jr + (j + 1) * q_dim1];
01392                     q[jr + j * q_dim1] = temp;
01393 /* L310: */
01394                 }
01395             }
01396 
01397 /*           Rotations from the right. */
01398 
01399             temp = t[j + 1 + (j + 1) * t_dim1];
01400             dlartg_(&temp, &t[j + 1 + j * t_dim1], &c__, &s, &t[j + 1 + (j + 
01401                     1) * t_dim1]);
01402             t[j + 1 + j * t_dim1] = 0.;
01403 
01404             i__2 = ilast;
01405             for (jr = ifrstm; jr <= i__2; ++jr) {
01406                 temp = c__ * h__[jr + (j + 1) * h_dim1] + s * h__[jr + j * 
01407                         h_dim1];
01408                 h__[jr + j * h_dim1] = -s * h__[jr + (j + 1) * h_dim1] + c__ *
01409                          h__[jr + j * h_dim1];
01410                 h__[jr + (j + 1) * h_dim1] = temp;
01411 /* L320: */
01412             }
01413             i__2 = ilast - 1;
01414             for (jr = ifrstm; jr <= i__2; ++jr) {
01415                 temp = c__ * t[jr + (j + 1) * t_dim1] + s * t[jr + j * t_dim1]
01416                         ;
01417                 t[jr + j * t_dim1] = -s * t[jr + (j + 1) * t_dim1] + c__ * t[
01418                         jr + j * t_dim1];
01419                 t[jr + (j + 1) * t_dim1] = temp;
01420 /* L330: */
01421             }
01422             if (ilz) {
01423                 i__2 = *n;
01424                 for (jr = 1; jr <= i__2; ++jr) {
01425                     temp = c__ * z__[jr + (j + 1) * z_dim1] + s * z__[jr + j *
01426                              z_dim1];
01427                     z__[jr + j * z_dim1] = -s * z__[jr + (j + 1) * z_dim1] + 
01428                             c__ * z__[jr + j * z_dim1];
01429                     z__[jr + (j + 1) * z_dim1] = temp;
01430 /* L340: */
01431                 }
01432             }
01433 
01434 /*           End of Double-Shift code */
01435 
01436         }
01437 
01438         goto L350;
01439 
01440 /*        End of iteration loop */
01441 
01442 L350:
01443 /* L360: */
01444         ;
01445     }
01446 
01447 /*     Drop-through = non-convergence */
01448 
01449     *info = ilast;
01450     goto L420;
01451 
01452 /*     Successful completion of all QZ steps */
01453 
01454 L380:
01455 
01456 /*     Set Eigenvalues 1:ILO-1 */
01457 
01458     i__1 = *ilo - 1;
01459     for (j = 1; j <= i__1; ++j) {
01460         if (t[j + j * t_dim1] < 0.) {
01461             if (ilschr) {
01462                 i__2 = j;
01463                 for (jr = 1; jr <= i__2; ++jr) {
01464                     h__[jr + j * h_dim1] = -h__[jr + j * h_dim1];
01465                     t[jr + j * t_dim1] = -t[jr + j * t_dim1];
01466 /* L390: */
01467                 }
01468             } else {
01469                 h__[j + j * h_dim1] = -h__[j + j * h_dim1];
01470                 t[j + j * t_dim1] = -t[j + j * t_dim1];
01471             }
01472             if (ilz) {
01473                 i__2 = *n;
01474                 for (jr = 1; jr <= i__2; ++jr) {
01475                     z__[jr + j * z_dim1] = -z__[jr + j * z_dim1];
01476 /* L400: */
01477                 }
01478             }
01479         }
01480         alphar[j] = h__[j + j * h_dim1];
01481         alphai[j] = 0.;
01482         beta[j] = t[j + j * t_dim1];
01483 /* L410: */
01484     }
01485 
01486 /*     Normal Termination */
01487 
01488     *info = 0;
01489 
01490 /*     Exit (other than argument error) -- return optimal workspace size */
01491 
01492 L420:
01493     work[1] = (doublereal) (*n);
01494     return 0;
01495 
01496 /*     End of DHGEQZ */
01497 
01498 } /* dhgeqz_ */


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:55:45