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 real c_b9 = 0.f;
00019 static real c_b10 = 1.f;
00020 static integer c__0 = 0;
00021 static integer c__1 = 1;
00022 static integer c__2 = 2;
00023
00024 int ssteqr_(char *compz, integer *n, real *d__, real *e,
00025 real *z__, integer *ldz, real *work, integer *info)
00026 {
00027
00028 integer z_dim1, z_offset, i__1, i__2;
00029 real r__1, r__2;
00030
00031
00032 double sqrt(doublereal), r_sign(real *, real *);
00033
00034
00035 real b, c__, f, g;
00036 integer i__, j, k, l, m;
00037 real p, r__, s;
00038 integer l1, ii, mm, lm1, mm1, nm1;
00039 real rt1, rt2, eps;
00040 integer lsv;
00041 real tst, eps2;
00042 integer lend, jtot;
00043 extern int slae2_(real *, real *, real *, real *, real *)
00044 ;
00045 extern logical lsame_(char *, char *);
00046 real anorm;
00047 extern int slasr_(char *, char *, char *, integer *,
00048 integer *, real *, real *, real *, integer *), sswap_(integer *, real *, integer *, real *, integer *);
00049 integer lendm1, lendp1;
00050 extern int slaev2_(real *, real *, real *, real *, real *
00051 , real *, real *);
00052 extern doublereal slapy2_(real *, real *);
00053 integer iscale;
00054 extern doublereal slamch_(char *);
00055 real safmin;
00056 extern int xerbla_(char *, integer *);
00057 real safmax;
00058 extern int slascl_(char *, integer *, integer *, real *,
00059 real *, integer *, integer *, real *, integer *, integer *);
00060 integer lendsv;
00061 extern int slartg_(real *, real *, real *, real *, real *
00062 ), slaset_(char *, integer *, integer *, real *, real *, real *,
00063 integer *);
00064 real ssfmin;
00065 integer nmaxit, icompz;
00066 real ssfmax;
00067 extern doublereal slanst_(char *, integer *, real *, real *);
00068 extern int slasrt_(char *, integer *, real *, integer *);
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
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 --d__;
00158 --e;
00159 z_dim1 = *ldz;
00160 z_offset = 1 + z_dim1;
00161 z__ -= z_offset;
00162 --work;
00163
00164
00165 *info = 0;
00166
00167 if (lsame_(compz, "N")) {
00168 icompz = 0;
00169 } else if (lsame_(compz, "V")) {
00170 icompz = 1;
00171 } else if (lsame_(compz, "I")) {
00172 icompz = 2;
00173 } else {
00174 icompz = -1;
00175 }
00176 if (icompz < 0) {
00177 *info = -1;
00178 } else if (*n < 0) {
00179 *info = -2;
00180 } else if (*ldz < 1 || icompz > 0 && *ldz < max(1,*n)) {
00181 *info = -6;
00182 }
00183 if (*info != 0) {
00184 i__1 = -(*info);
00185 xerbla_("SSTEQR", &i__1);
00186 return 0;
00187 }
00188
00189
00190
00191 if (*n == 0) {
00192 return 0;
00193 }
00194
00195 if (*n == 1) {
00196 if (icompz == 2) {
00197 z__[z_dim1 + 1] = 1.f;
00198 }
00199 return 0;
00200 }
00201
00202
00203
00204 eps = slamch_("E");
00205
00206 r__1 = eps;
00207 eps2 = r__1 * r__1;
00208 safmin = slamch_("S");
00209 safmax = 1.f / safmin;
00210 ssfmax = sqrt(safmax) / 3.f;
00211 ssfmin = sqrt(safmin) / eps2;
00212
00213
00214
00215
00216 if (icompz == 2) {
00217 slaset_("Full", n, n, &c_b9, &c_b10, &z__[z_offset], ldz);
00218 }
00219
00220 nmaxit = *n * 30;
00221 jtot = 0;
00222
00223
00224
00225
00226
00227 l1 = 1;
00228 nm1 = *n - 1;
00229
00230 L10:
00231 if (l1 > *n) {
00232 goto L160;
00233 }
00234 if (l1 > 1) {
00235 e[l1 - 1] = 0.f;
00236 }
00237 if (l1 <= nm1) {
00238 i__1 = nm1;
00239 for (m = l1; m <= i__1; ++m) {
00240 tst = (r__1 = e[m], dabs(r__1));
00241 if (tst == 0.f) {
00242 goto L30;
00243 }
00244 if (tst <= sqrt((r__1 = d__[m], dabs(r__1))) * sqrt((r__2 = d__[m
00245 + 1], dabs(r__2))) * eps) {
00246 e[m] = 0.f;
00247 goto L30;
00248 }
00249
00250 }
00251 }
00252 m = *n;
00253
00254 L30:
00255 l = l1;
00256 lsv = l;
00257 lend = m;
00258 lendsv = lend;
00259 l1 = m + 1;
00260 if (lend == l) {
00261 goto L10;
00262 }
00263
00264
00265
00266 i__1 = lend - l + 1;
00267 anorm = slanst_("I", &i__1, &d__[l], &e[l]);
00268 iscale = 0;
00269 if (anorm == 0.f) {
00270 goto L10;
00271 }
00272 if (anorm > ssfmax) {
00273 iscale = 1;
00274 i__1 = lend - l + 1;
00275 slascl_("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &d__[l], n,
00276 info);
00277 i__1 = lend - l;
00278 slascl_("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &e[l], n,
00279 info);
00280 } else if (anorm < ssfmin) {
00281 iscale = 2;
00282 i__1 = lend - l + 1;
00283 slascl_("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &d__[l], n,
00284 info);
00285 i__1 = lend - l;
00286 slascl_("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &e[l], n,
00287 info);
00288 }
00289
00290
00291
00292 if ((r__1 = d__[lend], dabs(r__1)) < (r__2 = d__[l], dabs(r__2))) {
00293 lend = lsv;
00294 l = lendsv;
00295 }
00296
00297 if (lend > l) {
00298
00299
00300
00301
00302
00303 L40:
00304 if (l != lend) {
00305 lendm1 = lend - 1;
00306 i__1 = lendm1;
00307 for (m = l; m <= i__1; ++m) {
00308
00309 r__2 = (r__1 = e[m], dabs(r__1));
00310 tst = r__2 * r__2;
00311 if (tst <= eps2 * (r__1 = d__[m], dabs(r__1)) * (r__2 = d__[m
00312 + 1], dabs(r__2)) + safmin) {
00313 goto L60;
00314 }
00315
00316 }
00317 }
00318
00319 m = lend;
00320
00321 L60:
00322 if (m < lend) {
00323 e[m] = 0.f;
00324 }
00325 p = d__[l];
00326 if (m == l) {
00327 goto L80;
00328 }
00329
00330
00331
00332
00333 if (m == l + 1) {
00334 if (icompz > 0) {
00335 slaev2_(&d__[l], &e[l], &d__[l + 1], &rt1, &rt2, &c__, &s);
00336 work[l] = c__;
00337 work[*n - 1 + l] = s;
00338 slasr_("R", "V", "B", n, &c__2, &work[l], &work[*n - 1 + l], &
00339 z__[l * z_dim1 + 1], ldz);
00340 } else {
00341 slae2_(&d__[l], &e[l], &d__[l + 1], &rt1, &rt2);
00342 }
00343 d__[l] = rt1;
00344 d__[l + 1] = rt2;
00345 e[l] = 0.f;
00346 l += 2;
00347 if (l <= lend) {
00348 goto L40;
00349 }
00350 goto L140;
00351 }
00352
00353 if (jtot == nmaxit) {
00354 goto L140;
00355 }
00356 ++jtot;
00357
00358
00359
00360 g = (d__[l + 1] - p) / (e[l] * 2.f);
00361 r__ = slapy2_(&g, &c_b10);
00362 g = d__[m] - p + e[l] / (g + r_sign(&r__, &g));
00363
00364 s = 1.f;
00365 c__ = 1.f;
00366 p = 0.f;
00367
00368
00369
00370 mm1 = m - 1;
00371 i__1 = l;
00372 for (i__ = mm1; i__ >= i__1; --i__) {
00373 f = s * e[i__];
00374 b = c__ * e[i__];
00375 slartg_(&g, &f, &c__, &s, &r__);
00376 if (i__ != m - 1) {
00377 e[i__ + 1] = r__;
00378 }
00379 g = d__[i__ + 1] - p;
00380 r__ = (d__[i__] - g) * s + c__ * 2.f * b;
00381 p = s * r__;
00382 d__[i__ + 1] = g + p;
00383 g = c__ * r__ - b;
00384
00385
00386
00387 if (icompz > 0) {
00388 work[i__] = c__;
00389 work[*n - 1 + i__] = -s;
00390 }
00391
00392
00393 }
00394
00395
00396
00397 if (icompz > 0) {
00398 mm = m - l + 1;
00399 slasr_("R", "V", "B", n, &mm, &work[l], &work[*n - 1 + l], &z__[l
00400 * z_dim1 + 1], ldz);
00401 }
00402
00403 d__[l] -= p;
00404 e[l] = g;
00405 goto L40;
00406
00407
00408
00409 L80:
00410 d__[l] = p;
00411
00412 ++l;
00413 if (l <= lend) {
00414 goto L40;
00415 }
00416 goto L140;
00417
00418 } else {
00419
00420
00421
00422
00423
00424 L90:
00425 if (l != lend) {
00426 lendp1 = lend + 1;
00427 i__1 = lendp1;
00428 for (m = l; m >= i__1; --m) {
00429
00430 r__2 = (r__1 = e[m - 1], dabs(r__1));
00431 tst = r__2 * r__2;
00432 if (tst <= eps2 * (r__1 = d__[m], dabs(r__1)) * (r__2 = d__[m
00433 - 1], dabs(r__2)) + safmin) {
00434 goto L110;
00435 }
00436
00437 }
00438 }
00439
00440 m = lend;
00441
00442 L110:
00443 if (m > lend) {
00444 e[m - 1] = 0.f;
00445 }
00446 p = d__[l];
00447 if (m == l) {
00448 goto L130;
00449 }
00450
00451
00452
00453
00454 if (m == l - 1) {
00455 if (icompz > 0) {
00456 slaev2_(&d__[l - 1], &e[l - 1], &d__[l], &rt1, &rt2, &c__, &s)
00457 ;
00458 work[m] = c__;
00459 work[*n - 1 + m] = s;
00460 slasr_("R", "V", "F", n, &c__2, &work[m], &work[*n - 1 + m], &
00461 z__[(l - 1) * z_dim1 + 1], ldz);
00462 } else {
00463 slae2_(&d__[l - 1], &e[l - 1], &d__[l], &rt1, &rt2);
00464 }
00465 d__[l - 1] = rt1;
00466 d__[l] = rt2;
00467 e[l - 1] = 0.f;
00468 l += -2;
00469 if (l >= lend) {
00470 goto L90;
00471 }
00472 goto L140;
00473 }
00474
00475 if (jtot == nmaxit) {
00476 goto L140;
00477 }
00478 ++jtot;
00479
00480
00481
00482 g = (d__[l - 1] - p) / (e[l - 1] * 2.f);
00483 r__ = slapy2_(&g, &c_b10);
00484 g = d__[m] - p + e[l - 1] / (g + r_sign(&r__, &g));
00485
00486 s = 1.f;
00487 c__ = 1.f;
00488 p = 0.f;
00489
00490
00491
00492 lm1 = l - 1;
00493 i__1 = lm1;
00494 for (i__ = m; i__ <= i__1; ++i__) {
00495 f = s * e[i__];
00496 b = c__ * e[i__];
00497 slartg_(&g, &f, &c__, &s, &r__);
00498 if (i__ != m) {
00499 e[i__ - 1] = r__;
00500 }
00501 g = d__[i__] - p;
00502 r__ = (d__[i__ + 1] - g) * s + c__ * 2.f * b;
00503 p = s * r__;
00504 d__[i__] = g + p;
00505 g = c__ * r__ - b;
00506
00507
00508
00509 if (icompz > 0) {
00510 work[i__] = c__;
00511 work[*n - 1 + i__] = s;
00512 }
00513
00514
00515 }
00516
00517
00518
00519 if (icompz > 0) {
00520 mm = l - m + 1;
00521 slasr_("R", "V", "F", n, &mm, &work[m], &work[*n - 1 + m], &z__[m
00522 * z_dim1 + 1], ldz);
00523 }
00524
00525 d__[l] -= p;
00526 e[lm1] = g;
00527 goto L90;
00528
00529
00530
00531 L130:
00532 d__[l] = p;
00533
00534 --l;
00535 if (l >= lend) {
00536 goto L90;
00537 }
00538 goto L140;
00539
00540 }
00541
00542
00543
00544 L140:
00545 if (iscale == 1) {
00546 i__1 = lendsv - lsv + 1;
00547 slascl_("G", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &d__[lsv],
00548 n, info);
00549 i__1 = lendsv - lsv;
00550 slascl_("G", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &e[lsv], n,
00551 info);
00552 } else if (iscale == 2) {
00553 i__1 = lendsv - lsv + 1;
00554 slascl_("G", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &d__[lsv],
00555 n, info);
00556 i__1 = lendsv - lsv;
00557 slascl_("G", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &e[lsv], n,
00558 info);
00559 }
00560
00561
00562
00563
00564 if (jtot < nmaxit) {
00565 goto L10;
00566 }
00567 i__1 = *n - 1;
00568 for (i__ = 1; i__ <= i__1; ++i__) {
00569 if (e[i__] != 0.f) {
00570 ++(*info);
00571 }
00572
00573 }
00574 goto L190;
00575
00576
00577
00578 L160:
00579 if (icompz == 0) {
00580
00581
00582
00583 slasrt_("I", n, &d__[1], info);
00584
00585 } else {
00586
00587
00588
00589 i__1 = *n;
00590 for (ii = 2; ii <= i__1; ++ii) {
00591 i__ = ii - 1;
00592 k = i__;
00593 p = d__[i__];
00594 i__2 = *n;
00595 for (j = ii; j <= i__2; ++j) {
00596 if (d__[j] < p) {
00597 k = j;
00598 p = d__[j];
00599 }
00600
00601 }
00602 if (k != i__) {
00603 d__[k] = d__[i__];
00604 d__[i__] = p;
00605 sswap_(n, &z__[i__ * z_dim1 + 1], &c__1, &z__[k * z_dim1 + 1],
00606 &c__1);
00607 }
00608
00609 }
00610 }
00611
00612 L190:
00613 return 0;
00614
00615
00616
00617 }