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