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 zgges_(char *jobvsl, char *jobvsr, char *sort, L_fp
00025 selctg, integer *n, doublecomplex *a, integer *lda, doublecomplex *b,
00026 integer *ldb, integer *sdim, doublecomplex *alpha, doublecomplex *
00027 beta, doublecomplex *vsl, integer *ldvsl, doublecomplex *vsr, integer
00028 *ldvsr, doublecomplex *work, integer *lwork, doublereal *rwork,
00029 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 doublereal dif[2];
00041 integer ihi, ilo;
00042 doublereal eps, anrm, bnrm;
00043 integer idum[1], ierr, itau, iwrk;
00044 doublereal pvsl, pvsr;
00045 extern logical lsame_(char *, char *);
00046 integer ileft, icols;
00047 logical cursl, ilvsl, ilvsr;
00048 integer irwrk, irows;
00049 extern int dlabad_(doublereal *, doublereal *);
00050 extern doublereal dlamch_(char *);
00051 extern int zggbak_(char *, char *, integer *, integer *,
00052 integer *, doublereal *, doublereal *, integer *, doublecomplex *,
00053 integer *, integer *), zggbal_(char *, integer *,
00054 doublecomplex *, integer *, doublecomplex *, integer *, integer *
00055 , integer *, doublereal *, doublereal *, doublereal *, integer *);
00056 logical ilascl, ilbscl;
00057 extern int xerbla_(char *, integer *);
00058 extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
00059 integer *, integer *);
00060 extern doublereal zlange_(char *, integer *, integer *, doublecomplex *,
00061 integer *, doublereal *);
00062 doublereal bignum;
00063 integer ijobvl, iright;
00064 extern int zgghrd_(char *, char *, integer *, integer *,
00065 integer *, doublecomplex *, integer *, doublecomplex *, integer *,
00066 doublecomplex *, integer *, doublecomplex *, integer *, integer *
00067 ), zlascl_(char *, integer *, integer *,
00068 doublereal *, doublereal *, integer *, integer *, doublecomplex *,
00069 integer *, integer *);
00070 integer ijobvr;
00071 extern int zgeqrf_(integer *, integer *, doublecomplex *,
00072 integer *, doublecomplex *, doublecomplex *, integer *, integer *
00073 );
00074 doublereal anrmto;
00075 integer lwkmin;
00076 logical lastsl;
00077 doublereal bnrmto;
00078 extern int zlacpy_(char *, integer *, integer *,
00079 doublecomplex *, integer *, doublecomplex *, integer *),
00080 zlaset_(char *, integer *, integer *, doublecomplex *,
00081 doublecomplex *, doublecomplex *, integer *), zhgeqz_(
00082 char *, char *, char *, integer *, integer *, integer *,
00083 doublecomplex *, integer *, doublecomplex *, integer *,
00084 doublecomplex *, doublecomplex *, doublecomplex *, integer *,
00085 doublecomplex *, integer *, doublecomplex *, integer *,
00086 doublereal *, integer *), ztgsen_(integer
00087 *, logical *, logical *, logical *, integer *, doublecomplex *,
00088 integer *, doublecomplex *, integer *, doublecomplex *,
00089 doublecomplex *, doublecomplex *, integer *, doublecomplex *,
00090 integer *, integer *, doublereal *, doublereal *, doublereal *,
00091 doublecomplex *, integer *, integer *, integer *, integer *);
00092 doublereal smlnum;
00093 logical wantst, lquery;
00094 integer lwkopt;
00095 extern int zungqr_(integer *, integer *, integer *,
00096 doublecomplex *, integer *, doublecomplex *, doublecomplex *,
00097 integer *, integer *), zunmqr_(char *, char *, integer *, integer
00098 *, integer *, doublecomplex *, integer *, doublecomplex *,
00099 doublecomplex *, integer *, doublecomplex *, integer *, integer *);
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 a_dim1 = *lda;
00280 a_offset = 1 + a_dim1;
00281 a -= a_offset;
00282 b_dim1 = *ldb;
00283 b_offset = 1 + b_dim1;
00284 b -= b_offset;
00285 --alpha;
00286 --beta;
00287 vsl_dim1 = *ldvsl;
00288 vsl_offset = 1 + vsl_dim1;
00289 vsl -= vsl_offset;
00290 vsr_dim1 = *ldvsr;
00291 vsr_offset = 1 + vsr_dim1;
00292 vsr -= vsr_offset;
00293 --work;
00294 --rwork;
00295 --bwork;
00296
00297
00298 if (lsame_(jobvsl, "N")) {
00299 ijobvl = 1;
00300 ilvsl = FALSE_;
00301 } else if (lsame_(jobvsl, "V")) {
00302 ijobvl = 2;
00303 ilvsl = TRUE_;
00304 } else {
00305 ijobvl = -1;
00306 ilvsl = FALSE_;
00307 }
00308
00309 if (lsame_(jobvsr, "N")) {
00310 ijobvr = 1;
00311 ilvsr = FALSE_;
00312 } else if (lsame_(jobvsr, "V")) {
00313 ijobvr = 2;
00314 ilvsr = TRUE_;
00315 } else {
00316 ijobvr = -1;
00317 ilvsr = FALSE_;
00318 }
00319
00320 wantst = lsame_(sort, "S");
00321
00322
00323
00324 *info = 0;
00325 lquery = *lwork == -1;
00326 if (ijobvl <= 0) {
00327 *info = -1;
00328 } else if (ijobvr <= 0) {
00329 *info = -2;
00330 } else if (! wantst && ! lsame_(sort, "N")) {
00331 *info = -3;
00332 } else if (*n < 0) {
00333 *info = -5;
00334 } else if (*lda < max(1,*n)) {
00335 *info = -7;
00336 } else if (*ldb < max(1,*n)) {
00337 *info = -9;
00338 } else if (*ldvsl < 1 || ilvsl && *ldvsl < *n) {
00339 *info = -14;
00340 } else if (*ldvsr < 1 || ilvsr && *ldvsr < *n) {
00341 *info = -16;
00342 }
00343
00344
00345
00346
00347
00348
00349
00350
00351 if (*info == 0) {
00352
00353 i__1 = 1, i__2 = *n << 1;
00354 lwkmin = max(i__1,i__2);
00355
00356 i__1 = 1, i__2 = *n + *n * ilaenv_(&c__1, "ZGEQRF", " ", n, &c__1, n,
00357 &c__0);
00358 lwkopt = max(i__1,i__2);
00359
00360 i__1 = lwkopt, i__2 = *n + *n * ilaenv_(&c__1, "ZUNMQR", " ", n, &
00361 c__1, n, &c_n1);
00362 lwkopt = max(i__1,i__2);
00363 if (ilvsl) {
00364
00365 i__1 = lwkopt, i__2 = *n + *n * ilaenv_(&c__1, "ZUNGQR", " ", n, &
00366 c__1, n, &c_n1);
00367 lwkopt = max(i__1,i__2);
00368 }
00369 work[1].r = (doublereal) lwkopt, work[1].i = 0.;
00370
00371 if (*lwork < lwkmin && ! lquery) {
00372 *info = -18;
00373 }
00374 }
00375
00376 if (*info != 0) {
00377 i__1 = -(*info);
00378 xerbla_("ZGGES ", &i__1);
00379 return 0;
00380 } else if (lquery) {
00381 return 0;
00382 }
00383
00384
00385
00386 if (*n == 0) {
00387 *sdim = 0;
00388 return 0;
00389 }
00390
00391
00392
00393 eps = dlamch_("P");
00394 smlnum = dlamch_("S");
00395 bignum = 1. / smlnum;
00396 dlabad_(&smlnum, &bignum);
00397 smlnum = sqrt(smlnum) / eps;
00398 bignum = 1. / smlnum;
00399
00400
00401
00402 anrm = zlange_("M", n, n, &a[a_offset], lda, &rwork[1]);
00403 ilascl = FALSE_;
00404 if (anrm > 0. && anrm < smlnum) {
00405 anrmto = smlnum;
00406 ilascl = TRUE_;
00407 } else if (anrm > bignum) {
00408 anrmto = bignum;
00409 ilascl = TRUE_;
00410 }
00411
00412 if (ilascl) {
00413 zlascl_("G", &c__0, &c__0, &anrm, &anrmto, n, n, &a[a_offset], lda, &
00414 ierr);
00415 }
00416
00417
00418
00419 bnrm = zlange_("M", n, n, &b[b_offset], ldb, &rwork[1]);
00420 ilbscl = FALSE_;
00421 if (bnrm > 0. && bnrm < smlnum) {
00422 bnrmto = smlnum;
00423 ilbscl = TRUE_;
00424 } else if (bnrm > bignum) {
00425 bnrmto = bignum;
00426 ilbscl = TRUE_;
00427 }
00428
00429 if (ilbscl) {
00430 zlascl_("G", &c__0, &c__0, &bnrm, &bnrmto, n, n, &b[b_offset], ldb, &
00431 ierr);
00432 }
00433
00434
00435
00436
00437 ileft = 1;
00438 iright = *n + 1;
00439 irwrk = iright + *n;
00440 zggbal_("P", n, &a[a_offset], lda, &b[b_offset], ldb, &ilo, &ihi, &rwork[
00441 ileft], &rwork[iright], &rwork[irwrk], &ierr);
00442
00443
00444
00445
00446 irows = ihi + 1 - ilo;
00447 icols = *n + 1 - ilo;
00448 itau = 1;
00449 iwrk = itau + irows;
00450 i__1 = *lwork + 1 - iwrk;
00451 zgeqrf_(&irows, &icols, &b[ilo + ilo * b_dim1], ldb, &work[itau], &work[
00452 iwrk], &i__1, &ierr);
00453
00454
00455
00456
00457 i__1 = *lwork + 1 - iwrk;
00458 zunmqr_("L", "C", &irows, &icols, &irows, &b[ilo + ilo * b_dim1], ldb, &
00459 work[itau], &a[ilo + ilo * a_dim1], lda, &work[iwrk], &i__1, &
00460 ierr);
00461
00462
00463
00464
00465 if (ilvsl) {
00466 zlaset_("Full", n, n, &c_b1, &c_b2, &vsl[vsl_offset], ldvsl);
00467 if (irows > 1) {
00468 i__1 = irows - 1;
00469 i__2 = irows - 1;
00470 zlacpy_("L", &i__1, &i__2, &b[ilo + 1 + ilo * b_dim1], ldb, &vsl[
00471 ilo + 1 + ilo * vsl_dim1], ldvsl);
00472 }
00473 i__1 = *lwork + 1 - iwrk;
00474 zungqr_(&irows, &irows, &irows, &vsl[ilo + ilo * vsl_dim1], ldvsl, &
00475 work[itau], &work[iwrk], &i__1, &ierr);
00476 }
00477
00478
00479
00480 if (ilvsr) {
00481 zlaset_("Full", n, n, &c_b1, &c_b2, &vsr[vsr_offset], ldvsr);
00482 }
00483
00484
00485
00486
00487 zgghrd_(jobvsl, jobvsr, n, &ilo, &ihi, &a[a_offset], lda, &b[b_offset],
00488 ldb, &vsl[vsl_offset], ldvsl, &vsr[vsr_offset], ldvsr, &ierr);
00489
00490 *sdim = 0;
00491
00492
00493
00494
00495
00496 iwrk = itau;
00497 i__1 = *lwork + 1 - iwrk;
00498 zhgeqz_("S", jobvsl, jobvsr, n, &ilo, &ihi, &a[a_offset], lda, &b[
00499 b_offset], ldb, &alpha[1], &beta[1], &vsl[vsl_offset], ldvsl, &
00500 vsr[vsr_offset], ldvsr, &work[iwrk], &i__1, &rwork[irwrk], &ierr);
00501 if (ierr != 0) {
00502 if (ierr > 0 && ierr <= *n) {
00503 *info = ierr;
00504 } else if (ierr > *n && ierr <= *n << 1) {
00505 *info = ierr - *n;
00506 } else {
00507 *info = *n + 1;
00508 }
00509 goto L30;
00510 }
00511
00512
00513
00514
00515 if (wantst) {
00516
00517
00518
00519 if (ilascl) {
00520 zlascl_("G", &c__0, &c__0, &anrm, &anrmto, n, &c__1, &alpha[1], n,
00521 &ierr);
00522 }
00523 if (ilbscl) {
00524 zlascl_("G", &c__0, &c__0, &bnrm, &bnrmto, n, &c__1, &beta[1], n,
00525 &ierr);
00526 }
00527
00528
00529
00530 i__1 = *n;
00531 for (i__ = 1; i__ <= i__1; ++i__) {
00532 bwork[i__] = (*selctg)(&alpha[i__], &beta[i__]);
00533
00534 }
00535
00536 i__1 = *lwork - iwrk + 1;
00537 ztgsen_(&c__0, &ilvsl, &ilvsr, &bwork[1], n, &a[a_offset], lda, &b[
00538 b_offset], ldb, &alpha[1], &beta[1], &vsl[vsl_offset], ldvsl,
00539 &vsr[vsr_offset], ldvsr, sdim, &pvsl, &pvsr, dif, &work[iwrk],
00540 &i__1, idum, &c__1, &ierr);
00541 if (ierr == 1) {
00542 *info = *n + 3;
00543 }
00544
00545 }
00546
00547
00548
00549
00550 if (ilvsl) {
00551 zggbak_("P", "L", n, &ilo, &ihi, &rwork[ileft], &rwork[iright], n, &
00552 vsl[vsl_offset], ldvsl, &ierr);
00553 }
00554 if (ilvsr) {
00555 zggbak_("P", "R", n, &ilo, &ihi, &rwork[ileft], &rwork[iright], n, &
00556 vsr[vsr_offset], ldvsr, &ierr);
00557 }
00558
00559
00560
00561 if (ilascl) {
00562 zlascl_("U", &c__0, &c__0, &anrmto, &anrm, n, n, &a[a_offset], lda, &
00563 ierr);
00564 zlascl_("G", &c__0, &c__0, &anrmto, &anrm, n, &c__1, &alpha[1], n, &
00565 ierr);
00566 }
00567
00568 if (ilbscl) {
00569 zlascl_("U", &c__0, &c__0, &bnrmto, &bnrm, n, n, &b[b_offset], ldb, &
00570 ierr);
00571 zlascl_("G", &c__0, &c__0, &bnrmto, &bnrm, n, &c__1, &beta[1], n, &
00572 ierr);
00573 }
00574
00575 if (wantst) {
00576
00577
00578
00579 lastsl = TRUE_;
00580 *sdim = 0;
00581 i__1 = *n;
00582 for (i__ = 1; i__ <= i__1; ++i__) {
00583 cursl = (*selctg)(&alpha[i__], &beta[i__]);
00584 if (cursl) {
00585 ++(*sdim);
00586 }
00587 if (cursl && ! lastsl) {
00588 *info = *n + 2;
00589 }
00590 lastsl = cursl;
00591
00592 }
00593
00594 }
00595
00596 L30:
00597
00598 work[1].r = (doublereal) lwkopt, work[1].i = 0.;
00599
00600 return 0;
00601
00602
00603
00604 }