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 integer c_n1 = -1;
00021 static doublereal c_b42 = 0.;
00022 static doublereal c_b43 = 1.;
00023
00024 int dggesx_(char *jobvsl, char *jobvsr, char *sort, L_fp
00025 selctg, char *sense, integer *n, doublereal *a, integer *lda,
00026 doublereal *b, integer *ldb, integer *sdim, doublereal *alphar,
00027 doublereal *alphai, doublereal *beta, doublereal *vsl, integer *ldvsl,
00028 doublereal *vsr, integer *ldvsr, doublereal *rconde, doublereal *
00029 rcondv, doublereal *work, integer *lwork, integer *iwork, integer *
00030 liwork, logical *bwork, integer *info)
00031 {
00032
00033 integer a_dim1, a_offset, b_dim1, b_offset, vsl_dim1, vsl_offset,
00034 vsr_dim1, vsr_offset, i__1, i__2;
00035 doublereal d__1;
00036
00037
00038 double sqrt(doublereal);
00039
00040
00041 integer i__, ip;
00042 doublereal pl, pr, dif[2];
00043 integer ihi, ilo;
00044 doublereal eps;
00045 integer ijob;
00046 doublereal anrm, bnrm;
00047 integer ierr, itau, iwrk, lwrk;
00048 extern logical lsame_(char *, char *);
00049 integer ileft, icols;
00050 logical cursl, ilvsl, ilvsr;
00051 integer irows;
00052 extern int dlabad_(doublereal *, doublereal *), dggbak_(
00053 char *, char *, integer *, integer *, integer *, doublereal *,
00054 doublereal *, integer *, doublereal *, integer *, integer *), dggbal_(char *, integer *, doublereal *, integer
00055 *, doublereal *, integer *, integer *, integer *, doublereal *,
00056 doublereal *, doublereal *, integer *);
00057 logical lst2sl;
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 *);
00070 doublereal safmin;
00071 extern int dlaset_(char *, integer *, integer *,
00072 doublereal *, doublereal *, doublereal *, integer *);
00073 doublereal safmax;
00074 extern int xerbla_(char *, integer *);
00075 doublereal bignum;
00076 extern int dhgeqz_(char *, char *, char *, integer *,
00077 integer *, integer *, doublereal *, integer *, doublereal *,
00078 integer *, doublereal *, doublereal *, doublereal *, doublereal *,
00079 integer *, doublereal *, integer *, doublereal *, integer *,
00080 integer *);
00081 integer ijobvl, iright;
00082 extern int dtgsen_(integer *, logical *, logical *,
00083 logical *, integer *, doublereal *, integer *, doublereal *,
00084 integer *, doublereal *, doublereal *, doublereal *, doublereal *,
00085 integer *, doublereal *, integer *, integer *, doublereal *,
00086 doublereal *, doublereal *, doublereal *, integer *, integer *,
00087 integer *, integer *);
00088 extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
00089 integer *, integer *);
00090 integer ijobvr;
00091 logical wantsb;
00092 integer liwmin;
00093 logical wantse, lastsl;
00094 doublereal anrmto, bnrmto;
00095 extern int dorgqr_(integer *, integer *, integer *,
00096 doublereal *, integer *, doublereal *, doublereal *, integer *,
00097 integer *);
00098 integer minwrk, maxwrk;
00099 logical wantsn;
00100 doublereal smlnum;
00101 extern int dormqr_(char *, char *, integer *, integer *,
00102 integer *, doublereal *, integer *, doublereal *, doublereal *,
00103 integer *, doublereal *, integer *, integer *);
00104 logical wantst, 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 a_dim1 = *lda;
00357 a_offset = 1 + a_dim1;
00358 a -= a_offset;
00359 b_dim1 = *ldb;
00360 b_offset = 1 + b_dim1;
00361 b -= b_offset;
00362 --alphar;
00363 --alphai;
00364 --beta;
00365 vsl_dim1 = *ldvsl;
00366 vsl_offset = 1 + vsl_dim1;
00367 vsl -= vsl_offset;
00368 vsr_dim1 = *ldvsr;
00369 vsr_offset = 1 + vsr_dim1;
00370 vsr -= vsr_offset;
00371 --rconde;
00372 --rcondv;
00373 --work;
00374 --iwork;
00375 --bwork;
00376
00377
00378 if (lsame_(jobvsl, "N")) {
00379 ijobvl = 1;
00380 ilvsl = FALSE_;
00381 } else if (lsame_(jobvsl, "V")) {
00382 ijobvl = 2;
00383 ilvsl = TRUE_;
00384 } else {
00385 ijobvl = -1;
00386 ilvsl = FALSE_;
00387 }
00388
00389 if (lsame_(jobvsr, "N")) {
00390 ijobvr = 1;
00391 ilvsr = FALSE_;
00392 } else if (lsame_(jobvsr, "V")) {
00393 ijobvr = 2;
00394 ilvsr = TRUE_;
00395 } else {
00396 ijobvr = -1;
00397 ilvsr = FALSE_;
00398 }
00399
00400 wantst = lsame_(sort, "S");
00401 wantsn = lsame_(sense, "N");
00402 wantse = lsame_(sense, "E");
00403 wantsv = lsame_(sense, "V");
00404 wantsb = lsame_(sense, "B");
00405 lquery = *lwork == -1 || *liwork == -1;
00406 if (wantsn) {
00407 ijob = 0;
00408 } else if (wantse) {
00409 ijob = 1;
00410 } else if (wantsv) {
00411 ijob = 2;
00412 } else if (wantsb) {
00413 ijob = 4;
00414 }
00415
00416
00417
00418 *info = 0;
00419 if (ijobvl <= 0) {
00420 *info = -1;
00421 } else if (ijobvr <= 0) {
00422 *info = -2;
00423 } else if (! wantst && ! lsame_(sort, "N")) {
00424 *info = -3;
00425 } else if (! (wantsn || wantse || wantsv || wantsb) || ! wantst && !
00426 wantsn) {
00427 *info = -5;
00428 } else if (*n < 0) {
00429 *info = -6;
00430 } else if (*lda < max(1,*n)) {
00431 *info = -8;
00432 } else if (*ldb < max(1,*n)) {
00433 *info = -10;
00434 } else if (*ldvsl < 1 || ilvsl && *ldvsl < *n) {
00435 *info = -16;
00436 } else if (*ldvsr < 1 || ilvsr && *ldvsr < *n) {
00437 *info = -18;
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447 if (*info == 0) {
00448 if (*n > 0) {
00449
00450 i__1 = *n << 3, i__2 = *n * 6 + 16;
00451 minwrk = max(i__1,i__2);
00452 maxwrk = minwrk - *n + *n * ilaenv_(&c__1, "DGEQRF", " ", n, &
00453 c__1, n, &c__0);
00454
00455 i__1 = maxwrk, i__2 = minwrk - *n + *n * ilaenv_(&c__1, "DORMQR",
00456 " ", n, &c__1, n, &c_n1);
00457 maxwrk = max(i__1,i__2);
00458 if (ilvsl) {
00459
00460 i__1 = maxwrk, i__2 = minwrk - *n + *n * ilaenv_(&c__1, "DOR"
00461 "GQR", " ", n, &c__1, n, &c_n1);
00462 maxwrk = max(i__1,i__2);
00463 }
00464 lwrk = maxwrk;
00465 if (ijob >= 1) {
00466
00467 i__1 = lwrk, i__2 = *n * *n / 2;
00468 lwrk = max(i__1,i__2);
00469 }
00470 } else {
00471 minwrk = 1;
00472 maxwrk = 1;
00473 lwrk = 1;
00474 }
00475 work[1] = (doublereal) lwrk;
00476 if (wantsn || *n == 0) {
00477 liwmin = 1;
00478 } else {
00479 liwmin = *n + 6;
00480 }
00481 iwork[1] = liwmin;
00482
00483 if (*lwork < minwrk && ! lquery) {
00484 *info = -22;
00485 } else if (*liwork < liwmin && ! lquery) {
00486 *info = -24;
00487 }
00488 }
00489
00490 if (*info != 0) {
00491 i__1 = -(*info);
00492 xerbla_("DGGESX", &i__1);
00493 return 0;
00494 } else if (lquery) {
00495 return 0;
00496 }
00497
00498
00499
00500 if (*n == 0) {
00501 *sdim = 0;
00502 return 0;
00503 }
00504
00505
00506
00507 eps = dlamch_("P");
00508 safmin = dlamch_("S");
00509 safmax = 1. / safmin;
00510 dlabad_(&safmin, &safmax);
00511 smlnum = sqrt(safmin) / eps;
00512 bignum = 1. / smlnum;
00513
00514
00515
00516 anrm = dlange_("M", n, n, &a[a_offset], lda, &work[1]);
00517 ilascl = FALSE_;
00518 if (anrm > 0. && anrm < smlnum) {
00519 anrmto = smlnum;
00520 ilascl = TRUE_;
00521 } else if (anrm > bignum) {
00522 anrmto = bignum;
00523 ilascl = TRUE_;
00524 }
00525 if (ilascl) {
00526 dlascl_("G", &c__0, &c__0, &anrm, &anrmto, n, n, &a[a_offset], lda, &
00527 ierr);
00528 }
00529
00530
00531
00532 bnrm = dlange_("M", n, n, &b[b_offset], ldb, &work[1]);
00533 ilbscl = FALSE_;
00534 if (bnrm > 0. && bnrm < smlnum) {
00535 bnrmto = smlnum;
00536 ilbscl = TRUE_;
00537 } else if (bnrm > bignum) {
00538 bnrmto = bignum;
00539 ilbscl = TRUE_;
00540 }
00541 if (ilbscl) {
00542 dlascl_("G", &c__0, &c__0, &bnrm, &bnrmto, n, n, &b[b_offset], ldb, &
00543 ierr);
00544 }
00545
00546
00547
00548
00549 ileft = 1;
00550 iright = *n + 1;
00551 iwrk = iright + *n;
00552 dggbal_("P", n, &a[a_offset], lda, &b[b_offset], ldb, &ilo, &ihi, &work[
00553 ileft], &work[iright], &work[iwrk], &ierr);
00554
00555
00556
00557
00558 irows = ihi + 1 - ilo;
00559 icols = *n + 1 - ilo;
00560 itau = iwrk;
00561 iwrk = itau + irows;
00562 i__1 = *lwork + 1 - iwrk;
00563 dgeqrf_(&irows, &icols, &b[ilo + ilo * b_dim1], ldb, &work[itau], &work[
00564 iwrk], &i__1, &ierr);
00565
00566
00567
00568
00569 i__1 = *lwork + 1 - iwrk;
00570 dormqr_("L", "T", &irows, &icols, &irows, &b[ilo + ilo * b_dim1], ldb, &
00571 work[itau], &a[ilo + ilo * a_dim1], lda, &work[iwrk], &i__1, &
00572 ierr);
00573
00574
00575
00576
00577 if (ilvsl) {
00578 dlaset_("Full", n, n, &c_b42, &c_b43, &vsl[vsl_offset], ldvsl);
00579 if (irows > 1) {
00580 i__1 = irows - 1;
00581 i__2 = irows - 1;
00582 dlacpy_("L", &i__1, &i__2, &b[ilo + 1 + ilo * b_dim1], ldb, &vsl[
00583 ilo + 1 + ilo * vsl_dim1], ldvsl);
00584 }
00585 i__1 = *lwork + 1 - iwrk;
00586 dorgqr_(&irows, &irows, &irows, &vsl[ilo + ilo * vsl_dim1], ldvsl, &
00587 work[itau], &work[iwrk], &i__1, &ierr);
00588 }
00589
00590
00591
00592 if (ilvsr) {
00593 dlaset_("Full", n, n, &c_b42, &c_b43, &vsr[vsr_offset], ldvsr);
00594 }
00595
00596
00597
00598
00599 dgghrd_(jobvsl, jobvsr, n, &ilo, &ihi, &a[a_offset], lda, &b[b_offset],
00600 ldb, &vsl[vsl_offset], ldvsl, &vsr[vsr_offset], ldvsr, &ierr);
00601
00602 *sdim = 0;
00603
00604
00605
00606
00607 iwrk = itau;
00608 i__1 = *lwork + 1 - iwrk;
00609 dhgeqz_("S", jobvsl, jobvsr, n, &ilo, &ihi, &a[a_offset], lda, &b[
00610 b_offset], ldb, &alphar[1], &alphai[1], &beta[1], &vsl[vsl_offset]
00611 , ldvsl, &vsr[vsr_offset], ldvsr, &work[iwrk], &i__1, &ierr);
00612 if (ierr != 0) {
00613 if (ierr > 0 && ierr <= *n) {
00614 *info = ierr;
00615 } else if (ierr > *n && ierr <= *n << 1) {
00616 *info = ierr - *n;
00617 } else {
00618 *info = *n + 1;
00619 }
00620 goto L60;
00621 }
00622
00623
00624
00625
00626
00627
00628 if (wantst) {
00629
00630
00631
00632 if (ilascl) {
00633 dlascl_("G", &c__0, &c__0, &anrmto, &anrm, n, &c__1, &alphar[1],
00634 n, &ierr);
00635 dlascl_("G", &c__0, &c__0, &anrmto, &anrm, n, &c__1, &alphai[1],
00636 n, &ierr);
00637 }
00638 if (ilbscl) {
00639 dlascl_("G", &c__0, &c__0, &bnrmto, &bnrm, n, &c__1, &beta[1], n,
00640 &ierr);
00641 }
00642
00643
00644
00645 i__1 = *n;
00646 for (i__ = 1; i__ <= i__1; ++i__) {
00647 bwork[i__] = (*selctg)(&alphar[i__], &alphai[i__], &beta[i__]);
00648
00649 }
00650
00651
00652
00653
00654 i__1 = *lwork - iwrk + 1;
00655 dtgsen_(&ijob, &ilvsl, &ilvsr, &bwork[1], n, &a[a_offset], lda, &b[
00656 b_offset], ldb, &alphar[1], &alphai[1], &beta[1], &vsl[
00657 vsl_offset], ldvsl, &vsr[vsr_offset], ldvsr, sdim, &pl, &pr,
00658 dif, &work[iwrk], &i__1, &iwork[1], liwork, &ierr);
00659
00660 if (ijob >= 1) {
00661
00662 i__1 = maxwrk, i__2 = (*sdim << 1) * (*n - *sdim);
00663 maxwrk = max(i__1,i__2);
00664 }
00665 if (ierr == -22) {
00666
00667
00668
00669 *info = -22;
00670 } else {
00671 if (ijob == 1 || ijob == 4) {
00672 rconde[1] = pl;
00673 rconde[2] = pr;
00674 }
00675 if (ijob == 2 || ijob == 4) {
00676 rcondv[1] = dif[0];
00677 rcondv[2] = dif[1];
00678 }
00679 if (ierr == 1) {
00680 *info = *n + 3;
00681 }
00682 }
00683
00684 }
00685
00686
00687
00688
00689 if (ilvsl) {
00690 dggbak_("P", "L", n, &ilo, &ihi, &work[ileft], &work[iright], n, &vsl[
00691 vsl_offset], ldvsl, &ierr);
00692 }
00693
00694 if (ilvsr) {
00695 dggbak_("P", "R", n, &ilo, &ihi, &work[ileft], &work[iright], n, &vsr[
00696 vsr_offset], ldvsr, &ierr);
00697 }
00698
00699
00700
00701
00702
00703 if (ilascl) {
00704 i__1 = *n;
00705 for (i__ = 1; i__ <= i__1; ++i__) {
00706 if (alphai[i__] != 0.) {
00707 if (alphar[i__] / safmax > anrmto / anrm || safmin / alphar[
00708 i__] > anrm / anrmto) {
00709 work[1] = (d__1 = a[i__ + i__ * a_dim1] / alphar[i__],
00710 abs(d__1));
00711 beta[i__] *= work[1];
00712 alphar[i__] *= work[1];
00713 alphai[i__] *= work[1];
00714 } else if (alphai[i__] / safmax > anrmto / anrm || safmin /
00715 alphai[i__] > anrm / anrmto) {
00716 work[1] = (d__1 = a[i__ + (i__ + 1) * a_dim1] / alphai[
00717 i__], abs(d__1));
00718 beta[i__] *= work[1];
00719 alphar[i__] *= work[1];
00720 alphai[i__] *= work[1];
00721 }
00722 }
00723
00724 }
00725 }
00726
00727 if (ilbscl) {
00728 i__1 = *n;
00729 for (i__ = 1; i__ <= i__1; ++i__) {
00730 if (alphai[i__] != 0.) {
00731 if (beta[i__] / safmax > bnrmto / bnrm || safmin / beta[i__]
00732 > bnrm / bnrmto) {
00733 work[1] = (d__1 = b[i__ + i__ * b_dim1] / beta[i__], abs(
00734 d__1));
00735 beta[i__] *= work[1];
00736 alphar[i__] *= work[1];
00737 alphai[i__] *= work[1];
00738 }
00739 }
00740
00741 }
00742 }
00743
00744
00745
00746 if (ilascl) {
00747 dlascl_("H", &c__0, &c__0, &anrmto, &anrm, n, n, &a[a_offset], lda, &
00748 ierr);
00749 dlascl_("G", &c__0, &c__0, &anrmto, &anrm, n, &c__1, &alphar[1], n, &
00750 ierr);
00751 dlascl_("G", &c__0, &c__0, &anrmto, &anrm, n, &c__1, &alphai[1], n, &
00752 ierr);
00753 }
00754
00755 if (ilbscl) {
00756 dlascl_("U", &c__0, &c__0, &bnrmto, &bnrm, n, n, &b[b_offset], ldb, &
00757 ierr);
00758 dlascl_("G", &c__0, &c__0, &bnrmto, &bnrm, n, &c__1, &beta[1], n, &
00759 ierr);
00760 }
00761
00762 if (wantst) {
00763
00764
00765
00766 lastsl = TRUE_;
00767 lst2sl = TRUE_;
00768 *sdim = 0;
00769 ip = 0;
00770 i__1 = *n;
00771 for (i__ = 1; i__ <= i__1; ++i__) {
00772 cursl = (*selctg)(&alphar[i__], &alphai[i__], &beta[i__]);
00773 if (alphai[i__] == 0.) {
00774 if (cursl) {
00775 ++(*sdim);
00776 }
00777 ip = 0;
00778 if (cursl && ! lastsl) {
00779 *info = *n + 2;
00780 }
00781 } else {
00782 if (ip == 1) {
00783
00784
00785
00786 cursl = cursl || lastsl;
00787 lastsl = cursl;
00788 if (cursl) {
00789 *sdim += 2;
00790 }
00791 ip = -1;
00792 if (cursl && ! lst2sl) {
00793 *info = *n + 2;
00794 }
00795 } else {
00796
00797
00798
00799 ip = 1;
00800 }
00801 }
00802 lst2sl = lastsl;
00803 lastsl = cursl;
00804
00805 }
00806
00807 }
00808
00809 L60:
00810
00811 work[1] = (doublereal) maxwrk;
00812 iwork[1] = liwmin;
00813
00814 return 0;
00815
00816
00817
00818 }