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
00023 int cggevx_(char *balanc, char *jobvl, char *jobvr, char *
00024 sense, integer *n, complex *a, integer *lda, complex *b, integer *ldb,
00025 complex *alpha, complex *beta, complex *vl, integer *ldvl, complex *
00026 vr, integer *ldvr, integer *ilo, integer *ihi, real *lscale, real *
00027 rscale, real *abnrm, real *bbnrm, real *rconde, real *rcondv, complex
00028 *work, integer *lwork, real *rwork, integer *iwork, logical *bwork,
00029 integer *info)
00030 {
00031
00032 integer a_dim1, a_offset, b_dim1, b_offset, vl_dim1, vl_offset, vr_dim1,
00033 vr_offset, i__1, i__2, i__3, i__4;
00034 real r__1, r__2, r__3, r__4;
00035 complex q__1;
00036
00037
00038 double sqrt(doublereal), r_imag(complex *);
00039
00040
00041 integer i__, j, m, jc, in, jr;
00042 real eps;
00043 logical ilv;
00044 real anrm, bnrm;
00045 integer ierr, itau;
00046 real temp;
00047 logical ilvl, ilvr;
00048 integer iwrk, iwrk1;
00049 extern logical lsame_(char *, char *);
00050 integer icols;
00051 logical noscl;
00052 integer irows;
00053 extern int cggbak_(char *, char *, integer *, integer *,
00054 integer *, real *, real *, integer *, complex *, integer *,
00055 integer *), cggbal_(char *, integer *, complex *,
00056 integer *, complex *, integer *, integer *, integer *, real *,
00057 real *, real *, integer *), slabad_(real *, real *);
00058 extern doublereal clange_(char *, integer *, integer *, complex *,
00059 integer *, real *);
00060 extern int cgghrd_(char *, char *, integer *, integer *,
00061 integer *, complex *, integer *, complex *, integer *, complex *,
00062 integer *, complex *, integer *, integer *),
00063 clascl_(char *, integer *, integer *, real *, real *, integer *,
00064 integer *, complex *, integer *, integer *);
00065 logical ilascl, ilbscl;
00066 extern int cgeqrf_(integer *, integer *, complex *,
00067 integer *, complex *, complex *, integer *, integer *), clacpy_(
00068 char *, integer *, integer *, complex *, integer *, complex *,
00069 integer *), claset_(char *, integer *, integer *, complex
00070 *, complex *, complex *, integer *), ctgevc_(char *, char
00071 *, logical *, integer *, complex *, integer *, complex *, integer
00072 *, complex *, integer *, complex *, integer *, integer *, integer
00073 *, complex *, real *, integer *);
00074 logical ldumma[1];
00075 char chtemp[1];
00076 real bignum;
00077 extern int chgeqz_(char *, char *, char *, integer *,
00078 integer *, integer *, complex *, integer *, complex *, integer *,
00079 complex *, complex *, complex *, integer *, complex *, integer *,
00080 complex *, integer *, real *, integer *),
00081 ctgsna_(char *, char *, logical *, integer *, complex *, integer *
00082 , complex *, integer *, complex *, integer *, complex *, integer *
00083 , real *, real *, integer *, integer *, complex *, integer *,
00084 integer *, integer *);
00085 integer ijobvl;
00086 extern int slascl_(char *, integer *, integer *, real *,
00087 real *, integer *, integer *, real *, integer *, integer *), xerbla_(char *, integer *);
00088 extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
00089 integer *, integer *);
00090 extern doublereal slamch_(char *);
00091 integer ijobvr;
00092 logical wantsb;
00093 extern int cungqr_(integer *, integer *, integer *,
00094 complex *, integer *, complex *, complex *, integer *, integer *);
00095 real anrmto;
00096 logical wantse;
00097 real bnrmto;
00098 extern int cunmqr_(char *, char *, integer *, integer *,
00099 integer *, complex *, integer *, complex *, complex *, integer *,
00100 complex *, integer *, integer *);
00101 integer minwrk, maxwrk;
00102 logical wantsn;
00103 real smlnum;
00104 logical lquery, wantsv;
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
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 a_dim1 = *lda;
00360 a_offset = 1 + a_dim1;
00361 a -= a_offset;
00362 b_dim1 = *ldb;
00363 b_offset = 1 + b_dim1;
00364 b -= b_offset;
00365 --alpha;
00366 --beta;
00367 vl_dim1 = *ldvl;
00368 vl_offset = 1 + vl_dim1;
00369 vl -= vl_offset;
00370 vr_dim1 = *ldvr;
00371 vr_offset = 1 + vr_dim1;
00372 vr -= vr_offset;
00373 --lscale;
00374 --rscale;
00375 --rconde;
00376 --rcondv;
00377 --work;
00378 --rwork;
00379 --iwork;
00380 --bwork;
00381
00382
00383 if (lsame_(jobvl, "N")) {
00384 ijobvl = 1;
00385 ilvl = FALSE_;
00386 } else if (lsame_(jobvl, "V")) {
00387 ijobvl = 2;
00388 ilvl = TRUE_;
00389 } else {
00390 ijobvl = -1;
00391 ilvl = FALSE_;
00392 }
00393
00394 if (lsame_(jobvr, "N")) {
00395 ijobvr = 1;
00396 ilvr = FALSE_;
00397 } else if (lsame_(jobvr, "V")) {
00398 ijobvr = 2;
00399 ilvr = TRUE_;
00400 } else {
00401 ijobvr = -1;
00402 ilvr = FALSE_;
00403 }
00404 ilv = ilvl || ilvr;
00405
00406 noscl = lsame_(balanc, "N") || lsame_(balanc, "P");
00407 wantsn = lsame_(sense, "N");
00408 wantse = lsame_(sense, "E");
00409 wantsv = lsame_(sense, "V");
00410 wantsb = lsame_(sense, "B");
00411
00412
00413
00414 *info = 0;
00415 lquery = *lwork == -1;
00416 if (! (noscl || lsame_(balanc, "S") || lsame_(
00417 balanc, "B"))) {
00418 *info = -1;
00419 } else if (ijobvl <= 0) {
00420 *info = -2;
00421 } else if (ijobvr <= 0) {
00422 *info = -3;
00423 } else if (! (wantsn || wantse || wantsb || wantsv)) {
00424 *info = -4;
00425 } else if (*n < 0) {
00426 *info = -5;
00427 } else if (*lda < max(1,*n)) {
00428 *info = -7;
00429 } else if (*ldb < max(1,*n)) {
00430 *info = -9;
00431 } else if (*ldvl < 1 || ilvl && *ldvl < *n) {
00432 *info = -13;
00433 } else if (*ldvr < 1 || ilvr && *ldvr < *n) {
00434 *info = -15;
00435 }
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 if (*info == 0) {
00446 if (*n == 0) {
00447 minwrk = 1;
00448 maxwrk = 1;
00449 } else {
00450 minwrk = *n << 1;
00451 if (wantse) {
00452 minwrk = *n << 2;
00453 } else if (wantsv || wantsb) {
00454 minwrk = (*n << 1) * (*n + 1);
00455 }
00456 maxwrk = minwrk;
00457
00458 i__1 = maxwrk, i__2 = *n + *n * ilaenv_(&c__1, "CGEQRF", " ", n, &
00459 c__1, n, &c__0);
00460 maxwrk = max(i__1,i__2);
00461
00462 i__1 = maxwrk, i__2 = *n + *n * ilaenv_(&c__1, "CUNMQR", " ", n, &
00463 c__1, n, &c__0);
00464 maxwrk = max(i__1,i__2);
00465 if (ilvl) {
00466
00467 i__1 = maxwrk, i__2 = *n + *n * ilaenv_(&c__1, "CUNGQR",
00468 " ", n, &c__1, n, &c__0);
00469 maxwrk = max(i__1,i__2);
00470 }
00471 }
00472 work[1].r = (real) maxwrk, work[1].i = 0.f;
00473
00474 if (*lwork < minwrk && ! lquery) {
00475 *info = -25;
00476 }
00477 }
00478
00479 if (*info != 0) {
00480 i__1 = -(*info);
00481 xerbla_("CGGEVX", &i__1);
00482 return 0;
00483 } else if (lquery) {
00484 return 0;
00485 }
00486
00487
00488
00489 if (*n == 0) {
00490 return 0;
00491 }
00492
00493
00494
00495 eps = slamch_("P");
00496 smlnum = slamch_("S");
00497 bignum = 1.f / smlnum;
00498 slabad_(&smlnum, &bignum);
00499 smlnum = sqrt(smlnum) / eps;
00500 bignum = 1.f / smlnum;
00501
00502
00503
00504 anrm = clange_("M", n, n, &a[a_offset], lda, &rwork[1]);
00505 ilascl = FALSE_;
00506 if (anrm > 0.f && anrm < smlnum) {
00507 anrmto = smlnum;
00508 ilascl = TRUE_;
00509 } else if (anrm > bignum) {
00510 anrmto = bignum;
00511 ilascl = TRUE_;
00512 }
00513 if (ilascl) {
00514 clascl_("G", &c__0, &c__0, &anrm, &anrmto, n, n, &a[a_offset], lda, &
00515 ierr);
00516 }
00517
00518
00519
00520 bnrm = clange_("M", n, n, &b[b_offset], ldb, &rwork[1]);
00521 ilbscl = FALSE_;
00522 if (bnrm > 0.f && bnrm < smlnum) {
00523 bnrmto = smlnum;
00524 ilbscl = TRUE_;
00525 } else if (bnrm > bignum) {
00526 bnrmto = bignum;
00527 ilbscl = TRUE_;
00528 }
00529 if (ilbscl) {
00530 clascl_("G", &c__0, &c__0, &bnrm, &bnrmto, n, n, &b[b_offset], ldb, &
00531 ierr);
00532 }
00533
00534
00535
00536
00537 cggbal_(balanc, n, &a[a_offset], lda, &b[b_offset], ldb, ilo, ihi, &
00538 lscale[1], &rscale[1], &rwork[1], &ierr);
00539
00540
00541
00542 *abnrm = clange_("1", n, n, &a[a_offset], lda, &rwork[1]);
00543 if (ilascl) {
00544 rwork[1] = *abnrm;
00545 slascl_("G", &c__0, &c__0, &anrmto, &anrm, &c__1, &c__1, &rwork[1], &
00546 c__1, &ierr);
00547 *abnrm = rwork[1];
00548 }
00549
00550 *bbnrm = clange_("1", n, n, &b[b_offset], ldb, &rwork[1]);
00551 if (ilbscl) {
00552 rwork[1] = *bbnrm;
00553 slascl_("G", &c__0, &c__0, &bnrmto, &bnrm, &c__1, &c__1, &rwork[1], &
00554 c__1, &ierr);
00555 *bbnrm = rwork[1];
00556 }
00557
00558
00559
00560
00561 irows = *ihi + 1 - *ilo;
00562 if (ilv || ! wantsn) {
00563 icols = *n + 1 - *ilo;
00564 } else {
00565 icols = irows;
00566 }
00567 itau = 1;
00568 iwrk = itau + irows;
00569 i__1 = *lwork + 1 - iwrk;
00570 cgeqrf_(&irows, &icols, &b[*ilo + *ilo * b_dim1], ldb, &work[itau], &work[
00571 iwrk], &i__1, &ierr);
00572
00573
00574
00575
00576 i__1 = *lwork + 1 - iwrk;
00577 cunmqr_("L", "C", &irows, &icols, &irows, &b[*ilo + *ilo * b_dim1], ldb, &
00578 work[itau], &a[*ilo + *ilo * a_dim1], lda, &work[iwrk], &i__1, &
00579 ierr);
00580
00581
00582
00583
00584 if (ilvl) {
00585 claset_("Full", n, n, &c_b1, &c_b2, &vl[vl_offset], ldvl);
00586 if (irows > 1) {
00587 i__1 = irows - 1;
00588 i__2 = irows - 1;
00589 clacpy_("L", &i__1, &i__2, &b[*ilo + 1 + *ilo * b_dim1], ldb, &vl[
00590 *ilo + 1 + *ilo * vl_dim1], ldvl);
00591 }
00592 i__1 = *lwork + 1 - iwrk;
00593 cungqr_(&irows, &irows, &irows, &vl[*ilo + *ilo * vl_dim1], ldvl, &
00594 work[itau], &work[iwrk], &i__1, &ierr);
00595 }
00596
00597 if (ilvr) {
00598 claset_("Full", n, n, &c_b1, &c_b2, &vr[vr_offset], ldvr);
00599 }
00600
00601
00602
00603
00604 if (ilv || ! wantsn) {
00605
00606
00607
00608 cgghrd_(jobvl, jobvr, n, ilo, ihi, &a[a_offset], lda, &b[b_offset],
00609 ldb, &vl[vl_offset], ldvl, &vr[vr_offset], ldvr, &ierr);
00610 } else {
00611 cgghrd_("N", "N", &irows, &c__1, &irows, &a[*ilo + *ilo * a_dim1],
00612 lda, &b[*ilo + *ilo * b_dim1], ldb, &vl[vl_offset], ldvl, &vr[
00613 vr_offset], ldvr, &ierr);
00614 }
00615
00616
00617
00618
00619
00620
00621 iwrk = itau;
00622 if (ilv || ! wantsn) {
00623 *(unsigned char *)chtemp = 'S';
00624 } else {
00625 *(unsigned char *)chtemp = 'E';
00626 }
00627
00628 i__1 = *lwork + 1 - iwrk;
00629 chgeqz_(chtemp, jobvl, jobvr, n, ilo, ihi, &a[a_offset], lda, &b[b_offset]
00630 , ldb, &alpha[1], &beta[1], &vl[vl_offset], ldvl, &vr[vr_offset],
00631 ldvr, &work[iwrk], &i__1, &rwork[1], &ierr);
00632 if (ierr != 0) {
00633 if (ierr > 0 && ierr <= *n) {
00634 *info = ierr;
00635 } else if (ierr > *n && ierr <= *n << 1) {
00636 *info = ierr - *n;
00637 } else {
00638 *info = *n + 1;
00639 }
00640 goto L90;
00641 }
00642
00643
00644
00645
00646
00647
00648
00649 if (ilv || ! wantsn) {
00650 if (ilv) {
00651 if (ilvl) {
00652 if (ilvr) {
00653 *(unsigned char *)chtemp = 'B';
00654 } else {
00655 *(unsigned char *)chtemp = 'L';
00656 }
00657 } else {
00658 *(unsigned char *)chtemp = 'R';
00659 }
00660
00661 ctgevc_(chtemp, "B", ldumma, n, &a[a_offset], lda, &b[b_offset],
00662 ldb, &vl[vl_offset], ldvl, &vr[vr_offset], ldvr, n, &in, &
00663 work[iwrk], &rwork[1], &ierr);
00664 if (ierr != 0) {
00665 *info = *n + 2;
00666 goto L90;
00667 }
00668 }
00669
00670 if (! wantsn) {
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681 i__1 = *n;
00682 for (i__ = 1; i__ <= i__1; ++i__) {
00683
00684 i__2 = *n;
00685 for (j = 1; j <= i__2; ++j) {
00686 bwork[j] = FALSE_;
00687
00688 }
00689 bwork[i__] = TRUE_;
00690
00691 iwrk = *n + 1;
00692 iwrk1 = iwrk + *n;
00693
00694 if (wantse || wantsb) {
00695 ctgevc_("B", "S", &bwork[1], n, &a[a_offset], lda, &b[
00696 b_offset], ldb, &work[1], n, &work[iwrk], n, &
00697 c__1, &m, &work[iwrk1], &rwork[1], &ierr);
00698 if (ierr != 0) {
00699 *info = *n + 2;
00700 goto L90;
00701 }
00702 }
00703
00704 i__2 = *lwork - iwrk1 + 1;
00705 ctgsna_(sense, "S", &bwork[1], n, &a[a_offset], lda, &b[
00706 b_offset], ldb, &work[1], n, &work[iwrk], n, &rconde[
00707 i__], &rcondv[i__], &c__1, &m, &work[iwrk1], &i__2, &
00708 iwork[1], &ierr);
00709
00710
00711 }
00712 }
00713 }
00714
00715
00716
00717
00718 if (ilvl) {
00719 cggbak_(balanc, "L", n, ilo, ihi, &lscale[1], &rscale[1], n, &vl[
00720 vl_offset], ldvl, &ierr);
00721
00722 i__1 = *n;
00723 for (jc = 1; jc <= i__1; ++jc) {
00724 temp = 0.f;
00725 i__2 = *n;
00726 for (jr = 1; jr <= i__2; ++jr) {
00727
00728 i__3 = jr + jc * vl_dim1;
00729 r__3 = temp, r__4 = (r__1 = vl[i__3].r, dabs(r__1)) + (r__2 =
00730 r_imag(&vl[jr + jc * vl_dim1]), dabs(r__2));
00731 temp = dmax(r__3,r__4);
00732
00733 }
00734 if (temp < smlnum) {
00735 goto L50;
00736 }
00737 temp = 1.f / temp;
00738 i__2 = *n;
00739 for (jr = 1; jr <= i__2; ++jr) {
00740 i__3 = jr + jc * vl_dim1;
00741 i__4 = jr + jc * vl_dim1;
00742 q__1.r = temp * vl[i__4].r, q__1.i = temp * vl[i__4].i;
00743 vl[i__3].r = q__1.r, vl[i__3].i = q__1.i;
00744
00745 }
00746 L50:
00747 ;
00748 }
00749 }
00750
00751 if (ilvr) {
00752 cggbak_(balanc, "R", n, ilo, ihi, &lscale[1], &rscale[1], n, &vr[
00753 vr_offset], ldvr, &ierr);
00754 i__1 = *n;
00755 for (jc = 1; jc <= i__1; ++jc) {
00756 temp = 0.f;
00757 i__2 = *n;
00758 for (jr = 1; jr <= i__2; ++jr) {
00759
00760 i__3 = jr + jc * vr_dim1;
00761 r__3 = temp, r__4 = (r__1 = vr[i__3].r, dabs(r__1)) + (r__2 =
00762 r_imag(&vr[jr + jc * vr_dim1]), dabs(r__2));
00763 temp = dmax(r__3,r__4);
00764
00765 }
00766 if (temp < smlnum) {
00767 goto L80;
00768 }
00769 temp = 1.f / temp;
00770 i__2 = *n;
00771 for (jr = 1; jr <= i__2; ++jr) {
00772 i__3 = jr + jc * vr_dim1;
00773 i__4 = jr + jc * vr_dim1;
00774 q__1.r = temp * vr[i__4].r, q__1.i = temp * vr[i__4].i;
00775 vr[i__3].r = q__1.r, vr[i__3].i = q__1.i;
00776
00777 }
00778 L80:
00779 ;
00780 }
00781 }
00782
00783
00784
00785 if (ilascl) {
00786 clascl_("G", &c__0, &c__0, &anrmto, &anrm, n, &c__1, &alpha[1], n, &
00787 ierr);
00788 }
00789
00790 if (ilbscl) {
00791 clascl_("G", &c__0, &c__0, &bnrmto, &bnrm, n, &c__1, &beta[1], n, &
00792 ierr);
00793 }
00794
00795 L90:
00796 work[1].r = (real) maxwrk, work[1].i = 0.f;
00797
00798 return 0;
00799
00800
00801
00802 }