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__0 = 0;
00022 static integer c_n1 = -1;
00023
00024 int zggesx_(char *jobvsl, char *jobvsr, char *sort, L_fp
00025 selctg, char *sense, integer *n, doublecomplex *a, integer *lda,
00026 doublecomplex *b, integer *ldb, integer *sdim, doublecomplex *alpha,
00027 doublecomplex *beta, doublecomplex *vsl, integer *ldvsl,
00028 doublecomplex *vsr, integer *ldvsr, doublereal *rconde, doublereal *
00029 rcondv, doublecomplex *work, integer *lwork, doublereal *rwork,
00030 integer *iwork, integer *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
00036
00037 double sqrt(doublereal);
00038
00039
00040 integer i__;
00041 doublereal pl, pr, dif[2];
00042 integer ihi, ilo;
00043 doublereal eps;
00044 integer ijob;
00045 doublereal anrm, bnrm;
00046 integer ierr, itau, iwrk, lwrk;
00047 extern logical lsame_(char *, char *);
00048 integer ileft, icols;
00049 logical cursl, ilvsl, ilvsr;
00050 integer irwrk, irows;
00051 extern int dlabad_(doublereal *, doublereal *);
00052 extern doublereal dlamch_(char *);
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 logical ilascl, ilbscl;
00059 extern int xerbla_(char *, integer *);
00060 extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
00061 integer *, integer *);
00062 extern doublereal zlange_(char *, integer *, integer *, doublecomplex *,
00063 integer *, doublereal *);
00064 doublereal bignum;
00065 integer ijobvl, iright;
00066 extern int zgghrd_(char *, char *, integer *, integer *,
00067 integer *, doublecomplex *, integer *, doublecomplex *, integer *,
00068 doublecomplex *, integer *, doublecomplex *, integer *, integer *
00069 ), zlascl_(char *, integer *, integer *,
00070 doublereal *, doublereal *, integer *, integer *, doublecomplex *,
00071 integer *, integer *);
00072 integer ijobvr;
00073 logical wantsb;
00074 integer liwmin;
00075 logical wantse, lastsl;
00076 doublereal anrmto, bnrmto;
00077 extern int zgeqrf_(integer *, integer *, doublecomplex *,
00078 integer *, doublecomplex *, doublecomplex *, integer *, integer *
00079 );
00080 integer maxwrk;
00081 logical wantsn;
00082 integer minwrk;
00083 doublereal smlnum;
00084 extern int zhgeqz_(char *, char *, char *, integer *,
00085 integer *, integer *, doublecomplex *, integer *, doublecomplex *,
00086 integer *, doublecomplex *, doublecomplex *, doublecomplex *,
00087 integer *, doublecomplex *, integer *, doublecomplex *, integer *,
00088 doublereal *, integer *), zlacpy_(char *,
00089 integer *, integer *, doublecomplex *, integer *, doublecomplex *
00090 , integer *), zlaset_(char *, integer *, integer *,
00091 doublecomplex *, doublecomplex *, doublecomplex *, integer *);
00092 logical wantst, lquery, wantsv;
00093 extern int ztgsen_(integer *, logical *, logical *,
00094 logical *, integer *, doublecomplex *, integer *, doublecomplex *,
00095 integer *, doublecomplex *, doublecomplex *, doublecomplex *,
00096 integer *, doublecomplex *, integer *, integer *, doublereal *,
00097 doublereal *, doublereal *, doublecomplex *, integer *, integer *,
00098 integer *, integer *), zungqr_(integer *, integer *, integer *,
00099 doublecomplex *, integer *, doublecomplex *, doublecomplex *,
00100 integer *, integer *), zunmqr_(char *, char *, integer *, integer
00101 *, integer *, doublecomplex *, integer *, doublecomplex *,
00102 doublecomplex *, integer *, doublecomplex *, integer *, integer *);
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 a_dim1 = *lda;
00324 a_offset = 1 + a_dim1;
00325 a -= a_offset;
00326 b_dim1 = *ldb;
00327 b_offset = 1 + b_dim1;
00328 b -= b_offset;
00329 --alpha;
00330 --beta;
00331 vsl_dim1 = *ldvsl;
00332 vsl_offset = 1 + vsl_dim1;
00333 vsl -= vsl_offset;
00334 vsr_dim1 = *ldvsr;
00335 vsr_offset = 1 + vsr_dim1;
00336 vsr -= vsr_offset;
00337 --rconde;
00338 --rcondv;
00339 --work;
00340 --rwork;
00341 --iwork;
00342 --bwork;
00343
00344
00345 if (lsame_(jobvsl, "N")) {
00346 ijobvl = 1;
00347 ilvsl = FALSE_;
00348 } else if (lsame_(jobvsl, "V")) {
00349 ijobvl = 2;
00350 ilvsl = TRUE_;
00351 } else {
00352 ijobvl = -1;
00353 ilvsl = FALSE_;
00354 }
00355
00356 if (lsame_(jobvsr, "N")) {
00357 ijobvr = 1;
00358 ilvsr = FALSE_;
00359 } else if (lsame_(jobvsr, "V")) {
00360 ijobvr = 2;
00361 ilvsr = TRUE_;
00362 } else {
00363 ijobvr = -1;
00364 ilvsr = FALSE_;
00365 }
00366
00367 wantst = lsame_(sort, "S");
00368 wantsn = lsame_(sense, "N");
00369 wantse = lsame_(sense, "E");
00370 wantsv = lsame_(sense, "V");
00371 wantsb = lsame_(sense, "B");
00372 lquery = *lwork == -1 || *liwork == -1;
00373 if (wantsn) {
00374 ijob = 0;
00375 } else if (wantse) {
00376 ijob = 1;
00377 } else if (wantsv) {
00378 ijob = 2;
00379 } else if (wantsb) {
00380 ijob = 4;
00381 }
00382
00383
00384
00385 *info = 0;
00386 if (ijobvl <= 0) {
00387 *info = -1;
00388 } else if (ijobvr <= 0) {
00389 *info = -2;
00390 } else if (! wantst && ! lsame_(sort, "N")) {
00391 *info = -3;
00392 } else if (! (wantsn || wantse || wantsv || wantsb) || ! wantst && !
00393 wantsn) {
00394 *info = -5;
00395 } else if (*n < 0) {
00396 *info = -6;
00397 } else if (*lda < max(1,*n)) {
00398 *info = -8;
00399 } else if (*ldb < max(1,*n)) {
00400 *info = -10;
00401 } else if (*ldvsl < 1 || ilvsl && *ldvsl < *n) {
00402 *info = -15;
00403 } else if (*ldvsr < 1 || ilvsr && *ldvsr < *n) {
00404 *info = -17;
00405 }
00406
00407
00408
00409
00410
00411
00412
00413
00414 if (*info == 0) {
00415 if (*n > 0) {
00416 minwrk = *n << 1;
00417 maxwrk = *n * (ilaenv_(&c__1, "ZGEQRF", " ", n, &c__1, n, &c__0) + 1);
00418
00419 i__1 = maxwrk, i__2 = *n * (ilaenv_(&c__1, "ZUNMQR", " ", n, &
00420 c__1, n, &c_n1) + 1);
00421 maxwrk = max(i__1,i__2);
00422 if (ilvsl) {
00423
00424 i__1 = maxwrk, i__2 = *n * (ilaenv_(&c__1, "ZUNGQR", " ", n, &
00425 c__1, n, &c_n1) + 1);
00426 maxwrk = max(i__1,i__2);
00427 }
00428 lwrk = maxwrk;
00429 if (ijob >= 1) {
00430
00431 i__1 = lwrk, i__2 = *n * *n / 2;
00432 lwrk = max(i__1,i__2);
00433 }
00434 } else {
00435 minwrk = 1;
00436 maxwrk = 1;
00437 lwrk = 1;
00438 }
00439 work[1].r = (doublereal) lwrk, work[1].i = 0.;
00440 if (wantsn || *n == 0) {
00441 liwmin = 1;
00442 } else {
00443 liwmin = *n + 2;
00444 }
00445 iwork[1] = liwmin;
00446
00447 if (*lwork < minwrk && ! lquery) {
00448 *info = -21;
00449 } else if (*liwork < liwmin && ! lquery) {
00450 *info = -24;
00451 }
00452 }
00453
00454 if (*info != 0) {
00455 i__1 = -(*info);
00456 xerbla_("ZGGESX", &i__1);
00457 return 0;
00458 } else if (lquery) {
00459 return 0;
00460 }
00461
00462
00463
00464 if (*n == 0) {
00465 *sdim = 0;
00466 return 0;
00467 }
00468
00469
00470
00471 eps = dlamch_("P");
00472 smlnum = dlamch_("S");
00473 bignum = 1. / smlnum;
00474 dlabad_(&smlnum, &bignum);
00475 smlnum = sqrt(smlnum) / eps;
00476 bignum = 1. / smlnum;
00477
00478
00479
00480 anrm = zlange_("M", n, n, &a[a_offset], lda, &rwork[1]);
00481 ilascl = FALSE_;
00482 if (anrm > 0. && anrm < smlnum) {
00483 anrmto = smlnum;
00484 ilascl = TRUE_;
00485 } else if (anrm > bignum) {
00486 anrmto = bignum;
00487 ilascl = TRUE_;
00488 }
00489 if (ilascl) {
00490 zlascl_("G", &c__0, &c__0, &anrm, &anrmto, n, n, &a[a_offset], lda, &
00491 ierr);
00492 }
00493
00494
00495
00496 bnrm = zlange_("M", n, n, &b[b_offset], ldb, &rwork[1]);
00497 ilbscl = FALSE_;
00498 if (bnrm > 0. && bnrm < smlnum) {
00499 bnrmto = smlnum;
00500 ilbscl = TRUE_;
00501 } else if (bnrm > bignum) {
00502 bnrmto = bignum;
00503 ilbscl = TRUE_;
00504 }
00505 if (ilbscl) {
00506 zlascl_("G", &c__0, &c__0, &bnrm, &bnrmto, n, n, &b[b_offset], ldb, &
00507 ierr);
00508 }
00509
00510
00511
00512
00513 ileft = 1;
00514 iright = *n + 1;
00515 irwrk = iright + *n;
00516 zggbal_("P", n, &a[a_offset], lda, &b[b_offset], ldb, &ilo, &ihi, &rwork[
00517 ileft], &rwork[iright], &rwork[irwrk], &ierr);
00518
00519
00520
00521
00522 irows = ihi + 1 - ilo;
00523 icols = *n + 1 - ilo;
00524 itau = 1;
00525 iwrk = itau + irows;
00526 i__1 = *lwork + 1 - iwrk;
00527 zgeqrf_(&irows, &icols, &b[ilo + ilo * b_dim1], ldb, &work[itau], &work[
00528 iwrk], &i__1, &ierr);
00529
00530
00531
00532
00533 i__1 = *lwork + 1 - iwrk;
00534 zunmqr_("L", "C", &irows, &icols, &irows, &b[ilo + ilo * b_dim1], ldb, &
00535 work[itau], &a[ilo + ilo * a_dim1], lda, &work[iwrk], &i__1, &
00536 ierr);
00537
00538
00539
00540
00541 if (ilvsl) {
00542 zlaset_("Full", n, n, &c_b1, &c_b2, &vsl[vsl_offset], ldvsl);
00543 if (irows > 1) {
00544 i__1 = irows - 1;
00545 i__2 = irows - 1;
00546 zlacpy_("L", &i__1, &i__2, &b[ilo + 1 + ilo * b_dim1], ldb, &vsl[
00547 ilo + 1 + ilo * vsl_dim1], ldvsl);
00548 }
00549 i__1 = *lwork + 1 - iwrk;
00550 zungqr_(&irows, &irows, &irows, &vsl[ilo + ilo * vsl_dim1], ldvsl, &
00551 work[itau], &work[iwrk], &i__1, &ierr);
00552 }
00553
00554
00555
00556 if (ilvsr) {
00557 zlaset_("Full", n, n, &c_b1, &c_b2, &vsr[vsr_offset], ldvsr);
00558 }
00559
00560
00561
00562
00563 zgghrd_(jobvsl, jobvsr, n, &ilo, &ihi, &a[a_offset], lda, &b[b_offset],
00564 ldb, &vsl[vsl_offset], ldvsl, &vsr[vsr_offset], ldvsr, &ierr);
00565
00566 *sdim = 0;
00567
00568
00569
00570
00571
00572 iwrk = itau;
00573 i__1 = *lwork + 1 - iwrk;
00574 zhgeqz_("S", jobvsl, jobvsr, n, &ilo, &ihi, &a[a_offset], lda, &b[
00575 b_offset], ldb, &alpha[1], &beta[1], &vsl[vsl_offset], ldvsl, &
00576 vsr[vsr_offset], ldvsr, &work[iwrk], &i__1, &rwork[irwrk], &ierr);
00577 if (ierr != 0) {
00578 if (ierr > 0 && ierr <= *n) {
00579 *info = ierr;
00580 } else if (ierr > *n && ierr <= *n << 1) {
00581 *info = ierr - *n;
00582 } else {
00583 *info = *n + 1;
00584 }
00585 goto L40;
00586 }
00587
00588
00589
00590
00591 if (wantst) {
00592
00593
00594
00595 if (ilascl) {
00596 zlascl_("G", &c__0, &c__0, &anrmto, &anrm, n, &c__1, &alpha[1], n,
00597 &ierr);
00598 }
00599 if (ilbscl) {
00600 zlascl_("G", &c__0, &c__0, &bnrmto, &bnrm, n, &c__1, &beta[1], n,
00601 &ierr);
00602 }
00603
00604
00605
00606 i__1 = *n;
00607 for (i__ = 1; i__ <= i__1; ++i__) {
00608 bwork[i__] = (*selctg)(&alpha[i__], &beta[i__]);
00609
00610 }
00611
00612
00613
00614
00615
00616
00617 i__1 = *lwork - iwrk + 1;
00618 ztgsen_(&ijob, &ilvsl, &ilvsr, &bwork[1], n, &a[a_offset], lda, &b[
00619 b_offset], ldb, &alpha[1], &beta[1], &vsl[vsl_offset], ldvsl,
00620 &vsr[vsr_offset], ldvsr, sdim, &pl, &pr, dif, &work[iwrk], &
00621 i__1, &iwork[1], liwork, &ierr);
00622
00623 if (ijob >= 1) {
00624
00625 i__1 = maxwrk, i__2 = (*sdim << 1) * (*n - *sdim);
00626 maxwrk = max(i__1,i__2);
00627 }
00628 if (ierr == -21) {
00629
00630
00631
00632 *info = -21;
00633 } else {
00634 if (ijob == 1 || ijob == 4) {
00635 rconde[1] = pl;
00636 rconde[2] = pr;
00637 }
00638 if (ijob == 2 || ijob == 4) {
00639 rcondv[1] = dif[0];
00640 rcondv[2] = dif[1];
00641 }
00642 if (ierr == 1) {
00643 *info = *n + 3;
00644 }
00645 }
00646
00647 }
00648
00649
00650
00651
00652 if (ilvsl) {
00653 zggbak_("P", "L", n, &ilo, &ihi, &rwork[ileft], &rwork[iright], n, &
00654 vsl[vsl_offset], ldvsl, &ierr);
00655 }
00656
00657 if (ilvsr) {
00658 zggbak_("P", "R", n, &ilo, &ihi, &rwork[ileft], &rwork[iright], n, &
00659 vsr[vsr_offset], ldvsr, &ierr);
00660 }
00661
00662
00663
00664 if (ilascl) {
00665 zlascl_("U", &c__0, &c__0, &anrmto, &anrm, n, n, &a[a_offset], lda, &
00666 ierr);
00667 zlascl_("G", &c__0, &c__0, &anrmto, &anrm, n, &c__1, &alpha[1], n, &
00668 ierr);
00669 }
00670
00671 if (ilbscl) {
00672 zlascl_("U", &c__0, &c__0, &bnrmto, &bnrm, n, n, &b[b_offset], ldb, &
00673 ierr);
00674 zlascl_("G", &c__0, &c__0, &bnrmto, &bnrm, n, &c__1, &beta[1], n, &
00675 ierr);
00676 }
00677
00678 if (wantst) {
00679
00680
00681
00682 lastsl = TRUE_;
00683 *sdim = 0;
00684 i__1 = *n;
00685 for (i__ = 1; i__ <= i__1; ++i__) {
00686 cursl = (*selctg)(&alpha[i__], &beta[i__]);
00687 if (cursl) {
00688 ++(*sdim);
00689 }
00690 if (cursl && ! lastsl) {
00691 *info = *n + 2;
00692 }
00693 lastsl = cursl;
00694
00695 }
00696
00697 }
00698
00699 L40:
00700
00701 work[1].r = (doublereal) maxwrk, work[1].i = 0.;
00702 iwork[1] = liwmin;
00703
00704 return 0;
00705
00706
00707
00708 }