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