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_n1 = -1;
00020 static real c_b27 = 1.f;
00021 static real c_b38 = 0.f;
00022
00023 int sgegv_(char *jobvl, char *jobvr, integer *n, real *a,
00024 integer *lda, real *b, integer *ldb, real *alphar, real *alphai, real
00025 *beta, real *vl, integer *ldvl, real *vr, integer *ldvr, real *work,
00026 integer *lwork, integer *info)
00027 {
00028
00029 integer a_dim1, a_offset, b_dim1, b_offset, vl_dim1, vl_offset, vr_dim1,
00030 vr_offset, i__1, i__2;
00031 real r__1, r__2, r__3, r__4;
00032
00033
00034 integer jc, nb, in, jr, nb1, nb2, nb3, ihi, ilo;
00035 real eps;
00036 logical ilv;
00037 real absb, anrm, bnrm;
00038 integer itau;
00039 real temp;
00040 logical ilvl, ilvr;
00041 integer lopt;
00042 real anrm1, anrm2, bnrm1, bnrm2, absai, scale, absar, sbeta;
00043 extern logical lsame_(char *, char *);
00044 integer ileft, iinfo, icols, iwork, irows;
00045 real salfai;
00046 extern int sggbak_(char *, char *, integer *, integer *,
00047 integer *, real *, real *, integer *, real *, integer *, integer *
00048 ), sggbal_(char *, integer *, real *, integer *,
00049 real *, integer *, integer *, integer *, real *, real *, real *,
00050 integer *);
00051 real salfar;
00052 extern doublereal slamch_(char *), slange_(char *, integer *,
00053 integer *, real *, integer *, real *);
00054 real safmin;
00055 extern int sgghrd_(char *, char *, integer *, integer *,
00056 integer *, real *, integer *, real *, integer *, real *, integer *
00057 , real *, integer *, integer *);
00058 real safmax;
00059 char chtemp[1];
00060 logical ldumma[1];
00061 extern int slascl_(char *, integer *, integer *, real *,
00062 real *, integer *, integer *, real *, integer *, integer *), xerbla_(char *, integer *);
00063 extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
00064 integer *, integer *);
00065 integer ijobvl, iright;
00066 logical ilimit;
00067 extern int sgeqrf_(integer *, integer *, real *, integer
00068 *, real *, real *, integer *, integer *);
00069 integer ijobvr;
00070 extern int slacpy_(char *, integer *, integer *, real *,
00071 integer *, real *, integer *), slaset_(char *, integer *,
00072 integer *, real *, real *, real *, integer *), stgevc_(
00073 char *, char *, logical *, integer *, real *, integer *, real *,
00074 integer *, real *, integer *, real *, integer *, integer *,
00075 integer *, real *, integer *);
00076 real onepls;
00077 integer lwkmin;
00078 extern int shgeqz_(char *, char *, char *, integer *,
00079 integer *, integer *, real *, integer *, real *, integer *, real *
00080 , real *, real *, real *, integer *, real *, integer *, real *,
00081 integer *, integer *), sorgqr_(integer *,
00082 integer *, integer *, real *, integer *, real *, real *, integer *
00083 , integer *);
00084 integer lwkopt;
00085 logical lquery;
00086 extern int sormqr_(char *, char *, integer *, integer *,
00087 integer *, real *, integer *, real *, real *, integer *, real *,
00088 integer *, integer *);
00089
00090
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
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 a_dim1 = *lda;
00322 a_offset = 1 + a_dim1;
00323 a -= a_offset;
00324 b_dim1 = *ldb;
00325 b_offset = 1 + b_dim1;
00326 b -= b_offset;
00327 --alphar;
00328 --alphai;
00329 --beta;
00330 vl_dim1 = *ldvl;
00331 vl_offset = 1 + vl_dim1;
00332 vl -= vl_offset;
00333 vr_dim1 = *ldvr;
00334 vr_offset = 1 + vr_dim1;
00335 vr -= vr_offset;
00336 --work;
00337
00338
00339 if (lsame_(jobvl, "N")) {
00340 ijobvl = 1;
00341 ilvl = FALSE_;
00342 } else if (lsame_(jobvl, "V")) {
00343 ijobvl = 2;
00344 ilvl = TRUE_;
00345 } else {
00346 ijobvl = -1;
00347 ilvl = FALSE_;
00348 }
00349
00350 if (lsame_(jobvr, "N")) {
00351 ijobvr = 1;
00352 ilvr = FALSE_;
00353 } else if (lsame_(jobvr, "V")) {
00354 ijobvr = 2;
00355 ilvr = TRUE_;
00356 } else {
00357 ijobvr = -1;
00358 ilvr = FALSE_;
00359 }
00360 ilv = ilvl || ilvr;
00361
00362
00363
00364
00365 i__1 = *n << 3;
00366 lwkmin = max(i__1,1);
00367 lwkopt = lwkmin;
00368 work[1] = (real) lwkopt;
00369 lquery = *lwork == -1;
00370 *info = 0;
00371 if (ijobvl <= 0) {
00372 *info = -1;
00373 } else if (ijobvr <= 0) {
00374 *info = -2;
00375 } else if (*n < 0) {
00376 *info = -3;
00377 } else if (*lda < max(1,*n)) {
00378 *info = -5;
00379 } else if (*ldb < max(1,*n)) {
00380 *info = -7;
00381 } else if (*ldvl < 1 || ilvl && *ldvl < *n) {
00382 *info = -12;
00383 } else if (*ldvr < 1 || ilvr && *ldvr < *n) {
00384 *info = -14;
00385 } else if (*lwork < lwkmin && ! lquery) {
00386 *info = -16;
00387 }
00388
00389 if (*info == 0) {
00390 nb1 = ilaenv_(&c__1, "SGEQRF", " ", n, n, &c_n1, &c_n1);
00391 nb2 = ilaenv_(&c__1, "SORMQR", " ", n, n, n, &c_n1);
00392 nb3 = ilaenv_(&c__1, "SORGQR", " ", n, n, n, &c_n1);
00393
00394 i__1 = max(nb1,nb2);
00395 nb = max(i__1,nb3);
00396
00397 i__1 = *n * 6, i__2 = *n * (nb + 1);
00398 lopt = (*n << 1) + max(i__1,i__2);
00399 work[1] = (real) lopt;
00400 }
00401
00402 if (*info != 0) {
00403 i__1 = -(*info);
00404 xerbla_("SGEGV ", &i__1);
00405 return 0;
00406 } else if (lquery) {
00407 return 0;
00408 }
00409
00410
00411
00412 if (*n == 0) {
00413 return 0;
00414 }
00415
00416
00417
00418 eps = slamch_("E") * slamch_("B");
00419 safmin = slamch_("S");
00420 safmin += safmin;
00421 safmax = 1.f / safmin;
00422 onepls = eps * 4 + 1.f;
00423
00424
00425
00426 anrm = slange_("M", n, n, &a[a_offset], lda, &work[1]);
00427 anrm1 = anrm;
00428 anrm2 = 1.f;
00429 if (anrm < 1.f) {
00430 if (safmax * anrm < 1.f) {
00431 anrm1 = safmin;
00432 anrm2 = safmax * anrm;
00433 }
00434 }
00435
00436 if (anrm > 0.f) {
00437 slascl_("G", &c_n1, &c_n1, &anrm, &c_b27, n, n, &a[a_offset], lda, &
00438 iinfo);
00439 if (iinfo != 0) {
00440 *info = *n + 10;
00441 return 0;
00442 }
00443 }
00444
00445
00446
00447 bnrm = slange_("M", n, n, &b[b_offset], ldb, &work[1]);
00448 bnrm1 = bnrm;
00449 bnrm2 = 1.f;
00450 if (bnrm < 1.f) {
00451 if (safmax * bnrm < 1.f) {
00452 bnrm1 = safmin;
00453 bnrm2 = safmax * bnrm;
00454 }
00455 }
00456
00457 if (bnrm > 0.f) {
00458 slascl_("G", &c_n1, &c_n1, &bnrm, &c_b27, n, n, &b[b_offset], ldb, &
00459 iinfo);
00460 if (iinfo != 0) {
00461 *info = *n + 10;
00462 return 0;
00463 }
00464 }
00465
00466
00467
00468
00469
00470 ileft = 1;
00471 iright = *n + 1;
00472 iwork = iright + *n;
00473 sggbal_("P", n, &a[a_offset], lda, &b[b_offset], ldb, &ilo, &ihi, &work[
00474 ileft], &work[iright], &work[iwork], &iinfo);
00475 if (iinfo != 0) {
00476 *info = *n + 1;
00477 goto L120;
00478 }
00479
00480
00481
00482
00483
00484 irows = ihi + 1 - ilo;
00485 if (ilv) {
00486 icols = *n + 1 - ilo;
00487 } else {
00488 icols = irows;
00489 }
00490 itau = iwork;
00491 iwork = itau + irows;
00492 i__1 = *lwork + 1 - iwork;
00493 sgeqrf_(&irows, &icols, &b[ilo + ilo * b_dim1], ldb, &work[itau], &work[
00494 iwork], &i__1, &iinfo);
00495 if (iinfo >= 0) {
00496
00497 i__1 = lwkopt, i__2 = (integer) work[iwork] + iwork - 1;
00498 lwkopt = max(i__1,i__2);
00499 }
00500 if (iinfo != 0) {
00501 *info = *n + 2;
00502 goto L120;
00503 }
00504
00505 i__1 = *lwork + 1 - iwork;
00506 sormqr_("L", "T", &irows, &icols, &irows, &b[ilo + ilo * b_dim1], ldb, &
00507 work[itau], &a[ilo + ilo * a_dim1], lda, &work[iwork], &i__1, &
00508 iinfo);
00509 if (iinfo >= 0) {
00510
00511 i__1 = lwkopt, i__2 = (integer) work[iwork] + iwork - 1;
00512 lwkopt = max(i__1,i__2);
00513 }
00514 if (iinfo != 0) {
00515 *info = *n + 3;
00516 goto L120;
00517 }
00518
00519 if (ilvl) {
00520 slaset_("Full", n, n, &c_b38, &c_b27, &vl[vl_offset], ldvl)
00521 ;
00522 i__1 = irows - 1;
00523 i__2 = irows - 1;
00524 slacpy_("L", &i__1, &i__2, &b[ilo + 1 + ilo * b_dim1], ldb, &vl[ilo +
00525 1 + ilo * vl_dim1], ldvl);
00526 i__1 = *lwork + 1 - iwork;
00527 sorgqr_(&irows, &irows, &irows, &vl[ilo + ilo * vl_dim1], ldvl, &work[
00528 itau], &work[iwork], &i__1, &iinfo);
00529 if (iinfo >= 0) {
00530
00531 i__1 = lwkopt, i__2 = (integer) work[iwork] + iwork - 1;
00532 lwkopt = max(i__1,i__2);
00533 }
00534 if (iinfo != 0) {
00535 *info = *n + 4;
00536 goto L120;
00537 }
00538 }
00539
00540 if (ilvr) {
00541 slaset_("Full", n, n, &c_b38, &c_b27, &vr[vr_offset], ldvr)
00542 ;
00543 }
00544
00545
00546
00547 if (ilv) {
00548
00549
00550
00551 sgghrd_(jobvl, jobvr, n, &ilo, &ihi, &a[a_offset], lda, &b[b_offset],
00552 ldb, &vl[vl_offset], ldvl, &vr[vr_offset], ldvr, &iinfo);
00553 } else {
00554 sgghrd_("N", "N", &irows, &c__1, &irows, &a[ilo + ilo * a_dim1], lda,
00555 &b[ilo + ilo * b_dim1], ldb, &vl[vl_offset], ldvl, &vr[
00556 vr_offset], ldvr, &iinfo);
00557 }
00558 if (iinfo != 0) {
00559 *info = *n + 5;
00560 goto L120;
00561 }
00562
00563
00564
00565
00566
00567 iwork = itau;
00568 if (ilv) {
00569 *(unsigned char *)chtemp = 'S';
00570 } else {
00571 *(unsigned char *)chtemp = 'E';
00572 }
00573 i__1 = *lwork + 1 - iwork;
00574 shgeqz_(chtemp, jobvl, jobvr, n, &ilo, &ihi, &a[a_offset], lda, &b[
00575 b_offset], ldb, &alphar[1], &alphai[1], &beta[1], &vl[vl_offset],
00576 ldvl, &vr[vr_offset], ldvr, &work[iwork], &i__1, &iinfo);
00577 if (iinfo >= 0) {
00578
00579 i__1 = lwkopt, i__2 = (integer) work[iwork] + iwork - 1;
00580 lwkopt = max(i__1,i__2);
00581 }
00582 if (iinfo != 0) {
00583 if (iinfo > 0 && iinfo <= *n) {
00584 *info = iinfo;
00585 } else if (iinfo > *n && iinfo <= *n << 1) {
00586 *info = iinfo - *n;
00587 } else {
00588 *info = *n + 6;
00589 }
00590 goto L120;
00591 }
00592
00593 if (ilv) {
00594
00595
00596
00597 if (ilvl) {
00598 if (ilvr) {
00599 *(unsigned char *)chtemp = 'B';
00600 } else {
00601 *(unsigned char *)chtemp = 'L';
00602 }
00603 } else {
00604 *(unsigned char *)chtemp = 'R';
00605 }
00606
00607 stgevc_(chtemp, "B", ldumma, n, &a[a_offset], lda, &b[b_offset], ldb,
00608 &vl[vl_offset], ldvl, &vr[vr_offset], ldvr, n, &in, &work[
00609 iwork], &iinfo);
00610 if (iinfo != 0) {
00611 *info = *n + 7;
00612 goto L120;
00613 }
00614
00615
00616
00617 if (ilvl) {
00618 sggbak_("P", "L", n, &ilo, &ihi, &work[ileft], &work[iright], n, &
00619 vl[vl_offset], ldvl, &iinfo);
00620 if (iinfo != 0) {
00621 *info = *n + 8;
00622 goto L120;
00623 }
00624 i__1 = *n;
00625 for (jc = 1; jc <= i__1; ++jc) {
00626 if (alphai[jc] < 0.f) {
00627 goto L50;
00628 }
00629 temp = 0.f;
00630 if (alphai[jc] == 0.f) {
00631 i__2 = *n;
00632 for (jr = 1; jr <= i__2; ++jr) {
00633
00634 r__2 = temp, r__3 = (r__1 = vl[jr + jc * vl_dim1],
00635 dabs(r__1));
00636 temp = dmax(r__2,r__3);
00637
00638 }
00639 } else {
00640 i__2 = *n;
00641 for (jr = 1; jr <= i__2; ++jr) {
00642
00643 r__3 = temp, r__4 = (r__1 = vl[jr + jc * vl_dim1],
00644 dabs(r__1)) + (r__2 = vl[jr + (jc + 1) *
00645 vl_dim1], dabs(r__2));
00646 temp = dmax(r__3,r__4);
00647
00648 }
00649 }
00650 if (temp < safmin) {
00651 goto L50;
00652 }
00653 temp = 1.f / temp;
00654 if (alphai[jc] == 0.f) {
00655 i__2 = *n;
00656 for (jr = 1; jr <= i__2; ++jr) {
00657 vl[jr + jc * vl_dim1] *= temp;
00658
00659 }
00660 } else {
00661 i__2 = *n;
00662 for (jr = 1; jr <= i__2; ++jr) {
00663 vl[jr + jc * vl_dim1] *= temp;
00664 vl[jr + (jc + 1) * vl_dim1] *= temp;
00665
00666 }
00667 }
00668 L50:
00669 ;
00670 }
00671 }
00672 if (ilvr) {
00673 sggbak_("P", "R", n, &ilo, &ihi, &work[ileft], &work[iright], n, &
00674 vr[vr_offset], ldvr, &iinfo);
00675 if (iinfo != 0) {
00676 *info = *n + 9;
00677 goto L120;
00678 }
00679 i__1 = *n;
00680 for (jc = 1; jc <= i__1; ++jc) {
00681 if (alphai[jc] < 0.f) {
00682 goto L100;
00683 }
00684 temp = 0.f;
00685 if (alphai[jc] == 0.f) {
00686 i__2 = *n;
00687 for (jr = 1; jr <= i__2; ++jr) {
00688
00689 r__2 = temp, r__3 = (r__1 = vr[jr + jc * vr_dim1],
00690 dabs(r__1));
00691 temp = dmax(r__2,r__3);
00692
00693 }
00694 } else {
00695 i__2 = *n;
00696 for (jr = 1; jr <= i__2; ++jr) {
00697
00698 r__3 = temp, r__4 = (r__1 = vr[jr + jc * vr_dim1],
00699 dabs(r__1)) + (r__2 = vr[jr + (jc + 1) *
00700 vr_dim1], dabs(r__2));
00701 temp = dmax(r__3,r__4);
00702
00703 }
00704 }
00705 if (temp < safmin) {
00706 goto L100;
00707 }
00708 temp = 1.f / temp;
00709 if (alphai[jc] == 0.f) {
00710 i__2 = *n;
00711 for (jr = 1; jr <= i__2; ++jr) {
00712 vr[jr + jc * vr_dim1] *= temp;
00713
00714 }
00715 } else {
00716 i__2 = *n;
00717 for (jr = 1; jr <= i__2; ++jr) {
00718 vr[jr + jc * vr_dim1] *= temp;
00719 vr[jr + (jc + 1) * vr_dim1] *= temp;
00720
00721 }
00722 }
00723 L100:
00724 ;
00725 }
00726 }
00727
00728
00729
00730 }
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740 i__1 = *n;
00741 for (jc = 1; jc <= i__1; ++jc) {
00742 absar = (r__1 = alphar[jc], dabs(r__1));
00743 absai = (r__1 = alphai[jc], dabs(r__1));
00744 absb = (r__1 = beta[jc], dabs(r__1));
00745 salfar = anrm * alphar[jc];
00746 salfai = anrm * alphai[jc];
00747 sbeta = bnrm * beta[jc];
00748 ilimit = FALSE_;
00749 scale = 1.f;
00750
00751
00752
00753
00754 r__1 = safmin, r__2 = eps * absar, r__1 = max(r__1,r__2), r__2 = eps *
00755 absb;
00756 if (dabs(salfai) < safmin && absai >= dmax(r__1,r__2)) {
00757 ilimit = TRUE_;
00758
00759 r__1 = onepls * safmin, r__2 = anrm2 * absai;
00760 scale = onepls * safmin / anrm1 / dmax(r__1,r__2);
00761
00762 } else if (salfai == 0.f) {
00763
00764
00765
00766
00767 if (alphai[jc] < 0.f && jc > 1) {
00768 alphai[jc - 1] = 0.f;
00769 } else if (alphai[jc] > 0.f && jc < *n) {
00770 alphai[jc + 1] = 0.f;
00771 }
00772 }
00773
00774
00775
00776
00777 r__1 = safmin, r__2 = eps * absai, r__1 = max(r__1,r__2), r__2 = eps *
00778 absb;
00779 if (dabs(salfar) < safmin && absar >= dmax(r__1,r__2)) {
00780 ilimit = TRUE_;
00781
00782
00783 r__3 = onepls * safmin, r__4 = anrm2 * absar;
00784 r__1 = scale, r__2 = onepls * safmin / anrm1 / dmax(r__3,r__4);
00785 scale = dmax(r__1,r__2);
00786 }
00787
00788
00789
00790
00791 r__1 = safmin, r__2 = eps * absar, r__1 = max(r__1,r__2), r__2 = eps *
00792 absai;
00793 if (dabs(sbeta) < safmin && absb >= dmax(r__1,r__2)) {
00794 ilimit = TRUE_;
00795
00796
00797 r__3 = onepls * safmin, r__4 = bnrm2 * absb;
00798 r__1 = scale, r__2 = onepls * safmin / bnrm1 / dmax(r__3,r__4);
00799 scale = dmax(r__1,r__2);
00800 }
00801
00802
00803
00804 if (ilimit) {
00805
00806 r__1 = dabs(salfar), r__2 = dabs(salfai), r__1 = max(r__1,r__2),
00807 r__2 = dabs(sbeta);
00808 temp = scale * safmin * dmax(r__1,r__2);
00809 if (temp > 1.f) {
00810 scale /= temp;
00811 }
00812 if (scale < 1.f) {
00813 ilimit = FALSE_;
00814 }
00815 }
00816
00817
00818
00819 if (ilimit) {
00820 salfar = scale * alphar[jc] * anrm;
00821 salfai = scale * alphai[jc] * anrm;
00822 sbeta = scale * beta[jc] * bnrm;
00823 }
00824 alphar[jc] = salfar;
00825 alphai[jc] = salfai;
00826 beta[jc] = sbeta;
00827
00828 }
00829
00830 L120:
00831 work[1] = (real) lwkopt;
00832
00833 return 0;
00834
00835
00836
00837 }