dtgevc.c
Go to the documentation of this file.
00001 /* dtgevc.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 logical c_true = TRUE_;
00019 static integer c__2 = 2;
00020 static doublereal c_b34 = 1.;
00021 static integer c__1 = 1;
00022 static doublereal c_b36 = 0.;
00023 static logical c_false = FALSE_;
00024 
00025 /* Subroutine */ int dtgevc_(char *side, char *howmny, logical *select, 
00026         integer *n, doublereal *s, integer *lds, doublereal *p, integer *ldp, 
00027         doublereal *vl, integer *ldvl, doublereal *vr, integer *ldvr, integer 
00028         *mm, integer *m, doublereal *work, integer *info)
00029 {
00030     /* System generated locals */
00031     integer p_dim1, p_offset, s_dim1, s_offset, vl_dim1, vl_offset, vr_dim1, 
00032             vr_offset, i__1, i__2, i__3, i__4, i__5;
00033     doublereal d__1, d__2, d__3, d__4, d__5, d__6;
00034 
00035     /* Local variables */
00036     integer i__, j, ja, jc, je, na, im, jr, jw, nw;
00037     doublereal big;
00038     logical lsa, lsb;
00039     doublereal ulp, sum[4]      /* was [2][2] */;
00040     integer ibeg, ieig, iend;
00041     doublereal dmin__, temp, xmax, sump[4]      /* was [2][2] */, sums[4]       
00042             /* was [2][2] */;
00043     extern /* Subroutine */ int dlag2_(doublereal *, integer *, doublereal *, 
00044             integer *, doublereal *, doublereal *, doublereal *, doublereal *, 
00045              doublereal *, doublereal *);
00046     doublereal cim2a, cim2b, cre2a, cre2b, temp2, bdiag[2], acoef, scale;
00047     logical ilall;
00048     integer iside;
00049     doublereal sbeta;
00050     extern logical lsame_(char *, char *);
00051     extern /* Subroutine */ int dgemv_(char *, integer *, integer *, 
00052             doublereal *, doublereal *, integer *, doublereal *, integer *, 
00053             doublereal *, doublereal *, integer *);
00054     logical il2by2;
00055     integer iinfo;
00056     doublereal small;
00057     logical compl;
00058     doublereal anorm, bnorm;
00059     logical compr;
00060     extern /* Subroutine */ int dlaln2_(logical *, integer *, integer *, 
00061             doublereal *, doublereal *, doublereal *, integer *, doublereal *, 
00062              doublereal *, doublereal *, integer *, doublereal *, doublereal *
00063 , doublereal *, integer *, doublereal *, doublereal *, integer *);
00064     doublereal temp2i;
00065     extern /* Subroutine */ int dlabad_(doublereal *, doublereal *);
00066     doublereal temp2r;
00067     logical ilabad, ilbbad;
00068     doublereal acoefa, bcoefa, cimaga, cimagb;
00069     logical ilback;
00070     doublereal bcoefi, ascale, bscale, creala, crealb;
00071     extern doublereal dlamch_(char *);
00072     doublereal bcoefr, salfar, safmin;
00073     extern /* Subroutine */ int dlacpy_(char *, integer *, integer *, 
00074             doublereal *, integer *, doublereal *, integer *);
00075     doublereal xscale, bignum;
00076     extern /* Subroutine */ int xerbla_(char *, integer *);
00077     logical ilcomp, ilcplx;
00078     integer ihwmny;
00079 
00080 
00081 /*  -- LAPACK routine (version 3.2) -- */
00082 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00083 /*     November 2006 */
00084 
00085 /*     .. Scalar Arguments .. */
00086 /*     .. */
00087 /*     .. Array Arguments .. */
00088 /*     .. */
00089 
00090 
00091 /*  Purpose */
00092 /*  ======= */
00093 
00094 /*  DTGEVC computes some or all of the right and/or left eigenvectors of */
00095 /*  a pair of real matrices (S,P), where S is a quasi-triangular matrix */
00096 /*  and P is upper triangular.  Matrix pairs of this type are produced by */
00097 /*  the generalized Schur factorization of a matrix pair (A,B): */
00098 
00099 /*     A = Q*S*Z**T,  B = Q*P*Z**T */
00100 
00101 /*  as computed by DGGHRD + DHGEQZ. */
00102 
00103 /*  The right eigenvector x and the left eigenvector y of (S,P) */
00104 /*  corresponding to an eigenvalue w are defined by: */
00105 
00106 /*     S*x = w*P*x,  (y**H)*S = w*(y**H)*P, */
00107 
00108 /*  where y**H denotes the conjugate tranpose of y. */
00109 /*  The eigenvalues are not input to this routine, but are computed */
00110 /*  directly from the diagonal blocks of S and P. */
00111 
00112 /*  This routine returns the matrices X and/or Y of right and left */
00113 /*  eigenvectors of (S,P), or the products Z*X and/or Q*Y, */
00114 /*  where Z and Q are input matrices. */
00115 /*  If Q and Z are the orthogonal factors from the generalized Schur */
00116 /*  factorization of a matrix pair (A,B), then Z*X and Q*Y */
00117 /*  are the matrices of right and left eigenvectors of (A,B). */
00118 
00119 /*  Arguments */
00120 /*  ========= */
00121 
00122 /*  SIDE    (input) CHARACTER*1 */
00123 /*          = 'R': compute right eigenvectors only; */
00124 /*          = 'L': compute left eigenvectors only; */
00125 /*          = 'B': compute both right and left eigenvectors. */
00126 
00127 /*  HOWMNY  (input) CHARACTER*1 */
00128 /*          = 'A': compute all right and/or left eigenvectors; */
00129 /*          = 'B': compute all right and/or left eigenvectors, */
00130 /*                 backtransformed by the matrices in VR and/or VL; */
00131 /*          = 'S': compute selected right and/or left eigenvectors, */
00132 /*                 specified by the logical array SELECT. */
00133 
00134 /*  SELECT  (input) LOGICAL array, dimension (N) */
00135 /*          If HOWMNY='S', SELECT specifies the eigenvectors to be */
00136 /*          computed.  If w(j) is a real eigenvalue, the corresponding */
00137 /*          real eigenvector is computed if SELECT(j) is .TRUE.. */
00138 /*          If w(j) and w(j+1) are the real and imaginary parts of a */
00139 /*          complex eigenvalue, the corresponding complex eigenvector */
00140 /*          is computed if either SELECT(j) or SELECT(j+1) is .TRUE., */
00141 /*          and on exit SELECT(j) is set to .TRUE. and SELECT(j+1) is */
00142 /*          set to .FALSE.. */
00143 /*          Not referenced if HOWMNY = 'A' or 'B'. */
00144 
00145 /*  N       (input) INTEGER */
00146 /*          The order of the matrices S and P.  N >= 0. */
00147 
00148 /*  S       (input) DOUBLE PRECISION array, dimension (LDS,N) */
00149 /*          The upper quasi-triangular matrix S from a generalized Schur */
00150 /*          factorization, as computed by DHGEQZ. */
00151 
00152 /*  LDS     (input) INTEGER */
00153 /*          The leading dimension of array S.  LDS >= max(1,N). */
00154 
00155 /*  P       (input) DOUBLE PRECISION array, dimension (LDP,N) */
00156 /*          The upper triangular matrix P from a generalized Schur */
00157 /*          factorization, as computed by DHGEQZ. */
00158 /*          2-by-2 diagonal blocks of P corresponding to 2-by-2 blocks */
00159 /*          of S must be in positive diagonal form. */
00160 
00161 /*  LDP     (input) INTEGER */
00162 /*          The leading dimension of array P.  LDP >= max(1,N). */
00163 
00164 /*  VL      (input/output) DOUBLE PRECISION array, dimension (LDVL,MM) */
00165 /*          On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must */
00166 /*          contain an N-by-N matrix Q (usually the orthogonal matrix Q */
00167 /*          of left Schur vectors returned by DHGEQZ). */
00168 /*          On exit, if SIDE = 'L' or 'B', VL contains: */
00169 /*          if HOWMNY = 'A', the matrix Y of left eigenvectors of (S,P); */
00170 /*          if HOWMNY = 'B', the matrix Q*Y; */
00171 /*          if HOWMNY = 'S', the left eigenvectors of (S,P) specified by */
00172 /*                      SELECT, stored consecutively in the columns of */
00173 /*                      VL, in the same order as their eigenvalues. */
00174 
00175 /*          A complex eigenvector corresponding to a complex eigenvalue */
00176 /*          is stored in two consecutive columns, the first holding the */
00177 /*          real part, and the second the imaginary part. */
00178 
00179 /*          Not referenced if SIDE = 'R'. */
00180 
00181 /*  LDVL    (input) INTEGER */
00182 /*          The leading dimension of array VL.  LDVL >= 1, and if */
00183 /*          SIDE = 'L' or 'B', LDVL >= N. */
00184 
00185 /*  VR      (input/output) DOUBLE PRECISION array, dimension (LDVR,MM) */
00186 /*          On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must */
00187 /*          contain an N-by-N matrix Z (usually the orthogonal matrix Z */
00188 /*          of right Schur vectors returned by DHGEQZ). */
00189 
00190 /*          On exit, if SIDE = 'R' or 'B', VR contains: */
00191 /*          if HOWMNY = 'A', the matrix X of right eigenvectors of (S,P); */
00192 /*          if HOWMNY = 'B' or 'b', the matrix Z*X; */
00193 /*          if HOWMNY = 'S' or 's', the right eigenvectors of (S,P) */
00194 /*                      specified by SELECT, stored consecutively in the */
00195 /*                      columns of VR, in the same order as their */
00196 /*                      eigenvalues. */
00197 
00198 /*          A complex eigenvector corresponding to a complex eigenvalue */
00199 /*          is stored in two consecutive columns, the first holding the */
00200 /*          real part and the second the imaginary part. */
00201 
00202 /*          Not referenced if SIDE = 'L'. */
00203 
00204 /*  LDVR    (input) INTEGER */
00205 /*          The leading dimension of the array VR.  LDVR >= 1, and if */
00206 /*          SIDE = 'R' or 'B', LDVR >= N. */
00207 
00208 /*  MM      (input) INTEGER */
00209 /*          The number of columns in the arrays VL and/or VR. MM >= M. */
00210 
00211 /*  M       (output) INTEGER */
00212 /*          The number of columns in the arrays VL and/or VR actually */
00213 /*          used to store the eigenvectors.  If HOWMNY = 'A' or 'B', M */
00214 /*          is set to N.  Each selected real eigenvector occupies one */
00215 /*          column and each selected complex eigenvector occupies two */
00216 /*          columns. */
00217 
00218 /*  WORK    (workspace) DOUBLE PRECISION array, dimension (6*N) */
00219 
00220 /*  INFO    (output) INTEGER */
00221 /*          = 0:  successful exit. */
00222 /*          < 0:  if INFO = -i, the i-th argument had an illegal value. */
00223 /*          > 0:  the 2-by-2 block (INFO:INFO+1) does not have a complex */
00224 /*                eigenvalue. */
00225 
00226 /*  Further Details */
00227 /*  =============== */
00228 
00229 /*  Allocation of workspace: */
00230 /*  ---------- -- --------- */
00231 
00232 /*     WORK( j ) = 1-norm of j-th column of A, above the diagonal */
00233 /*     WORK( N+j ) = 1-norm of j-th column of B, above the diagonal */
00234 /*     WORK( 2*N+1:3*N ) = real part of eigenvector */
00235 /*     WORK( 3*N+1:4*N ) = imaginary part of eigenvector */
00236 /*     WORK( 4*N+1:5*N ) = real part of back-transformed eigenvector */
00237 /*     WORK( 5*N+1:6*N ) = imaginary part of back-transformed eigenvector */
00238 
00239 /*  Rowwise vs. columnwise solution methods: */
00240 /*  ------- --  ---------- -------- ------- */
00241 
00242 /*  Finding a generalized eigenvector consists basically of solving the */
00243 /*  singular triangular system */
00244 
00245 /*   (A - w B) x = 0     (for right) or:   (A - w B)**H y = 0  (for left) */
00246 
00247 /*  Consider finding the i-th right eigenvector (assume all eigenvalues */
00248 /*  are real). The equation to be solved is: */
00249 /*       n                   i */
00250 /*  0 = sum  C(j,k) v(k)  = sum  C(j,k) v(k)     for j = i,. . .,1 */
00251 /*      k=j                 k=j */
00252 
00253 /*  where  C = (A - w B)  (The components v(i+1:n) are 0.) */
00254 
00255 /*  The "rowwise" method is: */
00256 
00257 /*  (1)  v(i) := 1 */
00258 /*  for j = i-1,. . .,1: */
00259 /*                          i */
00260 /*      (2) compute  s = - sum C(j,k) v(k)   and */
00261 /*                        k=j+1 */
00262 
00263 /*      (3) v(j) := s / C(j,j) */
00264 
00265 /*  Step 2 is sometimes called the "dot product" step, since it is an */
00266 /*  inner product between the j-th row and the portion of the eigenvector */
00267 /*  that has been computed so far. */
00268 
00269 /*  The "columnwise" method consists basically in doing the sums */
00270 /*  for all the rows in parallel.  As each v(j) is computed, the */
00271 /*  contribution of v(j) times the j-th column of C is added to the */
00272 /*  partial sums.  Since FORTRAN arrays are stored columnwise, this has */
00273 /*  the advantage that at each step, the elements of C that are accessed */
00274 /*  are adjacent to one another, whereas with the rowwise method, the */
00275 /*  elements accessed at a step are spaced LDS (and LDP) words apart. */
00276 
00277 /*  When finding left eigenvectors, the matrix in question is the */
00278 /*  transpose of the one in storage, so the rowwise method then */
00279 /*  actually accesses columns of A and B at each step, and so is the */
00280 /*  preferred method. */
00281 
00282 /*  ===================================================================== */
00283 
00284 /*     .. Parameters .. */
00285 /*     .. */
00286 /*     .. Local Scalars .. */
00287 /*     .. */
00288 /*     .. Local Arrays .. */
00289 /*     .. */
00290 /*     .. External Functions .. */
00291 /*     .. */
00292 /*     .. External Subroutines .. */
00293 /*     .. */
00294 /*     .. Intrinsic Functions .. */
00295 /*     .. */
00296 /*     .. Executable Statements .. */
00297 
00298 /*     Decode and Test the input parameters */
00299 
00300     /* Parameter adjustments */
00301     --select;
00302     s_dim1 = *lds;
00303     s_offset = 1 + s_dim1;
00304     s -= s_offset;
00305     p_dim1 = *ldp;
00306     p_offset = 1 + p_dim1;
00307     p -= p_offset;
00308     vl_dim1 = *ldvl;
00309     vl_offset = 1 + vl_dim1;
00310     vl -= vl_offset;
00311     vr_dim1 = *ldvr;
00312     vr_offset = 1 + vr_dim1;
00313     vr -= vr_offset;
00314     --work;
00315 
00316     /* Function Body */
00317     if (lsame_(howmny, "A")) {
00318         ihwmny = 1;
00319         ilall = TRUE_;
00320         ilback = FALSE_;
00321     } else if (lsame_(howmny, "S")) {
00322         ihwmny = 2;
00323         ilall = FALSE_;
00324         ilback = FALSE_;
00325     } else if (lsame_(howmny, "B")) {
00326         ihwmny = 3;
00327         ilall = TRUE_;
00328         ilback = TRUE_;
00329     } else {
00330         ihwmny = -1;
00331         ilall = TRUE_;
00332     }
00333 
00334     if (lsame_(side, "R")) {
00335         iside = 1;
00336         compl = FALSE_;
00337         compr = TRUE_;
00338     } else if (lsame_(side, "L")) {
00339         iside = 2;
00340         compl = TRUE_;
00341         compr = FALSE_;
00342     } else if (lsame_(side, "B")) {
00343         iside = 3;
00344         compl = TRUE_;
00345         compr = TRUE_;
00346     } else {
00347         iside = -1;
00348     }
00349 
00350     *info = 0;
00351     if (iside < 0) {
00352         *info = -1;
00353     } else if (ihwmny < 0) {
00354         *info = -2;
00355     } else if (*n < 0) {
00356         *info = -4;
00357     } else if (*lds < max(1,*n)) {
00358         *info = -6;
00359     } else if (*ldp < max(1,*n)) {
00360         *info = -8;
00361     }
00362     if (*info != 0) {
00363         i__1 = -(*info);
00364         xerbla_("DTGEVC", &i__1);
00365         return 0;
00366     }
00367 
00368 /*     Count the number of eigenvectors to be computed */
00369 
00370     if (! ilall) {
00371         im = 0;
00372         ilcplx = FALSE_;
00373         i__1 = *n;
00374         for (j = 1; j <= i__1; ++j) {
00375             if (ilcplx) {
00376                 ilcplx = FALSE_;
00377                 goto L10;
00378             }
00379             if (j < *n) {
00380                 if (s[j + 1 + j * s_dim1] != 0.) {
00381                     ilcplx = TRUE_;
00382                 }
00383             }
00384             if (ilcplx) {
00385                 if (select[j] || select[j + 1]) {
00386                     im += 2;
00387                 }
00388             } else {
00389                 if (select[j]) {
00390                     ++im;
00391                 }
00392             }
00393 L10:
00394             ;
00395         }
00396     } else {
00397         im = *n;
00398     }
00399 
00400 /*     Check 2-by-2 diagonal blocks of A, B */
00401 
00402     ilabad = FALSE_;
00403     ilbbad = FALSE_;
00404     i__1 = *n - 1;
00405     for (j = 1; j <= i__1; ++j) {
00406         if (s[j + 1 + j * s_dim1] != 0.) {
00407             if (p[j + j * p_dim1] == 0. || p[j + 1 + (j + 1) * p_dim1] == 0. 
00408                     || p[j + (j + 1) * p_dim1] != 0.) {
00409                 ilbbad = TRUE_;
00410             }
00411             if (j < *n - 1) {
00412                 if (s[j + 2 + (j + 1) * s_dim1] != 0.) {
00413                     ilabad = TRUE_;
00414                 }
00415             }
00416         }
00417 /* L20: */
00418     }
00419 
00420     if (ilabad) {
00421         *info = -5;
00422     } else if (ilbbad) {
00423         *info = -7;
00424     } else if (compl && *ldvl < *n || *ldvl < 1) {
00425         *info = -10;
00426     } else if (compr && *ldvr < *n || *ldvr < 1) {
00427         *info = -12;
00428     } else if (*mm < im) {
00429         *info = -13;
00430     }
00431     if (*info != 0) {
00432         i__1 = -(*info);
00433         xerbla_("DTGEVC", &i__1);
00434         return 0;
00435     }
00436 
00437 /*     Quick return if possible */
00438 
00439     *m = im;
00440     if (*n == 0) {
00441         return 0;
00442     }
00443 
00444 /*     Machine Constants */
00445 
00446     safmin = dlamch_("Safe minimum");
00447     big = 1. / safmin;
00448     dlabad_(&safmin, &big);
00449     ulp = dlamch_("Epsilon") * dlamch_("Base");
00450     small = safmin * *n / ulp;
00451     big = 1. / small;
00452     bignum = 1. / (safmin * *n);
00453 
00454 /*     Compute the 1-norm of each column of the strictly upper triangular */
00455 /*     part (i.e., excluding all elements belonging to the diagonal */
00456 /*     blocks) of A and B to check for possible overflow in the */
00457 /*     triangular solver. */
00458 
00459     anorm = (d__1 = s[s_dim1 + 1], abs(d__1));
00460     if (*n > 1) {
00461         anorm += (d__1 = s[s_dim1 + 2], abs(d__1));
00462     }
00463     bnorm = (d__1 = p[p_dim1 + 1], abs(d__1));
00464     work[1] = 0.;
00465     work[*n + 1] = 0.;
00466 
00467     i__1 = *n;
00468     for (j = 2; j <= i__1; ++j) {
00469         temp = 0.;
00470         temp2 = 0.;
00471         if (s[j + (j - 1) * s_dim1] == 0.) {
00472             iend = j - 1;
00473         } else {
00474             iend = j - 2;
00475         }
00476         i__2 = iend;
00477         for (i__ = 1; i__ <= i__2; ++i__) {
00478             temp += (d__1 = s[i__ + j * s_dim1], abs(d__1));
00479             temp2 += (d__1 = p[i__ + j * p_dim1], abs(d__1));
00480 /* L30: */
00481         }
00482         work[j] = temp;
00483         work[*n + j] = temp2;
00484 /* Computing MIN */
00485         i__3 = j + 1;
00486         i__2 = min(i__3,*n);
00487         for (i__ = iend + 1; i__ <= i__2; ++i__) {
00488             temp += (d__1 = s[i__ + j * s_dim1], abs(d__1));
00489             temp2 += (d__1 = p[i__ + j * p_dim1], abs(d__1));
00490 /* L40: */
00491         }
00492         anorm = max(anorm,temp);
00493         bnorm = max(bnorm,temp2);
00494 /* L50: */
00495     }
00496 
00497     ascale = 1. / max(anorm,safmin);
00498     bscale = 1. / max(bnorm,safmin);
00499 
00500 /*     Left eigenvectors */
00501 
00502     if (compl) {
00503         ieig = 0;
00504 
00505 /*        Main loop over eigenvalues */
00506 
00507         ilcplx = FALSE_;
00508         i__1 = *n;
00509         for (je = 1; je <= i__1; ++je) {
00510 
00511 /*           Skip this iteration if (a) HOWMNY='S' and SELECT=.FALSE., or */
00512 /*           (b) this would be the second of a complex pair. */
00513 /*           Check for complex eigenvalue, so as to be sure of which */
00514 /*           entry(-ies) of SELECT to look at. */
00515 
00516             if (ilcplx) {
00517                 ilcplx = FALSE_;
00518                 goto L220;
00519             }
00520             nw = 1;
00521             if (je < *n) {
00522                 if (s[je + 1 + je * s_dim1] != 0.) {
00523                     ilcplx = TRUE_;
00524                     nw = 2;
00525                 }
00526             }
00527             if (ilall) {
00528                 ilcomp = TRUE_;
00529             } else if (ilcplx) {
00530                 ilcomp = select[je] || select[je + 1];
00531             } else {
00532                 ilcomp = select[je];
00533             }
00534             if (! ilcomp) {
00535                 goto L220;
00536             }
00537 
00538 /*           Decide if (a) singular pencil, (b) real eigenvalue, or */
00539 /*           (c) complex eigenvalue. */
00540 
00541             if (! ilcplx) {
00542                 if ((d__1 = s[je + je * s_dim1], abs(d__1)) <= safmin && (
00543                         d__2 = p[je + je * p_dim1], abs(d__2)) <= safmin) {
00544 
00545 /*                 Singular matrix pencil -- return unit eigenvector */
00546 
00547                     ++ieig;
00548                     i__2 = *n;
00549                     for (jr = 1; jr <= i__2; ++jr) {
00550                         vl[jr + ieig * vl_dim1] = 0.;
00551 /* L60: */
00552                     }
00553                     vl[ieig + ieig * vl_dim1] = 1.;
00554                     goto L220;
00555                 }
00556             }
00557 
00558 /*           Clear vector */
00559 
00560             i__2 = nw * *n;
00561             for (jr = 1; jr <= i__2; ++jr) {
00562                 work[(*n << 1) + jr] = 0.;
00563 /* L70: */
00564             }
00565 /*                                                 T */
00566 /*           Compute coefficients in  ( a A - b B )  y = 0 */
00567 /*              a  is  ACOEF */
00568 /*              b  is  BCOEFR + i*BCOEFI */
00569 
00570             if (! ilcplx) {
00571 
00572 /*              Real eigenvalue */
00573 
00574 /* Computing MAX */
00575                 d__3 = (d__1 = s[je + je * s_dim1], abs(d__1)) * ascale, d__4 
00576                         = (d__2 = p[je + je * p_dim1], abs(d__2)) * bscale, 
00577                         d__3 = max(d__3,d__4);
00578                 temp = 1. / max(d__3,safmin);
00579                 salfar = temp * s[je + je * s_dim1] * ascale;
00580                 sbeta = temp * p[je + je * p_dim1] * bscale;
00581                 acoef = sbeta * ascale;
00582                 bcoefr = salfar * bscale;
00583                 bcoefi = 0.;
00584 
00585 /*              Scale to avoid underflow */
00586 
00587                 scale = 1.;
00588                 lsa = abs(sbeta) >= safmin && abs(acoef) < small;
00589                 lsb = abs(salfar) >= safmin && abs(bcoefr) < small;
00590                 if (lsa) {
00591                     scale = small / abs(sbeta) * min(anorm,big);
00592                 }
00593                 if (lsb) {
00594 /* Computing MAX */
00595                     d__1 = scale, d__2 = small / abs(salfar) * min(bnorm,big);
00596                     scale = max(d__1,d__2);
00597                 }
00598                 if (lsa || lsb) {
00599 /* Computing MIN */
00600 /* Computing MAX */
00601                     d__3 = 1., d__4 = abs(acoef), d__3 = max(d__3,d__4), d__4 
00602                             = abs(bcoefr);
00603                     d__1 = scale, d__2 = 1. / (safmin * max(d__3,d__4));
00604                     scale = min(d__1,d__2);
00605                     if (lsa) {
00606                         acoef = ascale * (scale * sbeta);
00607                     } else {
00608                         acoef = scale * acoef;
00609                     }
00610                     if (lsb) {
00611                         bcoefr = bscale * (scale * salfar);
00612                     } else {
00613                         bcoefr = scale * bcoefr;
00614                     }
00615                 }
00616                 acoefa = abs(acoef);
00617                 bcoefa = abs(bcoefr);
00618 
00619 /*              First component is 1 */
00620 
00621                 work[(*n << 1) + je] = 1.;
00622                 xmax = 1.;
00623             } else {
00624 
00625 /*              Complex eigenvalue */
00626 
00627                 d__1 = safmin * 100.;
00628                 dlag2_(&s[je + je * s_dim1], lds, &p[je + je * p_dim1], ldp, &
00629                         d__1, &acoef, &temp, &bcoefr, &temp2, &bcoefi);
00630                 bcoefi = -bcoefi;
00631                 if (bcoefi == 0.) {
00632                     *info = je;
00633                     return 0;
00634                 }
00635 
00636 /*              Scale to avoid over/underflow */
00637 
00638                 acoefa = abs(acoef);
00639                 bcoefa = abs(bcoefr) + abs(bcoefi);
00640                 scale = 1.;
00641                 if (acoefa * ulp < safmin && acoefa >= safmin) {
00642                     scale = safmin / ulp / acoefa;
00643                 }
00644                 if (bcoefa * ulp < safmin && bcoefa >= safmin) {
00645 /* Computing MAX */
00646                     d__1 = scale, d__2 = safmin / ulp / bcoefa;
00647                     scale = max(d__1,d__2);
00648                 }
00649                 if (safmin * acoefa > ascale) {
00650                     scale = ascale / (safmin * acoefa);
00651                 }
00652                 if (safmin * bcoefa > bscale) {
00653 /* Computing MIN */
00654                     d__1 = scale, d__2 = bscale / (safmin * bcoefa);
00655                     scale = min(d__1,d__2);
00656                 }
00657                 if (scale != 1.) {
00658                     acoef = scale * acoef;
00659                     acoefa = abs(acoef);
00660                     bcoefr = scale * bcoefr;
00661                     bcoefi = scale * bcoefi;
00662                     bcoefa = abs(bcoefr) + abs(bcoefi);
00663                 }
00664 
00665 /*              Compute first two components of eigenvector */
00666 
00667                 temp = acoef * s[je + 1 + je * s_dim1];
00668                 temp2r = acoef * s[je + je * s_dim1] - bcoefr * p[je + je * 
00669                         p_dim1];
00670                 temp2i = -bcoefi * p[je + je * p_dim1];
00671                 if (abs(temp) > abs(temp2r) + abs(temp2i)) {
00672                     work[(*n << 1) + je] = 1.;
00673                     work[*n * 3 + je] = 0.;
00674                     work[(*n << 1) + je + 1] = -temp2r / temp;
00675                     work[*n * 3 + je + 1] = -temp2i / temp;
00676                 } else {
00677                     work[(*n << 1) + je + 1] = 1.;
00678                     work[*n * 3 + je + 1] = 0.;
00679                     temp = acoef * s[je + (je + 1) * s_dim1];
00680                     work[(*n << 1) + je] = (bcoefr * p[je + 1 + (je + 1) * 
00681                             p_dim1] - acoef * s[je + 1 + (je + 1) * s_dim1]) /
00682                              temp;
00683                     work[*n * 3 + je] = bcoefi * p[je + 1 + (je + 1) * p_dim1]
00684                              / temp;
00685                 }
00686 /* Computing MAX */
00687                 d__5 = (d__1 = work[(*n << 1) + je], abs(d__1)) + (d__2 = 
00688                         work[*n * 3 + je], abs(d__2)), d__6 = (d__3 = work[(*
00689                         n << 1) + je + 1], abs(d__3)) + (d__4 = work[*n * 3 + 
00690                         je + 1], abs(d__4));
00691                 xmax = max(d__5,d__6);
00692             }
00693 
00694 /* Computing MAX */
00695             d__1 = ulp * acoefa * anorm, d__2 = ulp * bcoefa * bnorm, d__1 = 
00696                     max(d__1,d__2);
00697             dmin__ = max(d__1,safmin);
00698 
00699 /*                                           T */
00700 /*           Triangular solve of  (a A - b B)  y = 0 */
00701 
00702 /*                                   T */
00703 /*           (rowwise in  (a A - b B) , or columnwise in (a A - b B) ) */
00704 
00705             il2by2 = FALSE_;
00706 
00707             i__2 = *n;
00708             for (j = je + nw; j <= i__2; ++j) {
00709                 if (il2by2) {
00710                     il2by2 = FALSE_;
00711                     goto L160;
00712                 }
00713 
00714                 na = 1;
00715                 bdiag[0] = p[j + j * p_dim1];
00716                 if (j < *n) {
00717                     if (s[j + 1 + j * s_dim1] != 0.) {
00718                         il2by2 = TRUE_;
00719                         bdiag[1] = p[j + 1 + (j + 1) * p_dim1];
00720                         na = 2;
00721                     }
00722                 }
00723 
00724 /*              Check whether scaling is necessary for dot products */
00725 
00726                 xscale = 1. / max(1.,xmax);
00727 /* Computing MAX */
00728                 d__1 = work[j], d__2 = work[*n + j], d__1 = max(d__1,d__2), 
00729                         d__2 = acoefa * work[j] + bcoefa * work[*n + j];
00730                 temp = max(d__1,d__2);
00731                 if (il2by2) {
00732 /* Computing MAX */
00733                     d__1 = temp, d__2 = work[j + 1], d__1 = max(d__1,d__2), 
00734                             d__2 = work[*n + j + 1], d__1 = max(d__1,d__2), 
00735                             d__2 = acoefa * work[j + 1] + bcoefa * work[*n + 
00736                             j + 1];
00737                     temp = max(d__1,d__2);
00738                 }
00739                 if (temp > bignum * xscale) {
00740                     i__3 = nw - 1;
00741                     for (jw = 0; jw <= i__3; ++jw) {
00742                         i__4 = j - 1;
00743                         for (jr = je; jr <= i__4; ++jr) {
00744                             work[(jw + 2) * *n + jr] = xscale * work[(jw + 2) 
00745                                     * *n + jr];
00746 /* L80: */
00747                         }
00748 /* L90: */
00749                     }
00750                     xmax *= xscale;
00751                 }
00752 
00753 /*              Compute dot products */
00754 
00755 /*                    j-1 */
00756 /*              SUM = sum  conjg( a*S(k,j) - b*P(k,j) )*x(k) */
00757 /*                    k=je */
00758 
00759 /*              To reduce the op count, this is done as */
00760 
00761 /*              _        j-1                  _        j-1 */
00762 /*              a*conjg( sum  S(k,j)*x(k) ) - b*conjg( sum  P(k,j)*x(k) ) */
00763 /*                       k=je                          k=je */
00764 
00765 /*              which may cause underflow problems if A or B are close */
00766 /*              to underflow.  (E.g., less than SMALL.) */
00767 
00768 
00769 /*              A series of compiler directives to defeat vectorization */
00770 /*              for the next loop */
00771 
00772 /* $PL$ CMCHAR=' ' */
00773 /* DIR$          NEXTSCALAR */
00774 /* $DIR          SCALAR */
00775 /* DIR$          NEXT SCALAR */
00776 /* VD$L          NOVECTOR */
00777 /* DEC$          NOVECTOR */
00778 /* VD$           NOVECTOR */
00779 /* VDIR          NOVECTOR */
00780 /* VOCL          LOOP,SCALAR */
00781 /* IBM           PREFER SCALAR */
00782 /* $PL$ CMCHAR='*' */
00783 
00784                 i__3 = nw;
00785                 for (jw = 1; jw <= i__3; ++jw) {
00786 
00787 /* $PL$ CMCHAR=' ' */
00788 /* DIR$             NEXTSCALAR */
00789 /* $DIR             SCALAR */
00790 /* DIR$             NEXT SCALAR */
00791 /* VD$L             NOVECTOR */
00792 /* DEC$             NOVECTOR */
00793 /* VD$              NOVECTOR */
00794 /* VDIR             NOVECTOR */
00795 /* VOCL             LOOP,SCALAR */
00796 /* IBM              PREFER SCALAR */
00797 /* $PL$ CMCHAR='*' */
00798 
00799                     i__4 = na;
00800                     for (ja = 1; ja <= i__4; ++ja) {
00801                         sums[ja + (jw << 1) - 3] = 0.;
00802                         sump[ja + (jw << 1) - 3] = 0.;
00803 
00804                         i__5 = j - 1;
00805                         for (jr = je; jr <= i__5; ++jr) {
00806                             sums[ja + (jw << 1) - 3] += s[jr + (j + ja - 1) * 
00807                                     s_dim1] * work[(jw + 1) * *n + jr];
00808                             sump[ja + (jw << 1) - 3] += p[jr + (j + ja - 1) * 
00809                                     p_dim1] * work[(jw + 1) * *n + jr];
00810 /* L100: */
00811                         }
00812 /* L110: */
00813                     }
00814 /* L120: */
00815                 }
00816 
00817 /* $PL$ CMCHAR=' ' */
00818 /* DIR$          NEXTSCALAR */
00819 /* $DIR          SCALAR */
00820 /* DIR$          NEXT SCALAR */
00821 /* VD$L          NOVECTOR */
00822 /* DEC$          NOVECTOR */
00823 /* VD$           NOVECTOR */
00824 /* VDIR          NOVECTOR */
00825 /* VOCL          LOOP,SCALAR */
00826 /* IBM           PREFER SCALAR */
00827 /* $PL$ CMCHAR='*' */
00828 
00829                 i__3 = na;
00830                 for (ja = 1; ja <= i__3; ++ja) {
00831                     if (ilcplx) {
00832                         sum[ja - 1] = -acoef * sums[ja - 1] + bcoefr * sump[
00833                                 ja - 1] - bcoefi * sump[ja + 1];
00834                         sum[ja + 1] = -acoef * sums[ja + 1] + bcoefr * sump[
00835                                 ja + 1] + bcoefi * sump[ja - 1];
00836                     } else {
00837                         sum[ja - 1] = -acoef * sums[ja - 1] + bcoefr * sump[
00838                                 ja - 1];
00839                     }
00840 /* L130: */
00841                 }
00842 
00843 /*                                  T */
00844 /*              Solve  ( a A - b B )  y = SUM(,) */
00845 /*              with scaling and perturbation of the denominator */
00846 
00847                 dlaln2_(&c_true, &na, &nw, &dmin__, &acoef, &s[j + j * s_dim1]
00848 , lds, bdiag, &bdiag[1], sum, &c__2, &bcoefr, &bcoefi, 
00849                          &work[(*n << 1) + j], n, &scale, &temp, &iinfo);
00850                 if (scale < 1.) {
00851                     i__3 = nw - 1;
00852                     for (jw = 0; jw <= i__3; ++jw) {
00853                         i__4 = j - 1;
00854                         for (jr = je; jr <= i__4; ++jr) {
00855                             work[(jw + 2) * *n + jr] = scale * work[(jw + 2) *
00856                                      *n + jr];
00857 /* L140: */
00858                         }
00859 /* L150: */
00860                     }
00861                     xmax = scale * xmax;
00862                 }
00863                 xmax = max(xmax,temp);
00864 L160:
00865                 ;
00866             }
00867 
00868 /*           Copy eigenvector to VL, back transforming if */
00869 /*           HOWMNY='B'. */
00870 
00871             ++ieig;
00872             if (ilback) {
00873                 i__2 = nw - 1;
00874                 for (jw = 0; jw <= i__2; ++jw) {
00875                     i__3 = *n + 1 - je;
00876                     dgemv_("N", n, &i__3, &c_b34, &vl[je * vl_dim1 + 1], ldvl, 
00877                              &work[(jw + 2) * *n + je], &c__1, &c_b36, &work[(
00878                             jw + 4) * *n + 1], &c__1);
00879 /* L170: */
00880                 }
00881                 dlacpy_(" ", n, &nw, &work[(*n << 2) + 1], n, &vl[je * 
00882                         vl_dim1 + 1], ldvl);
00883                 ibeg = 1;
00884             } else {
00885                 dlacpy_(" ", n, &nw, &work[(*n << 1) + 1], n, &vl[ieig * 
00886                         vl_dim1 + 1], ldvl);
00887                 ibeg = je;
00888             }
00889 
00890 /*           Scale eigenvector */
00891 
00892             xmax = 0.;
00893             if (ilcplx) {
00894                 i__2 = *n;
00895                 for (j = ibeg; j <= i__2; ++j) {
00896 /* Computing MAX */
00897                     d__3 = xmax, d__4 = (d__1 = vl[j + ieig * vl_dim1], abs(
00898                             d__1)) + (d__2 = vl[j + (ieig + 1) * vl_dim1], 
00899                             abs(d__2));
00900                     xmax = max(d__3,d__4);
00901 /* L180: */
00902                 }
00903             } else {
00904                 i__2 = *n;
00905                 for (j = ibeg; j <= i__2; ++j) {
00906 /* Computing MAX */
00907                     d__2 = xmax, d__3 = (d__1 = vl[j + ieig * vl_dim1], abs(
00908                             d__1));
00909                     xmax = max(d__2,d__3);
00910 /* L190: */
00911                 }
00912             }
00913 
00914             if (xmax > safmin) {
00915                 xscale = 1. / xmax;
00916 
00917                 i__2 = nw - 1;
00918                 for (jw = 0; jw <= i__2; ++jw) {
00919                     i__3 = *n;
00920                     for (jr = ibeg; jr <= i__3; ++jr) {
00921                         vl[jr + (ieig + jw) * vl_dim1] = xscale * vl[jr + (
00922                                 ieig + jw) * vl_dim1];
00923 /* L200: */
00924                     }
00925 /* L210: */
00926                 }
00927             }
00928             ieig = ieig + nw - 1;
00929 
00930 L220:
00931             ;
00932         }
00933     }
00934 
00935 /*     Right eigenvectors */
00936 
00937     if (compr) {
00938         ieig = im + 1;
00939 
00940 /*        Main loop over eigenvalues */
00941 
00942         ilcplx = FALSE_;
00943         for (je = *n; je >= 1; --je) {
00944 
00945 /*           Skip this iteration if (a) HOWMNY='S' and SELECT=.FALSE., or */
00946 /*           (b) this would be the second of a complex pair. */
00947 /*           Check for complex eigenvalue, so as to be sure of which */
00948 /*           entry(-ies) of SELECT to look at -- if complex, SELECT(JE) */
00949 /*           or SELECT(JE-1). */
00950 /*           If this is a complex pair, the 2-by-2 diagonal block */
00951 /*           corresponding to the eigenvalue is in rows/columns JE-1:JE */
00952 
00953             if (ilcplx) {
00954                 ilcplx = FALSE_;
00955                 goto L500;
00956             }
00957             nw = 1;
00958             if (je > 1) {
00959                 if (s[je + (je - 1) * s_dim1] != 0.) {
00960                     ilcplx = TRUE_;
00961                     nw = 2;
00962                 }
00963             }
00964             if (ilall) {
00965                 ilcomp = TRUE_;
00966             } else if (ilcplx) {
00967                 ilcomp = select[je] || select[je - 1];
00968             } else {
00969                 ilcomp = select[je];
00970             }
00971             if (! ilcomp) {
00972                 goto L500;
00973             }
00974 
00975 /*           Decide if (a) singular pencil, (b) real eigenvalue, or */
00976 /*           (c) complex eigenvalue. */
00977 
00978             if (! ilcplx) {
00979                 if ((d__1 = s[je + je * s_dim1], abs(d__1)) <= safmin && (
00980                         d__2 = p[je + je * p_dim1], abs(d__2)) <= safmin) {
00981 
00982 /*                 Singular matrix pencil -- unit eigenvector */
00983 
00984                     --ieig;
00985                     i__1 = *n;
00986                     for (jr = 1; jr <= i__1; ++jr) {
00987                         vr[jr + ieig * vr_dim1] = 0.;
00988 /* L230: */
00989                     }
00990                     vr[ieig + ieig * vr_dim1] = 1.;
00991                     goto L500;
00992                 }
00993             }
00994 
00995 /*           Clear vector */
00996 
00997             i__1 = nw - 1;
00998             for (jw = 0; jw <= i__1; ++jw) {
00999                 i__2 = *n;
01000                 for (jr = 1; jr <= i__2; ++jr) {
01001                     work[(jw + 2) * *n + jr] = 0.;
01002 /* L240: */
01003                 }
01004 /* L250: */
01005             }
01006 
01007 /*           Compute coefficients in  ( a A - b B ) x = 0 */
01008 /*              a  is  ACOEF */
01009 /*              b  is  BCOEFR + i*BCOEFI */
01010 
01011             if (! ilcplx) {
01012 
01013 /*              Real eigenvalue */
01014 
01015 /* Computing MAX */
01016                 d__3 = (d__1 = s[je + je * s_dim1], abs(d__1)) * ascale, d__4 
01017                         = (d__2 = p[je + je * p_dim1], abs(d__2)) * bscale, 
01018                         d__3 = max(d__3,d__4);
01019                 temp = 1. / max(d__3,safmin);
01020                 salfar = temp * s[je + je * s_dim1] * ascale;
01021                 sbeta = temp * p[je + je * p_dim1] * bscale;
01022                 acoef = sbeta * ascale;
01023                 bcoefr = salfar * bscale;
01024                 bcoefi = 0.;
01025 
01026 /*              Scale to avoid underflow */
01027 
01028                 scale = 1.;
01029                 lsa = abs(sbeta) >= safmin && abs(acoef) < small;
01030                 lsb = abs(salfar) >= safmin && abs(bcoefr) < small;
01031                 if (lsa) {
01032                     scale = small / abs(sbeta) * min(anorm,big);
01033                 }
01034                 if (lsb) {
01035 /* Computing MAX */
01036                     d__1 = scale, d__2 = small / abs(salfar) * min(bnorm,big);
01037                     scale = max(d__1,d__2);
01038                 }
01039                 if (lsa || lsb) {
01040 /* Computing MIN */
01041 /* Computing MAX */
01042                     d__3 = 1., d__4 = abs(acoef), d__3 = max(d__3,d__4), d__4 
01043                             = abs(bcoefr);
01044                     d__1 = scale, d__2 = 1. / (safmin * max(d__3,d__4));
01045                     scale = min(d__1,d__2);
01046                     if (lsa) {
01047                         acoef = ascale * (scale * sbeta);
01048                     } else {
01049                         acoef = scale * acoef;
01050                     }
01051                     if (lsb) {
01052                         bcoefr = bscale * (scale * salfar);
01053                     } else {
01054                         bcoefr = scale * bcoefr;
01055                     }
01056                 }
01057                 acoefa = abs(acoef);
01058                 bcoefa = abs(bcoefr);
01059 
01060 /*              First component is 1 */
01061 
01062                 work[(*n << 1) + je] = 1.;
01063                 xmax = 1.;
01064 
01065 /*              Compute contribution from column JE of A and B to sum */
01066 /*              (See "Further Details", above.) */
01067 
01068                 i__1 = je - 1;
01069                 for (jr = 1; jr <= i__1; ++jr) {
01070                     work[(*n << 1) + jr] = bcoefr * p[jr + je * p_dim1] - 
01071                             acoef * s[jr + je * s_dim1];
01072 /* L260: */
01073                 }
01074             } else {
01075 
01076 /*              Complex eigenvalue */
01077 
01078                 d__1 = safmin * 100.;
01079                 dlag2_(&s[je - 1 + (je - 1) * s_dim1], lds, &p[je - 1 + (je - 
01080                         1) * p_dim1], ldp, &d__1, &acoef, &temp, &bcoefr, &
01081                         temp2, &bcoefi);
01082                 if (bcoefi == 0.) {
01083                     *info = je - 1;
01084                     return 0;
01085                 }
01086 
01087 /*              Scale to avoid over/underflow */
01088 
01089                 acoefa = abs(acoef);
01090                 bcoefa = abs(bcoefr) + abs(bcoefi);
01091                 scale = 1.;
01092                 if (acoefa * ulp < safmin && acoefa >= safmin) {
01093                     scale = safmin / ulp / acoefa;
01094                 }
01095                 if (bcoefa * ulp < safmin && bcoefa >= safmin) {
01096 /* Computing MAX */
01097                     d__1 = scale, d__2 = safmin / ulp / bcoefa;
01098                     scale = max(d__1,d__2);
01099                 }
01100                 if (safmin * acoefa > ascale) {
01101                     scale = ascale / (safmin * acoefa);
01102                 }
01103                 if (safmin * bcoefa > bscale) {
01104 /* Computing MIN */
01105                     d__1 = scale, d__2 = bscale / (safmin * bcoefa);
01106                     scale = min(d__1,d__2);
01107                 }
01108                 if (scale != 1.) {
01109                     acoef = scale * acoef;
01110                     acoefa = abs(acoef);
01111                     bcoefr = scale * bcoefr;
01112                     bcoefi = scale * bcoefi;
01113                     bcoefa = abs(bcoefr) + abs(bcoefi);
01114                 }
01115 
01116 /*              Compute first two components of eigenvector */
01117 /*              and contribution to sums */
01118 
01119                 temp = acoef * s[je + (je - 1) * s_dim1];
01120                 temp2r = acoef * s[je + je * s_dim1] - bcoefr * p[je + je * 
01121                         p_dim1];
01122                 temp2i = -bcoefi * p[je + je * p_dim1];
01123                 if (abs(temp) >= abs(temp2r) + abs(temp2i)) {
01124                     work[(*n << 1) + je] = 1.;
01125                     work[*n * 3 + je] = 0.;
01126                     work[(*n << 1) + je - 1] = -temp2r / temp;
01127                     work[*n * 3 + je - 1] = -temp2i / temp;
01128                 } else {
01129                     work[(*n << 1) + je - 1] = 1.;
01130                     work[*n * 3 + je - 1] = 0.;
01131                     temp = acoef * s[je - 1 + je * s_dim1];
01132                     work[(*n << 1) + je] = (bcoefr * p[je - 1 + (je - 1) * 
01133                             p_dim1] - acoef * s[je - 1 + (je - 1) * s_dim1]) /
01134                              temp;
01135                     work[*n * 3 + je] = bcoefi * p[je - 1 + (je - 1) * p_dim1]
01136                              / temp;
01137                 }
01138 
01139 /* Computing MAX */
01140                 d__5 = (d__1 = work[(*n << 1) + je], abs(d__1)) + (d__2 = 
01141                         work[*n * 3 + je], abs(d__2)), d__6 = (d__3 = work[(*
01142                         n << 1) + je - 1], abs(d__3)) + (d__4 = work[*n * 3 + 
01143                         je - 1], abs(d__4));
01144                 xmax = max(d__5,d__6);
01145 
01146 /*              Compute contribution from columns JE and JE-1 */
01147 /*              of A and B to the sums. */
01148 
01149                 creala = acoef * work[(*n << 1) + je - 1];
01150                 cimaga = acoef * work[*n * 3 + je - 1];
01151                 crealb = bcoefr * work[(*n << 1) + je - 1] - bcoefi * work[*n 
01152                         * 3 + je - 1];
01153                 cimagb = bcoefi * work[(*n << 1) + je - 1] + bcoefr * work[*n 
01154                         * 3 + je - 1];
01155                 cre2a = acoef * work[(*n << 1) + je];
01156                 cim2a = acoef * work[*n * 3 + je];
01157                 cre2b = bcoefr * work[(*n << 1) + je] - bcoefi * work[*n * 3 
01158                         + je];
01159                 cim2b = bcoefi * work[(*n << 1) + je] + bcoefr * work[*n * 3 
01160                         + je];
01161                 i__1 = je - 2;
01162                 for (jr = 1; jr <= i__1; ++jr) {
01163                     work[(*n << 1) + jr] = -creala * s[jr + (je - 1) * s_dim1]
01164                              + crealb * p[jr + (je - 1) * p_dim1] - cre2a * s[
01165                             jr + je * s_dim1] + cre2b * p[jr + je * p_dim1];
01166                     work[*n * 3 + jr] = -cimaga * s[jr + (je - 1) * s_dim1] + 
01167                             cimagb * p[jr + (je - 1) * p_dim1] - cim2a * s[jr 
01168                             + je * s_dim1] + cim2b * p[jr + je * p_dim1];
01169 /* L270: */
01170                 }
01171             }
01172 
01173 /* Computing MAX */
01174             d__1 = ulp * acoefa * anorm, d__2 = ulp * bcoefa * bnorm, d__1 = 
01175                     max(d__1,d__2);
01176             dmin__ = max(d__1,safmin);
01177 
01178 /*           Columnwise triangular solve of  (a A - b B)  x = 0 */
01179 
01180             il2by2 = FALSE_;
01181             for (j = je - nw; j >= 1; --j) {
01182 
01183 /*              If a 2-by-2 block, is in position j-1:j, wait until */
01184 /*              next iteration to process it (when it will be j:j+1) */
01185 
01186                 if (! il2by2 && j > 1) {
01187                     if (s[j + (j - 1) * s_dim1] != 0.) {
01188                         il2by2 = TRUE_;
01189                         goto L370;
01190                     }
01191                 }
01192                 bdiag[0] = p[j + j * p_dim1];
01193                 if (il2by2) {
01194                     na = 2;
01195                     bdiag[1] = p[j + 1 + (j + 1) * p_dim1];
01196                 } else {
01197                     na = 1;
01198                 }
01199 
01200 /*              Compute x(j) (and x(j+1), if 2-by-2 block) */
01201 
01202                 dlaln2_(&c_false, &na, &nw, &dmin__, &acoef, &s[j + j * 
01203                         s_dim1], lds, bdiag, &bdiag[1], &work[(*n << 1) + j], 
01204                         n, &bcoefr, &bcoefi, sum, &c__2, &scale, &temp, &
01205                         iinfo);
01206                 if (scale < 1.) {
01207 
01208                     i__1 = nw - 1;
01209                     for (jw = 0; jw <= i__1; ++jw) {
01210                         i__2 = je;
01211                         for (jr = 1; jr <= i__2; ++jr) {
01212                             work[(jw + 2) * *n + jr] = scale * work[(jw + 2) *
01213                                      *n + jr];
01214 /* L280: */
01215                         }
01216 /* L290: */
01217                     }
01218                 }
01219 /* Computing MAX */
01220                 d__1 = scale * xmax;
01221                 xmax = max(d__1,temp);
01222 
01223                 i__1 = nw;
01224                 for (jw = 1; jw <= i__1; ++jw) {
01225                     i__2 = na;
01226                     for (ja = 1; ja <= i__2; ++ja) {
01227                         work[(jw + 1) * *n + j + ja - 1] = sum[ja + (jw << 1) 
01228                                 - 3];
01229 /* L300: */
01230                     }
01231 /* L310: */
01232                 }
01233 
01234 /*              w = w + x(j)*(a S(*,j) - b P(*,j) ) with scaling */
01235 
01236                 if (j > 1) {
01237 
01238 /*                 Check whether scaling is necessary for sum. */
01239 
01240                     xscale = 1. / max(1.,xmax);
01241                     temp = acoefa * work[j] + bcoefa * work[*n + j];
01242                     if (il2by2) {
01243 /* Computing MAX */
01244                         d__1 = temp, d__2 = acoefa * work[j + 1] + bcoefa * 
01245                                 work[*n + j + 1];
01246                         temp = max(d__1,d__2);
01247                     }
01248 /* Computing MAX */
01249                     d__1 = max(temp,acoefa);
01250                     temp = max(d__1,bcoefa);
01251                     if (temp > bignum * xscale) {
01252 
01253                         i__1 = nw - 1;
01254                         for (jw = 0; jw <= i__1; ++jw) {
01255                             i__2 = je;
01256                             for (jr = 1; jr <= i__2; ++jr) {
01257                                 work[(jw + 2) * *n + jr] = xscale * work[(jw 
01258                                         + 2) * *n + jr];
01259 /* L320: */
01260                             }
01261 /* L330: */
01262                         }
01263                         xmax *= xscale;
01264                     }
01265 
01266 /*                 Compute the contributions of the off-diagonals of */
01267 /*                 column j (and j+1, if 2-by-2 block) of A and B to the */
01268 /*                 sums. */
01269 
01270 
01271                     i__1 = na;
01272                     for (ja = 1; ja <= i__1; ++ja) {
01273                         if (ilcplx) {
01274                             creala = acoef * work[(*n << 1) + j + ja - 1];
01275                             cimaga = acoef * work[*n * 3 + j + ja - 1];
01276                             crealb = bcoefr * work[(*n << 1) + j + ja - 1] - 
01277                                     bcoefi * work[*n * 3 + j + ja - 1];
01278                             cimagb = bcoefi * work[(*n << 1) + j + ja - 1] + 
01279                                     bcoefr * work[*n * 3 + j + ja - 1];
01280                             i__2 = j - 1;
01281                             for (jr = 1; jr <= i__2; ++jr) {
01282                                 work[(*n << 1) + jr] = work[(*n << 1) + jr] - 
01283                                         creala * s[jr + (j + ja - 1) * s_dim1]
01284                                          + crealb * p[jr + (j + ja - 1) * 
01285                                         p_dim1];
01286                                 work[*n * 3 + jr] = work[*n * 3 + jr] - 
01287                                         cimaga * s[jr + (j + ja - 1) * s_dim1]
01288                                          + cimagb * p[jr + (j + ja - 1) * 
01289                                         p_dim1];
01290 /* L340: */
01291                             }
01292                         } else {
01293                             creala = acoef * work[(*n << 1) + j + ja - 1];
01294                             crealb = bcoefr * work[(*n << 1) + j + ja - 1];
01295                             i__2 = j - 1;
01296                             for (jr = 1; jr <= i__2; ++jr) {
01297                                 work[(*n << 1) + jr] = work[(*n << 1) + jr] - 
01298                                         creala * s[jr + (j + ja - 1) * s_dim1]
01299                                          + crealb * p[jr + (j + ja - 1) * 
01300                                         p_dim1];
01301 /* L350: */
01302                             }
01303                         }
01304 /* L360: */
01305                     }
01306                 }
01307 
01308                 il2by2 = FALSE_;
01309 L370:
01310                 ;
01311             }
01312 
01313 /*           Copy eigenvector to VR, back transforming if */
01314 /*           HOWMNY='B'. */
01315 
01316             ieig -= nw;
01317             if (ilback) {
01318 
01319                 i__1 = nw - 1;
01320                 for (jw = 0; jw <= i__1; ++jw) {
01321                     i__2 = *n;
01322                     for (jr = 1; jr <= i__2; ++jr) {
01323                         work[(jw + 4) * *n + jr] = work[(jw + 2) * *n + 1] * 
01324                                 vr[jr + vr_dim1];
01325 /* L380: */
01326                     }
01327 
01328 /*                 A series of compiler directives to defeat */
01329 /*                 vectorization for the next loop */
01330 
01331 
01332                     i__2 = je;
01333                     for (jc = 2; jc <= i__2; ++jc) {
01334                         i__3 = *n;
01335                         for (jr = 1; jr <= i__3; ++jr) {
01336                             work[(jw + 4) * *n + jr] += work[(jw + 2) * *n + 
01337                                     jc] * vr[jr + jc * vr_dim1];
01338 /* L390: */
01339                         }
01340 /* L400: */
01341                     }
01342 /* L410: */
01343                 }
01344 
01345                 i__1 = nw - 1;
01346                 for (jw = 0; jw <= i__1; ++jw) {
01347                     i__2 = *n;
01348                     for (jr = 1; jr <= i__2; ++jr) {
01349                         vr[jr + (ieig + jw) * vr_dim1] = work[(jw + 4) * *n + 
01350                                 jr];
01351 /* L420: */
01352                     }
01353 /* L430: */
01354                 }
01355 
01356                 iend = *n;
01357             } else {
01358                 i__1 = nw - 1;
01359                 for (jw = 0; jw <= i__1; ++jw) {
01360                     i__2 = *n;
01361                     for (jr = 1; jr <= i__2; ++jr) {
01362                         vr[jr + (ieig + jw) * vr_dim1] = work[(jw + 2) * *n + 
01363                                 jr];
01364 /* L440: */
01365                     }
01366 /* L450: */
01367                 }
01368 
01369                 iend = je;
01370             }
01371 
01372 /*           Scale eigenvector */
01373 
01374             xmax = 0.;
01375             if (ilcplx) {
01376                 i__1 = iend;
01377                 for (j = 1; j <= i__1; ++j) {
01378 /* Computing MAX */
01379                     d__3 = xmax, d__4 = (d__1 = vr[j + ieig * vr_dim1], abs(
01380                             d__1)) + (d__2 = vr[j + (ieig + 1) * vr_dim1], 
01381                             abs(d__2));
01382                     xmax = max(d__3,d__4);
01383 /* L460: */
01384                 }
01385             } else {
01386                 i__1 = iend;
01387                 for (j = 1; j <= i__1; ++j) {
01388 /* Computing MAX */
01389                     d__2 = xmax, d__3 = (d__1 = vr[j + ieig * vr_dim1], abs(
01390                             d__1));
01391                     xmax = max(d__2,d__3);
01392 /* L470: */
01393                 }
01394             }
01395 
01396             if (xmax > safmin) {
01397                 xscale = 1. / xmax;
01398                 i__1 = nw - 1;
01399                 for (jw = 0; jw <= i__1; ++jw) {
01400                     i__2 = iend;
01401                     for (jr = 1; jr <= i__2; ++jr) {
01402                         vr[jr + (ieig + jw) * vr_dim1] = xscale * vr[jr + (
01403                                 ieig + jw) * vr_dim1];
01404 /* L480: */
01405                     }
01406 /* L490: */
01407                 }
01408             }
01409 L500:
01410             ;
01411         }
01412     }
01413 
01414     return 0;
01415 
01416 /*     End of DTGEVC */
01417 
01418 } /* dtgevc_ */


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