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_n1 = -1;
00020 static real c_b12 = 0.f;
00021 static real c_b13 = 1.f;
00022 static logical c_true = TRUE_;
00023
00024 int slaqr2_(logical *wantt, logical *wantz, integer *n,
00025 integer *ktop, integer *kbot, integer *nw, real *h__, integer *ldh,
00026 integer *iloz, integer *ihiz, real *z__, integer *ldz, integer *ns,
00027 integer *nd, real *sr, real *si, real *v, integer *ldv, integer *nh,
00028 real *t, integer *ldt, integer *nv, real *wv, integer *ldwv, real *
00029 work, integer *lwork)
00030 {
00031
00032 integer h_dim1, h_offset, t_dim1, t_offset, v_dim1, v_offset, wv_dim1,
00033 wv_offset, z_dim1, z_offset, i__1, i__2, i__3, i__4;
00034 real r__1, r__2, r__3, r__4, r__5, r__6;
00035
00036
00037 double sqrt(doublereal);
00038
00039
00040 integer i__, j, k;
00041 real s, aa, bb, cc, dd, cs, sn;
00042 integer jw;
00043 real evi, evk, foo;
00044 integer kln;
00045 real tau, ulp;
00046 integer lwk1, lwk2;
00047 real beta;
00048 integer kend, kcol, info, ifst, ilst, ltop, krow;
00049 logical bulge;
00050 extern int slarf_(char *, integer *, integer *, real *,
00051 integer *, real *, real *, integer *, real *), sgemm_(
00052 char *, char *, integer *, integer *, integer *, real *, real *,
00053 integer *, real *, integer *, real *, real *, integer *);
00054 integer infqr;
00055 extern int scopy_(integer *, real *, integer *, real *,
00056 integer *);
00057 integer kwtop;
00058 extern int slanv2_(real *, real *, real *, real *, real *
00059 , real *, real *, real *, real *, real *), slabad_(real *, real *)
00060 ;
00061 extern doublereal slamch_(char *);
00062 extern int sgehrd_(integer *, integer *, integer *, real
00063 *, integer *, real *, real *, integer *, integer *);
00064 real safmin;
00065 extern int slarfg_(integer *, real *, real *, integer *,
00066 real *);
00067 real safmax;
00068 extern int slahqr_(logical *, logical *, integer *,
00069 integer *, integer *, real *, integer *, real *, real *, integer *
00070 , integer *, real *, integer *, integer *), slacpy_(char *,
00071 integer *, integer *, real *, integer *, real *, integer *), slaset_(char *, integer *, integer *, real *, real *,
00072 real *, integer *);
00073 logical sorted;
00074 extern int strexc_(char *, integer *, real *, integer *,
00075 real *, integer *, integer *, integer *, real *, integer *), sormhr_(char *, char *, integer *, integer *, integer *,
00076 integer *, real *, integer *, real *, real *, integer *, real *,
00077 integer *, integer *);
00078 real smlnum;
00079 integer lwkopt;
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
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 h_dim1 = *ldh;
00248 h_offset = 1 + h_dim1;
00249 h__ -= h_offset;
00250 z_dim1 = *ldz;
00251 z_offset = 1 + z_dim1;
00252 z__ -= z_offset;
00253 --sr;
00254 --si;
00255 v_dim1 = *ldv;
00256 v_offset = 1 + v_dim1;
00257 v -= v_offset;
00258 t_dim1 = *ldt;
00259 t_offset = 1 + t_dim1;
00260 t -= t_offset;
00261 wv_dim1 = *ldwv;
00262 wv_offset = 1 + wv_dim1;
00263 wv -= wv_offset;
00264 --work;
00265
00266
00267
00268 i__1 = *nw, i__2 = *kbot - *ktop + 1;
00269 jw = min(i__1,i__2);
00270 if (jw <= 2) {
00271 lwkopt = 1;
00272 } else {
00273
00274
00275
00276 i__1 = jw - 1;
00277 sgehrd_(&jw, &c__1, &i__1, &t[t_offset], ldt, &work[1], &work[1], &
00278 c_n1, &info);
00279 lwk1 = (integer) work[1];
00280
00281
00282
00283 i__1 = jw - 1;
00284 sormhr_("R", "N", &jw, &jw, &c__1, &i__1, &t[t_offset], ldt, &work[1],
00285 &v[v_offset], ldv, &work[1], &c_n1, &info);
00286 lwk2 = (integer) work[1];
00287
00288
00289
00290 lwkopt = jw + max(lwk1,lwk2);
00291 }
00292
00293
00294
00295 if (*lwork == -1) {
00296 work[1] = (real) lwkopt;
00297 return 0;
00298 }
00299
00300
00301
00302 *ns = 0;
00303 *nd = 0;
00304 work[1] = 1.f;
00305 if (*ktop > *kbot) {
00306 return 0;
00307 }
00308
00309 if (*nw < 1) {
00310 return 0;
00311 }
00312
00313
00314
00315 safmin = slamch_("SAFE MINIMUM");
00316 safmax = 1.f / safmin;
00317 slabad_(&safmin, &safmax);
00318 ulp = slamch_("PRECISION");
00319 smlnum = safmin * ((real) (*n) / ulp);
00320
00321
00322
00323
00324 i__1 = *nw, i__2 = *kbot - *ktop + 1;
00325 jw = min(i__1,i__2);
00326 kwtop = *kbot - jw + 1;
00327 if (kwtop == *ktop) {
00328 s = 0.f;
00329 } else {
00330 s = h__[kwtop + (kwtop - 1) * h_dim1];
00331 }
00332
00333 if (*kbot == kwtop) {
00334
00335
00336
00337 sr[kwtop] = h__[kwtop + kwtop * h_dim1];
00338 si[kwtop] = 0.f;
00339 *ns = 1;
00340 *nd = 0;
00341
00342 r__2 = smlnum, r__3 = ulp * (r__1 = h__[kwtop + kwtop * h_dim1], dabs(
00343 r__1));
00344 if (dabs(s) <= dmax(r__2,r__3)) {
00345 *ns = 0;
00346 *nd = 1;
00347 if (kwtop > *ktop) {
00348 h__[kwtop + (kwtop - 1) * h_dim1] = 0.f;
00349 }
00350 }
00351 work[1] = 1.f;
00352 return 0;
00353 }
00354
00355
00356
00357
00358
00359
00360
00361 slacpy_("U", &jw, &jw, &h__[kwtop + kwtop * h_dim1], ldh, &t[t_offset],
00362 ldt);
00363 i__1 = jw - 1;
00364 i__2 = *ldh + 1;
00365 i__3 = *ldt + 1;
00366 scopy_(&i__1, &h__[kwtop + 1 + kwtop * h_dim1], &i__2, &t[t_dim1 + 2], &
00367 i__3);
00368
00369 slaset_("A", &jw, &jw, &c_b12, &c_b13, &v[v_offset], ldv);
00370 slahqr_(&c_true, &c_true, &jw, &c__1, &jw, &t[t_offset], ldt, &sr[kwtop],
00371 &si[kwtop], &c__1, &jw, &v[v_offset], ldv, &infqr);
00372
00373
00374
00375 i__1 = jw - 3;
00376 for (j = 1; j <= i__1; ++j) {
00377 t[j + 2 + j * t_dim1] = 0.f;
00378 t[j + 3 + j * t_dim1] = 0.f;
00379
00380 }
00381 if (jw > 2) {
00382 t[jw + (jw - 2) * t_dim1] = 0.f;
00383 }
00384
00385
00386
00387 *ns = jw;
00388 ilst = infqr + 1;
00389 L20:
00390 if (ilst <= *ns) {
00391 if (*ns == 1) {
00392 bulge = FALSE_;
00393 } else {
00394 bulge = t[*ns + (*ns - 1) * t_dim1] != 0.f;
00395 }
00396
00397
00398
00399 if (! bulge) {
00400
00401
00402
00403 foo = (r__1 = t[*ns + *ns * t_dim1], dabs(r__1));
00404 if (foo == 0.f) {
00405 foo = dabs(s);
00406 }
00407
00408 r__2 = smlnum, r__3 = ulp * foo;
00409 if ((r__1 = s * v[*ns * v_dim1 + 1], dabs(r__1)) <= dmax(r__2,
00410 r__3)) {
00411
00412
00413
00414 --(*ns);
00415 } else {
00416
00417
00418
00419
00420 ifst = *ns;
00421 strexc_("V", &jw, &t[t_offset], ldt, &v[v_offset], ldv, &ifst,
00422 &ilst, &work[1], &info);
00423 ++ilst;
00424 }
00425 } else {
00426
00427
00428
00429 foo = (r__3 = t[*ns + *ns * t_dim1], dabs(r__3)) + sqrt((r__1 = t[
00430 *ns + (*ns - 1) * t_dim1], dabs(r__1))) * sqrt((r__2 = t[*
00431 ns - 1 + *ns * t_dim1], dabs(r__2)));
00432 if (foo == 0.f) {
00433 foo = dabs(s);
00434 }
00435
00436 r__3 = (r__1 = s * v[*ns * v_dim1 + 1], dabs(r__1)), r__4 = (r__2
00437 = s * v[(*ns - 1) * v_dim1 + 1], dabs(r__2));
00438
00439 r__5 = smlnum, r__6 = ulp * foo;
00440 if (dmax(r__3,r__4) <= dmax(r__5,r__6)) {
00441
00442
00443
00444 *ns += -2;
00445 } else {
00446
00447
00448
00449
00450
00451 ifst = *ns;
00452 strexc_("V", &jw, &t[t_offset], ldt, &v[v_offset], ldv, &ifst,
00453 &ilst, &work[1], &info);
00454 ilst += 2;
00455 }
00456 }
00457
00458
00459
00460 goto L20;
00461 }
00462
00463
00464
00465 if (*ns == 0) {
00466 s = 0.f;
00467 }
00468
00469 if (*ns < jw) {
00470
00471
00472
00473
00474
00475 sorted = FALSE_;
00476 i__ = *ns + 1;
00477 L30:
00478 if (sorted) {
00479 goto L50;
00480 }
00481 sorted = TRUE_;
00482
00483 kend = i__ - 1;
00484 i__ = infqr + 1;
00485 if (i__ == *ns) {
00486 k = i__ + 1;
00487 } else if (t[i__ + 1 + i__ * t_dim1] == 0.f) {
00488 k = i__ + 1;
00489 } else {
00490 k = i__ + 2;
00491 }
00492 L40:
00493 if (k <= kend) {
00494 if (k == i__ + 1) {
00495 evi = (r__1 = t[i__ + i__ * t_dim1], dabs(r__1));
00496 } else {
00497 evi = (r__3 = t[i__ + i__ * t_dim1], dabs(r__3)) + sqrt((r__1
00498 = t[i__ + 1 + i__ * t_dim1], dabs(r__1))) * sqrt((
00499 r__2 = t[i__ + (i__ + 1) * t_dim1], dabs(r__2)));
00500 }
00501
00502 if (k == kend) {
00503 evk = (r__1 = t[k + k * t_dim1], dabs(r__1));
00504 } else if (t[k + 1 + k * t_dim1] == 0.f) {
00505 evk = (r__1 = t[k + k * t_dim1], dabs(r__1));
00506 } else {
00507 evk = (r__3 = t[k + k * t_dim1], dabs(r__3)) + sqrt((r__1 = t[
00508 k + 1 + k * t_dim1], dabs(r__1))) * sqrt((r__2 = t[k
00509 + (k + 1) * t_dim1], dabs(r__2)));
00510 }
00511
00512 if (evi >= evk) {
00513 i__ = k;
00514 } else {
00515 sorted = FALSE_;
00516 ifst = i__;
00517 ilst = k;
00518 strexc_("V", &jw, &t[t_offset], ldt, &v[v_offset], ldv, &ifst,
00519 &ilst, &work[1], &info);
00520 if (info == 0) {
00521 i__ = ilst;
00522 } else {
00523 i__ = k;
00524 }
00525 }
00526 if (i__ == kend) {
00527 k = i__ + 1;
00528 } else if (t[i__ + 1 + i__ * t_dim1] == 0.f) {
00529 k = i__ + 1;
00530 } else {
00531 k = i__ + 2;
00532 }
00533 goto L40;
00534 }
00535 goto L30;
00536 L50:
00537 ;
00538 }
00539
00540
00541
00542 i__ = jw;
00543 L60:
00544 if (i__ >= infqr + 1) {
00545 if (i__ == infqr + 1) {
00546 sr[kwtop + i__ - 1] = t[i__ + i__ * t_dim1];
00547 si[kwtop + i__ - 1] = 0.f;
00548 --i__;
00549 } else if (t[i__ + (i__ - 1) * t_dim1] == 0.f) {
00550 sr[kwtop + i__ - 1] = t[i__ + i__ * t_dim1];
00551 si[kwtop + i__ - 1] = 0.f;
00552 --i__;
00553 } else {
00554 aa = t[i__ - 1 + (i__ - 1) * t_dim1];
00555 cc = t[i__ + (i__ - 1) * t_dim1];
00556 bb = t[i__ - 1 + i__ * t_dim1];
00557 dd = t[i__ + i__ * t_dim1];
00558 slanv2_(&aa, &bb, &cc, &dd, &sr[kwtop + i__ - 2], &si[kwtop + i__
00559 - 2], &sr[kwtop + i__ - 1], &si[kwtop + i__ - 1], &cs, &
00560 sn);
00561 i__ += -2;
00562 }
00563 goto L60;
00564 }
00565
00566 if (*ns < jw || s == 0.f) {
00567 if (*ns > 1 && s != 0.f) {
00568
00569
00570
00571 scopy_(ns, &v[v_offset], ldv, &work[1], &c__1);
00572 beta = work[1];
00573 slarfg_(ns, &beta, &work[2], &c__1, &tau);
00574 work[1] = 1.f;
00575
00576 i__1 = jw - 2;
00577 i__2 = jw - 2;
00578 slaset_("L", &i__1, &i__2, &c_b12, &c_b12, &t[t_dim1 + 3], ldt);
00579
00580 slarf_("L", ns, &jw, &work[1], &c__1, &tau, &t[t_offset], ldt, &
00581 work[jw + 1]);
00582 slarf_("R", ns, ns, &work[1], &c__1, &tau, &t[t_offset], ldt, &
00583 work[jw + 1]);
00584 slarf_("R", &jw, ns, &work[1], &c__1, &tau, &v[v_offset], ldv, &
00585 work[jw + 1]);
00586
00587 i__1 = *lwork - jw;
00588 sgehrd_(&jw, &c__1, ns, &t[t_offset], ldt, &work[1], &work[jw + 1]
00589 , &i__1, &info);
00590 }
00591
00592
00593
00594 if (kwtop > 1) {
00595 h__[kwtop + (kwtop - 1) * h_dim1] = s * v[v_dim1 + 1];
00596 }
00597 slacpy_("U", &jw, &jw, &t[t_offset], ldt, &h__[kwtop + kwtop * h_dim1]
00598 , ldh);
00599 i__1 = jw - 1;
00600 i__2 = *ldt + 1;
00601 i__3 = *ldh + 1;
00602 scopy_(&i__1, &t[t_dim1 + 2], &i__2, &h__[kwtop + 1 + kwtop * h_dim1],
00603 &i__3);
00604
00605
00606
00607
00608 if (*ns > 1 && s != 0.f) {
00609 i__1 = *lwork - jw;
00610 sormhr_("R", "N", &jw, ns, &c__1, ns, &t[t_offset], ldt, &work[1],
00611 &v[v_offset], ldv, &work[jw + 1], &i__1, &info);
00612 }
00613
00614
00615
00616 if (*wantt) {
00617 ltop = 1;
00618 } else {
00619 ltop = *ktop;
00620 }
00621 i__1 = kwtop - 1;
00622 i__2 = *nv;
00623 for (krow = ltop; i__2 < 0 ? krow >= i__1 : krow <= i__1; krow +=
00624 i__2) {
00625
00626 i__3 = *nv, i__4 = kwtop - krow;
00627 kln = min(i__3,i__4);
00628 sgemm_("N", "N", &kln, &jw, &jw, &c_b13, &h__[krow + kwtop *
00629 h_dim1], ldh, &v[v_offset], ldv, &c_b12, &wv[wv_offset],
00630 ldwv);
00631 slacpy_("A", &kln, &jw, &wv[wv_offset], ldwv, &h__[krow + kwtop *
00632 h_dim1], ldh);
00633
00634 }
00635
00636
00637
00638 if (*wantt) {
00639 i__2 = *n;
00640 i__1 = *nh;
00641 for (kcol = *kbot + 1; i__1 < 0 ? kcol >= i__2 : kcol <= i__2;
00642 kcol += i__1) {
00643
00644 i__3 = *nh, i__4 = *n - kcol + 1;
00645 kln = min(i__3,i__4);
00646 sgemm_("C", "N", &jw, &kln, &jw, &c_b13, &v[v_offset], ldv, &
00647 h__[kwtop + kcol * h_dim1], ldh, &c_b12, &t[t_offset],
00648 ldt);
00649 slacpy_("A", &jw, &kln, &t[t_offset], ldt, &h__[kwtop + kcol *
00650 h_dim1], ldh);
00651
00652 }
00653 }
00654
00655
00656
00657 if (*wantz) {
00658 i__1 = *ihiz;
00659 i__2 = *nv;
00660 for (krow = *iloz; i__2 < 0 ? krow >= i__1 : krow <= i__1; krow +=
00661 i__2) {
00662
00663 i__3 = *nv, i__4 = *ihiz - krow + 1;
00664 kln = min(i__3,i__4);
00665 sgemm_("N", "N", &kln, &jw, &jw, &c_b13, &z__[krow + kwtop *
00666 z_dim1], ldz, &v[v_offset], ldv, &c_b12, &wv[
00667 wv_offset], ldwv);
00668 slacpy_("A", &kln, &jw, &wv[wv_offset], ldwv, &z__[krow +
00669 kwtop * z_dim1], ldz);
00670
00671 }
00672 }
00673 }
00674
00675
00676
00677 *nd = jw - *ns;
00678
00679
00680
00681
00682
00683
00684
00685 *ns -= infqr;
00686
00687
00688
00689 work[1] = (real) lwkopt;
00690
00691
00692
00693 return 0;
00694 }