dgegs.c
Go to the documentation of this file.
00001 /* dgegs.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 integer c__1 = 1;
00019 static integer c_n1 = -1;
00020 static doublereal c_b36 = 0.;
00021 static doublereal c_b37 = 1.;
00022 
00023 /* Subroutine */ int dgegs_(char *jobvsl, char *jobvsr, integer *n, 
00024         doublereal *a, integer *lda, doublereal *b, integer *ldb, doublereal *
00025         alphar, doublereal *alphai, doublereal *beta, doublereal *vsl, 
00026         integer *ldvsl, doublereal *vsr, integer *ldvsr, doublereal *work, 
00027         integer *lwork, integer *info)
00028 {
00029     /* System generated locals */
00030     integer a_dim1, a_offset, b_dim1, b_offset, vsl_dim1, vsl_offset, 
00031             vsr_dim1, vsr_offset, i__1, i__2;
00032 
00033     /* Local variables */
00034     integer nb, nb1, nb2, nb3, ihi, ilo;
00035     doublereal eps, anrm, bnrm;
00036     integer itau, lopt;
00037     extern logical lsame_(char *, char *);
00038     integer ileft, iinfo, icols;
00039     logical ilvsl;
00040     integer iwork;
00041     logical ilvsr;
00042     integer irows;
00043     extern /* Subroutine */ int dggbak_(char *, char *, integer *, integer *, 
00044             integer *, doublereal *, doublereal *, integer *, doublereal *, 
00045             integer *, integer *), dggbal_(char *, integer *, 
00046             doublereal *, integer *, doublereal *, integer *, integer *, 
00047             integer *, doublereal *, doublereal *, doublereal *, integer *);
00048     extern doublereal dlamch_(char *), dlange_(char *, integer *, 
00049             integer *, doublereal *, integer *, doublereal *);
00050     extern /* Subroutine */ int dgghrd_(char *, char *, integer *, integer *, 
00051             integer *, doublereal *, integer *, doublereal *, integer *, 
00052             doublereal *, integer *, doublereal *, integer *, integer *), dlascl_(char *, integer *, integer *, doublereal 
00053             *, doublereal *, integer *, integer *, doublereal *, integer *, 
00054             integer *);
00055     logical ilascl, ilbscl;
00056     extern /* Subroutine */ int dgeqrf_(integer *, integer *, doublereal *, 
00057             integer *, doublereal *, doublereal *, integer *, integer *), 
00058             dlacpy_(char *, integer *, integer *, doublereal *, integer *, 
00059             doublereal *, integer *);
00060     doublereal safmin;
00061     extern /* Subroutine */ int dlaset_(char *, integer *, integer *, 
00062             doublereal *, doublereal *, doublereal *, integer *), 
00063             xerbla_(char *, integer *);
00064     extern integer ilaenv_(integer *, char *, char *, integer *, integer *, 
00065             integer *, integer *);
00066     doublereal bignum;
00067     extern /* Subroutine */ int dhgeqz_(char *, char *, char *, integer *, 
00068             integer *, integer *, doublereal *, integer *, doublereal *, 
00069             integer *, doublereal *, doublereal *, doublereal *, doublereal *, 
00070              integer *, doublereal *, integer *, doublereal *, integer *, 
00071             integer *);
00072     integer ijobvl, iright, ijobvr;
00073     extern /* Subroutine */ int dorgqr_(integer *, integer *, integer *, 
00074             doublereal *, integer *, doublereal *, doublereal *, integer *, 
00075             integer *);
00076     doublereal anrmto;
00077     integer lwkmin;
00078     doublereal bnrmto;
00079     extern /* Subroutine */ int dormqr_(char *, char *, integer *, integer *, 
00080             integer *, doublereal *, integer *, doublereal *, doublereal *, 
00081             integer *, doublereal *, integer *, integer *);
00082     doublereal smlnum;
00083     integer lwkopt;
00084     logical lquery;
00085 
00086 
00087 /*  -- LAPACK driver routine (version 3.2) -- */
00088 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00089 /*     November 2006 */
00090 
00091 /*     .. Scalar Arguments .. */
00092 /*     .. */
00093 /*     .. Array Arguments .. */
00094 /*     .. */
00095 
00096 /*  Purpose */
00097 /*  ======= */
00098 
00099 /*  This routine is deprecated and has been replaced by routine DGGES. */
00100 
00101 /*  DGEGS computes the eigenvalues, real Schur form, and, optionally, */
00102 /*  left and or/right Schur vectors of a real matrix pair (A,B). */
00103 /*  Given two square matrices A and B, the generalized real Schur */
00104 /*  factorization has the form */
00105 
00106 /*    A = Q*S*Z**T,  B = Q*T*Z**T */
00107 
00108 /*  where Q and Z are orthogonal matrices, T is upper triangular, and S */
00109 /*  is an upper quasi-triangular matrix with 1-by-1 and 2-by-2 diagonal */
00110 /*  blocks, the 2-by-2 blocks corresponding to complex conjugate pairs */
00111 /*  of eigenvalues of (A,B).  The columns of Q are the left Schur vectors */
00112 /*  and the columns of Z are the right Schur vectors. */
00113 
00114 /*  If only the eigenvalues of (A,B) are needed, the driver routine */
00115 /*  DGEGV should be used instead.  See DGEGV for a description of the */
00116 /*  eigenvalues of the generalized nonsymmetric eigenvalue problem */
00117 /*  (GNEP). */
00118 
00119 /*  Arguments */
00120 /*  ========= */
00121 
00122 /*  JOBVSL  (input) CHARACTER*1 */
00123 /*          = 'N':  do not compute the left Schur vectors; */
00124 /*          = 'V':  compute the left Schur vectors (returned in VSL). */
00125 
00126 /*  JOBVSR  (input) CHARACTER*1 */
00127 /*          = 'N':  do not compute the right Schur vectors; */
00128 /*          = 'V':  compute the right Schur vectors (returned in VSR). */
00129 
00130 /*  N       (input) INTEGER */
00131 /*          The order of the matrices A, B, VSL, and VSR.  N >= 0. */
00132 
00133 /*  A       (input/output) DOUBLE PRECISION array, dimension (LDA, N) */
00134 /*          On entry, the matrix A. */
00135 /*          On exit, the upper quasi-triangular matrix S from the */
00136 /*          generalized real Schur factorization. */
00137 
00138 /*  LDA     (input) INTEGER */
00139 /*          The leading dimension of A.  LDA >= max(1,N). */
00140 
00141 /*  B       (input/output) DOUBLE PRECISION array, dimension (LDB, N) */
00142 /*          On entry, the matrix B. */
00143 /*          On exit, the upper triangular matrix T from the generalized */
00144 /*          real Schur factorization. */
00145 
00146 /*  LDB     (input) INTEGER */
00147 /*          The leading dimension of B.  LDB >= max(1,N). */
00148 
00149 /*  ALPHAR  (output) DOUBLE PRECISION array, dimension (N) */
00150 /*          The real parts of each scalar alpha defining an eigenvalue */
00151 /*          of GNEP. */
00152 
00153 /*  ALPHAI  (output) DOUBLE PRECISION array, dimension (N) */
00154 /*          The imaginary parts of each scalar alpha defining an */
00155 /*          eigenvalue of GNEP.  If ALPHAI(j) is zero, then the j-th */
00156 /*          eigenvalue is real; if positive, then the j-th and (j+1)-st */
00157 /*          eigenvalues are a complex conjugate pair, with */
00158 /*          ALPHAI(j+1) = -ALPHAI(j). */
00159 
00160 /*  BETA    (output) DOUBLE PRECISION array, dimension (N) */
00161 /*          The scalars beta that define the eigenvalues of GNEP. */
00162 /*          Together, the quantities alpha = (ALPHAR(j),ALPHAI(j)) and */
00163 /*          beta = BETA(j) represent the j-th eigenvalue of the matrix */
00164 /*          pair (A,B), in one of the forms lambda = alpha/beta or */
00165 /*          mu = beta/alpha.  Since either lambda or mu may overflow, */
00166 /*          they should not, in general, be computed. */
00167 
00168 /*  VSL     (output) DOUBLE PRECISION array, dimension (LDVSL,N) */
00169 /*          If JOBVSL = 'V', the matrix of left Schur vectors Q. */
00170 /*          Not referenced if JOBVSL = 'N'. */
00171 
00172 /*  LDVSL   (input) INTEGER */
00173 /*          The leading dimension of the matrix VSL. LDVSL >=1, and */
00174 /*          if JOBVSL = 'V', LDVSL >= N. */
00175 
00176 /*  VSR     (output) DOUBLE PRECISION array, dimension (LDVSR,N) */
00177 /*          If JOBVSR = 'V', the matrix of right Schur vectors Z. */
00178 /*          Not referenced if JOBVSR = 'N'. */
00179 
00180 /*  LDVSR   (input) INTEGER */
00181 /*          The leading dimension of the matrix VSR. LDVSR >= 1, and */
00182 /*          if JOBVSR = 'V', LDVSR >= N. */
00183 
00184 /*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK)) */
00185 /*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */
00186 
00187 /*  LWORK   (input) INTEGER */
00188 /*          The dimension of the array WORK.  LWORK >= max(1,4*N). */
00189 /*          For good performance, LWORK must generally be larger. */
00190 /*          To compute the optimal value of LWORK, call ILAENV to get */
00191 /*          blocksizes (for DGEQRF, DORMQR, and DORGQR.)  Then compute: */
00192 /*          NB  -- MAX of the blocksizes for DGEQRF, DORMQR, and DORGQR */
00193 /*          The optimal LWORK is  2*N + N*(NB+1). */
00194 
00195 /*          If LWORK = -1, then a workspace query is assumed; the routine */
00196 /*          only calculates the optimal size of the WORK array, returns */
00197 /*          this value as the first entry of the WORK array, and no error */
00198 /*          message related to LWORK is issued by XERBLA. */
00199 
00200 /*  INFO    (output) INTEGER */
00201 /*          = 0:  successful exit */
00202 /*          < 0:  if INFO = -i, the i-th argument had an illegal value. */
00203 /*          = 1,...,N: */
00204 /*                The QZ iteration failed.  (A,B) are not in Schur */
00205 /*                form, but ALPHAR(j), ALPHAI(j), and BETA(j) should */
00206 /*                be correct for j=INFO+1,...,N. */
00207 /*          > N:  errors that usually indicate LAPACK problems: */
00208 /*                =N+1: error return from DGGBAL */
00209 /*                =N+2: error return from DGEQRF */
00210 /*                =N+3: error return from DORMQR */
00211 /*                =N+4: error return from DORGQR */
00212 /*                =N+5: error return from DGGHRD */
00213 /*                =N+6: error return from DHGEQZ (other than failed */
00214 /*                                                iteration) */
00215 /*                =N+7: error return from DGGBAK (computing VSL) */
00216 /*                =N+8: error return from DGGBAK (computing VSR) */
00217 /*                =N+9: error return from DLASCL (various places) */
00218 
00219 /*  ===================================================================== */
00220 
00221 /*     .. Parameters .. */
00222 /*     .. */
00223 /*     .. Local Scalars .. */
00224 /*     .. */
00225 /*     .. External Subroutines .. */
00226 /*     .. */
00227 /*     .. External Functions .. */
00228 /*     .. */
00229 /*     .. Intrinsic Functions .. */
00230 /*     .. */
00231 /*     .. Executable Statements .. */
00232 
00233 /*     Decode the input arguments */
00234 
00235     /* Parameter adjustments */
00236     a_dim1 = *lda;
00237     a_offset = 1 + a_dim1;
00238     a -= a_offset;
00239     b_dim1 = *ldb;
00240     b_offset = 1 + b_dim1;
00241     b -= b_offset;
00242     --alphar;
00243     --alphai;
00244     --beta;
00245     vsl_dim1 = *ldvsl;
00246     vsl_offset = 1 + vsl_dim1;
00247     vsl -= vsl_offset;
00248     vsr_dim1 = *ldvsr;
00249     vsr_offset = 1 + vsr_dim1;
00250     vsr -= vsr_offset;
00251     --work;
00252 
00253     /* Function Body */
00254     if (lsame_(jobvsl, "N")) {
00255         ijobvl = 1;
00256         ilvsl = FALSE_;
00257     } else if (lsame_(jobvsl, "V")) {
00258         ijobvl = 2;
00259         ilvsl = TRUE_;
00260     } else {
00261         ijobvl = -1;
00262         ilvsl = FALSE_;
00263     }
00264 
00265     if (lsame_(jobvsr, "N")) {
00266         ijobvr = 1;
00267         ilvsr = FALSE_;
00268     } else if (lsame_(jobvsr, "V")) {
00269         ijobvr = 2;
00270         ilvsr = TRUE_;
00271     } else {
00272         ijobvr = -1;
00273         ilvsr = FALSE_;
00274     }
00275 
00276 /*     Test the input arguments */
00277 
00278 /* Computing MAX */
00279     i__1 = *n << 2;
00280     lwkmin = max(i__1,1);
00281     lwkopt = lwkmin;
00282     work[1] = (doublereal) lwkopt;
00283     lquery = *lwork == -1;
00284     *info = 0;
00285     if (ijobvl <= 0) {
00286         *info = -1;
00287     } else if (ijobvr <= 0) {
00288         *info = -2;
00289     } else if (*n < 0) {
00290         *info = -3;
00291     } else if (*lda < max(1,*n)) {
00292         *info = -5;
00293     } else if (*ldb < max(1,*n)) {
00294         *info = -7;
00295     } else if (*ldvsl < 1 || ilvsl && *ldvsl < *n) {
00296         *info = -12;
00297     } else if (*ldvsr < 1 || ilvsr && *ldvsr < *n) {
00298         *info = -14;
00299     } else if (*lwork < lwkmin && ! lquery) {
00300         *info = -16;
00301     }
00302 
00303     if (*info == 0) {
00304         nb1 = ilaenv_(&c__1, "DGEQRF", " ", n, n, &c_n1, &c_n1);
00305         nb2 = ilaenv_(&c__1, "DORMQR", " ", n, n, n, &c_n1);
00306         nb3 = ilaenv_(&c__1, "DORGQR", " ", n, n, n, &c_n1);
00307 /* Computing MAX */
00308         i__1 = max(nb1,nb2);
00309         nb = max(i__1,nb3);
00310         lopt = (*n << 1) + *n * (nb + 1);
00311         work[1] = (doublereal) lopt;
00312     }
00313 
00314     if (*info != 0) {
00315         i__1 = -(*info);
00316         xerbla_("DGEGS ", &i__1);
00317         return 0;
00318     } else if (lquery) {
00319         return 0;
00320     }
00321 
00322 /*     Quick return if possible */
00323 
00324     if (*n == 0) {
00325         return 0;
00326     }
00327 
00328 /*     Get machine constants */
00329 
00330     eps = dlamch_("E") * dlamch_("B");
00331     safmin = dlamch_("S");
00332     smlnum = *n * safmin / eps;
00333     bignum = 1. / smlnum;
00334 
00335 /*     Scale A if max element outside range [SMLNUM,BIGNUM] */
00336 
00337     anrm = dlange_("M", n, n, &a[a_offset], lda, &work[1]);
00338     ilascl = FALSE_;
00339     if (anrm > 0. && anrm < smlnum) {
00340         anrmto = smlnum;
00341         ilascl = TRUE_;
00342     } else if (anrm > bignum) {
00343         anrmto = bignum;
00344         ilascl = TRUE_;
00345     }
00346 
00347     if (ilascl) {
00348         dlascl_("G", &c_n1, &c_n1, &anrm, &anrmto, n, n, &a[a_offset], lda, &
00349                 iinfo);
00350         if (iinfo != 0) {
00351             *info = *n + 9;
00352             return 0;
00353         }
00354     }
00355 
00356 /*     Scale B if max element outside range [SMLNUM,BIGNUM] */
00357 
00358     bnrm = dlange_("M", n, n, &b[b_offset], ldb, &work[1]);
00359     ilbscl = FALSE_;
00360     if (bnrm > 0. && bnrm < smlnum) {
00361         bnrmto = smlnum;
00362         ilbscl = TRUE_;
00363     } else if (bnrm > bignum) {
00364         bnrmto = bignum;
00365         ilbscl = TRUE_;
00366     }
00367 
00368     if (ilbscl) {
00369         dlascl_("G", &c_n1, &c_n1, &bnrm, &bnrmto, n, n, &b[b_offset], ldb, &
00370                 iinfo);
00371         if (iinfo != 0) {
00372             *info = *n + 9;
00373             return 0;
00374         }
00375     }
00376 
00377 /*     Permute the matrix to make it more nearly triangular */
00378 /*     Workspace layout:  (2*N words -- "work..." not actually used) */
00379 /*        left_permutation, right_permutation, work... */
00380 
00381     ileft = 1;
00382     iright = *n + 1;
00383     iwork = iright + *n;
00384     dggbal_("P", n, &a[a_offset], lda, &b[b_offset], ldb, &ilo, &ihi, &work[
00385             ileft], &work[iright], &work[iwork], &iinfo);
00386     if (iinfo != 0) {
00387         *info = *n + 1;
00388         goto L10;
00389     }
00390 
00391 /*     Reduce B to triangular form, and initialize VSL and/or VSR */
00392 /*     Workspace layout:  ("work..." must have at least N words) */
00393 /*        left_permutation, right_permutation, tau, work... */
00394 
00395     irows = ihi + 1 - ilo;
00396     icols = *n + 1 - ilo;
00397     itau = iwork;
00398     iwork = itau + irows;
00399     i__1 = *lwork + 1 - iwork;
00400     dgeqrf_(&irows, &icols, &b[ilo + ilo * b_dim1], ldb, &work[itau], &work[
00401             iwork], &i__1, &iinfo);
00402     if (iinfo >= 0) {
00403 /* Computing MAX */
00404         i__1 = lwkopt, i__2 = (integer) work[iwork] + iwork - 1;
00405         lwkopt = max(i__1,i__2);
00406     }
00407     if (iinfo != 0) {
00408         *info = *n + 2;
00409         goto L10;
00410     }
00411 
00412     i__1 = *lwork + 1 - iwork;
00413     dormqr_("L", "T", &irows, &icols, &irows, &b[ilo + ilo * b_dim1], ldb, &
00414             work[itau], &a[ilo + ilo * a_dim1], lda, &work[iwork], &i__1, &
00415             iinfo);
00416     if (iinfo >= 0) {
00417 /* Computing MAX */
00418         i__1 = lwkopt, i__2 = (integer) work[iwork] + iwork - 1;
00419         lwkopt = max(i__1,i__2);
00420     }
00421     if (iinfo != 0) {
00422         *info = *n + 3;
00423         goto L10;
00424     }
00425 
00426     if (ilvsl) {
00427         dlaset_("Full", n, n, &c_b36, &c_b37, &vsl[vsl_offset], ldvsl);
00428         i__1 = irows - 1;
00429         i__2 = irows - 1;
00430         dlacpy_("L", &i__1, &i__2, &b[ilo + 1 + ilo * b_dim1], ldb, &vsl[ilo 
00431                 + 1 + ilo * vsl_dim1], ldvsl);
00432         i__1 = *lwork + 1 - iwork;
00433         dorgqr_(&irows, &irows, &irows, &vsl[ilo + ilo * vsl_dim1], ldvsl, &
00434                 work[itau], &work[iwork], &i__1, &iinfo);
00435         if (iinfo >= 0) {
00436 /* Computing MAX */
00437             i__1 = lwkopt, i__2 = (integer) work[iwork] + iwork - 1;
00438             lwkopt = max(i__1,i__2);
00439         }
00440         if (iinfo != 0) {
00441             *info = *n + 4;
00442             goto L10;
00443         }
00444     }
00445 
00446     if (ilvsr) {
00447         dlaset_("Full", n, n, &c_b36, &c_b37, &vsr[vsr_offset], ldvsr);
00448     }
00449 
00450 /*     Reduce to generalized Hessenberg form */
00451 
00452     dgghrd_(jobvsl, jobvsr, n, &ilo, &ihi, &a[a_offset], lda, &b[b_offset], 
00453             ldb, &vsl[vsl_offset], ldvsl, &vsr[vsr_offset], ldvsr, &iinfo);
00454     if (iinfo != 0) {
00455         *info = *n + 5;
00456         goto L10;
00457     }
00458 
00459 /*     Perform QZ algorithm, computing Schur vectors if desired */
00460 /*     Workspace layout:  ("work..." must have at least 1 word) */
00461 /*        left_permutation, right_permutation, work... */
00462 
00463     iwork = itau;
00464     i__1 = *lwork + 1 - iwork;
00465     dhgeqz_("S", jobvsl, jobvsr, n, &ilo, &ihi, &a[a_offset], lda, &b[
00466             b_offset], ldb, &alphar[1], &alphai[1], &beta[1], &vsl[vsl_offset]
00467 , ldvsl, &vsr[vsr_offset], ldvsr, &work[iwork], &i__1, &iinfo);
00468     if (iinfo >= 0) {
00469 /* Computing MAX */
00470         i__1 = lwkopt, i__2 = (integer) work[iwork] + iwork - 1;
00471         lwkopt = max(i__1,i__2);
00472     }
00473     if (iinfo != 0) {
00474         if (iinfo > 0 && iinfo <= *n) {
00475             *info = iinfo;
00476         } else if (iinfo > *n && iinfo <= *n << 1) {
00477             *info = iinfo - *n;
00478         } else {
00479             *info = *n + 6;
00480         }
00481         goto L10;
00482     }
00483 
00484 /*     Apply permutation to VSL and VSR */
00485 
00486     if (ilvsl) {
00487         dggbak_("P", "L", n, &ilo, &ihi, &work[ileft], &work[iright], n, &vsl[
00488                 vsl_offset], ldvsl, &iinfo);
00489         if (iinfo != 0) {
00490             *info = *n + 7;
00491             goto L10;
00492         }
00493     }
00494     if (ilvsr) {
00495         dggbak_("P", "R", n, &ilo, &ihi, &work[ileft], &work[iright], n, &vsr[
00496                 vsr_offset], ldvsr, &iinfo);
00497         if (iinfo != 0) {
00498             *info = *n + 8;
00499             goto L10;
00500         }
00501     }
00502 
00503 /*     Undo scaling */
00504 
00505     if (ilascl) {
00506         dlascl_("H", &c_n1, &c_n1, &anrmto, &anrm, n, n, &a[a_offset], lda, &
00507                 iinfo);
00508         if (iinfo != 0) {
00509             *info = *n + 9;
00510             return 0;
00511         }
00512         dlascl_("G", &c_n1, &c_n1, &anrmto, &anrm, n, &c__1, &alphar[1], n, &
00513                 iinfo);
00514         if (iinfo != 0) {
00515             *info = *n + 9;
00516             return 0;
00517         }
00518         dlascl_("G", &c_n1, &c_n1, &anrmto, &anrm, n, &c__1, &alphai[1], n, &
00519                 iinfo);
00520         if (iinfo != 0) {
00521             *info = *n + 9;
00522             return 0;
00523         }
00524     }
00525 
00526     if (ilbscl) {
00527         dlascl_("U", &c_n1, &c_n1, &bnrmto, &bnrm, n, n, &b[b_offset], ldb, &
00528                 iinfo);
00529         if (iinfo != 0) {
00530             *info = *n + 9;
00531             return 0;
00532         }
00533         dlascl_("G", &c_n1, &c_n1, &bnrmto, &bnrm, n, &c__1, &beta[1], n, &
00534                 iinfo);
00535         if (iinfo != 0) {
00536             *info = *n + 9;
00537             return 0;
00538         }
00539     }
00540 
00541 L10:
00542     work[1] = (doublereal) lwkopt;
00543 
00544     return 0;
00545 
00546 /*     End of DGEGS */
00547 
00548 } /* dgegs_ */


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