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 sgeevx_(char *balanc, char *jobvl, char *jobvr, char *
00023 sense, integer *n, real *a, integer *lda, real *wr, real *wi, real *
00024 vl, integer *ldvl, real *vr, integer *ldvr, integer *ilo, integer *
00025 ihi, real *scale, real *abnrm, real *rconde, real *rcondv, real *work,
00026 integer *lwork, integer *iwork, integer *info)
00027 {
00028
00029 integer a_dim1, a_offset, vl_dim1, vl_offset, vr_dim1, vr_offset, i__1,
00030 i__2, i__3;
00031 real r__1, r__2;
00032
00033
00034 double sqrt(doublereal);
00035
00036
00037 integer i__, k;
00038 real r__, cs, sn;
00039 char job[1];
00040 real scl, dum[1], eps;
00041 char side[1];
00042 real anrm;
00043 integer ierr, itau, iwrk, nout;
00044 extern int srot_(integer *, real *, integer *, real *,
00045 integer *, real *, real *);
00046 extern doublereal snrm2_(integer *, real *, integer *);
00047 integer icond;
00048 extern logical lsame_(char *, char *);
00049 extern int sscal_(integer *, real *, real *, integer *);
00050 extern doublereal slapy2_(real *, real *);
00051 extern int slabad_(real *, real *);
00052 logical scalea;
00053 real cscale;
00054 extern int sgebak_(char *, char *, integer *, integer *,
00055 integer *, real *, integer *, real *, integer *, integer *), sgebal_(char *, integer *, real *, integer *,
00056 integer *, integer *, real *, integer *);
00057 extern doublereal slamch_(char *), slange_(char *, integer *,
00058 integer *, real *, integer *, real *);
00059 extern int sgehrd_(integer *, integer *, integer *, real
00060 *, integer *, real *, real *, integer *, integer *), xerbla_(char
00061 *, integer *);
00062 extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
00063 integer *, integer *);
00064 logical select[1];
00065 real bignum;
00066 extern int slascl_(char *, integer *, integer *, real *,
00067 real *, integer *, integer *, real *, integer *, integer *);
00068 extern integer isamax_(integer *, real *, integer *);
00069 extern int slacpy_(char *, integer *, integer *, real *,
00070 integer *, real *, integer *), slartg_(real *, real *,
00071 real *, real *, real *), sorghr_(integer *, integer *, integer *,
00072 real *, integer *, real *, real *, integer *, integer *), shseqr_(
00073 char *, char *, integer *, integer *, integer *, real *, integer *
00074 , real *, real *, real *, integer *, real *, integer *, integer *), strevc_(char *, char *, logical *, integer *,
00075 real *, integer *, real *, integer *, real *, integer *, integer *
00076 , integer *, real *, integer *);
00077 integer minwrk, maxwrk;
00078 extern int strsna_(char *, char *, logical *, integer *,
00079 real *, integer *, real *, integer *, real *, integer *, real *,
00080 real *, integer *, integer *, real *, integer *, integer *,
00081 integer *);
00082 logical wantvl, wntsnb;
00083 integer hswork;
00084 logical wntsne;
00085 real smlnum;
00086 logical lquery, wantvr, wntsnn, wntsnv;
00087
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
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 a_dim1 = *lda;
00295 a_offset = 1 + a_dim1;
00296 a -= a_offset;
00297 --wr;
00298 --wi;
00299 vl_dim1 = *ldvl;
00300 vl_offset = 1 + vl_dim1;
00301 vl -= vl_offset;
00302 vr_dim1 = *ldvr;
00303 vr_offset = 1 + vr_dim1;
00304 vr -= vr_offset;
00305 --scale;
00306 --rconde;
00307 --rcondv;
00308 --work;
00309 --iwork;
00310
00311
00312 *info = 0;
00313 lquery = *lwork == -1;
00314 wantvl = lsame_(jobvl, "V");
00315 wantvr = lsame_(jobvr, "V");
00316 wntsnn = lsame_(sense, "N");
00317 wntsne = lsame_(sense, "E");
00318 wntsnv = lsame_(sense, "V");
00319 wntsnb = lsame_(sense, "B");
00320 if (! (lsame_(balanc, "N") || lsame_(balanc, "S") || lsame_(balanc, "P")
00321 || lsame_(balanc, "B"))) {
00322 *info = -1;
00323 } else if (! wantvl && ! lsame_(jobvl, "N")) {
00324 *info = -2;
00325 } else if (! wantvr && ! lsame_(jobvr, "N")) {
00326 *info = -3;
00327 } else if (! (wntsnn || wntsne || wntsnb || wntsnv) || (wntsne || wntsnb)
00328 && ! (wantvl && wantvr)) {
00329 *info = -4;
00330 } else if (*n < 0) {
00331 *info = -5;
00332 } else if (*lda < max(1,*n)) {
00333 *info = -7;
00334 } else if (*ldvl < 1 || wantvl && *ldvl < *n) {
00335 *info = -11;
00336 } else if (*ldvr < 1 || wantvr && *ldvr < *n) {
00337 *info = -13;
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 if (*info == 0) {
00351 if (*n == 0) {
00352 minwrk = 1;
00353 maxwrk = 1;
00354 } else {
00355 maxwrk = *n + *n * ilaenv_(&c__1, "SGEHRD", " ", n, &c__1, n, &
00356 c__0);
00357
00358 if (wantvl) {
00359 shseqr_("S", "V", n, &c__1, n, &a[a_offset], lda, &wr[1], &wi[
00360 1], &vl[vl_offset], ldvl, &work[1], &c_n1, info);
00361 } else if (wantvr) {
00362 shseqr_("S", "V", n, &c__1, n, &a[a_offset], lda, &wr[1], &wi[
00363 1], &vr[vr_offset], ldvr, &work[1], &c_n1, info);
00364 } else {
00365 if (wntsnn) {
00366 shseqr_("E", "N", n, &c__1, n, &a[a_offset], lda, &wr[1],
00367 &wi[1], &vr[vr_offset], ldvr, &work[1], &c_n1,
00368 info);
00369 } else {
00370 shseqr_("S", "N", n, &c__1, n, &a[a_offset], lda, &wr[1],
00371 &wi[1], &vr[vr_offset], ldvr, &work[1], &c_n1,
00372 info);
00373 }
00374 }
00375 hswork = work[1];
00376
00377 if (! wantvl && ! wantvr) {
00378 minwrk = *n << 1;
00379 if (! wntsnn) {
00380
00381 i__1 = minwrk, i__2 = *n * *n + *n * 6;
00382 minwrk = max(i__1,i__2);
00383 }
00384 maxwrk = max(maxwrk,hswork);
00385 if (! wntsnn) {
00386
00387 i__1 = maxwrk, i__2 = *n * *n + *n * 6;
00388 maxwrk = max(i__1,i__2);
00389 }
00390 } else {
00391 minwrk = *n * 3;
00392 if (! wntsnn && ! wntsne) {
00393
00394 i__1 = minwrk, i__2 = *n * *n + *n * 6;
00395 minwrk = max(i__1,i__2);
00396 }
00397 maxwrk = max(maxwrk,hswork);
00398
00399 i__1 = maxwrk, i__2 = *n + (*n - 1) * ilaenv_(&c__1, "SORGHR",
00400 " ", n, &c__1, n, &c_n1);
00401 maxwrk = max(i__1,i__2);
00402 if (! wntsnn && ! wntsne) {
00403
00404 i__1 = maxwrk, i__2 = *n * *n + *n * 6;
00405 maxwrk = max(i__1,i__2);
00406 }
00407
00408 i__1 = maxwrk, i__2 = *n * 3;
00409 maxwrk = max(i__1,i__2);
00410 }
00411 maxwrk = max(maxwrk,minwrk);
00412 }
00413 work[1] = (real) maxwrk;
00414
00415 if (*lwork < minwrk && ! lquery) {
00416 *info = -21;
00417 }
00418 }
00419
00420 if (*info != 0) {
00421 i__1 = -(*info);
00422 xerbla_("SGEEVX", &i__1);
00423 return 0;
00424 } else if (lquery) {
00425 return 0;
00426 }
00427
00428
00429
00430 if (*n == 0) {
00431 return 0;
00432 }
00433
00434
00435
00436 eps = slamch_("P");
00437 smlnum = slamch_("S");
00438 bignum = 1.f / smlnum;
00439 slabad_(&smlnum, &bignum);
00440 smlnum = sqrt(smlnum) / eps;
00441 bignum = 1.f / smlnum;
00442
00443
00444
00445 icond = 0;
00446 anrm = slange_("M", n, n, &a[a_offset], lda, dum);
00447 scalea = FALSE_;
00448 if (anrm > 0.f && anrm < smlnum) {
00449 scalea = TRUE_;
00450 cscale = smlnum;
00451 } else if (anrm > bignum) {
00452 scalea = TRUE_;
00453 cscale = bignum;
00454 }
00455 if (scalea) {
00456 slascl_("G", &c__0, &c__0, &anrm, &cscale, n, n, &a[a_offset], lda, &
00457 ierr);
00458 }
00459
00460
00461
00462 sgebal_(balanc, n, &a[a_offset], lda, ilo, ihi, &scale[1], &ierr);
00463 *abnrm = slange_("1", n, n, &a[a_offset], lda, dum);
00464 if (scalea) {
00465 dum[0] = *abnrm;
00466 slascl_("G", &c__0, &c__0, &cscale, &anrm, &c__1, &c__1, dum, &c__1, &
00467 ierr);
00468 *abnrm = dum[0];
00469 }
00470
00471
00472
00473
00474 itau = 1;
00475 iwrk = itau + *n;
00476 i__1 = *lwork - iwrk + 1;
00477 sgehrd_(n, ilo, ihi, &a[a_offset], lda, &work[itau], &work[iwrk], &i__1, &
00478 ierr);
00479
00480 if (wantvl) {
00481
00482
00483
00484
00485 *(unsigned char *)side = 'L';
00486 slacpy_("L", n, n, &a[a_offset], lda, &vl[vl_offset], ldvl)
00487 ;
00488
00489
00490
00491
00492 i__1 = *lwork - iwrk + 1;
00493 sorghr_(n, ilo, ihi, &vl[vl_offset], ldvl, &work[itau], &work[iwrk], &
00494 i__1, &ierr);
00495
00496
00497
00498
00499 iwrk = itau;
00500 i__1 = *lwork - iwrk + 1;
00501 shseqr_("S", "V", n, ilo, ihi, &a[a_offset], lda, &wr[1], &wi[1], &vl[
00502 vl_offset], ldvl, &work[iwrk], &i__1, info);
00503
00504 if (wantvr) {
00505
00506
00507
00508
00509 *(unsigned char *)side = 'B';
00510 slacpy_("F", n, n, &vl[vl_offset], ldvl, &vr[vr_offset], ldvr);
00511 }
00512
00513 } else if (wantvr) {
00514
00515
00516
00517
00518 *(unsigned char *)side = 'R';
00519 slacpy_("L", n, n, &a[a_offset], lda, &vr[vr_offset], ldvr)
00520 ;
00521
00522
00523
00524
00525 i__1 = *lwork - iwrk + 1;
00526 sorghr_(n, ilo, ihi, &vr[vr_offset], ldvr, &work[itau], &work[iwrk], &
00527 i__1, &ierr);
00528
00529
00530
00531
00532 iwrk = itau;
00533 i__1 = *lwork - iwrk + 1;
00534 shseqr_("S", "V", n, ilo, ihi, &a[a_offset], lda, &wr[1], &wi[1], &vr[
00535 vr_offset], ldvr, &work[iwrk], &i__1, info);
00536
00537 } else {
00538
00539
00540
00541
00542 if (wntsnn) {
00543 *(unsigned char *)job = 'E';
00544 } else {
00545 *(unsigned char *)job = 'S';
00546 }
00547
00548
00549
00550 iwrk = itau;
00551 i__1 = *lwork - iwrk + 1;
00552 shseqr_(job, "N", n, ilo, ihi, &a[a_offset], lda, &wr[1], &wi[1], &vr[
00553 vr_offset], ldvr, &work[iwrk], &i__1, info);
00554 }
00555
00556
00557
00558 if (*info > 0) {
00559 goto L50;
00560 }
00561
00562 if (wantvl || wantvr) {
00563
00564
00565
00566
00567 strevc_(side, "B", select, n, &a[a_offset], lda, &vl[vl_offset], ldvl,
00568 &vr[vr_offset], ldvr, n, &nout, &work[iwrk], &ierr);
00569 }
00570
00571
00572
00573
00574 if (! wntsnn) {
00575 strsna_(sense, "A", select, n, &a[a_offset], lda, &vl[vl_offset],
00576 ldvl, &vr[vr_offset], ldvr, &rconde[1], &rcondv[1], n, &nout,
00577 &work[iwrk], n, &iwork[1], &icond);
00578 }
00579
00580 if (wantvl) {
00581
00582
00583
00584 sgebak_(balanc, "L", n, ilo, ihi, &scale[1], n, &vl[vl_offset], ldvl,
00585 &ierr);
00586
00587
00588
00589 i__1 = *n;
00590 for (i__ = 1; i__ <= i__1; ++i__) {
00591 if (wi[i__] == 0.f) {
00592 scl = 1.f / snrm2_(n, &vl[i__ * vl_dim1 + 1], &c__1);
00593 sscal_(n, &scl, &vl[i__ * vl_dim1 + 1], &c__1);
00594 } else if (wi[i__] > 0.f) {
00595 r__1 = snrm2_(n, &vl[i__ * vl_dim1 + 1], &c__1);
00596 r__2 = snrm2_(n, &vl[(i__ + 1) * vl_dim1 + 1], &c__1);
00597 scl = 1.f / slapy2_(&r__1, &r__2);
00598 sscal_(n, &scl, &vl[i__ * vl_dim1 + 1], &c__1);
00599 sscal_(n, &scl, &vl[(i__ + 1) * vl_dim1 + 1], &c__1);
00600 i__2 = *n;
00601 for (k = 1; k <= i__2; ++k) {
00602
00603 r__1 = vl[k + i__ * vl_dim1];
00604
00605 r__2 = vl[k + (i__ + 1) * vl_dim1];
00606 work[k] = r__1 * r__1 + r__2 * r__2;
00607
00608 }
00609 k = isamax_(n, &work[1], &c__1);
00610 slartg_(&vl[k + i__ * vl_dim1], &vl[k + (i__ + 1) * vl_dim1],
00611 &cs, &sn, &r__);
00612 srot_(n, &vl[i__ * vl_dim1 + 1], &c__1, &vl[(i__ + 1) *
00613 vl_dim1 + 1], &c__1, &cs, &sn);
00614 vl[k + (i__ + 1) * vl_dim1] = 0.f;
00615 }
00616
00617 }
00618 }
00619
00620 if (wantvr) {
00621
00622
00623
00624 sgebak_(balanc, "R", n, ilo, ihi, &scale[1], n, &vr[vr_offset], ldvr,
00625 &ierr);
00626
00627
00628
00629 i__1 = *n;
00630 for (i__ = 1; i__ <= i__1; ++i__) {
00631 if (wi[i__] == 0.f) {
00632 scl = 1.f / snrm2_(n, &vr[i__ * vr_dim1 + 1], &c__1);
00633 sscal_(n, &scl, &vr[i__ * vr_dim1 + 1], &c__1);
00634 } else if (wi[i__] > 0.f) {
00635 r__1 = snrm2_(n, &vr[i__ * vr_dim1 + 1], &c__1);
00636 r__2 = snrm2_(n, &vr[(i__ + 1) * vr_dim1 + 1], &c__1);
00637 scl = 1.f / slapy2_(&r__1, &r__2);
00638 sscal_(n, &scl, &vr[i__ * vr_dim1 + 1], &c__1);
00639 sscal_(n, &scl, &vr[(i__ + 1) * vr_dim1 + 1], &c__1);
00640 i__2 = *n;
00641 for (k = 1; k <= i__2; ++k) {
00642
00643 r__1 = vr[k + i__ * vr_dim1];
00644
00645 r__2 = vr[k + (i__ + 1) * vr_dim1];
00646 work[k] = r__1 * r__1 + r__2 * r__2;
00647
00648 }
00649 k = isamax_(n, &work[1], &c__1);
00650 slartg_(&vr[k + i__ * vr_dim1], &vr[k + (i__ + 1) * vr_dim1],
00651 &cs, &sn, &r__);
00652 srot_(n, &vr[i__ * vr_dim1 + 1], &c__1, &vr[(i__ + 1) *
00653 vr_dim1 + 1], &c__1, &cs, &sn);
00654 vr[k + (i__ + 1) * vr_dim1] = 0.f;
00655 }
00656
00657 }
00658 }
00659
00660
00661
00662 L50:
00663 if (scalea) {
00664 i__1 = *n - *info;
00665
00666 i__3 = *n - *info;
00667 i__2 = max(i__3,1);
00668 slascl_("G", &c__0, &c__0, &cscale, &anrm, &i__1, &c__1, &wr[*info +
00669 1], &i__2, &ierr);
00670 i__1 = *n - *info;
00671
00672 i__3 = *n - *info;
00673 i__2 = max(i__3,1);
00674 slascl_("G", &c__0, &c__0, &cscale, &anrm, &i__1, &c__1, &wi[*info +
00675 1], &i__2, &ierr);
00676 if (*info == 0) {
00677 if ((wntsnv || wntsnb) && icond == 0) {
00678 slascl_("G", &c__0, &c__0, &cscale, &anrm, n, &c__1, &rcondv[
00679 1], n, &ierr);
00680 }
00681 } else {
00682 i__1 = *ilo - 1;
00683 slascl_("G", &c__0, &c__0, &cscale, &anrm, &i__1, &c__1, &wr[1],
00684 n, &ierr);
00685 i__1 = *ilo - 1;
00686 slascl_("G", &c__0, &c__0, &cscale, &anrm, &i__1, &c__1, &wi[1],
00687 n, &ierr);
00688 }
00689 }
00690
00691 work[1] = (real) maxwrk;
00692 return 0;
00693
00694
00695
00696 }