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