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
00022 int dgeev_(char *jobvl, char *jobvr, integer *n, doublereal *
00023 a, integer *lda, doublereal *wr, doublereal *wi, doublereal *vl,
00024 integer *ldvl, doublereal *vr, integer *ldvr, doublereal *work,
00025 integer *lwork, integer *info)
00026 {
00027
00028 integer a_dim1, a_offset, vl_dim1, vl_offset, vr_dim1, vr_offset, i__1,
00029 i__2, i__3;
00030 doublereal d__1, d__2;
00031
00032
00033 double sqrt(doublereal);
00034
00035
00036 integer i__, k;
00037 doublereal r__, cs, sn;
00038 integer ihi;
00039 doublereal scl;
00040 integer ilo;
00041 doublereal dum[1], eps;
00042 integer ibal;
00043 char side[1];
00044 doublereal anrm;
00045 integer ierr, itau;
00046 extern int drot_(integer *, doublereal *, integer *,
00047 doublereal *, integer *, doublereal *, doublereal *);
00048 integer iwrk, nout;
00049 extern doublereal dnrm2_(integer *, doublereal *, integer *);
00050 extern int dscal_(integer *, doublereal *, doublereal *,
00051 integer *);
00052 extern logical lsame_(char *, char *);
00053 extern doublereal dlapy2_(doublereal *, doublereal *);
00054 extern int dlabad_(doublereal *, doublereal *), dgebak_(
00055 char *, char *, integer *, integer *, integer *, doublereal *,
00056 integer *, doublereal *, integer *, integer *),
00057 dgebal_(char *, integer *, doublereal *, integer *, integer *,
00058 integer *, doublereal *, integer *);
00059 logical scalea;
00060 extern doublereal dlamch_(char *);
00061 doublereal cscale;
00062 extern doublereal dlange_(char *, integer *, integer *, doublereal *,
00063 integer *, doublereal *);
00064 extern int dgehrd_(integer *, integer *, integer *,
00065 doublereal *, integer *, doublereal *, doublereal *, integer *,
00066 integer *), dlascl_(char *, integer *, integer *, doublereal *,
00067 doublereal *, integer *, integer *, doublereal *, integer *,
00068 integer *);
00069 extern integer idamax_(integer *, doublereal *, integer *);
00070 extern int dlacpy_(char *, integer *, integer *,
00071 doublereal *, integer *, doublereal *, integer *),
00072 dlartg_(doublereal *, doublereal *, doublereal *, doublereal *,
00073 doublereal *), xerbla_(char *, integer *);
00074 logical select[1];
00075 extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
00076 integer *, integer *);
00077 doublereal bignum;
00078 extern int dorghr_(integer *, integer *, integer *,
00079 doublereal *, integer *, doublereal *, doublereal *, integer *,
00080 integer *), dhseqr_(char *, char *, integer *, integer *, integer
00081 *, doublereal *, integer *, doublereal *, doublereal *,
00082 doublereal *, integer *, doublereal *, integer *, integer *), dtrevc_(char *, char *, logical *, integer *,
00083 doublereal *, integer *, doublereal *, integer *, doublereal *,
00084 integer *, integer *, integer *, doublereal *, integer *);
00085 integer minwrk, maxwrk;
00086 logical wantvl;
00087 doublereal smlnum;
00088 integer hswork;
00089 logical lquery, wantvr;
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 a_dim1 = *lda;
00217 a_offset = 1 + a_dim1;
00218 a -= a_offset;
00219 --wr;
00220 --wi;
00221 vl_dim1 = *ldvl;
00222 vl_offset = 1 + vl_dim1;
00223 vl -= vl_offset;
00224 vr_dim1 = *ldvr;
00225 vr_offset = 1 + vr_dim1;
00226 vr -= vr_offset;
00227 --work;
00228
00229
00230 *info = 0;
00231 lquery = *lwork == -1;
00232 wantvl = lsame_(jobvl, "V");
00233 wantvr = lsame_(jobvr, "V");
00234 if (! wantvl && ! lsame_(jobvl, "N")) {
00235 *info = -1;
00236 } else if (! wantvr && ! lsame_(jobvr, "N")) {
00237 *info = -2;
00238 } else if (*n < 0) {
00239 *info = -3;
00240 } else if (*lda < max(1,*n)) {
00241 *info = -5;
00242 } else if (*ldvl < 1 || wantvl && *ldvl < *n) {
00243 *info = -9;
00244 } else if (*ldvr < 1 || wantvr && *ldvr < *n) {
00245 *info = -11;
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 if (*info == 0) {
00259 if (*n == 0) {
00260 minwrk = 1;
00261 maxwrk = 1;
00262 } else {
00263 maxwrk = (*n << 1) + *n * ilaenv_(&c__1, "DGEHRD", " ", n, &c__1,
00264 n, &c__0);
00265 if (wantvl) {
00266 minwrk = *n << 2;
00267
00268 i__1 = maxwrk, i__2 = (*n << 1) + (*n - 1) * ilaenv_(&c__1,
00269 "DORGHR", " ", n, &c__1, n, &c_n1);
00270 maxwrk = max(i__1,i__2);
00271 dhseqr_("S", "V", n, &c__1, n, &a[a_offset], lda, &wr[1], &wi[
00272 1], &vl[vl_offset], ldvl, &work[1], &c_n1, info);
00273 hswork = (integer) work[1];
00274
00275 i__1 = maxwrk, i__2 = *n + 1, i__1 = max(i__1,i__2), i__2 = *
00276 n + hswork;
00277 maxwrk = max(i__1,i__2);
00278
00279 i__1 = maxwrk, i__2 = *n << 2;
00280 maxwrk = max(i__1,i__2);
00281 } else if (wantvr) {
00282 minwrk = *n << 2;
00283
00284 i__1 = maxwrk, i__2 = (*n << 1) + (*n - 1) * ilaenv_(&c__1,
00285 "DORGHR", " ", n, &c__1, n, &c_n1);
00286 maxwrk = max(i__1,i__2);
00287 dhseqr_("S", "V", n, &c__1, n, &a[a_offset], lda, &wr[1], &wi[
00288 1], &vr[vr_offset], ldvr, &work[1], &c_n1, info);
00289 hswork = (integer) work[1];
00290
00291 i__1 = maxwrk, i__2 = *n + 1, i__1 = max(i__1,i__2), i__2 = *
00292 n + hswork;
00293 maxwrk = max(i__1,i__2);
00294
00295 i__1 = maxwrk, i__2 = *n << 2;
00296 maxwrk = max(i__1,i__2);
00297 } else {
00298 minwrk = *n * 3;
00299 dhseqr_("E", "N", n, &c__1, n, &a[a_offset], lda, &wr[1], &wi[
00300 1], &vr[vr_offset], ldvr, &work[1], &c_n1, info);
00301 hswork = (integer) work[1];
00302
00303 i__1 = maxwrk, i__2 = *n + 1, i__1 = max(i__1,i__2), i__2 = *
00304 n + hswork;
00305 maxwrk = max(i__1,i__2);
00306 }
00307 maxwrk = max(maxwrk,minwrk);
00308 }
00309 work[1] = (doublereal) maxwrk;
00310
00311 if (*lwork < minwrk && ! lquery) {
00312 *info = -13;
00313 }
00314 }
00315
00316 if (*info != 0) {
00317 i__1 = -(*info);
00318 xerbla_("DGEEV ", &i__1);
00319 return 0;
00320 } else if (lquery) {
00321 return 0;
00322 }
00323
00324
00325
00326 if (*n == 0) {
00327 return 0;
00328 }
00329
00330
00331
00332 eps = dlamch_("P");
00333 smlnum = dlamch_("S");
00334 bignum = 1. / smlnum;
00335 dlabad_(&smlnum, &bignum);
00336 smlnum = sqrt(smlnum) / eps;
00337 bignum = 1. / smlnum;
00338
00339
00340
00341 anrm = dlange_("M", n, n, &a[a_offset], lda, dum);
00342 scalea = FALSE_;
00343 if (anrm > 0. && anrm < smlnum) {
00344 scalea = TRUE_;
00345 cscale = smlnum;
00346 } else if (anrm > bignum) {
00347 scalea = TRUE_;
00348 cscale = bignum;
00349 }
00350 if (scalea) {
00351 dlascl_("G", &c__0, &c__0, &anrm, &cscale, n, n, &a[a_offset], lda, &
00352 ierr);
00353 }
00354
00355
00356
00357
00358 ibal = 1;
00359 dgebal_("B", n, &a[a_offset], lda, &ilo, &ihi, &work[ibal], &ierr);
00360
00361
00362
00363
00364 itau = ibal + *n;
00365 iwrk = itau + *n;
00366 i__1 = *lwork - iwrk + 1;
00367 dgehrd_(n, &ilo, &ihi, &a[a_offset], lda, &work[itau], &work[iwrk], &i__1,
00368 &ierr);
00369
00370 if (wantvl) {
00371
00372
00373
00374
00375 *(unsigned char *)side = 'L';
00376 dlacpy_("L", n, n, &a[a_offset], lda, &vl[vl_offset], ldvl)
00377 ;
00378
00379
00380
00381
00382 i__1 = *lwork - iwrk + 1;
00383 dorghr_(n, &ilo, &ihi, &vl[vl_offset], ldvl, &work[itau], &work[iwrk],
00384 &i__1, &ierr);
00385
00386
00387
00388
00389 iwrk = itau;
00390 i__1 = *lwork - iwrk + 1;
00391 dhseqr_("S", "V", n, &ilo, &ihi, &a[a_offset], lda, &wr[1], &wi[1], &
00392 vl[vl_offset], ldvl, &work[iwrk], &i__1, info);
00393
00394 if (wantvr) {
00395
00396
00397
00398
00399 *(unsigned char *)side = 'B';
00400 dlacpy_("F", n, n, &vl[vl_offset], ldvl, &vr[vr_offset], ldvr);
00401 }
00402
00403 } else if (wantvr) {
00404
00405
00406
00407
00408 *(unsigned char *)side = 'R';
00409 dlacpy_("L", n, n, &a[a_offset], lda, &vr[vr_offset], ldvr)
00410 ;
00411
00412
00413
00414
00415 i__1 = *lwork - iwrk + 1;
00416 dorghr_(n, &ilo, &ihi, &vr[vr_offset], ldvr, &work[itau], &work[iwrk],
00417 &i__1, &ierr);
00418
00419
00420
00421
00422 iwrk = itau;
00423 i__1 = *lwork - iwrk + 1;
00424 dhseqr_("S", "V", n, &ilo, &ihi, &a[a_offset], lda, &wr[1], &wi[1], &
00425 vr[vr_offset], ldvr, &work[iwrk], &i__1, info);
00426
00427 } else {
00428
00429
00430
00431
00432 iwrk = itau;
00433 i__1 = *lwork - iwrk + 1;
00434 dhseqr_("E", "N", n, &ilo, &ihi, &a[a_offset], lda, &wr[1], &wi[1], &
00435 vr[vr_offset], ldvr, &work[iwrk], &i__1, info);
00436 }
00437
00438
00439
00440 if (*info > 0) {
00441 goto L50;
00442 }
00443
00444 if (wantvl || wantvr) {
00445
00446
00447
00448
00449 dtrevc_(side, "B", select, n, &a[a_offset], lda, &vl[vl_offset], ldvl,
00450 &vr[vr_offset], ldvr, n, &nout, &work[iwrk], &ierr);
00451 }
00452
00453 if (wantvl) {
00454
00455
00456
00457
00458 dgebak_("B", "L", n, &ilo, &ihi, &work[ibal], n, &vl[vl_offset], ldvl,
00459 &ierr);
00460
00461
00462
00463 i__1 = *n;
00464 for (i__ = 1; i__ <= i__1; ++i__) {
00465 if (wi[i__] == 0.) {
00466 scl = 1. / dnrm2_(n, &vl[i__ * vl_dim1 + 1], &c__1);
00467 dscal_(n, &scl, &vl[i__ * vl_dim1 + 1], &c__1);
00468 } else if (wi[i__] > 0.) {
00469 d__1 = dnrm2_(n, &vl[i__ * vl_dim1 + 1], &c__1);
00470 d__2 = dnrm2_(n, &vl[(i__ + 1) * vl_dim1 + 1], &c__1);
00471 scl = 1. / dlapy2_(&d__1, &d__2);
00472 dscal_(n, &scl, &vl[i__ * vl_dim1 + 1], &c__1);
00473 dscal_(n, &scl, &vl[(i__ + 1) * vl_dim1 + 1], &c__1);
00474 i__2 = *n;
00475 for (k = 1; k <= i__2; ++k) {
00476
00477 d__1 = vl[k + i__ * vl_dim1];
00478
00479 d__2 = vl[k + (i__ + 1) * vl_dim1];
00480 work[iwrk + k - 1] = d__1 * d__1 + d__2 * d__2;
00481
00482 }
00483 k = idamax_(n, &work[iwrk], &c__1);
00484 dlartg_(&vl[k + i__ * vl_dim1], &vl[k + (i__ + 1) * vl_dim1],
00485 &cs, &sn, &r__);
00486 drot_(n, &vl[i__ * vl_dim1 + 1], &c__1, &vl[(i__ + 1) *
00487 vl_dim1 + 1], &c__1, &cs, &sn);
00488 vl[k + (i__ + 1) * vl_dim1] = 0.;
00489 }
00490
00491 }
00492 }
00493
00494 if (wantvr) {
00495
00496
00497
00498
00499 dgebak_("B", "R", n, &ilo, &ihi, &work[ibal], n, &vr[vr_offset], ldvr,
00500 &ierr);
00501
00502
00503
00504 i__1 = *n;
00505 for (i__ = 1; i__ <= i__1; ++i__) {
00506 if (wi[i__] == 0.) {
00507 scl = 1. / dnrm2_(n, &vr[i__ * vr_dim1 + 1], &c__1);
00508 dscal_(n, &scl, &vr[i__ * vr_dim1 + 1], &c__1);
00509 } else if (wi[i__] > 0.) {
00510 d__1 = dnrm2_(n, &vr[i__ * vr_dim1 + 1], &c__1);
00511 d__2 = dnrm2_(n, &vr[(i__ + 1) * vr_dim1 + 1], &c__1);
00512 scl = 1. / dlapy2_(&d__1, &d__2);
00513 dscal_(n, &scl, &vr[i__ * vr_dim1 + 1], &c__1);
00514 dscal_(n, &scl, &vr[(i__ + 1) * vr_dim1 + 1], &c__1);
00515 i__2 = *n;
00516 for (k = 1; k <= i__2; ++k) {
00517
00518 d__1 = vr[k + i__ * vr_dim1];
00519
00520 d__2 = vr[k + (i__ + 1) * vr_dim1];
00521 work[iwrk + k - 1] = d__1 * d__1 + d__2 * d__2;
00522
00523 }
00524 k = idamax_(n, &work[iwrk], &c__1);
00525 dlartg_(&vr[k + i__ * vr_dim1], &vr[k + (i__ + 1) * vr_dim1],
00526 &cs, &sn, &r__);
00527 drot_(n, &vr[i__ * vr_dim1 + 1], &c__1, &vr[(i__ + 1) *
00528 vr_dim1 + 1], &c__1, &cs, &sn);
00529 vr[k + (i__ + 1) * vr_dim1] = 0.;
00530 }
00531
00532 }
00533 }
00534
00535
00536
00537 L50:
00538 if (scalea) {
00539 i__1 = *n - *info;
00540
00541 i__3 = *n - *info;
00542 i__2 = max(i__3,1);
00543 dlascl_("G", &c__0, &c__0, &cscale, &anrm, &i__1, &c__1, &wr[*info +
00544 1], &i__2, &ierr);
00545 i__1 = *n - *info;
00546
00547 i__3 = *n - *info;
00548 i__2 = max(i__3,1);
00549 dlascl_("G", &c__0, &c__0, &cscale, &anrm, &i__1, &c__1, &wi[*info +
00550 1], &i__2, &ierr);
00551 if (*info > 0) {
00552 i__1 = ilo - 1;
00553 dlascl_("G", &c__0, &c__0, &cscale, &anrm, &i__1, &c__1, &wr[1],
00554 n, &ierr);
00555 i__1 = ilo - 1;
00556 dlascl_("G", &c__0, &c__0, &cscale, &anrm, &i__1, &c__1, &wi[1],
00557 n, &ierr);
00558 }
00559 }
00560
00561 work[1] = (doublereal) maxwrk;
00562 return 0;
00563
00564
00565
00566 }