00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "f2c.h"
00014 #include "blaswrap.h"
00015
00016
00017
00018 static complex c_b1 = {0.f,0.f};
00019 static complex c_b2 = {1.f,0.f};
00020 static integer c__1 = 1;
00021 static integer c__0 = 0;
00022 static integer c_n1 = -1;
00023
00024 int cggev_(char *jobvl, char *jobvr, integer *n, complex *a,
00025 integer *lda, complex *b, integer *ldb, complex *alpha, complex *beta,
00026 complex *vl, integer *ldvl, complex *vr, integer *ldvr, complex *
00027 work, integer *lwork, real *rwork, integer *info)
00028 {
00029
00030 integer a_dim1, a_offset, b_dim1, b_offset, vl_dim1, vl_offset, vr_dim1,
00031 vr_offset, i__1, i__2, i__3, i__4;
00032 real r__1, r__2, r__3, r__4;
00033 complex q__1;
00034
00035
00036 double sqrt(doublereal), r_imag(complex *);
00037
00038
00039 integer jc, in, jr, ihi, ilo;
00040 real eps;
00041 logical ilv;
00042 real anrm, bnrm;
00043 integer ierr, itau;
00044 real temp;
00045 logical ilvl, ilvr;
00046 integer iwrk;
00047 extern logical lsame_(char *, char *);
00048 integer ileft, icols, irwrk, irows;
00049 extern int cggbak_(char *, char *, integer *, integer *,
00050 integer *, real *, real *, integer *, complex *, integer *,
00051 integer *), cggbal_(char *, integer *, complex *,
00052 integer *, complex *, integer *, integer *, integer *, real *,
00053 real *, real *, integer *), slabad_(real *, real *);
00054 extern doublereal clange_(char *, integer *, integer *, complex *,
00055 integer *, real *);
00056 extern int cgghrd_(char *, char *, integer *, integer *,
00057 integer *, complex *, integer *, complex *, integer *, complex *,
00058 integer *, complex *, integer *, integer *),
00059 clascl_(char *, integer *, integer *, real *, real *, integer *,
00060 integer *, complex *, integer *, integer *);
00061 logical ilascl, ilbscl;
00062 extern int cgeqrf_(integer *, integer *, complex *,
00063 integer *, complex *, complex *, integer *, integer *);
00064 extern doublereal slamch_(char *);
00065 extern int clacpy_(char *, integer *, integer *, complex
00066 *, integer *, complex *, integer *), claset_(char *,
00067 integer *, integer *, complex *, complex *, complex *, integer *), ctgevc_(char *, char *, logical *, integer *, complex *,
00068 integer *, complex *, integer *, complex *, integer *, complex *,
00069 integer *, integer *, integer *, complex *, real *, integer *), xerbla_(char *, integer *);
00070 logical ldumma[1];
00071 char chtemp[1];
00072 real bignum;
00073 extern int chgeqz_(char *, char *, char *, integer *,
00074 integer *, integer *, complex *, integer *, complex *, integer *,
00075 complex *, complex *, complex *, integer *, complex *, integer *,
00076 complex *, integer *, real *, integer *);
00077 extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
00078 integer *, integer *);
00079 integer ijobvl, iright, ijobvr;
00080 extern int cungqr_(integer *, integer *, integer *,
00081 complex *, integer *, complex *, complex *, integer *, integer *);
00082 real anrmto;
00083 integer lwkmin;
00084 real bnrmto;
00085 extern int cunmqr_(char *, char *, integer *, integer *,
00086 integer *, complex *, integer *, complex *, complex *, integer *,
00087 complex *, integer *, integer *);
00088 real smlnum;
00089 integer lwkopt;
00090 logical lquery;
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 a_dim1 = *lda;
00239 a_offset = 1 + a_dim1;
00240 a -= a_offset;
00241 b_dim1 = *ldb;
00242 b_offset = 1 + b_dim1;
00243 b -= b_offset;
00244 --alpha;
00245 --beta;
00246 vl_dim1 = *ldvl;
00247 vl_offset = 1 + vl_dim1;
00248 vl -= vl_offset;
00249 vr_dim1 = *ldvr;
00250 vr_offset = 1 + vr_dim1;
00251 vr -= vr_offset;
00252 --work;
00253 --rwork;
00254
00255
00256 if (lsame_(jobvl, "N")) {
00257 ijobvl = 1;
00258 ilvl = FALSE_;
00259 } else if (lsame_(jobvl, "V")) {
00260 ijobvl = 2;
00261 ilvl = TRUE_;
00262 } else {
00263 ijobvl = -1;
00264 ilvl = FALSE_;
00265 }
00266
00267 if (lsame_(jobvr, "N")) {
00268 ijobvr = 1;
00269 ilvr = FALSE_;
00270 } else if (lsame_(jobvr, "V")) {
00271 ijobvr = 2;
00272 ilvr = TRUE_;
00273 } else {
00274 ijobvr = -1;
00275 ilvr = FALSE_;
00276 }
00277 ilv = ilvl || ilvr;
00278
00279
00280
00281 *info = 0;
00282 lquery = *lwork == -1;
00283 if (ijobvl <= 0) {
00284 *info = -1;
00285 } else if (ijobvr <= 0) {
00286 *info = -2;
00287 } else if (*n < 0) {
00288 *info = -3;
00289 } else if (*lda < max(1,*n)) {
00290 *info = -5;
00291 } else if (*ldb < max(1,*n)) {
00292 *info = -7;
00293 } else if (*ldvl < 1 || ilvl && *ldvl < *n) {
00294 *info = -11;
00295 } else if (*ldvr < 1 || ilvr && *ldvr < *n) {
00296 *info = -13;
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 if (*info == 0) {
00308
00309 i__1 = 1, i__2 = *n << 1;
00310 lwkmin = max(i__1,i__2);
00311
00312 i__1 = 1, i__2 = *n + *n * ilaenv_(&c__1, "CGEQRF", " ", n, &c__1, n,
00313 &c__0);
00314 lwkopt = max(i__1,i__2);
00315
00316 i__1 = lwkopt, i__2 = *n + *n * ilaenv_(&c__1, "CUNMQR", " ", n, &
00317 c__1, n, &c__0);
00318 lwkopt = max(i__1,i__2);
00319 if (ilvl) {
00320
00321 i__1 = lwkopt, i__2 = *n + *n * ilaenv_(&c__1, "CUNGQR", " ", n, &
00322 c__1, n, &c_n1);
00323 lwkopt = max(i__1,i__2);
00324 }
00325 work[1].r = (real) lwkopt, work[1].i = 0.f;
00326
00327 if (*lwork < lwkmin && ! lquery) {
00328 *info = -15;
00329 }
00330 }
00331
00332 if (*info != 0) {
00333 i__1 = -(*info);
00334 xerbla_("CGGEV ", &i__1);
00335 return 0;
00336 } else if (lquery) {
00337 return 0;
00338 }
00339
00340
00341
00342 if (*n == 0) {
00343 return 0;
00344 }
00345
00346
00347
00348 eps = slamch_("E") * slamch_("B");
00349 smlnum = slamch_("S");
00350 bignum = 1.f / smlnum;
00351 slabad_(&smlnum, &bignum);
00352 smlnum = sqrt(smlnum) / eps;
00353 bignum = 1.f / smlnum;
00354
00355
00356
00357 anrm = clange_("M", n, n, &a[a_offset], lda, &rwork[1]);
00358 ilascl = FALSE_;
00359 if (anrm > 0.f && anrm < smlnum) {
00360 anrmto = smlnum;
00361 ilascl = TRUE_;
00362 } else if (anrm > bignum) {
00363 anrmto = bignum;
00364 ilascl = TRUE_;
00365 }
00366 if (ilascl) {
00367 clascl_("G", &c__0, &c__0, &anrm, &anrmto, n, n, &a[a_offset], lda, &
00368 ierr);
00369 }
00370
00371
00372
00373 bnrm = clange_("M", n, n, &b[b_offset], ldb, &rwork[1]);
00374 ilbscl = FALSE_;
00375 if (bnrm > 0.f && bnrm < smlnum) {
00376 bnrmto = smlnum;
00377 ilbscl = TRUE_;
00378 } else if (bnrm > bignum) {
00379 bnrmto = bignum;
00380 ilbscl = TRUE_;
00381 }
00382 if (ilbscl) {
00383 clascl_("G", &c__0, &c__0, &bnrm, &bnrmto, n, n, &b[b_offset], ldb, &
00384 ierr);
00385 }
00386
00387
00388
00389
00390 ileft = 1;
00391 iright = *n + 1;
00392 irwrk = iright + *n;
00393 cggbal_("P", n, &a[a_offset], lda, &b[b_offset], ldb, &ilo, &ihi, &rwork[
00394 ileft], &rwork[iright], &rwork[irwrk], &ierr);
00395
00396
00397
00398
00399 irows = ihi + 1 - ilo;
00400 if (ilv) {
00401 icols = *n + 1 - ilo;
00402 } else {
00403 icols = irows;
00404 }
00405 itau = 1;
00406 iwrk = itau + irows;
00407 i__1 = *lwork + 1 - iwrk;
00408 cgeqrf_(&irows, &icols, &b[ilo + ilo * b_dim1], ldb, &work[itau], &work[
00409 iwrk], &i__1, &ierr);
00410
00411
00412
00413
00414 i__1 = *lwork + 1 - iwrk;
00415 cunmqr_("L", "C", &irows, &icols, &irows, &b[ilo + ilo * b_dim1], ldb, &
00416 work[itau], &a[ilo + ilo * a_dim1], lda, &work[iwrk], &i__1, &
00417 ierr);
00418
00419
00420
00421
00422 if (ilvl) {
00423 claset_("Full", n, n, &c_b1, &c_b2, &vl[vl_offset], ldvl);
00424 if (irows > 1) {
00425 i__1 = irows - 1;
00426 i__2 = irows - 1;
00427 clacpy_("L", &i__1, &i__2, &b[ilo + 1 + ilo * b_dim1], ldb, &vl[
00428 ilo + 1 + ilo * vl_dim1], ldvl);
00429 }
00430 i__1 = *lwork + 1 - iwrk;
00431 cungqr_(&irows, &irows, &irows, &vl[ilo + ilo * vl_dim1], ldvl, &work[
00432 itau], &work[iwrk], &i__1, &ierr);
00433 }
00434
00435
00436
00437 if (ilvr) {
00438 claset_("Full", n, n, &c_b1, &c_b2, &vr[vr_offset], ldvr);
00439 }
00440
00441
00442
00443 if (ilv) {
00444
00445
00446
00447 cgghrd_(jobvl, jobvr, n, &ilo, &ihi, &a[a_offset], lda, &b[b_offset],
00448 ldb, &vl[vl_offset], ldvl, &vr[vr_offset], ldvr, &ierr);
00449 } else {
00450 cgghrd_("N", "N", &irows, &c__1, &irows, &a[ilo + ilo * a_dim1], lda,
00451 &b[ilo + ilo * b_dim1], ldb, &vl[vl_offset], ldvl, &vr[
00452 vr_offset], ldvr, &ierr);
00453 }
00454
00455
00456
00457
00458
00459
00460 iwrk = itau;
00461 if (ilv) {
00462 *(unsigned char *)chtemp = 'S';
00463 } else {
00464 *(unsigned char *)chtemp = 'E';
00465 }
00466 i__1 = *lwork + 1 - iwrk;
00467 chgeqz_(chtemp, jobvl, jobvr, n, &ilo, &ihi, &a[a_offset], lda, &b[
00468 b_offset], ldb, &alpha[1], &beta[1], &vl[vl_offset], ldvl, &vr[
00469 vr_offset], ldvr, &work[iwrk], &i__1, &rwork[irwrk], &ierr);
00470 if (ierr != 0) {
00471 if (ierr > 0 && ierr <= *n) {
00472 *info = ierr;
00473 } else if (ierr > *n && ierr <= *n << 1) {
00474 *info = ierr - *n;
00475 } else {
00476 *info = *n + 1;
00477 }
00478 goto L70;
00479 }
00480
00481
00482
00483
00484
00485 if (ilv) {
00486 if (ilvl) {
00487 if (ilvr) {
00488 *(unsigned char *)chtemp = 'B';
00489 } else {
00490 *(unsigned char *)chtemp = 'L';
00491 }
00492 } else {
00493 *(unsigned char *)chtemp = 'R';
00494 }
00495
00496 ctgevc_(chtemp, "B", ldumma, n, &a[a_offset], lda, &b[b_offset], ldb,
00497 &vl[vl_offset], ldvl, &vr[vr_offset], ldvr, n, &in, &work[
00498 iwrk], &rwork[irwrk], &ierr);
00499 if (ierr != 0) {
00500 *info = *n + 2;
00501 goto L70;
00502 }
00503
00504
00505
00506
00507 if (ilvl) {
00508 cggbak_("P", "L", n, &ilo, &ihi, &rwork[ileft], &rwork[iright], n,
00509 &vl[vl_offset], ldvl, &ierr);
00510 i__1 = *n;
00511 for (jc = 1; jc <= i__1; ++jc) {
00512 temp = 0.f;
00513 i__2 = *n;
00514 for (jr = 1; jr <= i__2; ++jr) {
00515
00516 i__3 = jr + jc * vl_dim1;
00517 r__3 = temp, r__4 = (r__1 = vl[i__3].r, dabs(r__1)) + (
00518 r__2 = r_imag(&vl[jr + jc * vl_dim1]), dabs(r__2))
00519 ;
00520 temp = dmax(r__3,r__4);
00521
00522 }
00523 if (temp < smlnum) {
00524 goto L30;
00525 }
00526 temp = 1.f / temp;
00527 i__2 = *n;
00528 for (jr = 1; jr <= i__2; ++jr) {
00529 i__3 = jr + jc * vl_dim1;
00530 i__4 = jr + jc * vl_dim1;
00531 q__1.r = temp * vl[i__4].r, q__1.i = temp * vl[i__4].i;
00532 vl[i__3].r = q__1.r, vl[i__3].i = q__1.i;
00533
00534 }
00535 L30:
00536 ;
00537 }
00538 }
00539 if (ilvr) {
00540 cggbak_("P", "R", n, &ilo, &ihi, &rwork[ileft], &rwork[iright], n,
00541 &vr[vr_offset], ldvr, &ierr);
00542 i__1 = *n;
00543 for (jc = 1; jc <= i__1; ++jc) {
00544 temp = 0.f;
00545 i__2 = *n;
00546 for (jr = 1; jr <= i__2; ++jr) {
00547
00548 i__3 = jr + jc * vr_dim1;
00549 r__3 = temp, r__4 = (r__1 = vr[i__3].r, dabs(r__1)) + (
00550 r__2 = r_imag(&vr[jr + jc * vr_dim1]), dabs(r__2))
00551 ;
00552 temp = dmax(r__3,r__4);
00553
00554 }
00555 if (temp < smlnum) {
00556 goto L60;
00557 }
00558 temp = 1.f / temp;
00559 i__2 = *n;
00560 for (jr = 1; jr <= i__2; ++jr) {
00561 i__3 = jr + jc * vr_dim1;
00562 i__4 = jr + jc * vr_dim1;
00563 q__1.r = temp * vr[i__4].r, q__1.i = temp * vr[i__4].i;
00564 vr[i__3].r = q__1.r, vr[i__3].i = q__1.i;
00565
00566 }
00567 L60:
00568 ;
00569 }
00570 }
00571 }
00572
00573
00574
00575 if (ilascl) {
00576 clascl_("G", &c__0, &c__0, &anrmto, &anrm, n, &c__1, &alpha[1], n, &
00577 ierr);
00578 }
00579
00580 if (ilbscl) {
00581 clascl_("G", &c__0, &c__0, &bnrmto, &bnrm, n, &c__1, &beta[1], n, &
00582 ierr);
00583 }
00584
00585 L70:
00586 work[1].r = (real) lwkopt, work[1].i = 0.f;
00587
00588 return 0;
00589
00590
00591
00592 }