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_n1 = -1;
00022
00023 int zgegs_(char *jobvsl, char *jobvsr, integer *n,
00024 doublecomplex *a, integer *lda, doublecomplex *b, integer *ldb,
00025 doublecomplex *alpha, doublecomplex *beta, doublecomplex *vsl,
00026 integer *ldvsl, doublecomplex *vsr, integer *ldvsr, doublecomplex *
00027 work, integer *lwork, doublereal *rwork, integer *info)
00028 {
00029
00030 integer a_dim1, a_offset, b_dim1, b_offset, vsl_dim1, vsl_offset,
00031 vsr_dim1, vsr_offset, i__1, i__2, i__3;
00032
00033
00034 integer nb, nb1, nb2, nb3, ihi, ilo;
00035 doublereal eps, anrm, bnrm;
00036 integer itau, lopt;
00037 extern logical lsame_(char *, char *);
00038 integer ileft, iinfo, icols;
00039 logical ilvsl;
00040 integer iwork;
00041 logical ilvsr;
00042 integer irows;
00043 extern doublereal dlamch_(char *);
00044 extern int zggbak_(char *, char *, integer *, integer *,
00045 integer *, doublereal *, doublereal *, integer *, doublecomplex *,
00046 integer *, integer *), zggbal_(char *, integer *,
00047 doublecomplex *, integer *, doublecomplex *, integer *, integer *
00048 , integer *, doublereal *, doublereal *, doublereal *, integer *);
00049 logical ilascl, ilbscl;
00050 doublereal safmin;
00051 extern int xerbla_(char *, integer *);
00052 extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
00053 integer *, integer *);
00054 extern doublereal zlange_(char *, integer *, integer *, doublecomplex *,
00055 integer *, doublereal *);
00056 doublereal bignum;
00057 integer ijobvl, iright;
00058 extern int zgghrd_(char *, char *, integer *, integer *,
00059 integer *, doublecomplex *, integer *, doublecomplex *, integer *,
00060 doublecomplex *, integer *, doublecomplex *, integer *, integer *
00061 ), zlascl_(char *, integer *, integer *,
00062 doublereal *, doublereal *, integer *, integer *, doublecomplex *,
00063 integer *, integer *);
00064 integer ijobvr;
00065 extern int zgeqrf_(integer *, integer *, doublecomplex *,
00066 integer *, doublecomplex *, doublecomplex *, integer *, integer *
00067 );
00068 doublereal anrmto;
00069 integer lwkmin;
00070 doublereal bnrmto;
00071 extern int zlacpy_(char *, integer *, integer *,
00072 doublecomplex *, integer *, doublecomplex *, integer *),
00073 zlaset_(char *, integer *, integer *, doublecomplex *,
00074 doublecomplex *, doublecomplex *, integer *), zhgeqz_(
00075 char *, char *, char *, integer *, integer *, integer *,
00076 doublecomplex *, integer *, doublecomplex *, integer *,
00077 doublecomplex *, doublecomplex *, doublecomplex *, integer *,
00078 doublecomplex *, integer *, doublecomplex *, integer *,
00079 doublereal *, integer *);
00080 doublereal smlnum;
00081 integer irwork, lwkopt;
00082 logical lquery;
00083 extern int zungqr_(integer *, integer *, integer *,
00084 doublecomplex *, integer *, doublecomplex *, doublecomplex *,
00085 integer *, integer *), zunmqr_(char *, char *, integer *, integer
00086 *, integer *, doublecomplex *, integer *, doublecomplex *,
00087 doublecomplex *, integer *, doublecomplex *, integer *, integer *);
00088
00089
00090
00091
00092
00093
00094
00095
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 a_dim1 = *lda;
00238 a_offset = 1 + a_dim1;
00239 a -= a_offset;
00240 b_dim1 = *ldb;
00241 b_offset = 1 + b_dim1;
00242 b -= b_offset;
00243 --alpha;
00244 --beta;
00245 vsl_dim1 = *ldvsl;
00246 vsl_offset = 1 + vsl_dim1;
00247 vsl -= vsl_offset;
00248 vsr_dim1 = *ldvsr;
00249 vsr_offset = 1 + vsr_dim1;
00250 vsr -= vsr_offset;
00251 --work;
00252 --rwork;
00253
00254
00255 if (lsame_(jobvsl, "N")) {
00256 ijobvl = 1;
00257 ilvsl = FALSE_;
00258 } else if (lsame_(jobvsl, "V")) {
00259 ijobvl = 2;
00260 ilvsl = TRUE_;
00261 } else {
00262 ijobvl = -1;
00263 ilvsl = FALSE_;
00264 }
00265
00266 if (lsame_(jobvsr, "N")) {
00267 ijobvr = 1;
00268 ilvsr = FALSE_;
00269 } else if (lsame_(jobvsr, "V")) {
00270 ijobvr = 2;
00271 ilvsr = TRUE_;
00272 } else {
00273 ijobvr = -1;
00274 ilvsr = FALSE_;
00275 }
00276
00277
00278
00279
00280 i__1 = *n << 1;
00281 lwkmin = max(i__1,1);
00282 lwkopt = lwkmin;
00283 work[1].r = (doublereal) lwkopt, work[1].i = 0.;
00284 lquery = *lwork == -1;
00285 *info = 0;
00286 if (ijobvl <= 0) {
00287 *info = -1;
00288 } else if (ijobvr <= 0) {
00289 *info = -2;
00290 } else if (*n < 0) {
00291 *info = -3;
00292 } else if (*lda < max(1,*n)) {
00293 *info = -5;
00294 } else if (*ldb < max(1,*n)) {
00295 *info = -7;
00296 } else if (*ldvsl < 1 || ilvsl && *ldvsl < *n) {
00297 *info = -11;
00298 } else if (*ldvsr < 1 || ilvsr && *ldvsr < *n) {
00299 *info = -13;
00300 } else if (*lwork < lwkmin && ! lquery) {
00301 *info = -15;
00302 }
00303
00304 if (*info == 0) {
00305 nb1 = ilaenv_(&c__1, "ZGEQRF", " ", n, n, &c_n1, &c_n1);
00306 nb2 = ilaenv_(&c__1, "ZUNMQR", " ", n, n, n, &c_n1);
00307 nb3 = ilaenv_(&c__1, "ZUNGQR", " ", n, n, n, &c_n1);
00308
00309 i__1 = max(nb1,nb2);
00310 nb = max(i__1,nb3);
00311 lopt = *n * (nb + 1);
00312 work[1].r = (doublereal) lopt, work[1].i = 0.;
00313 }
00314
00315 if (*info != 0) {
00316 i__1 = -(*info);
00317 xerbla_("ZGEGS ", &i__1);
00318 return 0;
00319 } else if (lquery) {
00320 return 0;
00321 }
00322
00323
00324
00325 if (*n == 0) {
00326 return 0;
00327 }
00328
00329
00330
00331 eps = dlamch_("E") * dlamch_("B");
00332 safmin = dlamch_("S");
00333 smlnum = *n * safmin / eps;
00334 bignum = 1. / smlnum;
00335
00336
00337
00338 anrm = zlange_("M", n, n, &a[a_offset], lda, &rwork[1]);
00339 ilascl = FALSE_;
00340 if (anrm > 0. && anrm < smlnum) {
00341 anrmto = smlnum;
00342 ilascl = TRUE_;
00343 } else if (anrm > bignum) {
00344 anrmto = bignum;
00345 ilascl = TRUE_;
00346 }
00347
00348 if (ilascl) {
00349 zlascl_("G", &c_n1, &c_n1, &anrm, &anrmto, n, n, &a[a_offset], lda, &
00350 iinfo);
00351 if (iinfo != 0) {
00352 *info = *n + 9;
00353 return 0;
00354 }
00355 }
00356
00357
00358
00359 bnrm = zlange_("M", n, n, &b[b_offset], ldb, &rwork[1]);
00360 ilbscl = FALSE_;
00361 if (bnrm > 0. && bnrm < smlnum) {
00362 bnrmto = smlnum;
00363 ilbscl = TRUE_;
00364 } else if (bnrm > bignum) {
00365 bnrmto = bignum;
00366 ilbscl = TRUE_;
00367 }
00368
00369 if (ilbscl) {
00370 zlascl_("G", &c_n1, &c_n1, &bnrm, &bnrmto, n, n, &b[b_offset], ldb, &
00371 iinfo);
00372 if (iinfo != 0) {
00373 *info = *n + 9;
00374 return 0;
00375 }
00376 }
00377
00378
00379
00380 ileft = 1;
00381 iright = *n + 1;
00382 irwork = iright + *n;
00383 iwork = 1;
00384 zggbal_("P", n, &a[a_offset], lda, &b[b_offset], ldb, &ilo, &ihi, &rwork[
00385 ileft], &rwork[iright], &rwork[irwork], &iinfo);
00386 if (iinfo != 0) {
00387 *info = *n + 1;
00388 goto L10;
00389 }
00390
00391
00392
00393 irows = ihi + 1 - ilo;
00394 icols = *n + 1 - ilo;
00395 itau = iwork;
00396 iwork = itau + irows;
00397 i__1 = *lwork + 1 - iwork;
00398 zgeqrf_(&irows, &icols, &b[ilo + ilo * b_dim1], ldb, &work[itau], &work[
00399 iwork], &i__1, &iinfo);
00400 if (iinfo >= 0) {
00401
00402 i__3 = iwork;
00403 i__1 = lwkopt, i__2 = (integer) work[i__3].r + iwork - 1;
00404 lwkopt = max(i__1,i__2);
00405 }
00406 if (iinfo != 0) {
00407 *info = *n + 2;
00408 goto L10;
00409 }
00410
00411 i__1 = *lwork + 1 - iwork;
00412 zunmqr_("L", "C", &irows, &icols, &irows, &b[ilo + ilo * b_dim1], ldb, &
00413 work[itau], &a[ilo + ilo * a_dim1], lda, &work[iwork], &i__1, &
00414 iinfo);
00415 if (iinfo >= 0) {
00416
00417 i__3 = iwork;
00418 i__1 = lwkopt, i__2 = (integer) work[i__3].r + iwork - 1;
00419 lwkopt = max(i__1,i__2);
00420 }
00421 if (iinfo != 0) {
00422 *info = *n + 3;
00423 goto L10;
00424 }
00425
00426 if (ilvsl) {
00427 zlaset_("Full", n, n, &c_b1, &c_b2, &vsl[vsl_offset], ldvsl);
00428 i__1 = irows - 1;
00429 i__2 = irows - 1;
00430 zlacpy_("L", &i__1, &i__2, &b[ilo + 1 + ilo * b_dim1], ldb, &vsl[ilo
00431 + 1 + ilo * vsl_dim1], ldvsl);
00432 i__1 = *lwork + 1 - iwork;
00433 zungqr_(&irows, &irows, &irows, &vsl[ilo + ilo * vsl_dim1], ldvsl, &
00434 work[itau], &work[iwork], &i__1, &iinfo);
00435 if (iinfo >= 0) {
00436
00437 i__3 = iwork;
00438 i__1 = lwkopt, i__2 = (integer) work[i__3].r + iwork - 1;
00439 lwkopt = max(i__1,i__2);
00440 }
00441 if (iinfo != 0) {
00442 *info = *n + 4;
00443 goto L10;
00444 }
00445 }
00446
00447 if (ilvsr) {
00448 zlaset_("Full", n, n, &c_b1, &c_b2, &vsr[vsr_offset], ldvsr);
00449 }
00450
00451
00452
00453 zgghrd_(jobvsl, jobvsr, n, &ilo, &ihi, &a[a_offset], lda, &b[b_offset],
00454 ldb, &vsl[vsl_offset], ldvsl, &vsr[vsr_offset], ldvsr, &iinfo);
00455 if (iinfo != 0) {
00456 *info = *n + 5;
00457 goto L10;
00458 }
00459
00460
00461
00462 iwork = itau;
00463 i__1 = *lwork + 1 - iwork;
00464 zhgeqz_("S", jobvsl, jobvsr, n, &ilo, &ihi, &a[a_offset], lda, &b[
00465 b_offset], ldb, &alpha[1], &beta[1], &vsl[vsl_offset], ldvsl, &
00466 vsr[vsr_offset], ldvsr, &work[iwork], &i__1, &rwork[irwork], &
00467 iinfo);
00468 if (iinfo >= 0) {
00469
00470 i__3 = iwork;
00471 i__1 = lwkopt, i__2 = (integer) work[i__3].r + iwork - 1;
00472 lwkopt = max(i__1,i__2);
00473 }
00474 if (iinfo != 0) {
00475 if (iinfo > 0 && iinfo <= *n) {
00476 *info = iinfo;
00477 } else if (iinfo > *n && iinfo <= *n << 1) {
00478 *info = iinfo - *n;
00479 } else {
00480 *info = *n + 6;
00481 }
00482 goto L10;
00483 }
00484
00485
00486
00487 if (ilvsl) {
00488 zggbak_("P", "L", n, &ilo, &ihi, &rwork[ileft], &rwork[iright], n, &
00489 vsl[vsl_offset], ldvsl, &iinfo);
00490 if (iinfo != 0) {
00491 *info = *n + 7;
00492 goto L10;
00493 }
00494 }
00495 if (ilvsr) {
00496 zggbak_("P", "R", n, &ilo, &ihi, &rwork[ileft], &rwork[iright], n, &
00497 vsr[vsr_offset], ldvsr, &iinfo);
00498 if (iinfo != 0) {
00499 *info = *n + 8;
00500 goto L10;
00501 }
00502 }
00503
00504
00505
00506 if (ilascl) {
00507 zlascl_("U", &c_n1, &c_n1, &anrmto, &anrm, n, n, &a[a_offset], lda, &
00508 iinfo);
00509 if (iinfo != 0) {
00510 *info = *n + 9;
00511 return 0;
00512 }
00513 zlascl_("G", &c_n1, &c_n1, &anrmto, &anrm, n, &c__1, &alpha[1], n, &
00514 iinfo);
00515 if (iinfo != 0) {
00516 *info = *n + 9;
00517 return 0;
00518 }
00519 }
00520
00521 if (ilbscl) {
00522 zlascl_("U", &c_n1, &c_n1, &bnrmto, &bnrm, n, n, &b[b_offset], ldb, &
00523 iinfo);
00524 if (iinfo != 0) {
00525 *info = *n + 9;
00526 return 0;
00527 }
00528 zlascl_("G", &c_n1, &c_n1, &bnrmto, &bnrm, n, &c__1, &beta[1], n, &
00529 iinfo);
00530 if (iinfo != 0) {
00531 *info = *n + 9;
00532 return 0;
00533 }
00534 }
00535
00536 L10:
00537 work[1].r = (doublereal) lwkopt, work[1].i = 0.;
00538
00539 return 0;
00540
00541
00542
00543 }