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