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