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 integer c__1 = 1;
00019 static integer c__0 = 0;
00020 static doublereal c_b59 = 0.;
00021 static doublereal c_b60 = 1.;
00022
00023 int dggevx_(char *balanc, char *jobvl, char *jobvr, char *
00024 sense, integer *n, doublereal *a, integer *lda, doublereal *b,
00025 integer *ldb, doublereal *alphar, doublereal *alphai, doublereal *
00026 beta, doublereal *vl, integer *ldvl, doublereal *vr, integer *ldvr,
00027 integer *ilo, integer *ihi, doublereal *lscale, doublereal *rscale,
00028 doublereal *abnrm, doublereal *bbnrm, doublereal *rconde, doublereal *
00029 rcondv, doublereal *work, integer *lwork, integer *iwork, logical *
00030 bwork, integer *info)
00031 {
00032
00033 integer a_dim1, a_offset, b_dim1, b_offset, vl_dim1, vl_offset, vr_dim1,
00034 vr_offset, i__1, i__2;
00035 doublereal d__1, d__2, d__3, d__4;
00036
00037
00038 double sqrt(doublereal);
00039
00040
00041 integer i__, j, m, jc, in, mm, jr;
00042 doublereal eps;
00043 logical ilv, pair;
00044 doublereal anrm, bnrm;
00045 integer ierr, itau;
00046 doublereal 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 dlabad_(doublereal *, doublereal *), dggbak_(
00054 char *, char *, integer *, integer *, integer *, doublereal *,
00055 doublereal *, integer *, doublereal *, integer *, integer *), dggbal_(char *, integer *, doublereal *, integer
00056 *, doublereal *, integer *, integer *, integer *, doublereal *,
00057 doublereal *, doublereal *, integer *);
00058 extern doublereal dlamch_(char *), dlange_(char *, integer *,
00059 integer *, doublereal *, integer *, doublereal *);
00060 extern int dgghrd_(char *, char *, integer *, integer *,
00061 integer *, doublereal *, integer *, doublereal *, integer *,
00062 doublereal *, integer *, doublereal *, integer *, integer *), dlascl_(char *, integer *, integer *, doublereal
00063 *, doublereal *, integer *, integer *, doublereal *, integer *,
00064 integer *);
00065 logical ilascl, ilbscl;
00066 extern int dgeqrf_(integer *, integer *, doublereal *,
00067 integer *, doublereal *, doublereal *, integer *, integer *),
00068 dlacpy_(char *, integer *, integer *, doublereal *, integer *,
00069 doublereal *, integer *), dlaset_(char *, integer *,
00070 integer *, doublereal *, doublereal *, doublereal *, integer *);
00071 logical ldumma[1];
00072 char chtemp[1];
00073 doublereal bignum;
00074 extern int dhgeqz_(char *, char *, char *, integer *,
00075 integer *, integer *, doublereal *, integer *, doublereal *,
00076 integer *, doublereal *, doublereal *, doublereal *, doublereal *,
00077 integer *, doublereal *, integer *, doublereal *, integer *,
00078 integer *), dtgevc_(char *, char *,
00079 logical *, integer *, doublereal *, integer *, doublereal *,
00080 integer *, doublereal *, integer *, doublereal *, integer *,
00081 integer *, integer *, doublereal *, integer *);
00082 integer ijobvl;
00083 extern int dtgsna_(char *, char *, logical *, integer *,
00084 doublereal *, integer *, doublereal *, integer *, doublereal *,
00085 integer *, doublereal *, integer *, doublereal *, doublereal *,
00086 integer *, integer *, doublereal *, integer *, integer *, integer
00087 *), xerbla_(char *, integer *);
00088 extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
00089 integer *, integer *);
00090 integer ijobvr;
00091 logical wantsb;
00092 extern int dorgqr_(integer *, integer *, integer *,
00093 doublereal *, integer *, doublereal *, doublereal *, integer *,
00094 integer *);
00095 doublereal anrmto;
00096 logical wantse;
00097 doublereal bnrmto;
00098 extern int dormqr_(char *, char *, integer *, integer *,
00099 integer *, doublereal *, integer *, doublereal *, doublereal *,
00100 integer *, doublereal *, integer *, integer *);
00101 integer minwrk, maxwrk;
00102 logical wantsn;
00103 doublereal 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
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 a_dim1 = *lda;
00375 a_offset = 1 + a_dim1;
00376 a -= a_offset;
00377 b_dim1 = *ldb;
00378 b_offset = 1 + b_dim1;
00379 b -= b_offset;
00380 --alphar;
00381 --alphai;
00382 --beta;
00383 vl_dim1 = *ldvl;
00384 vl_offset = 1 + vl_dim1;
00385 vl -= vl_offset;
00386 vr_dim1 = *ldvr;
00387 vr_offset = 1 + vr_dim1;
00388 vr -= vr_offset;
00389 --lscale;
00390 --rscale;
00391 --rconde;
00392 --rcondv;
00393 --work;
00394 --iwork;
00395 --bwork;
00396
00397
00398 if (lsame_(jobvl, "N")) {
00399 ijobvl = 1;
00400 ilvl = FALSE_;
00401 } else if (lsame_(jobvl, "V")) {
00402 ijobvl = 2;
00403 ilvl = TRUE_;
00404 } else {
00405 ijobvl = -1;
00406 ilvl = FALSE_;
00407 }
00408
00409 if (lsame_(jobvr, "N")) {
00410 ijobvr = 1;
00411 ilvr = FALSE_;
00412 } else if (lsame_(jobvr, "V")) {
00413 ijobvr = 2;
00414 ilvr = TRUE_;
00415 } else {
00416 ijobvr = -1;
00417 ilvr = FALSE_;
00418 }
00419 ilv = ilvl || ilvr;
00420
00421 noscl = lsame_(balanc, "N") || lsame_(balanc, "P");
00422 wantsn = lsame_(sense, "N");
00423 wantse = lsame_(sense, "E");
00424 wantsv = lsame_(sense, "V");
00425 wantsb = lsame_(sense, "B");
00426
00427
00428
00429 *info = 0;
00430 lquery = *lwork == -1;
00431 if (! (lsame_(balanc, "N") || lsame_(balanc, "S") || lsame_(balanc, "P")
00432 || lsame_(balanc, "B"))) {
00433 *info = -1;
00434 } else if (ijobvl <= 0) {
00435 *info = -2;
00436 } else if (ijobvr <= 0) {
00437 *info = -3;
00438 } else if (! (wantsn || wantse || wantsb || wantsv)) {
00439 *info = -4;
00440 } else if (*n < 0) {
00441 *info = -5;
00442 } else if (*lda < max(1,*n)) {
00443 *info = -7;
00444 } else if (*ldb < max(1,*n)) {
00445 *info = -9;
00446 } else if (*ldvl < 1 || ilvl && *ldvl < *n) {
00447 *info = -14;
00448 } else if (*ldvr < 1 || ilvr && *ldvr < *n) {
00449 *info = -16;
00450 }
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460 if (*info == 0) {
00461 if (*n == 0) {
00462 minwrk = 1;
00463 maxwrk = 1;
00464 } else {
00465 if (noscl && ! ilv) {
00466 minwrk = *n << 1;
00467 } else {
00468 minwrk = *n * 6;
00469 }
00470 if (wantse || wantsb) {
00471 minwrk = *n * 10;
00472 }
00473 if (wantsv || wantsb) {
00474
00475 i__1 = minwrk, i__2 = (*n << 1) * (*n + 4) + 16;
00476 minwrk = max(i__1,i__2);
00477 }
00478 maxwrk = minwrk;
00479
00480 i__1 = maxwrk, i__2 = *n + *n * ilaenv_(&c__1, "DGEQRF", " ", n, &
00481 c__1, n, &c__0);
00482 maxwrk = max(i__1,i__2);
00483
00484 i__1 = maxwrk, i__2 = *n + *n * ilaenv_(&c__1, "DORMQR", " ", n, &
00485 c__1, n, &c__0);
00486 maxwrk = max(i__1,i__2);
00487 if (ilvl) {
00488
00489 i__1 = maxwrk, i__2 = *n + *n * ilaenv_(&c__1, "DORGQR",
00490 " ", n, &c__1, n, &c__0);
00491 maxwrk = max(i__1,i__2);
00492 }
00493 }
00494 work[1] = (doublereal) maxwrk;
00495
00496 if (*lwork < minwrk && ! lquery) {
00497 *info = -26;
00498 }
00499 }
00500
00501 if (*info != 0) {
00502 i__1 = -(*info);
00503 xerbla_("DGGEVX", &i__1);
00504 return 0;
00505 } else if (lquery) {
00506 return 0;
00507 }
00508
00509
00510
00511 if (*n == 0) {
00512 return 0;
00513 }
00514
00515
00516
00517
00518 eps = dlamch_("P");
00519 smlnum = dlamch_("S");
00520 bignum = 1. / smlnum;
00521 dlabad_(&smlnum, &bignum);
00522 smlnum = sqrt(smlnum) / eps;
00523 bignum = 1. / smlnum;
00524
00525
00526
00527 anrm = dlange_("M", n, n, &a[a_offset], lda, &work[1]);
00528 ilascl = FALSE_;
00529 if (anrm > 0. && anrm < smlnum) {
00530 anrmto = smlnum;
00531 ilascl = TRUE_;
00532 } else if (anrm > bignum) {
00533 anrmto = bignum;
00534 ilascl = TRUE_;
00535 }
00536 if (ilascl) {
00537 dlascl_("G", &c__0, &c__0, &anrm, &anrmto, n, n, &a[a_offset], lda, &
00538 ierr);
00539 }
00540
00541
00542
00543 bnrm = dlange_("M", n, n, &b[b_offset], ldb, &work[1]);
00544 ilbscl = FALSE_;
00545 if (bnrm > 0. && bnrm < smlnum) {
00546 bnrmto = smlnum;
00547 ilbscl = TRUE_;
00548 } else if (bnrm > bignum) {
00549 bnrmto = bignum;
00550 ilbscl = TRUE_;
00551 }
00552 if (ilbscl) {
00553 dlascl_("G", &c__0, &c__0, &bnrm, &bnrmto, n, n, &b[b_offset], ldb, &
00554 ierr);
00555 }
00556
00557
00558
00559
00560 dggbal_(balanc, n, &a[a_offset], lda, &b[b_offset], ldb, ilo, ihi, &
00561 lscale[1], &rscale[1], &work[1], &ierr);
00562
00563
00564
00565 *abnrm = dlange_("1", n, n, &a[a_offset], lda, &work[1]);
00566 if (ilascl) {
00567 work[1] = *abnrm;
00568 dlascl_("G", &c__0, &c__0, &anrmto, &anrm, &c__1, &c__1, &work[1], &
00569 c__1, &ierr);
00570 *abnrm = work[1];
00571 }
00572
00573 *bbnrm = dlange_("1", n, n, &b[b_offset], ldb, &work[1]);
00574 if (ilbscl) {
00575 work[1] = *bbnrm;
00576 dlascl_("G", &c__0, &c__0, &bnrmto, &bnrm, &c__1, &c__1, &work[1], &
00577 c__1, &ierr);
00578 *bbnrm = work[1];
00579 }
00580
00581
00582
00583
00584 irows = *ihi + 1 - *ilo;
00585 if (ilv || ! wantsn) {
00586 icols = *n + 1 - *ilo;
00587 } else {
00588 icols = irows;
00589 }
00590 itau = 1;
00591 iwrk = itau + irows;
00592 i__1 = *lwork + 1 - iwrk;
00593 dgeqrf_(&irows, &icols, &b[*ilo + *ilo * b_dim1], ldb, &work[itau], &work[
00594 iwrk], &i__1, &ierr);
00595
00596
00597
00598
00599 i__1 = *lwork + 1 - iwrk;
00600 dormqr_("L", "T", &irows, &icols, &irows, &b[*ilo + *ilo * b_dim1], ldb, &
00601 work[itau], &a[*ilo + *ilo * a_dim1], lda, &work[iwrk], &i__1, &
00602 ierr);
00603
00604
00605
00606
00607 if (ilvl) {
00608 dlaset_("Full", n, n, &c_b59, &c_b60, &vl[vl_offset], ldvl)
00609 ;
00610 if (irows > 1) {
00611 i__1 = irows - 1;
00612 i__2 = irows - 1;
00613 dlacpy_("L", &i__1, &i__2, &b[*ilo + 1 + *ilo * b_dim1], ldb, &vl[
00614 *ilo + 1 + *ilo * vl_dim1], ldvl);
00615 }
00616 i__1 = *lwork + 1 - iwrk;
00617 dorgqr_(&irows, &irows, &irows, &vl[*ilo + *ilo * vl_dim1], ldvl, &
00618 work[itau], &work[iwrk], &i__1, &ierr);
00619 }
00620
00621 if (ilvr) {
00622 dlaset_("Full", n, n, &c_b59, &c_b60, &vr[vr_offset], ldvr)
00623 ;
00624 }
00625
00626
00627
00628
00629 if (ilv || ! wantsn) {
00630
00631
00632
00633 dgghrd_(jobvl, jobvr, n, ilo, ihi, &a[a_offset], lda, &b[b_offset],
00634 ldb, &vl[vl_offset], ldvl, &vr[vr_offset], ldvr, &ierr);
00635 } else {
00636 dgghrd_("N", "N", &irows, &c__1, &irows, &a[*ilo + *ilo * a_dim1],
00637 lda, &b[*ilo + *ilo * b_dim1], ldb, &vl[vl_offset], ldvl, &vr[
00638 vr_offset], ldvr, &ierr);
00639 }
00640
00641
00642
00643
00644
00645 if (ilv || ! wantsn) {
00646 *(unsigned char *)chtemp = 'S';
00647 } else {
00648 *(unsigned char *)chtemp = 'E';
00649 }
00650
00651 dhgeqz_(chtemp, jobvl, jobvr, n, ilo, ihi, &a[a_offset], lda, &b[b_offset]
00652 , ldb, &alphar[1], &alphai[1], &beta[1], &vl[vl_offset], ldvl, &
00653 vr[vr_offset], ldvr, &work[1], lwork, &ierr);
00654 if (ierr != 0) {
00655 if (ierr > 0 && ierr <= *n) {
00656 *info = ierr;
00657 } else if (ierr > *n && ierr <= *n << 1) {
00658 *info = ierr - *n;
00659 } else {
00660 *info = *n + 1;
00661 }
00662 goto L130;
00663 }
00664
00665
00666
00667
00668
00669
00670 if (ilv || ! wantsn) {
00671 if (ilv) {
00672 if (ilvl) {
00673 if (ilvr) {
00674 *(unsigned char *)chtemp = 'B';
00675 } else {
00676 *(unsigned char *)chtemp = 'L';
00677 }
00678 } else {
00679 *(unsigned char *)chtemp = 'R';
00680 }
00681
00682 dtgevc_(chtemp, "B", ldumma, n, &a[a_offset], lda, &b[b_offset],
00683 ldb, &vl[vl_offset], ldvl, &vr[vr_offset], ldvr, n, &in, &
00684 work[1], &ierr);
00685 if (ierr != 0) {
00686 *info = *n + 2;
00687 goto L130;
00688 }
00689 }
00690
00691 if (! wantsn) {
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701 pair = FALSE_;
00702 i__1 = *n;
00703 for (i__ = 1; i__ <= i__1; ++i__) {
00704
00705 if (pair) {
00706 pair = FALSE_;
00707 goto L20;
00708 }
00709 mm = 1;
00710 if (i__ < *n) {
00711 if (a[i__ + 1 + i__ * a_dim1] != 0.) {
00712 pair = TRUE_;
00713 mm = 2;
00714 }
00715 }
00716
00717 i__2 = *n;
00718 for (j = 1; j <= i__2; ++j) {
00719 bwork[j] = FALSE_;
00720
00721 }
00722 if (mm == 1) {
00723 bwork[i__] = TRUE_;
00724 } else if (mm == 2) {
00725 bwork[i__] = TRUE_;
00726 bwork[i__ + 1] = TRUE_;
00727 }
00728
00729 iwrk = mm * *n + 1;
00730 iwrk1 = iwrk + mm * *n;
00731
00732
00733
00734
00735 if (wantse || wantsb) {
00736 dtgevc_("B", "S", &bwork[1], n, &a[a_offset], lda, &b[
00737 b_offset], ldb, &work[1], n, &work[iwrk], n, &mm,
00738 &m, &work[iwrk1], &ierr);
00739 if (ierr != 0) {
00740 *info = *n + 2;
00741 goto L130;
00742 }
00743 }
00744
00745 i__2 = *lwork - iwrk1 + 1;
00746 dtgsna_(sense, "S", &bwork[1], n, &a[a_offset], lda, &b[
00747 b_offset], ldb, &work[1], n, &work[iwrk], n, &rconde[
00748 i__], &rcondv[i__], &mm, &m, &work[iwrk1], &i__2, &
00749 iwork[1], &ierr);
00750
00751 L20:
00752 ;
00753 }
00754 }
00755 }
00756
00757
00758
00759
00760 if (ilvl) {
00761 dggbak_(balanc, "L", n, ilo, ihi, &lscale[1], &rscale[1], n, &vl[
00762 vl_offset], ldvl, &ierr);
00763
00764 i__1 = *n;
00765 for (jc = 1; jc <= i__1; ++jc) {
00766 if (alphai[jc] < 0.) {
00767 goto L70;
00768 }
00769 temp = 0.;
00770 if (alphai[jc] == 0.) {
00771 i__2 = *n;
00772 for (jr = 1; jr <= i__2; ++jr) {
00773
00774 d__2 = temp, d__3 = (d__1 = vl[jr + jc * vl_dim1], abs(
00775 d__1));
00776 temp = max(d__2,d__3);
00777
00778 }
00779 } else {
00780 i__2 = *n;
00781 for (jr = 1; jr <= i__2; ++jr) {
00782
00783 d__3 = temp, d__4 = (d__1 = vl[jr + jc * vl_dim1], abs(
00784 d__1)) + (d__2 = vl[jr + (jc + 1) * vl_dim1], abs(
00785 d__2));
00786 temp = max(d__3,d__4);
00787
00788 }
00789 }
00790 if (temp < smlnum) {
00791 goto L70;
00792 }
00793 temp = 1. / temp;
00794 if (alphai[jc] == 0.) {
00795 i__2 = *n;
00796 for (jr = 1; jr <= i__2; ++jr) {
00797 vl[jr + jc * vl_dim1] *= temp;
00798
00799 }
00800 } else {
00801 i__2 = *n;
00802 for (jr = 1; jr <= i__2; ++jr) {
00803 vl[jr + jc * vl_dim1] *= temp;
00804 vl[jr + (jc + 1) * vl_dim1] *= temp;
00805
00806 }
00807 }
00808 L70:
00809 ;
00810 }
00811 }
00812 if (ilvr) {
00813 dggbak_(balanc, "R", n, ilo, ihi, &lscale[1], &rscale[1], n, &vr[
00814 vr_offset], ldvr, &ierr);
00815 i__1 = *n;
00816 for (jc = 1; jc <= i__1; ++jc) {
00817 if (alphai[jc] < 0.) {
00818 goto L120;
00819 }
00820 temp = 0.;
00821 if (alphai[jc] == 0.) {
00822 i__2 = *n;
00823 for (jr = 1; jr <= i__2; ++jr) {
00824
00825 d__2 = temp, d__3 = (d__1 = vr[jr + jc * vr_dim1], abs(
00826 d__1));
00827 temp = max(d__2,d__3);
00828
00829 }
00830 } else {
00831 i__2 = *n;
00832 for (jr = 1; jr <= i__2; ++jr) {
00833
00834 d__3 = temp, d__4 = (d__1 = vr[jr + jc * vr_dim1], abs(
00835 d__1)) + (d__2 = vr[jr + (jc + 1) * vr_dim1], abs(
00836 d__2));
00837 temp = max(d__3,d__4);
00838
00839 }
00840 }
00841 if (temp < smlnum) {
00842 goto L120;
00843 }
00844 temp = 1. / temp;
00845 if (alphai[jc] == 0.) {
00846 i__2 = *n;
00847 for (jr = 1; jr <= i__2; ++jr) {
00848 vr[jr + jc * vr_dim1] *= temp;
00849
00850 }
00851 } else {
00852 i__2 = *n;
00853 for (jr = 1; jr <= i__2; ++jr) {
00854 vr[jr + jc * vr_dim1] *= temp;
00855 vr[jr + (jc + 1) * vr_dim1] *= temp;
00856
00857 }
00858 }
00859 L120:
00860 ;
00861 }
00862 }
00863
00864
00865
00866 if (ilascl) {
00867 dlascl_("G", &c__0, &c__0, &anrmto, &anrm, n, &c__1, &alphar[1], n, &
00868 ierr);
00869 dlascl_("G", &c__0, &c__0, &anrmto, &anrm, n, &c__1, &alphai[1], n, &
00870 ierr);
00871 }
00872
00873 if (ilbscl) {
00874 dlascl_("G", &c__0, &c__0, &bnrmto, &bnrm, n, &c__1, &beta[1], n, &
00875 ierr);
00876 }
00877
00878 L130:
00879 work[1] = (doublereal) maxwrk;
00880
00881 return 0;
00882
00883
00884
00885 }