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
00020 int dlahqr_(logical *wantt, logical *wantz, integer *n,
00021 integer *ilo, integer *ihi, doublereal *h__, integer *ldh, doublereal
00022 *wr, doublereal *wi, integer *iloz, integer *ihiz, doublereal *z__,
00023 integer *ldz, integer *info)
00024 {
00025
00026 integer h_dim1, h_offset, z_dim1, z_offset, i__1, i__2, i__3;
00027 doublereal d__1, d__2, d__3, d__4;
00028
00029
00030 double sqrt(doublereal);
00031
00032
00033 integer i__, j, k, l, m;
00034 doublereal s, v[3];
00035 integer i1, i2;
00036 doublereal t1, t2, t3, v2, v3, aa, ab, ba, bb, h11, h12, h21, h22, cs;
00037 integer nh;
00038 doublereal sn;
00039 integer nr;
00040 doublereal tr;
00041 integer nz;
00042 doublereal det, h21s;
00043 integer its;
00044 doublereal ulp, sum, tst, rt1i, rt2i, rt1r, rt2r;
00045 extern int drot_(integer *, doublereal *, integer *,
00046 doublereal *, integer *, doublereal *, doublereal *), dcopy_(
00047 integer *, doublereal *, integer *, doublereal *, integer *),
00048 dlanv2_(doublereal *, doublereal *, doublereal *, doublereal *,
00049 doublereal *, doublereal *, doublereal *, doublereal *,
00050 doublereal *, doublereal *), dlabad_(doublereal *, doublereal *);
00051 extern doublereal dlamch_(char *);
00052 extern int dlarfg_(integer *, doublereal *, doublereal *,
00053 integer *, doublereal *);
00054 doublereal safmin, safmax, rtdisc, smlnum;
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
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
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 h_dim1 = *ldh;
00194 h_offset = 1 + h_dim1;
00195 h__ -= h_offset;
00196 --wr;
00197 --wi;
00198 z_dim1 = *ldz;
00199 z_offset = 1 + z_dim1;
00200 z__ -= z_offset;
00201
00202
00203 *info = 0;
00204
00205
00206
00207 if (*n == 0) {
00208 return 0;
00209 }
00210 if (*ilo == *ihi) {
00211 wr[*ilo] = h__[*ilo + *ilo * h_dim1];
00212 wi[*ilo] = 0.;
00213 return 0;
00214 }
00215
00216
00217 i__1 = *ihi - 3;
00218 for (j = *ilo; j <= i__1; ++j) {
00219 h__[j + 2 + j * h_dim1] = 0.;
00220 h__[j + 3 + j * h_dim1] = 0.;
00221
00222 }
00223 if (*ilo <= *ihi - 2) {
00224 h__[*ihi + (*ihi - 2) * h_dim1] = 0.;
00225 }
00226
00227 nh = *ihi - *ilo + 1;
00228 nz = *ihiz - *iloz + 1;
00229
00230
00231
00232 safmin = dlamch_("SAFE MINIMUM");
00233 safmax = 1. / safmin;
00234 dlabad_(&safmin, &safmax);
00235 ulp = dlamch_("PRECISION");
00236 smlnum = safmin * ((doublereal) nh / ulp);
00237
00238
00239
00240
00241
00242 if (*wantt) {
00243 i1 = 1;
00244 i2 = *n;
00245 }
00246
00247
00248
00249
00250
00251
00252
00253 i__ = *ihi;
00254 L20:
00255 l = *ilo;
00256 if (i__ < *ilo) {
00257 goto L160;
00258 }
00259
00260
00261
00262
00263
00264 for (its = 0; its <= 30; ++its) {
00265
00266
00267
00268 i__1 = l + 1;
00269 for (k = i__; k >= i__1; --k) {
00270 if ((d__1 = h__[k + (k - 1) * h_dim1], abs(d__1)) <= smlnum) {
00271 goto L40;
00272 }
00273 tst = (d__1 = h__[k - 1 + (k - 1) * h_dim1], abs(d__1)) + (d__2 =
00274 h__[k + k * h_dim1], abs(d__2));
00275 if (tst == 0.) {
00276 if (k - 2 >= *ilo) {
00277 tst += (d__1 = h__[k - 1 + (k - 2) * h_dim1], abs(d__1));
00278 }
00279 if (k + 1 <= *ihi) {
00280 tst += (d__1 = h__[k + 1 + k * h_dim1], abs(d__1));
00281 }
00282 }
00283
00284
00285
00286
00287 if ((d__1 = h__[k + (k - 1) * h_dim1], abs(d__1)) <= ulp * tst) {
00288
00289 d__3 = (d__1 = h__[k + (k - 1) * h_dim1], abs(d__1)), d__4 = (
00290 d__2 = h__[k - 1 + k * h_dim1], abs(d__2));
00291 ab = max(d__3,d__4);
00292
00293 d__3 = (d__1 = h__[k + (k - 1) * h_dim1], abs(d__1)), d__4 = (
00294 d__2 = h__[k - 1 + k * h_dim1], abs(d__2));
00295 ba = min(d__3,d__4);
00296
00297 d__3 = (d__1 = h__[k + k * h_dim1], abs(d__1)), d__4 = (d__2 =
00298 h__[k - 1 + (k - 1) * h_dim1] - h__[k + k * h_dim1],
00299 abs(d__2));
00300 aa = max(d__3,d__4);
00301
00302 d__3 = (d__1 = h__[k + k * h_dim1], abs(d__1)), d__4 = (d__2 =
00303 h__[k - 1 + (k - 1) * h_dim1] - h__[k + k * h_dim1],
00304 abs(d__2));
00305 bb = min(d__3,d__4);
00306 s = aa + ab;
00307
00308 d__1 = smlnum, d__2 = ulp * (bb * (aa / s));
00309 if (ba * (ab / s) <= max(d__1,d__2)) {
00310 goto L40;
00311 }
00312 }
00313
00314 }
00315 L40:
00316 l = k;
00317 if (l > *ilo) {
00318
00319
00320
00321 h__[l + (l - 1) * h_dim1] = 0.;
00322 }
00323
00324
00325
00326 if (l >= i__ - 1) {
00327 goto L150;
00328 }
00329
00330
00331
00332
00333
00334 if (! (*wantt)) {
00335 i1 = l;
00336 i2 = i__;
00337 }
00338
00339 if (its == 10) {
00340
00341
00342
00343 s = (d__1 = h__[l + 1 + l * h_dim1], abs(d__1)) + (d__2 = h__[l +
00344 2 + (l + 1) * h_dim1], abs(d__2));
00345 h11 = s * .75 + h__[l + l * h_dim1];
00346 h12 = s * -.4375;
00347 h21 = s;
00348 h22 = h11;
00349 } else if (its == 20) {
00350
00351
00352
00353 s = (d__1 = h__[i__ + (i__ - 1) * h_dim1], abs(d__1)) + (d__2 =
00354 h__[i__ - 1 + (i__ - 2) * h_dim1], abs(d__2));
00355 h11 = s * .75 + h__[i__ + i__ * h_dim1];
00356 h12 = s * -.4375;
00357 h21 = s;
00358 h22 = h11;
00359 } else {
00360
00361
00362
00363
00364 h11 = h__[i__ - 1 + (i__ - 1) * h_dim1];
00365 h21 = h__[i__ + (i__ - 1) * h_dim1];
00366 h12 = h__[i__ - 1 + i__ * h_dim1];
00367 h22 = h__[i__ + i__ * h_dim1];
00368 }
00369 s = abs(h11) + abs(h12) + abs(h21) + abs(h22);
00370 if (s == 0.) {
00371 rt1r = 0.;
00372 rt1i = 0.;
00373 rt2r = 0.;
00374 rt2i = 0.;
00375 } else {
00376 h11 /= s;
00377 h21 /= s;
00378 h12 /= s;
00379 h22 /= s;
00380 tr = (h11 + h22) / 2.;
00381 det = (h11 - tr) * (h22 - tr) - h12 * h21;
00382 rtdisc = sqrt((abs(det)));
00383 if (det >= 0.) {
00384
00385
00386
00387 rt1r = tr * s;
00388 rt2r = rt1r;
00389 rt1i = rtdisc * s;
00390 rt2i = -rt1i;
00391 } else {
00392
00393
00394
00395 rt1r = tr + rtdisc;
00396 rt2r = tr - rtdisc;
00397 if ((d__1 = rt1r - h22, abs(d__1)) <= (d__2 = rt2r - h22, abs(
00398 d__2))) {
00399 rt1r *= s;
00400 rt2r = rt1r;
00401 } else {
00402 rt2r *= s;
00403 rt1r = rt2r;
00404 }
00405 rt1i = 0.;
00406 rt2i = 0.;
00407 }
00408 }
00409
00410
00411
00412 i__1 = l;
00413 for (m = i__ - 2; m >= i__1; --m) {
00414
00415
00416
00417
00418
00419 h21s = h__[m + 1 + m * h_dim1];
00420 s = (d__1 = h__[m + m * h_dim1] - rt2r, abs(d__1)) + abs(rt2i) +
00421 abs(h21s);
00422 h21s = h__[m + 1 + m * h_dim1] / s;
00423 v[0] = h21s * h__[m + (m + 1) * h_dim1] + (h__[m + m * h_dim1] -
00424 rt1r) * ((h__[m + m * h_dim1] - rt2r) / s) - rt1i * (rt2i
00425 / s);
00426 v[1] = h21s * (h__[m + m * h_dim1] + h__[m + 1 + (m + 1) * h_dim1]
00427 - rt1r - rt2r);
00428 v[2] = h21s * h__[m + 2 + (m + 1) * h_dim1];
00429 s = abs(v[0]) + abs(v[1]) + abs(v[2]);
00430 v[0] /= s;
00431 v[1] /= s;
00432 v[2] /= s;
00433 if (m == l) {
00434 goto L60;
00435 }
00436 if ((d__1 = h__[m + (m - 1) * h_dim1], abs(d__1)) * (abs(v[1]) +
00437 abs(v[2])) <= ulp * abs(v[0]) * ((d__2 = h__[m - 1 + (m -
00438 1) * h_dim1], abs(d__2)) + (d__3 = h__[m + m * h_dim1],
00439 abs(d__3)) + (d__4 = h__[m + 1 + (m + 1) * h_dim1], abs(
00440 d__4)))) {
00441 goto L60;
00442 }
00443
00444 }
00445 L60:
00446
00447
00448
00449 i__1 = i__ - 1;
00450 for (k = m; k <= i__1; ++k) {
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462 i__2 = 3, i__3 = i__ - k + 1;
00463 nr = min(i__2,i__3);
00464 if (k > m) {
00465 dcopy_(&nr, &h__[k + (k - 1) * h_dim1], &c__1, v, &c__1);
00466 }
00467 dlarfg_(&nr, v, &v[1], &c__1, &t1);
00468 if (k > m) {
00469 h__[k + (k - 1) * h_dim1] = v[0];
00470 h__[k + 1 + (k - 1) * h_dim1] = 0.;
00471 if (k < i__ - 1) {
00472 h__[k + 2 + (k - 1) * h_dim1] = 0.;
00473 }
00474 } else if (m > l) {
00475
00476
00477
00478
00479 h__[k + (k - 1) * h_dim1] *= 1. - t1;
00480 }
00481 v2 = v[1];
00482 t2 = t1 * v2;
00483 if (nr == 3) {
00484 v3 = v[2];
00485 t3 = t1 * v3;
00486
00487
00488
00489
00490 i__2 = i2;
00491 for (j = k; j <= i__2; ++j) {
00492 sum = h__[k + j * h_dim1] + v2 * h__[k + 1 + j * h_dim1]
00493 + v3 * h__[k + 2 + j * h_dim1];
00494 h__[k + j * h_dim1] -= sum * t1;
00495 h__[k + 1 + j * h_dim1] -= sum * t2;
00496 h__[k + 2 + j * h_dim1] -= sum * t3;
00497
00498 }
00499
00500
00501
00502
00503
00504 i__3 = k + 3;
00505 i__2 = min(i__3,i__);
00506 for (j = i1; j <= i__2; ++j) {
00507 sum = h__[j + k * h_dim1] + v2 * h__[j + (k + 1) * h_dim1]
00508 + v3 * h__[j + (k + 2) * h_dim1];
00509 h__[j + k * h_dim1] -= sum * t1;
00510 h__[j + (k + 1) * h_dim1] -= sum * t2;
00511 h__[j + (k + 2) * h_dim1] -= sum * t3;
00512
00513 }
00514
00515 if (*wantz) {
00516
00517
00518
00519 i__2 = *ihiz;
00520 for (j = *iloz; j <= i__2; ++j) {
00521 sum = z__[j + k * z_dim1] + v2 * z__[j + (k + 1) *
00522 z_dim1] + v3 * z__[j + (k + 2) * z_dim1];
00523 z__[j + k * z_dim1] -= sum * t1;
00524 z__[j + (k + 1) * z_dim1] -= sum * t2;
00525 z__[j + (k + 2) * z_dim1] -= sum * t3;
00526
00527 }
00528 }
00529 } else if (nr == 2) {
00530
00531
00532
00533
00534 i__2 = i2;
00535 for (j = k; j <= i__2; ++j) {
00536 sum = h__[k + j * h_dim1] + v2 * h__[k + 1 + j * h_dim1];
00537 h__[k + j * h_dim1] -= sum * t1;
00538 h__[k + 1 + j * h_dim1] -= sum * t2;
00539
00540 }
00541
00542
00543
00544
00545 i__2 = i__;
00546 for (j = i1; j <= i__2; ++j) {
00547 sum = h__[j + k * h_dim1] + v2 * h__[j + (k + 1) * h_dim1]
00548 ;
00549 h__[j + k * h_dim1] -= sum * t1;
00550 h__[j + (k + 1) * h_dim1] -= sum * t2;
00551
00552 }
00553
00554 if (*wantz) {
00555
00556
00557
00558 i__2 = *ihiz;
00559 for (j = *iloz; j <= i__2; ++j) {
00560 sum = z__[j + k * z_dim1] + v2 * z__[j + (k + 1) *
00561 z_dim1];
00562 z__[j + k * z_dim1] -= sum * t1;
00563 z__[j + (k + 1) * z_dim1] -= sum * t2;
00564
00565 }
00566 }
00567 }
00568
00569 }
00570
00571
00572 }
00573
00574
00575
00576 *info = i__;
00577 return 0;
00578
00579 L150:
00580
00581 if (l == i__) {
00582
00583
00584
00585 wr[i__] = h__[i__ + i__ * h_dim1];
00586 wi[i__] = 0.;
00587 } else if (l == i__ - 1) {
00588
00589
00590
00591
00592
00593
00594 dlanv2_(&h__[i__ - 1 + (i__ - 1) * h_dim1], &h__[i__ - 1 + i__ *
00595 h_dim1], &h__[i__ + (i__ - 1) * h_dim1], &h__[i__ + i__ *
00596 h_dim1], &wr[i__ - 1], &wi[i__ - 1], &wr[i__], &wi[i__], &cs,
00597 &sn);
00598
00599 if (*wantt) {
00600
00601
00602
00603 if (i2 > i__) {
00604 i__1 = i2 - i__;
00605 drot_(&i__1, &h__[i__ - 1 + (i__ + 1) * h_dim1], ldh, &h__[
00606 i__ + (i__ + 1) * h_dim1], ldh, &cs, &sn);
00607 }
00608 i__1 = i__ - i1 - 1;
00609 drot_(&i__1, &h__[i1 + (i__ - 1) * h_dim1], &c__1, &h__[i1 + i__ *
00610 h_dim1], &c__1, &cs, &sn);
00611 }
00612 if (*wantz) {
00613
00614
00615
00616 drot_(&nz, &z__[*iloz + (i__ - 1) * z_dim1], &c__1, &z__[*iloz +
00617 i__ * z_dim1], &c__1, &cs, &sn);
00618 }
00619 }
00620
00621
00622
00623 i__ = l - 1;
00624 goto L20;
00625
00626 L160:
00627 return 0;
00628
00629
00630
00631 }