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