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